index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. <template>
  2. <!--商品关联系统表单-->
  3. <view v-if="value.length>0" class="wrapper virtual_form bg-f boder-24 px-30">
  4. <view class='item acea-row row-between-wrapper'
  5. :class="{on:(item.name=='radios' || item.name=='checkboxs'),on2:item.name == 'dateranges',on3:item.name == 'citys',pd0:item.name == 'uploadPicture'}"
  6. v-for="(item,index) in orderNewForm" :key="index">
  7. <view class="name">
  8. <text class="item-require" v-if="item.titleShow.val">*</text>
  9. {{ item.titleConfig.val }}
  10. </view>
  11. <!-- radio -->
  12. <view v-if="item.name=='radios'" class="discount">
  13. <radio-group @change="radioChange($event, index, item)" class="acea-row row-middle row-right">
  14. <label class="radio" v-for="(j,jindex) in item.wordsConfig.list" :key="jindex">
  15. <view class="acea-row row-middle">
  16. <!-- #ifndef MP -->
  17. <radio :value="jindex.toString()" :checked='j.show' />
  18. <!-- #endif -->
  19. <!-- #ifdef MP -->
  20. <radio :value="jindex" :checked='j.show' />
  21. <!-- #endif -->
  22. <view>{{j.val}}</view>
  23. </view>
  24. </label>
  25. </radio-group>
  26. </view>
  27. <!-- checkbox -->
  28. <view v-if="item.name=='checkboxs'" class="discount acea-row">
  29. <checkbox-group @change="checkboxChange($event, index, item)" class="acea-row row-middle row-right">
  30. <label class="radio" v-for="(j,jindex) in item.wordsConfig.list" :key="jindex">
  31. <view class="acea-row row-middle">
  32. <!-- #ifndef MP -->
  33. <checkbox :value="jindex.toString()" :checked="j.show" style="transform:scale(0.9)" />
  34. <!-- #endif -->
  35. <!-- #ifdef MP -->
  36. <checkbox :value="jindex" :checked="j.show" style="transform:scale(0.9)" />
  37. <!-- #endif -->
  38. <view>{{j.val}}</view>
  39. </view>
  40. </label>
  41. </checkbox-group>
  42. </view>
  43. <!-- text -->
  44. <view v-if="item.name=='texts' && item.valConfig.tabVal == 0" class="discount">
  45. <input type="text" :placeholder="item.tipConfig.val" class="text-28rpx" placeholder-class="placeholder"
  46. v-model="item.value" />
  47. </view>
  48. <!-- number -->
  49. <view v-if="item.name=='texts' && item.valConfig.tabVal == 4" class="discount">
  50. <input type="number" :placeholder="item.tipConfig.val" class="text-28rpx" placeholder-class="placeholder"
  51. v-model="item.value" />
  52. </view>
  53. <!-- email -->
  54. <view v-if="item.name=='texts' && item.valConfig.tabVal == 3" class="discount">
  55. <input type="text" :placeholder="item.tipConfig.val" class="text-28rpx" placeholder-class="placeholder"
  56. v-model="item.value" />
  57. </view>
  58. <!-- data -->
  59. <view v-if="item.name=='dates'" class="discount">
  60. <picker mode="date" :value="item.value" @change="bindDateChange($event,index)">
  61. <view class="acea-row row-between-wrapper text-28rpx">
  62. <view v-if="item.value == ''" class="text--w111-ccc">{{item.tipConfig.val}}</view>
  63. <view v-else>{{item.value}}</view>
  64. <text class='iconfont icon-xiangxia'></text>
  65. </view>
  66. </picker>
  67. </view>
  68. <!-- dateranges -->
  69. <view v-if="item.name=='dateranges'" class="discount">
  70. <uni-datetime-picker v-model="item.value" type="daterange" class="text-28rpx flex" @maskClick="maskClick">
  71. <view v-if="item.value == ''" class="text--w111-ccc">请选择</view>
  72. <view v-else>{{item.value.length?item.value[0]+' - '+item.value[1]:item.tipConfig.val}}</view>
  73. <text class='iconfont icon-xiangxia'></text>
  74. </uni-datetime-picker>
  75. </view>
  76. <!-- time -->
  77. <view v-if="item.name=='times'" class="discount">
  78. <picker mode="time" :value="item.value" @change="bindTimeChange($event,index)"
  79. :placeholder="item.tipConfig.value">
  80. <view class="acea-row row-between-wrapper text-28rpx">
  81. <view v-if="item.value == ''" class="text--w111-ccc">{{item.tipConfig.val}}</view>
  82. <view v-else>{{item.value}}</view>
  83. <text class='iconfont icon-xiangxia'></text>
  84. </view>
  85. </picker>
  86. </view>
  87. <!-- timeranges -->
  88. <view v-if="item.name=='timeranges'" class="discount acea-row row-between-wrapper"
  89. @click="getTimeranges(index)">
  90. <view v-if="item.value" class="text-28rpx">{{item.value}}</view>
  91. <view v-else class="text--w111-ccc text-28rpx">{{item.tipConfig.val}}</view>
  92. <text class='iconfont icon-xiangxia'></text>
  93. </view>
  94. <!-- select -->
  95. <view v-if="item.name=='selects'" class="discount">
  96. <picker :value="item.value" :range="item.wordsConfig.list" @change="bindSelectChange($event,index,item)"
  97. range-key="val">
  98. <view class="acea-row row-between-wrapper">
  99. <view v-if="item.value" class="text-28rpx">{{item.value}}</view>
  100. <view v-else class="text--w111-ccc text-28rpx">请选择</view>
  101. <text class='iconfont icon-xiangxia'></text>
  102. </view>
  103. </picker>
  104. </view>
  105. <!-- city -->
  106. <view v-if="item.name=='citys'" class="discount" @click="changeRegion(index)">
  107. <view class="acea-row row-middle row-right">
  108. <view class="city text--w111-ccc" v-if="item.value == ''">{{item.tipConfig.val}}</view>
  109. <view class="city text-28rpx" v-else>{{item.value}}</view>
  110. <text class='iconfont icon-xiangxia'></text>
  111. </view>
  112. </view>
  113. <!-- id -->
  114. <view v-if="item.name=='texts' && item.valConfig.tabVal == 2" class="discount">
  115. <input type="idcard" :placeholder="item.tipConfig.val" class="text-28rpx" placeholder-class="placeholder"
  116. v-model="item.value" />
  117. </view>
  118. <!-- phone -->
  119. <view v-if="item.name=='texts' && item.valConfig.tabVal == 1" class="discount">
  120. <input type="number" :placeholder="item.tipConfig.val" class="text-28rpx" placeholder-class="placeholder"
  121. v-model="item.value" />
  122. </view>
  123. <!-- img -->
  124. <view v-if="item.name=='uploadPicture'" class="confirmImg" style="padding-bottom: 0;">
  125. <view class='upload acea-row row-middle justify-end'>
  126. <view class='pictrue' v-for="(items,indexs) in item.value" :key="indexs">
  127. <image :src='items' mode="aspectFill"></image>
  128. <view class="close acea-row row-center-wrapper" @tap='DelPic(index,indexs)'>
  129. <view class="iconfont icon-guanbi1"></view>
  130. </view>
  131. </view>
  132. <view class='pictrue acea-row row-center-wrapper row-column' @tap='uploadpic(item)' style="margin-right: 0"
  133. v-if="item.value.length < item.numConfig.val">
  134. <view>上传图片</view>
  135. </view>
  136. </view>
  137. </view>
  138. </view>
  139. <!-- 时间选择 -->
  140. <timerangesFrom :isShow='isShow' :time='timeranges' @confrim="confrim" @cancel="cancels"></timerangesFrom>
  141. <areaWindow ref="areaWindow" :display="display" :address='addressInfoArea' :cityShow='cityShow'
  142. @submit="OnChangeAddress" @changeClose="changeAddressClose"></areaWindow>
  143. </view>
  144. </template>
  145. <script>
  146. import areaWindow from '../areaWindow';
  147. import timerangesFrom from '../timeranges';
  148. import uniDatetimePicker from '../uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue';
  149. import dayjs from "@/plugin/dayjs/dayjs.min.js";
  150. const CACHE_CITY = {};
  151. export default {
  152. props: {
  153. value: {
  154. type: Array,
  155. default: function() {
  156. return []
  157. }
  158. },
  159. },
  160. components: {
  161. areaWindow,
  162. timerangesFrom,
  163. uniDatetimePicker
  164. },
  165. data() {
  166. return {
  167. orderNewForm: [],
  168. isShow: false,
  169. timerangesIndex: 0,
  170. display: false,
  171. addressInfoArea: [],
  172. cityShow: 2,
  173. timeranges: [],
  174. }
  175. },
  176. watch: {
  177. orderNewForm: {
  178. handler(newVal) {
  179. this.$emit('input', newVal);
  180. },
  181. deep: true,
  182. },
  183. },
  184. mounted() {
  185. this.getFromData()
  186. },
  187. methods: {
  188. getFromData() {
  189. let formData = [...this.value];
  190. formData.forEach((item, index, arr) => {
  191. this.$set(item, 'value', "");
  192. CACHE_CITY[index] = ''; //清空省市区
  193. if (item.name == 'texts') {
  194. if (item.defaultValConfig.val) {
  195. item.value = item.defaultValConfig.val
  196. } else {
  197. item.value = ''
  198. }
  199. } else if (item.name == 'radios') {
  200. item.value = item.wordsConfig.list[0].val
  201. } else if (item.name == 'uploadPicture') {
  202. item.value = [];
  203. } else if (item.name == 'dateranges') {
  204. if (item.valConfig.tabVal == 0) {
  205. if (item.valConfig.tabData == 0) {
  206. let obj = dayjs(new Date(Number(new Date().getTime()))).format('YYYY-MM-DD');
  207. item.value = [obj, obj]
  208. } else {
  209. let data1 = dayjs(new Date(Number(new Date(item.valConfig.specifyDate[0])
  210. .getTime()))).format('YYYY-MM-DD');
  211. let data2 = dayjs(new Date(Number(new Date(item.valConfig.specifyDate[1])
  212. .getTime()))).format('YYYY-MM-DD');
  213. item.value = [data1, data2];
  214. }
  215. } else {
  216. item.value = [];
  217. }
  218. } else {
  219. if (['times', 'dates', 'timeranges'].indexOf(item.name) != -1) {
  220. if (item.valConfig.tabVal == 0) { //显示默认值
  221. if (item.valConfig.tabData == 0) {
  222. if (item.name == 'times') {
  223. item.value = dayjs(new Date(Number(new Date().getTime()))).format('HH:mm');
  224. } else if (item.name == 'dates') {
  225. item.value = dayjs(new Date(Number(new Date().getTime()))).format(
  226. 'YYYY-MM-DD');
  227. } else {
  228. let current = dayjs(new Date(Number(new Date().getTime()))).format(
  229. 'HH:mm');
  230. item.value = current + ' - ' + current;
  231. }
  232. } else {
  233. if (item.name == 'times' || item.name == 'dates') {
  234. item.value = item.valConfig.specifyDate;
  235. } else {
  236. item.value = item.valConfig.specifyDate[0] + ' - ' + item.valConfig
  237. .specifyDate[1];
  238. }
  239. }
  240. } else {
  241. item.value = '';
  242. }
  243. } else {
  244. item.value = '';
  245. }
  246. }
  247. })
  248. function sortNumber(a, b) {
  249. return a.timestamp - b.timestamp;
  250. }
  251. formData.sort(sortNumber);
  252. this.$set(this, 'orderNewForm', formData);
  253. },
  254. // 单选
  255. radioChange(e, index, item) {
  256. this.orderNewForm[index].value = item.wordsConfig.list[e.detail.value].val
  257. },
  258. // 多选
  259. checkboxChange(e, index, item) {
  260. let obj = e.detail.value;
  261. let val = '';
  262. item.wordsConfig.list.forEach((j, jindex) => {
  263. obj.forEach(x => {
  264. if (jindex == x) {
  265. val = val + (val ? ',' : '') + j.val;
  266. }
  267. })
  268. })
  269. this.orderNewForm[index].value = val
  270. },
  271. //日期
  272. bindDateChange(e, index) {
  273. this.orderNewForm[index].value = e.target.value
  274. this.$forceUpdate()
  275. },
  276. //时间
  277. bindTimeChange(e, index) {
  278. this.orderNewForm[index].value = e.target.value
  279. },
  280. //时间选择
  281. getTimeranges(index) {
  282. this.isShow = true
  283. this.timerangesIndex = index
  284. },
  285. //时间选择回调
  286. confrim(e) {
  287. this.isShow = false;
  288. this.orderNewForm[this.timerangesIndex].value = e.time;
  289. let arrayNew = [];
  290. e.val.forEach(item => {
  291. arrayNew.push(Number(item))
  292. })
  293. this.timeranges = arrayNew;
  294. },
  295. //关闭时间选择弹窗
  296. cancels() {
  297. this.isShow = false;
  298. },
  299. //sel选择
  300. bindSelectChange(e, index, item) {
  301. this.$set(this.orderNewForm[index], 'value', item.wordsConfig.list[e.detail.value].val);
  302. },
  303. //城市地址选择
  304. changeRegion(index) {
  305. if (!this.orderNewForm[index].value) {
  306. this.addressInfoArea = [];
  307. }
  308. this.timerangesIndex = index;
  309. this.cityShow = Number(this.orderNewForm[index].valConfig.tabVal) + 1;
  310. this.display = true;
  311. if (CACHE_CITY[index]) {
  312. this.addressInfoArea = CACHE_CITY[index];
  313. }
  314. },
  315. //选择地址回调
  316. OnChangeAddress(address) {
  317. // let addr = '';
  318. let addr = address.map(v => v.regionName).join('/');
  319. this.orderNewForm[this.timerangesIndex].value = addr;
  320. CACHE_CITY[this.timerangesIndex] = address;
  321. },
  322. // 关闭地址弹窗;
  323. changeAddressClose() {
  324. this.display = false;
  325. },
  326. /**上传文件*/
  327. uploadpic(item) {
  328. let that = this;
  329. that.$util.uploadImageOne({
  330. url: 'upload/image',
  331. name: 'multipart',
  332. model: "order",
  333. pid: 0
  334. }, function(res) {
  335. let pics = item.value || []
  336. pics.push(res);
  337. that.$set(item, 'value', pics);
  338. });
  339. },
  340. //删除图片
  341. DelPic(index, indexs) {
  342. let pic = this.orderNewForm[index].value;
  343. this.orderNewForm[index].value.splice(indexs, 1);
  344. this.$set(this.orderNewForm[index], 'value', this.orderNewForm[index].value);
  345. },
  346. }
  347. }
  348. </script>
  349. <style scoped lang="scss">
  350. .item {
  351. font-size: 28rpx;
  352. color: #282828;
  353. margin-top: 20rpx;
  354. }
  355. .name{
  356. width: 168rpx;
  357. }
  358. .virtual_form {
  359. .uni-input-wrapper {
  360. text-align: right;
  361. }
  362. .item-require {
  363. color: red;
  364. margin-right: 4rpx;
  365. }
  366. .item {
  367. padding: 27rpx 0;
  368. .pd0 {
  369. padding-bottom: 0;
  370. }
  371. .radio {
  372. margin: 0 22rpx 0 22rpx;
  373. padding: 10rpx 0;
  374. }
  375. .discount .placeholder {
  376. color: #ccc;
  377. text-align: right;
  378. font-size: 28rpx;
  379. }
  380. .discount {
  381. max-width: 480rpx;
  382. font-size: 28rpx;
  383. text-align: right;
  384. &.discount_voice {
  385. overflow: hidden;
  386. text-overflow: ellipsis;
  387. white-space: nowrap;
  388. max-width: 460rpx;
  389. text-align: right;
  390. }
  391. .iconfont {
  392. color: #515151;
  393. font-size: 20rpx;
  394. margin-left: 12rpx;
  395. }
  396. .num {
  397. font-size: 28rpx;
  398. margin-right: 20rpx;
  399. }
  400. }
  401. }
  402. }
  403. </style>