app-diy-form.vue 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861
  1. <template>
  2. <view class="app-diy-form" :style="{
  3. paddingTop: `${marginTop}rpx`,
  4. paddingBottom: `${marginBottom}rpx`,
  5. backgroundColor: `${marginColor}`
  6. }">
  7. <view class="title" v-if="title !== '' && title !== null">{{title}}</view>
  8. <!--<view style="border: 1rpx solid #ff3455">
  9. <view v-for="(item, index) in myList" :key="index">{{item.name}}:{{item.value}}</view>
  10. </view>-->
  11. <view :style="{
  12. backgroundColor: backgroundColor,
  13. backgroundImage: backgroundImage ? `url(${backgroundImage})` : `none`,
  14. backgroundPosition: backgroundPosition,
  15. backgroundSize: `${backgroundWidth}% ${backgroundHeight}%`,
  16. backgroundRepeat: backgroundRepeat,
  17. paddingTop: `${paddingTop}rpx`,
  18. paddingBottom: `${paddingBottom}rpx`,
  19. }">
  20. <view class="list"
  21. :class="[showItemBorder?'item-border':'', showAllItems?'show-all':'show-first',labelFs28?'label-fs-28':'']">
  22. <template v-for="(item, index) in myList">
  23. <view :key="index" v-if="item.key=='text'"
  24. class="item"
  25. :class="[itemClass, index===0 ? `is-first-item` : ``,]"
  26. :style="{
  27. 'padding': `0 ${itemPaddingX}rpx`,
  28. 'margin-bottom': `${itemMarginY}rpx`,
  29. }">
  30. <view v-if="labelPosition !== 'inset'" class="box-grow-0 cross-top label">
  31. <image v-if="showRequiredIcon && (item.is_required == 1 || item.is_required == '1')"
  32. class="required-icon"
  33. src="/static/image/icon/required.png"></image>
  34. <view class="name-key"
  35. :class="[`text-align-${labelTextAlign}`]"
  36. :style="{
  37. 'color': labelColor
  38. }">{{item.name}}
  39. </view>
  40. </view>
  41. <view class="box-grow-1">
  42. <app-input v-model="item.value"
  43. :default-value="item.value"
  44. :background-color="inputBackground"
  45. @input="textInput"
  46. :color="inputTextColor"
  47. :placeholder="labelPosition === 'inset' ? item.name:item.hint"
  48. :height="`${itemHeight}`"
  49. :border="showInputBorder"
  50. :radius="inputRadius"
  51. :placeholder-style="`color:${inputPlaceholderColor}`"
  52. :padding-left="getInputPaddingLeft"
  53. :border-color="inputBorderColor"></app-input>
  54. </view>
  55. </view>
  56. <view :key="index" v-if="item.key=='textarea'"
  57. class="item"
  58. :class="[itemClass, index===0 ? `is-first-item` : ``,]"
  59. :style="{
  60. 'padding': `0 ${itemPaddingX}rpx`,
  61. 'margin-bottom': `${itemMarginY}rpx`,
  62. }">
  63. <view v-if="labelPosition !== 'inset'" class="box-grow-0 cross-top label">
  64. <image v-if="showRequiredIcon && (item.is_required == 1 || item.is_required == '1')"
  65. class="required-icon"
  66. src="/static/image/icon/required.png"></image>
  67. <view class="name-key"
  68. :class="[`text-align-${labelTextAlign}`]"
  69. :style="{
  70. 'color': labelColor
  71. }">{{item.name}}
  72. </view>
  73. </view>
  74. <view class="box-grow-1">
  75. <app-textarea v-model="item.value"
  76. :default-value="item.value"
  77. :background="inputBackground"
  78. @input="textInput"
  79. :color="inputTextColor"
  80. :placeholder="labelPosition === 'inset' ? item.name:item.hint"
  81. :show-border="showInputBorder"
  82. :border-radius="inputRadius"
  83. :padding-x="getInputPaddingLeft"
  84. :placeholder-style="[`color:${inputPlaceholderColor}`]"
  85. :border-color="inputBorderColor"></app-textarea>
  86. </view>
  87. </view>
  88. <view :key="index" v-if="item.key=='date'"
  89. class="item"
  90. :class="[itemClass, index===0 ? `is-first-item` : ``,]"
  91. :style="{
  92. 'padding': `0 ${itemPaddingX}rpx`,
  93. 'margin-bottom': `${itemMarginY}rpx`,
  94. }">
  95. <view class="box-grow-0 cross-top label">
  96. <image v-if="showRequiredIcon && (item.is_required == 1 || item.is_required == '1')"
  97. class="required-icon"
  98. src="/static/image/icon/required.png"></image>
  99. <view class="name-key"
  100. :class="[`text-align-${labelTextAlign}`]"
  101. :style="{
  102. 'color': labelColor
  103. }">{{item.name}}
  104. </view>
  105. </view>
  106. <view class="box-grow-1">
  107. <app-datetime-picker v-model="item.value"
  108. @change="datetimeChange"
  109. :text="item.value||''"
  110. :sign="index"
  111. :show-border="showInputBorder"
  112. :background="inputBackground"
  113. :height="itemHeight"
  114. :radius="inputRadius"
  115. :default-value="item.default"
  116. :text-color="inputTextColor"
  117. :text-position="getDateTimeTextPosition"
  118. :border-color="inputBorderColor"
  119. :start="item.min ? item.min : ''"
  120. :padding="datePadding"
  121. :end="item.max ? item.max : ''">
  122. <!-- #ifdef MP-TOUTIAO -->
  123. {{item.value||''}}
  124. <!-- #endif -->
  125. </app-datetime-picker>
  126. </view>
  127. </view>
  128. <view :key="index" v-if="item.key=='time'"
  129. class="item"
  130. :class="[itemClass, index===0 ? `is-first-item` : ``,]"
  131. :style="{
  132. 'padding': `0 ${itemPaddingX}rpx`,
  133. 'margin-bottom': `${itemMarginY}rpx`,
  134. }">
  135. <view class="box-grow-0 cross-top label">
  136. <image v-if="showRequiredIcon && (item.is_required == 1 || item.is_required == '1')"
  137. class="required-icon"
  138. src="/static/image/icon/required.png"></image>
  139. <view class="name-key"
  140. :class="[`text-align-${labelTextAlign}`]"
  141. :style="{
  142. 'color': labelColor
  143. }">{{item.name}}
  144. </view>
  145. </view>
  146. <view class="box-grow-1">
  147. <app-datetime-picker v-model="item.value"
  148. @change="datetimeChange"
  149. mode="time"
  150. :text="item.value||''"
  151. :sign="index"
  152. :default-value="item.default"
  153. :show-border="showInputBorder"
  154. :background="inputBackground"
  155. :height="itemHeight"
  156. :radius="inputRadius"
  157. :text-color="inputTextColor"
  158. :text-position="getDateTimeTextPosition"
  159. :border-color="inputBorderColor"
  160. :start="item.min ? item.min : ''"
  161. :end="item.max ? item.max : ''">
  162. <!-- #ifdef MP-TOUTIAO -->
  163. {{item.value||''}}
  164. <!-- #endif -->
  165. </app-datetime-picker>
  166. </view>
  167. </view>
  168. <view :key="index" v-if="item.key=='radio'"
  169. class="item"
  170. :class="[itemClass, index===0 ? `is-first-item` : ``,]"
  171. :style="{
  172. 'padding': `0 ${itemPaddingX}rpx`,
  173. 'margin-bottom': `${itemMarginY}rpx`,
  174. }">
  175. <view class="box-grow-0 cross-top label">
  176. <image v-if="showRequiredIcon && (item.is_required == 1 || item.is_required == '1')"
  177. class="required-icon"
  178. src="/static/image/icon/required.png"></image>
  179. <view class="name-key"
  180. :class="[`text-align-${labelTextAlign}`]"
  181. :style="{
  182. 'color': labelColor
  183. }">{{item.name}}
  184. </view>
  185. </view>
  186. <view class="box-grow-1" :style="{
  187. padding: labelPosition === 'top' ? `0 0` : `0 12rpx`,
  188. }">
  189. <app-radio-group :list="item.list" v-model="item.value"
  190. :color="selectBoxColor"
  191. type="round"
  192. :height="74"
  193. @change="checkChange"></app-radio-group>
  194. </view>
  195. </view>
  196. <view :key="index" v-if="item.key=='checkbox'"
  197. class="item"
  198. :class="[itemClass, index===0 ? `is-first-item` : ``,]"
  199. :style="{
  200. 'padding': `0 ${itemPaddingX}rpx`,
  201. 'margin-bottom': `${itemMarginY}rpx`,
  202. }">
  203. <view class="box-grow-0 cross-top label">
  204. <image v-if="showRequiredIcon && (item.is_required == 1 || item.is_required == '1')"
  205. class="required-icon"
  206. src="/static/image/icon/required.png"></image>
  207. <view class="name-key"
  208. :class="[`text-align-${labelTextAlign}`]"
  209. :style="{
  210. 'color': labelColor
  211. }">{{item.name}}
  212. </view>
  213. </view>
  214. <view class="box-grow-1 dir-left-wrap" :style="{
  215. padding: labelPosition === 'top' ? `0 0` : `0 12rpx`,
  216. }">
  217. <app-diy-form-checkbox-group :list="item.list"
  218. v-model="item.value"
  219. :color="selectBoxColor"
  220. @change="checkChange"></app-diy-form-checkbox-group>
  221. </view>
  222. </view>
  223. <view :key="index" v-if="item.key=='img_upload'"
  224. class="item"
  225. :class="[itemClass, index===0 ? `is-first-item` : ``,]"
  226. :style="{
  227. 'padding': `0 ${itemPaddingX}rpx`,
  228. 'margin-bottom': `${itemMarginY}rpx`,
  229. }">
  230. <view class="box-grow-0 cross-top label">
  231. <image v-if="showRequiredIcon && (item.is_required == 1 || item.is_required == '1')"
  232. class="required-icon"
  233. src="/static/image/icon/required.png"></image>
  234. <view class="name-key"
  235. :class="[`text-align-${labelTextAlign}`]"
  236. :style="{
  237. 'color': labelColor
  238. }">{{item.name}}
  239. </view>
  240. </view>
  241. <view class="box-grow-1 dir-left-wrap" :style="{
  242. padding: labelPosition === 'top' ? `12rpx 0` : `12rpx 12rpx`,
  243. }">
  244. <!-- 普通图片 -->
  245. <template v-if="item.img_type == 1">
  246. <app-upload-image
  247. :value="uploadShowImage(item)"
  248. :max-num="item.num ? item.num:1"
  249. @imageEvent="handleImageUpload"
  250. :sign="`${index}`"
  251. :show-number="false"
  252. ></app-upload-image>
  253. </template>
  254. <!-- 身份证,正反面 -->
  255. <template v-if="item.img_type == 2">
  256. <app-upload-image
  257. :value="(item.value && item.value[0])?[item.value[0]]:null"
  258. style="margin-right: 12rpx"
  259. :max-num="1"
  260. @imageEvent="handleUserIdFrontUpload"
  261. :sign="`${index}`"
  262. text="身份证正面"
  263. :show-number="false"
  264. default-img="/static/image/user-id-card-front.png"></app-upload-image>
  265. <app-upload-image
  266. :value="(item.value && item.value[1])?[item.value[1]]:null"
  267. :max-num="1"
  268. @imageEvent="handleUserIdBackUpload"
  269. :sign="`${index}`"
  270. text="身份证反面"
  271. :show-number="false"
  272. default-img="/static/image/user-id-card-back.png"></app-upload-image>
  273. </template>
  274. <!-- 营业执照 -->
  275. <template v-if="item.img_type == 3">
  276. <app-upload-image
  277. :value="item.value?[item.value]:null"
  278. :max-num="1"
  279. @imageEvent="handleImageUpload"
  280. :sign="`${index}`"
  281. text="营业执照"
  282. :show-number="false"
  283. default-img="/static/image/company-license.png"></app-upload-image>
  284. </template>
  285. </view>
  286. </view>
  287. </template>
  288. </view>
  289. <view class="main-center cross-center scroll-bar" v-if="showScrollBtn"
  290. @click="showAllItems = !showAllItems">
  291. <view class="cross-center">点击{{showAllItems?'收起':'展开'}}</view>
  292. <view class="cross-center">
  293. <image v-if="showAllItems" src="/static/image/icon/icon-up.png"
  294. style="width: 18rpx;height: 10rpx;"></image>
  295. <image v-else src="/static/image/icon/icon-down.png"
  296. style="width: 18rpx;height: 10rpx;"></image>
  297. </view>
  298. </view>
  299. <view v-if="showSubmit" class="submit" :style="{
  300. 'padding': `${submitBtnMargin}rpx ${submitBtnPadding}rpx 24rpx`,
  301. }">
  302. <app-form-id @click="submit">
  303. <view class="submit-button" :style="{
  304. 'background-color': submitBtnBackground,
  305. 'border-color': submitBtnBorderColor,
  306. 'color': submitBtnTextColor,
  307. 'border-radius': `${submitBtnRadius}rpx`,
  308. 'height': `${submitBtnHeight}rpx`,
  309. 'line-height': `${submitBtnHeight-2}rpx`,
  310. }">{{submitBtnText}}
  311. </view>
  312. </app-form-id>
  313. </view>
  314. </view>
  315. </view>
  316. </template>
  317. <script>
  318. import AppDatetimePicker from '../../basic-component/app-datetime-picker/app-datetime-picker.vue';
  319. import AppRadio from "../../basic-component/app-radio/app-radio";
  320. import AppRadioGroup from "../../basic-component/app-radio/app-radio-group";
  321. import AppDiyFormCheckboxGroup from "./app-diy-form-checkbox-group";
  322. import AppUploadImage from "../../basic-component/app-upload-image/app-upload-image";
  323. import AppTextarea from "../../basic-component/app-textarea/app-textarea";
  324. export default {
  325. name: 'app-diy-form',
  326. components: {AppTextarea, AppUploadImage, AppDiyFormCheckboxGroup, AppRadioGroup, AppRadio, AppDatetimePicker},
  327. props: {
  328. sign: {
  329. default: null,
  330. },
  331. datePadding: {
  332. type: String,
  333. default: '0 24rpx',
  334. },
  335. title: {
  336. type: String,
  337. default: null,
  338. },
  339. backgroundColor: {
  340. default: '#ffffff',
  341. },
  342. backgroundImage: {
  343. default: null,
  344. },
  345. backgroundPosition: {
  346. default: 'center',
  347. },
  348. backgroundWidth: {
  349. default: 100,
  350. },
  351. backgroundHeight: {
  352. default: 100,
  353. },
  354. backgroundRepeat: {
  355. default: 'no-repeat',
  356. },
  357. marginTop: {
  358. default: 0,
  359. },
  360. marginBottom: {
  361. default: 0,
  362. },
  363. paddingTop: {
  364. default: 0,
  365. },
  366. paddingBottom: {
  367. default: 0,
  368. },
  369. list: {
  370. type: Array,
  371. default: [],
  372. },
  373. showRequiredIcon: {
  374. type: Boolean,
  375. default: false,
  376. },
  377. itemPaddingX: {
  378. default: 24,
  379. },
  380. itemMarginY: {
  381. default: 0,
  382. },
  383. itemHeight: {
  384. type: Number,
  385. default: 88,
  386. },
  387. showItemBorder: {
  388. default: true,
  389. },
  390. labelPosition: {
  391. default: 'left',
  392. },
  393. labelColor: {
  394. default: '#666666',
  395. },
  396. labelTextAlign: {
  397. default: 'right',
  398. },
  399. showInputBorder: {
  400. type: Boolean,
  401. default: false,
  402. },
  403. inputBackground: {
  404. default: '#ffffff',
  405. },
  406. inputBorderColor: {
  407. default: '#c0c4cc',
  408. },
  409. inputTextColor: {
  410. default: '#666666',
  411. },
  412. inputPlaceholderColor: {
  413. default: '#bbbbbb',
  414. },
  415. inputRadius: {
  416. default: 0,
  417. },
  418. showSubmit: {
  419. type: Boolean,
  420. default: false,
  421. },
  422. submitUrl: {
  423. type: String,
  424. default: null,
  425. },
  426. submitBtnText: {
  427. default: '提交',
  428. },
  429. submitBtnHeight: {
  430. default: 80,
  431. },
  432. submitBtnPadding: {
  433. default: 24,
  434. },
  435. submitBtnMargin: {
  436. default: 40,
  437. },
  438. submitBtnRadius: {
  439. default: 40,
  440. },
  441. submitBtnBackground: {
  442. default: '#ff4544',
  443. },
  444. submitBtnBorderColor: {
  445. default: '#ff4544',
  446. },
  447. submitBtnTextColor: {
  448. default: '#ffffff',
  449. },
  450. showScrollBtn: {
  451. default: false,
  452. },
  453. labelFs28: {
  454. default: false,
  455. },
  456. marginColor: {
  457. default: '#ffffff',
  458. },
  459. selectBoxColor: {
  460. default: '#ff4544',
  461. },
  462. },
  463. data() {
  464. const newList = [];
  465. for (let i in this.list) {
  466. const item = this.list[i];
  467. // if (typeof item.default === 'undefined') {
  468. // item.default = null;
  469. // }
  470. if (typeof item.default === 'undefined' || item.default === null || item.default === '') {
  471. if (item.key === 'text' || item.key === 'textarea' || item.key === 'time' || item.key === 'date') {
  472. item.default = '';
  473. }
  474. if (item.key === 'radio' || item.key === 'checkbox') {
  475. item.default = [];
  476. }
  477. }
  478. if (typeof item.value === 'undefined' || item.value === null || item.value === '') {
  479. item.value = item.default;
  480. }
  481. item.hint = item.hint || '';
  482. if (item.key === 'radio' || item.key === 'checkbox') {
  483. if (!item.list) item.list = [];
  484. for (let j in item.list) {
  485. if (!item.list[j].value || item.list[j].value === false || item.list[j].value === 'false') {
  486. item.list[j].value = false;
  487. } else {
  488. item.list[j].value = true;
  489. }
  490. }
  491. }
  492. if (item.key === 'img_upload' && (item.img_type === 2 || item.img_type === '2') && !item.value) {
  493. item.value = ['', ''];
  494. }
  495. if(item.key == 'text') {
  496. }
  497. newList[i] = item;
  498. }
  499. return {
  500. myList: newList,
  501. randomString: '',
  502. validateResult: {
  503. hasError: false,
  504. errors: [],
  505. },
  506. showAllItems: true, //默认展开全部
  507. };
  508. },
  509. computed: {
  510. uploadShowImage() {
  511. return function (item) {
  512. if (Array.isArray(item.value)) {
  513. return item.value;
  514. }
  515. if (item.value) {
  516. return [item.value];
  517. }
  518. return null;
  519. }
  520. },
  521. itemClass() {
  522. if (this.labelPosition === 'left') {
  523. return 'label-left dir-left-nowrap cross-top';
  524. }
  525. if (this.labelPosition === 'inset') {
  526. return 'label-inset dir-left-nowrap cross-top';
  527. }
  528. if (this.labelPosition === 'top') {
  529. return 'label-top';
  530. }
  531. },
  532. getDateTimeTextPosition() {
  533. if (this.labelPosition === 'top') {
  534. return 'left';
  535. }
  536. return 'right';
  537. },
  538. getInputPaddingLeft() {
  539. if (this.labelPosition === 'top') {
  540. if (this.showInputBorder) {
  541. return 24;
  542. } else {
  543. return 0;
  544. }
  545. }
  546. return 24;
  547. },
  548. },
  549. created() {
  550. this.validate();
  551. this.outputData();
  552. },
  553. methods: {
  554. textInput() {
  555. this.outputData();
  556. // #ifdef H5
  557. this.$forceUpdate()
  558. // #endif
  559. },
  560. datetimeChange() {
  561. this.outputData();
  562. // #ifdef H5
  563. this.$forceUpdate()
  564. // #endif
  565. },
  566. checkChange() {
  567. setTimeout(() => {
  568. this.outputData();
  569. }, 10);
  570. },
  571. handleImageUpload({sign, imageList}) {
  572. const index = parseInt(sign);
  573. if (imageList.length === 1) {
  574. this.myList[index].value = imageList[0];
  575. } else if (imageList.length > 0) {
  576. this.myList[index].value = imageList;
  577. } else {
  578. this.myList[index].value = '';
  579. }
  580. this.outputData();
  581. },
  582. handleUserIdFrontUpload({sign, imageList}) {
  583. const index = parseInt(sign);
  584. if (imageList.length > 0) {
  585. this.myList[index].value[0] = imageList[0];
  586. } else {
  587. this.myList[index].value[0] = '';
  588. }
  589. this.outputData();
  590. },
  591. handleUserIdBackUpload({sign, imageList}) {
  592. const index = parseInt(sign);
  593. if (imageList.length > 0) {
  594. this.myList[index].value[1] = imageList[0];
  595. } else {
  596. this.myList[index].value[1] = '';
  597. }
  598. this.outputData();
  599. },
  600. validate() {
  601. this.validateResult = {
  602. hasError: false,
  603. errors: [],
  604. };
  605. for (let i in this.myList) {
  606. const item = this.myList[i];
  607. if (item.is_required === 1 || item.is_required === '1') {
  608. if ((typeof item.value === 'undefined'
  609. || item.value === null
  610. || item.value === ''
  611. || ['radio', 'checkbox'].indexOf(item.key) !== -1 && !item.value.length)
  612. ) {
  613. this.validateResult.hasError = true;
  614. this.validateResult.errors.push({
  615. index: i,
  616. msg: `"${item.name}"不能为空。`,
  617. });
  618. continue;
  619. }
  620. if (item.img_type && parseInt(item.img_type) === 2) {
  621. if (!item.value || !item.value.length) {
  622. this.validateResult.hasError = true;
  623. this.validateResult.errors.push({
  624. index: i,
  625. msg: `"${item.name}"不能为空。`,
  626. });
  627. continue;
  628. }
  629. let imgErr = false;
  630. for (let j in item.value) {
  631. if (item.value[j] === null || item.value[j] === '') {
  632. imgErr = true;
  633. break;
  634. }
  635. }
  636. if (imgErr) {
  637. this.validateResult.hasError = true;
  638. this.validateResult.errors.push({
  639. index: i,
  640. msg: `"${item.name}"不能为空。`,
  641. });
  642. continue;
  643. }
  644. }
  645. }
  646. }
  647. this.$emit('validate',{
  648. result: this.validateResult,
  649. sign: this.sign
  650. });
  651. },
  652. outputData() {
  653. this.validate();
  654. for (let i in this.myList) {
  655. this.myList[i].label = this.myList[i].name;
  656. this.myList[i].required = this.myList[i].is_required;
  657. }
  658. this.$emit('input',{
  659. data: this.myList,
  660. sign: this.sign
  661. });
  662. // #ifdef MP-TOUTIAO
  663. setTimeout(() => {
  664. this.randomString = this.$utils.randomString(32);
  665. }, 1);
  666. // #endif
  667. },
  668. submit() {
  669. this.outputData();
  670. if (this.validateResult.hasError && this.validateResult.errors) {
  671. uni.showModal({
  672. title: '提示',
  673. content: this.validateResult.errors[0].msg,
  674. showCancel: false,
  675. });
  676. return;
  677. }
  678. uni.showLoading({
  679. mask: true,
  680. title: '正在提交...',
  681. });
  682. this.$request({
  683. url: this.submitUrl ? this.submitUrl : this.$api.diy.page_store,
  684. method: 'post',
  685. data: {
  686. form_data: JSON.stringify(this.myList),
  687. },
  688. }).then(response => {
  689. uni.hideLoading();
  690. if (response.code === 0) {
  691. setTimeout(() => {
  692. let copyList = this.myList;
  693. for (let i in copyList) {
  694. copyList[i].value = copyList[i].default;
  695. }
  696. this.myList = [];
  697. setTimeout(() => {
  698. this.myList = copyList;
  699. }, 0);
  700. }, 300);
  701. uni.showModal({
  702. title: '提示',
  703. content: response.msg || '提交成功',
  704. showCancel: false,
  705. });
  706. } else {
  707. uni.showModal({
  708. title: '提示',
  709. content: response.msg || '提交失败',
  710. showCancel: false,
  711. });
  712. }
  713. }).catch(() => {
  714. uni.hideLoading();
  715. });
  716. },
  717. },
  718. }
  719. </script>
  720. <style scoped lang="scss">
  721. .name-key {
  722. width: 100%;
  723. text-align: right;
  724. font-size: #{32rpx};
  725. color: #353535
  726. }
  727. .name-key.text-align-left {
  728. text-align: left;
  729. }
  730. .name-key.text-align-right {
  731. text-align: right;
  732. }
  733. .title {
  734. padding: #{24rpx};
  735. color: #999;
  736. font-size: #{26rpx};
  737. }
  738. .arrow {
  739. width: #{12rpx};
  740. height: #{22rpx};
  741. }
  742. .scroll-bar {
  743. border-top: #{1rpx} solid $uni-weak-color-one;
  744. height: #{72rpx};
  745. color: $uni-general-color-two;
  746. image {
  747. margin-left: #{16rpx};
  748. }
  749. }
  750. .list {
  751. .item {
  752. height: 0 !important;
  753. overflow: hidden;
  754. .label {
  755. min-width: #{125rpx};
  756. padding: #{24rpx} #{12rpx} #{12rpx} 0;
  757. height: 100%;
  758. position: relative;
  759. }
  760. .required-icon {
  761. width: #{15rpx};
  762. height: #{15rpx};
  763. display: inline-block;
  764. position: absolute;
  765. left: #{-14rpx};
  766. top: #{23rpx};
  767. }
  768. }
  769. .item.is-first-item {
  770. height: auto !important;
  771. overflow: auto;
  772. }
  773. .item.label-left {
  774. .name-key {
  775. max-width: #{200rpx};
  776. }
  777. }
  778. .item.label-top {
  779. .name-key {
  780. text-align: left;
  781. }
  782. .label {
  783. padding: #{20rpx} #{12rpx} #{8rpx} 0;
  784. }
  785. }
  786. .item:last-child {
  787. margin-bottom: 0 !important;
  788. }
  789. }
  790. .show-all {
  791. .item {
  792. height: auto !important;
  793. overflow: auto;
  794. }
  795. }
  796. .show-first {
  797. .item {
  798. margin-bottom: 0 !important;
  799. border: none !important;
  800. }
  801. }
  802. .item-border {
  803. .item {
  804. border-bottom: #{2rpx} solid $uni-weak-color-one;
  805. }
  806. .item:last-child {
  807. border-bottom: none;
  808. }
  809. }
  810. .submit-button {
  811. text-align: center;
  812. border: #{1rpx} solid;
  813. }
  814. .submit-button:active {
  815. box-shadow: inset 0 0 #{1000rpx} rgba(0, 0, 0, .15);
  816. }
  817. .label-fs-28 {
  818. .name-key {
  819. font-size: #{28rpx};
  820. }
  821. }
  822. </style>