index.vue 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <template>
  2. <div class="volume-container">
  3. <div class="body scroll-view">
  4. <div class="bl-flex hw" center>
  5. <div class="bl-flex" size-md bg-color-f items-center padding-sm padding-left-md padding-right-md round-pie1
  6. v-if="$route.query.buyer">
  7. <i class="font-ileads ileads-icon-gouxuan1" size-lg color-success margin-right-sm></i>
  8. <div bold>购买成功</div>
  9. </div>
  10. </div>
  11. <div class="bl-flex" v-if="data.topic.is_memo && data.topic.memo" column padding-left-lg>
  12. <div color-f bold class="h-memo-h1">留下您的联系方式,</div>
  13. <div color-f bold class="h-memo-h2">我们尽快为您预约哦</div>
  14. </div>
  15. <div class="bl-flex" column padding-lg>
  16. <div class="bl-flex" flex-end>
  17. <div class="bl-flex">
  18. <img :src="ImgLeads1" class="il-img2" />
  19. </div>
  20. </div>
  21. <div class="bl-flex card" column card not-margin not-padding>
  22. <div margin-bottom-md shadow round padding-bottom-sm padding-top-xs
  23. v-for="(combo, comboIndex) in putResult"
  24. :key="comboIndex">
  25. <div class="bl-flex" flex-wrap items-center between border-bottom padding-md padding-left-lg
  26. v-if="combo.id">
  27. <div color-warning bold size-sm>{{ combo.name }}</div>
  28. <span color active padding-top-xs padding-bottom-xs size-xs v-if="!!comboIndex" @click="copyPrevVal(combo.result, comboIndex)">与上一个内容一致</span>
  29. </div>
  30. <transition-group name="flip-list" class="volume-content bl-flex" tag="div" column size-sm padding-left-lg padding-right-lg>
  31. <div
  32. v-for="(item, index) in combo.result"
  33. :key="index + 1"
  34. :class="{ cur: edataItem === item }"
  35. @click="$emit('selectItem', item)">
  36. <div class="bl-flex" border-bottom
  37. :items-center="item.type != 'textarea'">
  38. <label class="f-label" nowrap :padding-top-lg="item.type == 'textarea'">
  39. <span v-if="item.required" color-error>*</span>
  40. {{ item.title }}
  41. </label>
  42. <div flex1>
  43. <textarea
  44. v-model="item.val"
  45. :maxlength="item.max || 200" placeholder="请填写"
  46. :text-right="(item.layout_align || data.topic.layout_align) === 'right'"
  47. v-if="item.type === 'textarea'" />
  48. <input v-model="item.val"
  49. :maxlength="item.max || 200"
  50. :text-right="(item.layout_align || data.topic.layout_align) === 'right'"
  51. :placeholder="['input'].includes(item.type) ? '请填写' : '请选择'"
  52. :readonly="!['input'].includes(item.type) || item.disabled"
  53. v-if="['input', 'select', 'date'].includes(item.type)"
  54. @click="!['input'].includes(item.type) && btnOpen(item)" />
  55. <div class="slider-layout" v-if="item.type === 'slider'">
  56. <div class="val" v-if="item.val">{{ item.val }}</div>
  57. <div class="warn" v-else>拨动滑块选择</div>
  58. <van-slider
  59. v-model="item.sliderVal"
  60. :min="-1"
  61. :max="item.content.length - 1"
  62. @input="item.val = (item.content[item.sliderVal] || {}).title || ''" />
  63. <div class="ruler-layout">
  64. <div class="ruler-item">
  65. <span></span>
  66. </div>
  67. <div class="ruler-item"
  68. v-for="(it, itIndex) in item.content"
  69. :key="itIndex">
  70. <span v-if="!it.sliderHide">
  71. {{ it.title }}
  72. <br v-if="it.memo" />
  73. {{ it.memo || '' }}
  74. </span>
  75. </div>
  76. </div>
  77. </div>
  78. <van-radio-group padding-top-sm padding-bottom-sm
  79. v-model="item.val"
  80. :style="{ justifyContent: (item.layout_align || data.topic.layout_align) === 'right' ? 'flex-end' : 'flex-start' }"
  81. :direction="(item.layout_inline || data.topic.layout_inline) === 2 ? 'vertical' : 'horizontal'"
  82. v-if="['radio'].includes(item.type)">
  83. <van-radio
  84. :class="(item.layout_inline || data.topic.layout_inline) === 2 ? 'vertical' : 'horizontal'"
  85. :name="it.title"
  86. v-for="(it, itIndex) in item.content"
  87. :key="itIndex">{{ it.title }}{{ it.memo && `(${it.memo})` }}</van-radio>
  88. </van-radio-group>
  89. <van-checkbox-group padding-top-sm padding-bottom-sm
  90. v-model="item.val"
  91. :style="{ justifyContent: (item.layout_align || data.topic.layout_align) === 'right' ? 'flex-end' : 'flex-start' }"
  92. :direction="(item.layout_inline || data.topic.layout_inline) === 2 ? 'vertical' : 'horizontal'"
  93. :max="item.max"
  94. v-if="item.type === 'checkbox'">
  95. <van-checkbox
  96. :class="(item.layout_inline || data.topic.layout_inline) === 2 ? 'vertical' : 'horizontal'"
  97. :name="it.title"
  98. v-for="(it, itIndex) in item.content"
  99. :key="itIndex"
  100. shape="square">{{ it.title }}{{ it.memo && `(${it.memo})` }}</van-checkbox>
  101. </van-checkbox-group>
  102. </div>
  103. <i class="font-ileads ileads-icon-jiantou" color-des padding-sm not-padding-right
  104. v-if="['select', 'date'].includes(item.type)"
  105. @click="btnOpen(item)"></i>
  106. </div>
  107. </div>
  108. </transition-group>
  109. </div>
  110. <div class="bl-flex" relative between padding-top-lg>
  111. <div class="l-pie" round-pie bg-color-6></div>
  112. <div class="r-pie" round-pie bg-color-6></div>
  113. </div>
  114. <div class="bl-flex" padding-lg padding-left-xl padding-right-xl v-if="!!data.result.length">
  115. <button class="btn primary" round-pie1
  116. :disabled="loading.submit || !data.result.length"
  117. @click="$emit('submit', combos)">提交</button>
  118. </div>
  119. </div>
  120. </div>
  121. </div>
  122. <slot />
  123. <van-popup v-model="show.picker" position="bottom">
  124. <van-picker
  125. :title="comPicker.title"
  126. show-toolbar
  127. :columns="comPicker.columns"
  128. @confirm="onConfirmPicker"
  129. @cancel="onCancelPicker"
  130. />
  131. </van-popup>
  132. <van-popup v-model="show.date" position="bottom">
  133. <van-datetime-picker
  134. v-model="comDate.currentDate"
  135. type="date"
  136. :title="comDate.title"
  137. :min-date="minDate"
  138. :max-date="maxDate"
  139. @confirm="onConfirmDate"
  140. @cancel="onCancelDate"
  141. />
  142. </van-popup>
  143. </div>
  144. </template>
  145. <script>
  146. import mixinLayout from '../mixins/layout'
  147. import ImgLeads1 from '~/img/leads-img1.png'
  148. export default {
  149. mixins: [mixinLayout],
  150. data () {
  151. let maxDate = new Date()
  152. let minDate = new Date(maxDate.getFullYear() - 100, 0, 1)
  153. return {
  154. ImgLeads1,
  155. maxDate,
  156. minDate,
  157. show: {
  158. picker: false,
  159. date: false
  160. },
  161. comPicker: {
  162. title: '',
  163. columns: [],
  164. defaultIndex: 0,
  165. data: {}
  166. },
  167. comDate: {
  168. title: '',
  169. currentDate: '',
  170. data: {}
  171. },
  172. combos: []
  173. }
  174. },
  175. computed: {
  176. putResult () {
  177. return (this.combos && this.combos.length)
  178. ? this.combos
  179. : [this.data]
  180. }
  181. },
  182. methods: {
  183. btnOpen (item) {
  184. let config = {
  185. 'select': () => this.onOpenPicker(item),
  186. 'date': () => this.onOpenDate(item)
  187. }
  188. let fn = config[item.type]
  189. fn && fn()
  190. },
  191. onOpenPicker (item) {
  192. let columns = item.content.map(it => it.title)
  193. let index = columns.indexOf(item.val)
  194. this.$set(this, 'comPicker', {
  195. title: `请选择${item.title}`,
  196. columns,
  197. defaultIndex: index != -1 ? index : 0,
  198. data: item
  199. })
  200. this.show.picker = true
  201. },
  202. onConfirmPicker (value) {
  203. this.comPicker.data.val = value
  204. this.onCancelPicker()
  205. },
  206. onCancelPicker () {
  207. this.show.picker = false
  208. },
  209. onOpenDate (item) {
  210. let currentDate
  211. try {
  212. if (item.val) {
  213. currentDate = new Date(item.val.replace(/-/g, '/'))
  214. } else {
  215. currentDate = new Date()
  216. }
  217. } catch (err) {
  218. currentDate = new Date()
  219. }
  220. this.$set(this, 'comDate', {
  221. title: `请选择${item.title}`,
  222. currentDate,
  223. data: item
  224. })
  225. this.show.date = true
  226. },
  227. onConfirmDate (value) {
  228. this.comDate.data.val = value.toString('yyyy-MM-dd')
  229. this.onCancelDate()
  230. },
  231. onCancelDate () {
  232. this.show.date = false
  233. },
  234. inCombos () {
  235. let { ids, combos } = this.$route.query
  236. let arr_ids = ids && ids.split(',')
  237. let arr_combos = combos && combos.split(',')
  238. let comboRst = arr_ids && arr_ids.map((id, index) => {
  239. return {
  240. id,
  241. name: arr_combos[index],
  242. query: {
  243. buyer_id: id
  244. },
  245. result: JSON.parse(JSON.stringify(this.data.result))
  246. }
  247. })
  248. this.combos = comboRst
  249. },
  250. // 与上一个内容一致
  251. copyPrevVal (result, index) {
  252. try {
  253. let prevItem = this.combos[index - 1]
  254. if (!prevItem) {
  255. throw new Error('缺少上一个表单对象')
  256. }
  257. result.forEach((item, i) => {
  258. item.val = prevItem.result[i].val
  259. })
  260. } catch (err) {
  261. this.$toast.fail('引用错误')
  262. }
  263. },
  264. init () {
  265. this.inCombos()
  266. }
  267. },
  268. created () {
  269. this.init()
  270. }
  271. }
  272. </script>
  273. <style lang="scss" scoped>
  274. @import './style.scss';
  275. </style>