index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. <template>
  2. <view class="container main">
  3. <view class="one">
  4. <view class="register" v-if="!user.id">
  5. <uni-forms ref="baseForm" :rules="rules" :modelValue="form" label-width="80px">
  6. <uni-forms-item label="账号" required name="account">
  7. <uni-easyinput v-model="form.account" placeholder="请输入账号" />
  8. </uni-forms-item>
  9. <uni-forms-item label="密码" required name="password">
  10. <uni-easyinput type="password" v-model="form.password" placeholder="请输入密码" />
  11. </uni-forms-item>
  12. <uni-forms-item label="确认密码" required name="ispassword">
  13. <uni-easyinput type="password" v-model="form.ispassword" placeholder="请输入确认密码" />
  14. </uni-forms-item>
  15. <uni-forms-item label="手机号" required name="phone">
  16. <uni-easyinput v-model="form.phone" placeholder="请输入手机号" />
  17. </uni-forms-item>
  18. <uni-forms-item label="电子邮箱">
  19. <uni-easyinput v-model="form.email" placeholder="请输入电子邮箱" />
  20. </uni-forms-item>
  21. </uni-forms>
  22. </view>
  23. <view class="list" v-for="(item, index) in investigate" :key="index">
  24. <div class="problem">
  25. <text v-if="item.is_must=='0'" class="t-icon t-icon-xinghao"></text>
  26. <span v-if="item.is_must=='0'">{{item.problem}}</span>
  27. <span style="margin: 0 0 0 2vw;" v-else>{{item.problem}}</span>
  28. </div>
  29. <div class="type" v-if="item.type =='0'">
  30. <div class="remark" v-if="item.remark">{{item.remark}}</div>
  31. <uni-data-checkbox v-model="item.reply" :localdata="item.answer"
  32. :map="{text:'text',value:'text'}" />
  33. </div>
  34. <div class="type" v-if="item.type =='1'">
  35. <div class="remark" v-if="item.remark">{{item.remark}}</div>
  36. <uni-data-checkbox v-model="item.reply" multiple :localdata="item.answer"
  37. :map="{text:'text',value:'text'}" />
  38. </div>
  39. <div class="type" v-if="item.type =='2'">
  40. <div class="remark" v-if="item.remark">{{item.remark}}</div>
  41. <uni-data-select v-model="item.reply" :localdata="item.answer"></uni-data-select>
  42. </div>
  43. <div class="type" v-if="item.type =='3'">
  44. <div class="remark" v-if="item.remark">{{item.remark}}</div>
  45. <uni-easyinput v-model="item.reply" type="number" :placeholder="getField(item.problem)"></uni-easyinput>
  46. </div>
  47. <div class="type" v-if="item.type =='4'">
  48. <div class="remark" v-if="item.remark">{{item.remark}}</div>
  49. <uni-easyinput v-model="item.reply" :placeholder="getField(item.problem)"></uni-easyinput>
  50. </div>
  51. <div class="type" v-if="item.type =='5'">
  52. <div class="remark" v-if="item.remark">{{item.remark}}</div>
  53. <uni-easyinput type="textarea" v-model="item.reply"
  54. :placeholder="getField(item.problem)"></uni-easyinput>
  55. </div>
  56. <div class="type" v-if="item.type =='6'">
  57. <div class="remark" v-if="item.remark">{{item.remark}}</div>
  58. <upload class='upload' :list="item.reply" name="reply" :count="1" @uplSuc="uplSuc($event,item)"
  59. @uplDel="uplDel($event,item)">
  60. </upload>
  61. </div>
  62. <div class="type" v-if="item.type =='7'">
  63. <div class="list">
  64. <div v-for="(aa, ina) in item.answer" :key="ina" class="name">{{aa.text}}</div>
  65. </div>
  66. <div class="list" v-for="(gg, inx) in item.reply" :key="inx">
  67. <div v-for="(aa, ina) in item.answer" :key="ina" class="input">
  68. <uni-easyinput v-model="gg[aa.text]" :clearable="false"
  69. :placeholder="getField(aa.text)"></uni-easyinput>
  70. </div>
  71. <uni-icons @tap="toDel(item,gg.sid)" class="icon" type="closeempty" size="20"></uni-icons>
  72. </div>
  73. <div class="add" @tap="toAdd(item)">+新增一行</div>
  74. </div>
  75. <div class="type" v-if="item.type =='8'">
  76. <image class="image" v-if="item.answer&&item.answer.length>0" v-for="(as, img) in item.answer"
  77. :key="img" :src="getUrl(as.url)"></image>
  78. <div class="remark" v-if="item.remark">{{item.remark}}</div>
  79. </div>
  80. </view>
  81. <view class="button">
  82. <button type="warn" @tap="toSave">保存</button>
  83. </view>
  84. </view>
  85. </view>
  86. </template>
  87. <script>
  88. import upload from '../../components/upload/index.vue';
  89. import moment from 'moment';
  90. export default {
  91. components: {
  92. upload
  93. },
  94. data() {
  95. return {
  96. openid: "",
  97. id: '',
  98. user: {},
  99. info: {},
  100. investigate: [],
  101. form: {
  102. gender: '0',
  103. account: '',
  104. password: '',
  105. ispassword: '',
  106. email: '',
  107. role: ['User']
  108. },
  109. // 校验规则
  110. rules: {
  111. account: {
  112. rules: [{
  113. required: true,
  114. errorMessage: '账号不能为空'
  115. }]
  116. },
  117. password: {
  118. rules: [{
  119. required: true,
  120. errorMessage: '密码不能为空'
  121. }, {
  122. validateFunction: function(rule, value, data, callback) {
  123. const reg =
  124. /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[._~!@#$^&*])[A-Za-z0-9._~!@#$^&*]{8,16}$/g
  125. if (!reg.test(value)) {
  126. callback('请输入包含英文字母大小写、数字和特殊符号的 8-16 位组合')
  127. }
  128. return true
  129. }
  130. }]
  131. },
  132. ispassword: {
  133. rules: [{
  134. required: true,
  135. errorMessage: '确认密码不能为空'
  136. },
  137. {
  138. validateFunction: function(rule, value, data, callback) {
  139. if (value != data.password) {
  140. callback('两次输入的密码必须相同')
  141. }
  142. return true
  143. }
  144. }
  145. ]
  146. },
  147. phone: {
  148. rules: [{
  149. required: true,
  150. errorMessage: '手机号不能为空'
  151. }, {
  152. validateFunction: function(rule, value, data, callback) {
  153. const reg = /^1[3-9]\d{9}$/
  154. if (!reg.test(value)) {
  155. callback('请输入正确的手机号')
  156. }
  157. return true
  158. }
  159. }]
  160. },
  161. },
  162. }
  163. },
  164. onLoad: async function(e) {
  165. const that = this;
  166. that.$set(that, `id`, e && e.id || '');
  167. await that.searchOpenids();
  168. await that.searchToken();
  169. await that.search();
  170. },
  171. onReady() {
  172. // 需要在onReady中设置规则
  173. this.$refs.baseForm.setRules(this.rules)
  174. },
  175. methods: {
  176. async searchOpenids() {
  177. const that = this;
  178. uni.getStorage({
  179. key: 'openid',
  180. success: function(res) {
  181. that.$set(that, `openid`, res.data);
  182. },
  183. fail: function(err) {
  184. uni.login({
  185. success: async function(res) {
  186. if (res.code) {
  187. const aee = await that.$app('/wechat/api/login/app',
  188. 'GET', {
  189. js_code: res.code,
  190. config: that.$config.wx_projectkey
  191. })
  192. if (aee.errcode == '0') {
  193. uni.setStorage({
  194. key: "openid",
  195. data: aee.data.openid
  196. })
  197. that.$set(that, `openid`, aee.data.openid);
  198. } else {
  199. uni.showToast({
  200. title: aee.errmsg,
  201. icon: 'none'
  202. })
  203. }
  204. } else {
  205. uni.showToast({
  206. title: res.errMsg,
  207. icon: 'none'
  208. })
  209. }
  210. }
  211. });
  212. }
  213. })
  214. },
  215. // 用户信息
  216. searchToken() {
  217. const that = this;
  218. try {
  219. const res = uni.getStorageSync('token');
  220. if (res) {
  221. const user = that.$jwt(res);
  222. that.$set(that, `user`, user);
  223. }
  224. } catch (e) {}
  225. },
  226. // 查询
  227. async search() {
  228. const that = this;
  229. if (that.id) {
  230. let res;
  231. res = await that.$api(`/match/${that.id}`, 'GET', {})
  232. if (res.errcode == '0') {
  233. that.$set(that, `info`, res.data)
  234. if (res.data.ext_info && res.data.ext_info.length > 0) {
  235. for (let val of res.data.ext_info) {
  236. if (val.type == '2') {
  237. for (let s of val.answer) {
  238. s.value = s.text
  239. }
  240. }
  241. }
  242. that.$set(that, `investigate`, res.data.ext_info)
  243. }
  244. } else {
  245. uni.showToast({
  246. title: res.errmsg,
  247. icon: 'none'
  248. });
  249. }
  250. }
  251. },
  252. getField(data) {
  253. let res = "请输入内容"
  254. if (data) res = `请输入${data}`
  255. return res
  256. },
  257. // 图片处理
  258. getUrl(e) {
  259. const that = this;
  260. if (e) return that.$config.serverFile + e
  261. },
  262. // 图片上传
  263. uplSuc(e, item) {
  264. const that = this;
  265. for (let val of that.investigate) {
  266. if (val.sid == item.sid) val.reply = [e.data]
  267. }
  268. },
  269. // 图片删除
  270. uplDel(e, item) {
  271. const that = this;
  272. for (let val of that.investigate) {
  273. if (val.sid == item.sid) val.reply = []
  274. }
  275. },
  276. // 新增一行
  277. toAdd(item) {
  278. const that = this;
  279. for (let val of that.investigate) {
  280. if (val.sid == item.sid) {
  281. let answer = []
  282. let obj = {
  283. sid: moment().valueOf(),
  284. }
  285. for (let s of val.answer) {
  286. obj[s.text] = '';
  287. }
  288. answer.push(obj)
  289. if (val.reply) val.reply = [...val.reply, ...answer, ]
  290. else val.reply = answer
  291. }
  292. }
  293. },
  294. // 删除一行
  295. toDel(item, sid) {
  296. const that = this;
  297. if (item && item.reply && item.reply.length > 0) {
  298. let answer = item.reply.filter((i) => i.sid != sid)
  299. for (let val of that.investigate) {
  300. if (val.sid == item.sid) {
  301. val.reply = answer
  302. }
  303. }
  304. }
  305. },
  306. async toSave() {
  307. const that = this;
  308. let data = {
  309. match_id: that.info.id,
  310. info: that.investigate
  311. }
  312. if (that.user.id) {
  313. data.user_id = that.user.id
  314. const res = await that.$api(`/matchReg`, 'POST', data)
  315. if (res.errcode == '0') {
  316. uni.showModal({
  317. content: "调查问卷填写成功!",
  318. showCancel: false
  319. });
  320. uni.navigateBack({
  321. delta: 1
  322. })
  323. } else {
  324. uni.showToast({
  325. title: res.errmsg,
  326. icon: 'none'
  327. });
  328. }
  329. } else {
  330. that.$refs.baseForm.validate().then(async ass => {
  331. if (ass.password == ass.ispassword) {
  332. ass.openid = that.openid
  333. data.user = {
  334. nick_name: ass.account,
  335. ...that.form,
  336. ...ass
  337. }
  338. const res = await that.$api(`/matchReg`, 'POST', data)
  339. if (res.errcode == '0') {
  340. uni.showModal({
  341. content: "调查问卷填写成功!",
  342. showCancel: false
  343. });
  344. uni.navigateBack({
  345. delta: 1
  346. })
  347. } else {
  348. uni.showToast({
  349. title: res.errmsg,
  350. icon: 'none'
  351. });
  352. }
  353. } else {
  354. uni.showToast({
  355. title: `密码不一致`,
  356. icon: 'error'
  357. });
  358. return;
  359. }
  360. }).catch(err => {
  361. console.log('err', err);
  362. return;
  363. })
  364. }
  365. console.log(data, user);
  366. },
  367. }
  368. }
  369. </script>
  370. <style lang="scss" scoped>
  371. .main {
  372. .one {
  373. padding: 2vw;
  374. .list {
  375. .problem {
  376. display: flex;
  377. align-items: center;
  378. .t-icon {
  379. width: 30px !important;
  380. height: 30px !important;
  381. }
  382. }
  383. .type {
  384. padding: 2vw 0 2vw 2vw;
  385. .list {
  386. display: flex;
  387. align-items: center;
  388. justify-content: center;
  389. margin: 2vw 0;
  390. .name {
  391. width: 50%;
  392. text-align: center;
  393. }
  394. .input {
  395. margin: 0 1vw 0 0;
  396. .name {
  397. width: 50%;
  398. text-align: center;
  399. margin: 0 0 2vw 0;
  400. }
  401. }
  402. .icon {
  403. display: none;
  404. margin: 1vw 0 0 0;
  405. }
  406. }
  407. .list:hover {
  408. .icon {
  409. display: block;
  410. }
  411. }
  412. .add {
  413. border: 1px solid #e5e5e5;
  414. border-radius: 5px;
  415. text-align: center;
  416. padding: 2vw;
  417. }
  418. .image {
  419. width: 96%;
  420. }
  421. .remark {
  422. margin: 2vw;
  423. font-size: 12px;
  424. color: red;
  425. }
  426. }
  427. }
  428. .button {
  429. margin: 2vw 0 0 0;
  430. padding: 2vw;
  431. text-align: center;
  432. button {
  433. background-color: var(--f3CColor);
  434. font-size: var(--font14Size);
  435. border-radius: 2vw;
  436. }
  437. }
  438. }
  439. }
  440. </style>