diyform.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. <template>
  2. <view>
  3. <!-- 顶部导航 -->
  4. <fa-navbar :title="diyform.title"></fa-navbar>
  5. <view class="u-p-30" v-if="showForm">
  6. <u-form :model="form" :rules="rules" ref="uForm" :errorType="errorType">
  7. <!-- 自定义字段 -->
  8. <block v-for="(item, index) in fields" :key="index">
  9. <!-- 字符 -->
  10. <u-form-item
  11. :label-position="labelPosition"
  12. label-width="130"
  13. :prop="item.name"
  14. :label="item.title"
  15. :required="rules[item.name] && rules[item.name].length > 0"
  16. v-if="item.type == 'string'"
  17. >
  18. <u-input type="text" :border="border" :placeholder="'请填写' + item.title" v-model="form[item.name]"></u-input>
  19. </u-form-item>
  20. <!-- 文本 -->
  21. <u-form-item
  22. :label-position="labelPosition"
  23. label-width="130"
  24. :prop="item.name"
  25. :label="item.title"
  26. :required="rules[item.name] && rules[item.name].length > 0"
  27. v-if="item.type == 'text'"
  28. >
  29. <u-input type="textarea" :border="border" :placeholder="'请填写' + item.title" v-model="form[item.name]"></u-input>
  30. </u-form-item>
  31. <!-- 编辑器 -->
  32. <!-- #ifdef MP-WEIXIN || H5 || APP-PLUS -->
  33. <u-form-item
  34. :label-position="labelPosition"
  35. label-width="130"
  36. :prop="item.name"
  37. :label="item.title"
  38. :required="rules[item.name] && rules[item.name].length > 0"
  39. v-if="item.type == 'editor'"
  40. >
  41. <fa-editor v-model="form[item.name]" :html="item.value"></fa-editor>
  42. </u-form-item>
  43. <!-- #endif -->
  44. <!-- 数组 -->
  45. <u-form-item
  46. :label-position="labelPosition"
  47. label-width="130"
  48. :prop="item.name"
  49. :label="item.title"
  50. :required="rules[item.name] && rules[item.name].length > 0"
  51. v-if="item.type == 'array'"
  52. >
  53. <fa-array
  54. :faKey="item.setting.key"
  55. :faVal="item.setting.value"
  56. v-model="form[item.name]"
  57. :showValue="item.value || item.content_list"
  58. ></fa-array>
  59. </u-form-item>
  60. <!-- 日期 -->
  61. <u-form-item
  62. :label-position="labelPosition"
  63. label-width="130"
  64. :prop="item.name"
  65. :label="item.title"
  66. :required="rules[item.name] && rules[item.name].length > 0"
  67. v-if="item.type == 'date'"
  68. >
  69. <u-input
  70. :border="border"
  71. type="select"
  72. :select-open="showPicker && mode == 'date'"
  73. v-model="form[item.name]"
  74. :placeholder="'请选择' + item.title"
  75. @click="selectPicker('date', item.name)"
  76. ></u-input>
  77. </u-form-item>
  78. <!-- 时间 -->
  79. <u-form-item
  80. :label-position="labelPosition"
  81. label-width="130"
  82. :prop="item.name"
  83. :label="item.title"
  84. :required="rules[item.name] && rules[item.name].length > 0"
  85. v-if="item.type == 'time'"
  86. >
  87. <u-input
  88. :border="border"
  89. type="select"
  90. :select-open="showPicker && mode == 'time'"
  91. v-model="form[item.name]"
  92. :placeholder="'请选择' + item.title"
  93. @click="selectPicker('time', item.name)"
  94. ></u-input>
  95. </u-form-item>
  96. <!-- 日期时间 -->
  97. <u-form-item
  98. :label-position="labelPosition"
  99. label-width="130"
  100. :prop="item.name"
  101. :label="item.title"
  102. :required="rules[item.name] && rules[item.name].length > 0"
  103. v-if="item.type == 'datetime'"
  104. >
  105. <u-input
  106. :border="border"
  107. type="select"
  108. :select-open="showPicker && mode == 'datetime'"
  109. v-model="form[item.name]"
  110. :placeholder="'请选择' + item.title"
  111. @click="selectPicker('datetime', item.name)"
  112. ></u-input>
  113. </u-form-item>
  114. <!-- 日期区间 -->
  115. <u-form-item
  116. :label-position="labelPosition"
  117. label-width="130"
  118. :prop="item.name"
  119. :label="item.title"
  120. :required="rules[item.name] && rules[item.name].length > 0"
  121. v-if="item.type == 'datetimerange'"
  122. >
  123. <u-input
  124. :border="border"
  125. type="select"
  126. :select-open="calendarShow"
  127. v-model="form[item.name]"
  128. :placeholder="'请选择' + item.title"
  129. @click="
  130. calendarShow = true;
  131. time_field = item.name;
  132. "
  133. ></u-input>
  134. </u-form-item>
  135. <!-- 数字 -->
  136. <u-form-item
  137. :label-position="labelPosition"
  138. label-width="130"
  139. :prop="item.name"
  140. :label="item.title"
  141. :required="rules[item.name] && rules[item.name].length > 0"
  142. v-if="item.type == 'number'"
  143. >
  144. <u-input type="number" :border="border" :placeholder="'请填写' + item.title" v-model="form[item.name]"></u-input>
  145. </u-form-item>
  146. <!-- 多选框 -->
  147. <u-form-item
  148. :label-position="labelPosition"
  149. label-width="130"
  150. :prop="item.name"
  151. :label="item.title"
  152. :required="rules[item.name] && rules[item.name].length > 0"
  153. v-if="item.type == 'checkbox'"
  154. >
  155. <fa-check-radio :faList="item.content_list" v-model="form[item.name]" :checkValue="item.value || item.defaultvalue"></fa-check-radio>
  156. </u-form-item>
  157. <!-- 单选框 -->
  158. <u-form-item
  159. :label-position="labelPosition"
  160. label-width="130"
  161. :prop="item.name"
  162. :label="item.title"
  163. :required="rules[item.name] && rules[item.name].length > 0"
  164. v-if="item.type == 'radio'"
  165. >
  166. <fa-check-radio :faList="item.content_list" type="radio" v-model="form[item.name]" :checkValue="item.value || item.defaultvalue"></fa-check-radio>
  167. </u-form-item>
  168. <!-- 列表单选 -->
  169. <u-form-item
  170. :label-position="labelPosition"
  171. label-width="130"
  172. :prop="item.name"
  173. :label="item.title"
  174. :required="rules[item.name] && rules[item.name].length > 0"
  175. v-if="item.type == 'select'"
  176. >
  177. <fa-selects
  178. :fa-list="item.content_list"
  179. :title="item.title"
  180. :checkeType="item.type"
  181. :showValue="item.value || item.defaultvalue"
  182. v-model="form[item.name]"
  183. ></fa-selects>
  184. </u-form-item>
  185. <!-- 列表多选 -->
  186. <u-form-item
  187. :label-position="labelPosition"
  188. label-width="130"
  189. :prop="item.name"
  190. :label="item.title"
  191. :required="rules[item.name] && rules[item.name].length > 0"
  192. v-if="item.type == 'selects'"
  193. >
  194. <fa-selects
  195. :fa-list="item.content_list"
  196. :title="item.title"
  197. :checkeType="item.type"
  198. :showValue="item.value || item.defaultvalue"
  199. v-model="form[item.name]"
  200. ></fa-selects>
  201. </u-form-item>
  202. <!-- 单图 -->
  203. <u-form-item
  204. :label-position="labelPosition"
  205. label-width="130"
  206. :prop="item.name"
  207. :label="item.title"
  208. :required="rules[item.name] && rules[item.name].length > 0"
  209. v-if="item.type == 'image'"
  210. >
  211. <fa-upload-image v-model="form[item.name]" :file-list="item.value"></fa-upload-image>
  212. </u-form-item>
  213. <!-- 多图 -->
  214. <u-form-item
  215. :label-position="labelPosition"
  216. label-width="130"
  217. :prop="item.name"
  218. :label="item.title"
  219. :required="rules[item.name] && rules[item.name].length > 0"
  220. v-if="item.type == 'images'"
  221. >
  222. <fa-upload-image v-model="form[item.name]" imgType="many" :file-list="item.value"></fa-upload-image>
  223. </u-form-item>
  224. <!-- #ifdef APP-PLUS || H5 || MP-WEIXIN -->
  225. <!-- 单文件 -->
  226. <u-form-item
  227. :label-position="labelPosition"
  228. label-width="130"
  229. :prop="item.name"
  230. :label="item.title"
  231. :required="rules[item.name] && rules[item.name].length > 0"
  232. v-if="item.type == 'file'"
  233. >
  234. <fa-upload-file v-model="form[item.name]" :isDom="true" :showValue="item.value"></fa-upload-file>
  235. </u-form-item>
  236. <!-- 多文件 -->
  237. <u-form-item
  238. :label-position="labelPosition"
  239. label-width="130"
  240. :prop="item.name"
  241. :label="item.title"
  242. :required="rules[item.name] && rules[item.name].length > 0"
  243. v-if="item.type == 'files'"
  244. >
  245. <fa-upload-file v-model="form[item.name]" fileType="many" :isDom="true" :showValue="item.value"></fa-upload-file>
  246. </u-form-item>
  247. <!-- #endif -->
  248. <!-- 开关 -->
  249. <u-form-item
  250. :label-position="labelPosition"
  251. label-width="130"
  252. :prop="item.name"
  253. :label="item.title"
  254. :required="rules[item.name] && rules[item.name].length > 0"
  255. v-if="item.type == 'switch'"
  256. >
  257. <fa-switch v-model="form[item.name]" :defvalue="item.value || 0"></fa-switch>
  258. </u-form-item>
  259. <!-- 关联城市 -->
  260. <u-form-item
  261. :label-position="labelPosition"
  262. label-width="130"
  263. :prop="item.name"
  264. :label="item.title"
  265. :required="rules[item.name] && rules[item.name].length > 0"
  266. v-if="item.type == 'city'"
  267. >
  268. <u-input
  269. :border="border"
  270. type="select"
  271. :select-open="cityShow"
  272. v-model="form[item.name]"
  273. :placeholder="'请选择' + item.title"
  274. @click="
  275. cityShow = true;
  276. city_field = item.name;
  277. "
  278. ></u-input>
  279. </u-form-item>
  280. <!-- 关联单选 -->
  281. <u-form-item
  282. :label-position="labelPosition"
  283. label-width="130"
  284. :prop="item.name"
  285. :label="item.title"
  286. :required="rules[item.name] && rules[item.name].length > 0"
  287. v-if="item.type == 'selectpage'"
  288. >
  289. <fa-selectpages
  290. :fa-id="item.id"
  291. :title="item.title"
  292. :checkeType="item.type"
  293. :showField="item.setting.field"
  294. :keyField="item.setting.primarykey"
  295. :showValue="(form[item.name] ? form[item.name] : item.value) || item.defaultvalue"
  296. v-model="form[item.name]"
  297. ></fa-selectpages>
  298. </u-form-item>
  299. <!-- 关联多选 -->
  300. <u-form-item
  301. :label-position="labelPosition"
  302. label-width="130"
  303. :prop="item.name"
  304. :label="item.title"
  305. :required="rules[item.name] && rules[item.name].length > 0"
  306. v-if="item.type == 'selectpages'"
  307. >
  308. <fa-selectpages
  309. :fa-id="item.id"
  310. :title="item.title"
  311. :checkeType="item.type"
  312. :showField="item.setting.field"
  313. :keyField="item.setting.primarykey"
  314. :showValue="(form[item.name] ? form[item.name] : item.value) || item.defaultvalue"
  315. v-model="form[item.name]"
  316. ></fa-selectpages>
  317. </u-form-item>
  318. </block>
  319. </u-form>
  320. <view class="u-p-30">
  321. <u-button type="primary" hover-class="none" :custom-style="{ backgroundColor: theme.bgColor, color: theme.color }" shape="circle" @click="submit">
  322. 提交
  323. </u-button>
  324. </view>
  325. </view>
  326. <u-picker v-model="showPicker" mode="time" :params="params" @confirm="pickerResult"></u-picker>
  327. <u-calendar v-model="calendarShow" mode="range" @change="calendarResult" max-date="3000-01-01"></u-calendar>
  328. <!-- 城市 -->
  329. <fa-citys v-model="cityShow" @city-change="cityResult"></fa-citys>
  330. <!-- 底部导航 -->
  331. <fa-tabbar></fa-tabbar>
  332. </view>
  333. </template>
  334. <script>
  335. import { formRule, tools } from '@/common/fa.mixin.js';
  336. export default {
  337. mixins: [formRule, tools],
  338. onLoad(e) {
  339. let query = this.$Route.query || e || {};
  340. this.diyname = query.diyname || '';
  341. this.id = query.id || '';
  342. this.init();
  343. },
  344. data() {
  345. return {
  346. diyname: '',
  347. id: '',
  348. labelPosition: 'top',
  349. border: false,
  350. errorType: ['message'],
  351. showForm: false,
  352. // 表单字段
  353. fields: [],
  354. //表单信息
  355. diyform: {},
  356. form: {},
  357. rules: {},
  358. calendarShow: false,
  359. showPicker: false,
  360. mode: '',
  361. time_field: '',
  362. params: {},
  363. cityShow: false,
  364. city_field: '',
  365. imageList: {}
  366. };
  367. },
  368. methods: {
  369. init() {
  370. this.$api.formField({ diyname: this.diyname, id: this.id }).then(res => {
  371. if (res.code) {
  372. this.diyform = res.data.diyform;
  373. this.fields = res.data.fields;
  374. //渲染自定义字段
  375. let custom_form = {};
  376. let rules = {
  377. title: [
  378. {
  379. required: true,
  380. message: '请输入标题',
  381. // 可以单个或者同时写两个触发验证方式
  382. trigger: ['change', 'blur']
  383. }
  384. ]
  385. };
  386. this.fields.map(item => {
  387. // console.log(item)
  388. //表单赋值
  389. if (item.type == 'number') {
  390. custom_form[item.name] = item.value || item.defaultvalue || 0;
  391. } else {
  392. custom_form[item.name] = item.value || item.defaultvalue || '';
  393. }
  394. //单图赋值
  395. if (item.type == 'image') {
  396. if (item.value) {
  397. item.value = [
  398. {
  399. url: this.cdnurl(item.value)
  400. }
  401. ];
  402. } else {
  403. item.value = [];
  404. }
  405. }
  406. //多图赋值
  407. if (item.type == 'images') {
  408. if (item.value) {
  409. let images = item.value.split(',');
  410. let urls = [];
  411. images.forEach(it => {
  412. urls.push({
  413. url: this.cdnurl(it)
  414. });
  415. });
  416. item.value = urls;
  417. } else {
  418. item.value = [];
  419. }
  420. }
  421. //单文件
  422. if (item.type == 'file') {
  423. item.value = item.value ? [item.value] : [];
  424. }
  425. //多文件
  426. if (item.type == 'files') {
  427. if (item.value) {
  428. item.value = item.value.split(',');
  429. } else {
  430. item.value = [];
  431. }
  432. }
  433. //追加自定义表单验证
  434. rules[item.name] = this.getRules(item);
  435. });
  436. this.form = custom_form;
  437. this.rules = rules;
  438. this.showForm = true;
  439. //设置表单验证规则
  440. // console.log(this.form, this.rules,this.fields);
  441. this.$nextTick(() => {
  442. this.$refs.uForm.setRules(this.rules);
  443. });
  444. } else {
  445. this.$u.toast(res.msg);
  446. }
  447. });
  448. },
  449. //标签数据
  450. tagsChange(e) {
  451. this.$set(this.form, 'tags', e.join(','));
  452. },
  453. //时间显示
  454. selectPicker(mode, field) {
  455. this.mode = mode;
  456. this.time_field = field;
  457. switch (mode) {
  458. case 'date':
  459. this.params = {
  460. year: true,
  461. month: true,
  462. day: true,
  463. hour: false,
  464. minute: false,
  465. second: false
  466. };
  467. break;
  468. case 'time':
  469. this.params = {
  470. year: false,
  471. month: false,
  472. day: false,
  473. hour: true,
  474. minute: true,
  475. second: true
  476. };
  477. break;
  478. case 'datetime':
  479. this.params = {
  480. year: true,
  481. month: true,
  482. day: true,
  483. hour: true,
  484. minute: true,
  485. second: true
  486. };
  487. break;
  488. }
  489. this.showPicker = true;
  490. },
  491. //时间的选择结果
  492. pickerResult(e) {
  493. switch (this.mode) {
  494. case 'date':
  495. this.$set(this.form, this.time_field, e.year + '-' + e.month + '-' + e.day);
  496. break;
  497. case 'time':
  498. this.$set(this.form, this.time_field, e.hour + ':' + e.minute + ':' + e.second);
  499. break;
  500. case 'datetime':
  501. this.$set(this.form, this.time_field, e.year + '-' + e.month + '-' + e.day + ' ' + e.hour + ':' + e.minute + ':' + e.second);
  502. break;
  503. }
  504. },
  505. //时间范围选择的结果
  506. calendarResult(e) {
  507. this.$set(this.form, this.time_field, e.startDate + ' 00:00:00 - ' + e.endDate + ' 23:59:59');
  508. },
  509. //城市选择
  510. cityResult(e) {
  511. this.$set(this.form, this.city_field, e.province.label + '/' + e.city.label + '/' + e.area.label);
  512. },
  513. //提交
  514. submit: async function() {
  515. console.log('验证开始', this.form);
  516. //校验
  517. this.$refs.uForm.validate(valid => {
  518. if (valid) {
  519. console.log('验证通过', this.form);
  520. this.form.diyname = this.diyform.diyname;
  521. this.form.id = this.id;
  522. this.$api.postForm(this.form).then(res => {
  523. this.$u.toast(res.msg);
  524. if (res.code) {
  525. setTimeout(() => {
  526. this.$Router.replace({
  527. path: '/pages/diyform/lists',
  528. query: { diyname: this.diyname }
  529. });
  530. }, 1500);
  531. }
  532. });
  533. } else {
  534. console.log('验证失败', this.form);
  535. }
  536. });
  537. }
  538. }
  539. };
  540. </script>
  541. <style></style>