index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. <template>
  2. <view class="register-form-container">
  3. <u--form
  4. labelPosition="left"
  5. :model="model1"
  6. :rules="rules"
  7. ref="uForm"
  8. @submit="onSubmit"
  9. >
  10. <u-form-item
  11. label="姓名"
  12. v-if="rules['userInfo.usrName']"
  13. prop="userInfo.usrName"
  14. borderBottom
  15. :class="{
  16. 'require': rules['userInfo.usrName'].required
  17. }"
  18. >
  19. <u--input
  20. placeholder="输入姓名"
  21. v-model="model1.userInfo.usrName"
  22. border="none"
  23. ></u--input>
  24. </u-form-item>
  25. <u-form-item
  26. label="单位名称"
  27. prop="userInfo.orgUnitName"
  28. v-if="rules['userInfo.orgUnitName']"
  29. borderBottom
  30. :class="{
  31. 'require': rules['userInfo.orgUnitName'].required
  32. }"
  33. >
  34. <u--input
  35. placeholder="输入单位名称"
  36. v-model="model1.userInfo.orgUnitName"
  37. border="none"
  38. ></u--input>
  39. </u-form-item>
  40. <u-form-item
  41. label="职务"
  42. prop="userInfo.uniLevel"
  43. v-if="rules['userInfo.uniLevel']"
  44. borderBottom
  45. :class="{
  46. 'require': rules['userInfo.uniLevel'].required
  47. }"
  48. >
  49. <u--input
  50. placeholder="输入职务"
  51. v-model="model1.userInfo.uniLevel"
  52. border="none"
  53. ></u--input>
  54. </u-form-item>
  55. <u-form-item
  56. label="联系电话"
  57. prop="userInfo.tel"
  58. borderBottom
  59. v-if="rules['userInfo.tel']"
  60. :class="{
  61. 'require': rules['userInfo.tel'].required
  62. }"
  63. >
  64. <u--input
  65. placeholder="输入联系电话"
  66. border="none"
  67. type="number"
  68. maxlength="11"
  69. v-model="model1.userInfo.tel"
  70. ></u--input>
  71. </u-form-item>
  72. <u-form-item
  73. label="邮箱"
  74. prop="userInfo.email"
  75. borderBottom
  76. v-if="rules['userInfo.email']"
  77. :class="{
  78. 'require': rules['userInfo.email'].required
  79. }"
  80. >
  81. <u--input
  82. placeholder="输入邮箱"
  83. border="none"
  84. v-model="model1.userInfo.email"
  85. ></u--input>
  86. </u-form-item>
  87. <u-form-item
  88. label="人员类型"
  89. prop="userInfo.usrType"
  90. borderBottom
  91. v-if="rules['userInfo.usrType']"
  92. :class="{
  93. 'require': rules['userInfo.usrType'].required
  94. }"
  95. >
  96. <u-radio-group
  97. v-model="model1.userInfo.usrType"
  98. placement="row"
  99. @change="usrTypeChange"
  100. >
  101. <u-radio
  102. :style="{
  103. marginRight: '20rpx'
  104. }"
  105. v-for="(item, index) in USR_TYPE_LIST"
  106. :key="index"
  107. :label="item.name"
  108. :name="item.value"
  109. >
  110. </u-radio>
  111. </u-radio-group>
  112. </u-form-item>
  113. <u-form-item
  114. label="是否参加现场调研"
  115. prop="userInfo.conferenceFlag"
  116. borderBottom
  117. v-if="rules['userInfo.conferenceFlag']&& model1.userInfo.usrType === USR_TYPE['1'].value"
  118. :class="{
  119. 'require': rules['userInfo.conferenceFlag'].required
  120. }"
  121. >
  122. <u-radio-group
  123. v-model="model1.userInfo.conferenceFlag"
  124. placement="row"
  125. >
  126. <u-radio
  127. :style="{
  128. marginRight: '20rpx'
  129. }"
  130. label="是"
  131. name="0"
  132. >
  133. </u-radio>
  134. <u-radio
  135. :style="{
  136. marginRight: '20rpx'
  137. }"
  138. label="否"
  139. name="1"
  140. >
  141. </u-radio>
  142. </u-radio-group>
  143. </u-form-item>
  144. <u-form-item
  145. label="调研会场"
  146. prop="userInfo.contentId"
  147. borderBottom
  148. :class="{
  149. 'require': rules['userInfo.contentId'].required
  150. }"
  151. v-if="rules['userInfo.contentId'] && false"
  152. >
  153. <SingleDropList
  154. :style="{
  155. marginLeft: '20rpx'
  156. }"
  157. :defaultValue="model1.userInfo.contentId"
  158. :src="conferenceHall"
  159. placeholder="请选择会场"
  160. @onChange="conferenceSelect"
  161. >
  162. </SingleDropList>
  163. </u-form-item>
  164. <u-form-item
  165. label="是否参加主题研讨"
  166. prop="userInfo.themeFlag"
  167. borderBottom
  168. v-if="rules['userInfo.themeFlag']"
  169. :class="{
  170. 'require': rules['userInfo.themeFlag'].required
  171. }"
  172. >
  173. <u-radio-group
  174. v-model="model1.userInfo.themeFlag"
  175. placement="row"
  176. >
  177. <u-radio
  178. :style="{
  179. marginRight: '20rpx'
  180. }"
  181. label="是"
  182. name="0"
  183. >
  184. </u-radio>
  185. <u-radio
  186. :style="{
  187. marginRight: '20rpx'
  188. }"
  189. label="否"
  190. name="1"
  191. >
  192. </u-radio>
  193. </u-radio-group>
  194. </u-form-item>
  195. <u-form-item
  196. label="研讨主题"
  197. prop="userInfo.themeId"
  198. borderBottom
  199. :class="{
  200. 'require': rules['userInfo.themeId'].required
  201. }"
  202. v-if="rules['userInfo.themeId'] && model1.userInfo.themeFlag === '0' && model1.userInfo.usrType === USR_TYPE['2'].value"
  203. >
  204. <SingleDropList
  205. :style="{
  206. marginLeft: '20rpx'
  207. }"
  208. :defaultValue="model1.userInfo.themeId"
  209. :src="themes"
  210. placeholder="请选择主题"
  211. @onChange="themesSelect"
  212. >
  213. </SingleDropList>
  214. </u-form-item>
  215. <u-form-item
  216. label="来程交通方式"
  217. prop="userInfo.wayComing"
  218. borderBottom
  219. v-if="rules['userInfo.wayComing']"
  220. :class="{
  221. 'require': rules['userInfo.wayComing'].required
  222. }"
  223. >
  224. <u-radio-group
  225. v-model="model1.userInfo.wayComing"
  226. placement="row"
  227. @change="waycomChange"
  228. >
  229. <u-radio
  230. v-for="way in tfcDic"
  231. :key="way.value"
  232. :style="{
  233. marginRight: '20rpx'
  234. }"
  235. :label="way.name"
  236. :name="way.value"
  237. >
  238. </u-radio>
  239. </u-radio-group>
  240. </u-form-item>
  241. <u-form-item
  242. :label="comLabel"
  243. prop="userInfo.comInfo"
  244. borderBottom
  245. v-if="rules['userInfo.comInfo']&& model1.userInfo.wayComing!=TFC_TYPE['3'].value"
  246. :class="{
  247. 'require': rules['userInfo.comInfo'].required
  248. }"
  249. >
  250. <u--input
  251. :placeholder="`输入${comLabel}`"
  252. border="none"
  253. v-model="model1.userInfo.comInfo"
  254. ></u--input>
  255. </u-form-item>
  256. <u-form-item
  257. label="返程交通方式"
  258. prop="userInfo.wayBack"
  259. borderBottom
  260. v-if="rules['userInfo.wayBack']"
  261. :class="{
  262. 'require': rules['userInfo.wayBack'].required
  263. }"
  264. >
  265. <u-radio-group
  266. v-model="model1.userInfo.wayBack"
  267. placement="row"
  268. @change="wayBackChange"
  269. >
  270. <u-radio
  271. v-for="way in tfcDic"
  272. :key="way.value"
  273. :style="{
  274. marginRight: '20rpx'
  275. }"
  276. :label="way.name"
  277. :name="way.value"
  278. >
  279. </u-radio>
  280. </u-radio-group>
  281. </u-form-item>
  282. <u-form-item
  283. :label="backLabel"
  284. prop="userInfo.backInfo"
  285. borderBottom
  286. v-if="rules['userInfo.backInfo'] && model1.userInfo.wayBack!=TFC_TYPE['3'].value"
  287. :class="{
  288. 'require': rules['userInfo.backInfo'].required
  289. }"
  290. >
  291. <u--input
  292. :placeholder="`输入${backLabel}`"
  293. border="none"
  294. v-model="model1.userInfo.backInfo"
  295. ></u--input>
  296. </u-form-item>
  297. <u-form-item
  298. label="备注"
  299. prop="userInfo.remark"
  300. borderBottom
  301. ref="item3"
  302. >
  303. <u--textarea
  304. placeholder="请输入备注"
  305. v-model="model1.userInfo.remark"
  306. ></u--textarea>
  307. </u-form-item>
  308. <u-form-item
  309. label="随行人员名单"
  310. >
  311. <u-icon name="plus-circle-fill" color="#2979ff" size="28" @click="addFollower" style="margin-left: auto">新增
  312. </u-icon>
  313. </u-form-item>
  314. <view>
  315. <u-form-item
  316. prop="userInfo.follows"
  317. class="follower-item"
  318. >
  319. <view v-for="(item, index) in model1.userInfo.follows"
  320. :key="index"
  321. >
  322. <view style="display: flex;align-items: center;justify-content: flex-start;">
  323. {{ `随行人员${index + 1}` }}
  324. <u-icon name="minus-circle-fill" color="red" size="28" @click="()=>minusFollower(index)"
  325. style="margin-left: auto">
  326. </u-icon>
  327. </view>
  328. <u-form-item
  329. label="姓名"
  330. prop="item.usrName"
  331. class="require"
  332. >
  333. <u--input
  334. placeholder="输入姓名"
  335. v-model="item.usrName"
  336. @change="followsValidate"
  337. @blur="followsValidate"
  338. border="none"
  339. ></u--input>
  340. </u-form-item>
  341. <view
  342. v-if="followErrors[index] && followErrors[index].usrName"
  343. style="font-size: 12px;line-height: 12px;color: #f56c6c;">
  344. 请填写姓名
  345. </view>
  346. <u-form-item
  347. label="单位职务"
  348. prop="item.usrLevel"
  349. class="require"
  350. >
  351. <u--input
  352. placeholder="输入单位职务"
  353. @change="followsValidate"
  354. @blur="followsValidate"
  355. v-model="item.usrLevel"
  356. border="none"
  357. ></u--input>
  358. </u-form-item>
  359. <view
  360. v-if="followErrors[index] && followErrors[index].usrLevel"
  361. style="font-size: 12px;line-height: 12px;color: #f56c6c;">请填写单位职务
  362. </view>
  363. <u-form-item
  364. label="联系电话"
  365. prop="item.tel"
  366. border="none"
  367. class="require"
  368. >
  369. <u--input
  370. placeholder="输入联系电话"
  371. border="none"
  372. type="number"
  373. maxlength="11"
  374. @change="followsValidate"
  375. @blur="followsValidate"
  376. v-model="item.tel"
  377. ></u--input>
  378. </u-form-item>
  379. <view
  380. v-if="followErrors[index] && followErrors[index].tel"
  381. style="font-size: 12px;line-height: 12px;color: #f56c6c;">请填写正确的手机号
  382. </view>
  383. <u-line margin="20rpx 0" color="#d6d7d9"></u-line>
  384. </view>
  385. </u-form-item>
  386. <view
  387. style="color: #fb0000c7;margin-top: 10rpx;font-size: 24rpx"
  388. >
  389. * 温馨提示:请同步填写随行人员信息。
  390. </view>
  391. </view>
  392. </u--form>
  393. <slot name="footer"></slot>
  394. <u-button
  395. type="primary"
  396. text="提交"
  397. style="margin-top: 20px;"
  398. :disabled="loading"
  399. :loading="loading"
  400. loadingText="正在提交..."
  401. @click="onSubmit"
  402. >
  403. </u-button>
  404. </view>
  405. </template>
  406. <script>
  407. import { fetchContentInfo, getDicts } from '@/common/api';
  408. import { CONTENT_TYPE, FORM_MOD, TFC_INFO, TFC_TYPE, USR_TYPE, USR_TYPE_LIST } from '@/common/EnumConst';
  409. import SingleDropList from '@/components/SingleDropList/index.vue';
  410. import { getImageUrl, getUserInfo } from '@/util';
  411. export default {
  412. computed: {
  413. USR_TYPE() {
  414. return USR_TYPE;
  415. },
  416. TFC_TYPE() {
  417. return TFC_TYPE;
  418. },
  419. },
  420. components: {
  421. SingleDropList,
  422. },
  423. props: {
  424. rules: {},
  425. onSubmitHandle: {
  426. type: Function,
  427. default: function () {},
  428. },
  429. mode: {
  430. type: String,
  431. default: 'add',
  432. },
  433. registInfo: {
  434. type: Object,
  435. default: function () {
  436. return {};
  437. },
  438. },
  439. },
  440. watch: {
  441. registInfo: {
  442. handler(newVal) {
  443. if (newVal) {
  444. this.model1.userInfo = newVal;
  445. }
  446. },
  447. immediate: true,
  448. },
  449. },
  450. data() {
  451. return {
  452. USR_TYPE_LIST,
  453. loading: false,
  454. comLabel: '',
  455. tfcDic: [],
  456. backLabel: '',
  457. followErrors: {},
  458. model1: {
  459. userInfo: {
  460. usrName: '',
  461. conferenceFlag: '0',
  462. usrType: '1',
  463. follows: [],
  464. },
  465. },
  466. conferenceHall: [],
  467. themes: [],
  468. };
  469. },
  470. created() {
  471. this.initUser();
  472. },
  473. onLoad() {
  474. },
  475. onReady() {
  476. this.setFormRules();
  477. },
  478. methods: {
  479. followsValidate(index) {
  480. debugger
  481. this.$refs.uForm.validateField('userInfo.follows');
  482. },
  483. initUser() {
  484. const user = getUserInfo();
  485. if (user) {
  486. this.model1.userInfo.tel = user.tel;
  487. }
  488. this.init();
  489. },
  490. setFormRules() {
  491. const that = this;
  492. //如果需要兼容微信小程序,并且校验规则中含有方法等,只能通过setRules方法设置规则。
  493. const rules = {
  494. 'userInfo.follows': [
  495. {
  496. // 自定义验证函数,见上说明
  497. validator: (rule, value, callback) => {
  498. debugger
  499. const followMsg = {};
  500. value.forEach((item, index) => {
  501. const msgs = {};
  502. if (!item.usrName) {
  503. msgs.usrName = '姓名不能为空';
  504. }
  505. if (!uni.$u.test.mobile(item.tel)) {
  506. msgs.tel = '手机号码不正确';
  507. }
  508. if (!item.usrLevel) {
  509. msgs.usrLevel = '单位职务不能为空';
  510. }
  511. if (Object.keys(msgs).length > 0) {
  512. followMsg[index] = msgs;
  513. }
  514. });
  515. that.followErrors = followMsg;
  516. return Object.keys(followMsg).length < 1;
  517. },
  518. message: ' ',
  519. // 触发器可以同时用blur和change
  520. trigger: ['change', 'blur'],
  521. },
  522. ],
  523. ...this.rules,
  524. };
  525. this.$refs.uForm.setRules(rules);
  526. },
  527. getImageUrl,
  528. addFollower() {
  529. this.model1.userInfo.follows.push({
  530. usrName: '',
  531. tel: '',
  532. });
  533. },
  534. minusFollower(index) {
  535. this.removeItemAtIndex(this.model1.userInfo.follows, index);
  536. },
  537. removeItemAtIndex(array, index) {
  538. array.splice(index, 1);
  539. },
  540. conferenceSelect(item) {
  541. this.model1.userInfo.contentId = item.value;
  542. this.$refs.uForm.clearValidate('userInfo.contentId');
  543. },
  544. themesSelect(item) {
  545. this.model1.userInfo.themeId = item.value;
  546. this.$refs.uForm.clearValidate('userInfo.themeId');
  547. },
  548. validateUsername(rule, value, callback) {
  549. console.log(value);
  550. // 自定义验证规则,例如用户名必须包含"uview"
  551. if (value.indexOf('uview') === -1) {
  552. // 验证不通过,调用callback并传入错误信息
  553. callback(new Error('用户名必须包含"uview"'));
  554. } else {
  555. // 验证通过,调用callback并不传入参数或者传入null
  556. callback();
  557. }
  558. },
  559. async init() {
  560. const {
  561. code: conferenceCode,
  562. rows: conferenceData,
  563. } = await fetchContentInfo({
  564. pageNum: 1,
  565. pageSize: 99,
  566. contentType: CONTENT_TYPE.conference,
  567. title: this.keyword,
  568. });
  569. this.conferenceHall = conferenceData.map(item => {
  570. return {
  571. name: item.title,
  572. value: item.id,
  573. };
  574. });
  575. const {
  576. code: themedCode,
  577. rows: themeData,
  578. } = await fetchContentInfo({
  579. pageNum: 1,
  580. pageSize: 99,
  581. contentType: CONTENT_TYPE.theme,
  582. });
  583. this.themes = themeData.map(item => {
  584. return {
  585. name: item.title,
  586. value: item.id,
  587. };
  588. });
  589. const {
  590. code,
  591. data,
  592. } = await getDicts('tfc_type');
  593. if (data) {
  594. this.tfcDic = data.map(item => {
  595. return {
  596. name: item.dictLabel,
  597. value: item.dictValue,
  598. };
  599. });
  600. if (this.mode !== FORM_MOD.modify) {
  601. this.model1.userInfo.wayComing = data[0].dictValue;
  602. this.model1.userInfo.wayBack = data[0].dictValue;
  603. this.waycomChange(data[0].dictValue);
  604. this.wayBackChange(data[0].dictValue);
  605. }
  606. }
  607. },
  608. onSubmit() {
  609. this.loading = true;
  610. this.$refs.uForm.validate().then((res) => {
  611. this.$emit('onSubmitHandle', this.model1.userInfo);
  612. this.loading = false;
  613. }).catch(errors => {
  614. console.error(errors);
  615. this.loading = false;
  616. });
  617. },
  618. hideKeyboard() {
  619. uni.hideKeyboard();
  620. },
  621. waycomChange(e) {
  622. this.comLabel = TFC_INFO[e].name;
  623. if (e == 3) {
  624. this.model1.userInfo.comInfo = '无';
  625. }
  626. },
  627. wayBackChange(e) {
  628. this.backLabel = TFC_INFO[e].name;
  629. if (e == 3) {
  630. this.model1.userInfo.backInfo = '无';
  631. }
  632. },
  633. restForm() {
  634. this.model1 = {
  635. userInfo: {
  636. usrName: '',
  637. conferenceFlag: '0',
  638. usrType: '1',
  639. follows: [],
  640. },
  641. };
  642. const user = getUserInfo();
  643. if (user) {
  644. this.model1.userInfo.usrName = user.usrName;
  645. this.model1.userInfo.tel = user.tel;
  646. }
  647. },
  648. clearValidate() {
  649. this.$refs.uForm.clearValidate();
  650. },
  651. usrTypeChange(val) {
  652. if (val === '2') {
  653. this.model1.userInfo.conferenceFlag = '3';
  654. return;
  655. }
  656. this.model1.userInfo.conferenceFlag = '0';
  657. this.$refs.uForm.setRules(this.rules);
  658. },
  659. },
  660. };
  661. </script>