order-submit.vue 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102
  1. <template>
  2. <app-layout>
  3. <view class="page" v-if="previewData">
  4. <template v-if="previewData.show_address !== false">
  5. <view v-if="previewData.allZiti" class="address">
  6. <app-order-submit-row :show-nav="false" :no-padding="true">
  7. <view class="dir-left-nowrap px-12">
  8. <view class="box-grow-1">
  9. <app-input placeholder="请填写联系人" height="100"
  10. v-model="previewData.address.name"></app-input>
  11. </view>
  12. <view class="box-grow-1">
  13. <app-input placeholder="请填写手机号" height="100"
  14. v-model="previewData.address.mobile"></app-input>
  15. </view>
  16. </view>
  17. <view slot="footer">
  18. <image class="bottom-image" :src="appImg.common.address_bottom"></image>
  19. </view>
  20. </app-order-submit-row>
  21. </view>
  22. <view v-else @click="navigateAddress" class="address">
  23. <app-order-submit-row>
  24. <view v-if="previewData.address">
  25. <!-- <view class="dir-left-nowrap mb-12">
  26. <view class="box-grow-1">参训人: {{previewData.address.name}}</view>
  27. <view class="box-grow-0">电话: {{previewData.address.mobile}}</view>
  28. </view>
  29. <view class="mb-12">
  30. 收货地址:
  31. {{previewData.address.province}}
  32. {{previewData.address.city}}
  33. {{previewData.address.district}}
  34. {{previewData.address.detail}}
  35. </view> -->
  36. <!-- <view class="dir-left-nowrap mb-12">
  37. <view class="box-grow-1">性别: {{previewData.address.name}}</view>
  38. <view class="box-grow-0">年龄: {{previewData.address.mobile}}</view>
  39. </view>
  40. <view class="dir-left-nowrap mb-12">
  41. <view class="box-grow-1">体重: {{previewData.address.name}}</view>
  42. <view class="box-grow-0">年龄: {{previewData.address.mobile}}</view>
  43. </view>
  44. <view class="dir-left-nowrap mb-12">
  45. <view class="box-grow-1">身高: {{previewData.address.name}}</view>
  46. <view class="box-grow-0">身份证号码: {{previewData.address.mobile}}</view>
  47. </view> -->
  48. <view class="felx-three">
  49. <view class="box-grow-2">
  50. 参训人: 诸葛村夫
  51. </view>
  52. <view class="box-grow-3">
  53. 性别: 男
  54. </view>
  55. <view class="box-grow-4">
  56. 联系电话: 13985840801
  57. </view>
  58. </view>
  59. <view class="felx-three">
  60. <view class="box-grow-2">
  61. 年龄: 100
  62. </view>
  63. <view class="box-grow-3">
  64. 体重: 男
  65. </view>
  66. <view class="box-grow-4">
  67. 身高: 13985840801
  68. </view>
  69. </view>
  70. <view class="felx-three">
  71. <view class="box-grow-5">
  72. 身份证号码: 51300198808080018
  73. </view>
  74. </view>
  75. </view>
  76. <view v-else>请选择收货地址</view>
  77. <view v-if="previewData.has_ziti" class="ziti-tip" :class="[`${theme}-color`]">
  78. (收货地址中的手机号码将用于自提信息)
  79. </view>
  80. <!-- <view slot="footer">
  81. <image class="bottom-image" :src="appImg.common.address_bottom"></image>
  82. </view> -->
  83. </app-order-submit-row>
  84. </view>
  85. </template>
  86. <view class="mch-list">
  87. <view v-for="(mch, mchIndex) in previewData.mch_list"
  88. :key="mchIndex"
  89. class="mch-item">
  90. <view class="mch-name">{{mch.mch.name}}</view>
  91. <!-- <view v-if="mch.show_delivery !== false" class="dir-left-nowrap cross-center delivery">
  92. <view class="box-grow-1">配送方式</view>
  93. <view class="box-grow-0">
  94. <view v-for="(sendType, sendTypeIndex) in mch.delivery.send_type_list"
  95. :key="sendTypeIndex"
  96. class="send-type"
  97. :class="sendType.value == mch.delivery.send_type ? `${theme}-background` : 'weak-two-background'"
  98. @click="changeSendType(mchIndex,sendType.value)">
  99. {{sendType.name}}
  100. </view>
  101. </view>
  102. </view> -->
  103. <view class="pick-up cross-center" v-if="!mch.pick_up_enable">
  104. <view>以下商品满{{mch.pick_up_price}}元起送</view>
  105. </view>
  106. <view v-if="mch.delivery.send_type == 'offline'" class="store">
  107. <app-order-submit-row v-if="mch.no_store && mch.no_store === true" :show-nav="false">
  108. 暂无门店,请选择其他配送方式
  109. </app-order-submit-row>
  110. <app-order-submit-row v-else @click="navigateStore(mchIndex)" :show-nav="mch.mch.id == 0">
  111. <view slot="header" class="title">门店信息</view>
  112. <template v-if="mch.store">
  113. <view class="dir-left-nowrap mb-12">
  114. <view class="box-grow-1">{{mch.store.name}}</view>
  115. <view class="box-grow-0 location">
  116. <image class="icon" src="/static/image/icon/location.png"></image>
  117. <view v-if="getLocationFail" class="inline-block">
  118. <view class="inline-block">定位失败</view>
  119. <view class="inline-block open-location-setting"
  120. @click.stop="openLocationSetting">
  121. <view class="open-location-btn" :class="[
  122. `${theme}-color`, `${theme}-border`,
  123. ]">获取位置
  124. </view>
  125. </view>
  126. </view>
  127. <view v-else class="inline-block">距离您{{mch.store.distance}}</view>
  128. </view>
  129. </view>
  130. <view class="store-address">{{mch.store.address}}</view>
  131. </template>
  132. <view v-else>请选择门店</view>
  133. </app-order-submit-row>
  134. </view>
  135. <view v-else-if="mch.delivery.send_type == 'city' && mch.city" class="city">
  136. <template v-if="mch.city.error">
  137. <view class="dir-left-nowrap cross-center">
  138. <view class="box-grow-1 t-omit error">{{mch.city.error}}</view>
  139. <view class="box-grow-0 btn" @click="jump(mchIndex)">查看配送范围</view>
  140. </view>
  141. </template>
  142. <template v-else>
  143. <view class="t-omit">发货地址:{{mch.city.address}}</view>
  144. <view class="t-omit" v-if="mch.city.explain">{{mch.city.explain}}</view>
  145. <view class="dir-left-nowrap cross-center">
  146. <view class="box-grow-1 t-omit error" style="color: #353535;">该地址在配送范围内</view>
  147. <view class="box-grow-0 btn" @click="jump(mchIndex)">查看配送范围</view>
  148. </view>
  149. </template>
  150. </view>
  151. <app-submit-goods v-on:updateList="updateList" :index="mchIndex" :plugin="plugin" :list="mch"></app-submit-goods>
  152. <template v-if="mch.insert_rows && mch.insert_rows.length">
  153. <view v-for="(insertRow, insertRowIndex) in mch.insert_rows" :key="insertRowIndex">
  154. <app-order-submit-row :show-nav="false">
  155. <view class="dir-left-nowrap">
  156. <view class="box-grow-1">{{insertRow.title}}</view>
  157. <view class="box-grow-0" :class="[`${theme}-color`]">{{insertRow.value}}</view>
  158. </view>
  159. </app-order-submit-row>
  160. </view>
  161. </template>
  162. <view v-if="mch.coupon && mch.coupon.enabled" class="coupon" @click="navigateCoupon(mchIndex)">
  163. <app-order-submit-row>
  164. <view class="dir-left-nowrap">
  165. <view class="box-grow-1">优惠券</view>
  166. <view class="box-grow-0" v-if="mch.coupon.use" :class="[`${theme}-color`]">
  167. 已优惠{{mch.coupon.coupon_discount}}元
  168. </view>
  169. <view class="box-grow-0 tip" v-else>选择优惠券</view>
  170. </view>
  171. </app-order-submit-row>
  172. </view>
  173. <view v-if="mch.integral && mch.integral.can_use" class="integral">
  174. <app-order-submit-row
  175. :show-nav="false">
  176. <view class="dir-left-nowrap">
  177. <view class="box-grow-1 dir-left-nowrap">
  178. <view>
  179. 使用
  180. {{mch.integral.use_num}}
  181. 积分抵扣
  182. <text :class="[`${theme}-color`]">{{mch.integral.deduction_price}}</text>
  183. </view>
  184. <view class="tip-btn" @click="showIntegralTip">
  185. <image class="icon" src="/static/image/icon/warning.png"></image>
  186. </view>
  187. </view>
  188. <view class="box-grow-0">
  189. <app-radio type="round" :value="mch.integral.use" :theme="theme"
  190. @input="changeIntegral(mchIndex)"></app-radio>
  191. </view>
  192. </view>
  193. </app-order-submit-row>
  194. <!-- <view>
  195. </view> -->
  196. </view>
  197. <!-- <view v-if="mch.show_express_price !== false">
  198. <app-order-submit-row :show-nav="false" :showBorder="false">
  199. <view class="dir-left-nowrap">
  200. <view class="box-grow-1">运费</view>
  201. <view class="box-grow-0 express-price" :class="[`${theme}-color`]">
  202. <template v-if="mch.express_price_origin && mch.express_price_desc">
  203. <view>¥{{mch.express_price_origin}}元</view>
  204. <view class="express-price-desc">{{mch.express_price_desc}}
  205. </view>
  206. </template>
  207. <view v-else>¥{{mch.express_price}}元</view>
  208. </view>
  209. </view>
  210. </app-order-submit-row>
  211. </view> -->
  212. <view v-if="mch.order_form && mch.order_form.status == '1'">
  213. <app-diy-form :title="mch.order_form.name"
  214. :list="mch.order_form.value"
  215. @input="handleOrderFormInput"
  216. @validate="handleOrderFormValidate"
  217. :sign="mchIndex"
  218. label-position="top"
  219. :show-scroll-btn="mch.order_form.show_scroll"></app-diy-form>
  220. </view>
  221. <view v-else-if="mch.show_remark !== false && mch.has_goods_form !== true" class="remark">
  222. <app-input @input="inputRemark(mchIndex)"
  223. v-model="mch.remark"
  224. placeholder="买家留言"
  225. height="100"></app-input>
  226. </view>
  227. <template v-if="mch.has_goods_form">
  228. <view v-for="(goodsItem, goodsIndex) in mch.goods_list"
  229. :key="goodsIndex"
  230. v-if="goodsItem.form && !goodsItem.form.same_form"
  231. style="margin-bottom: 20rpx">
  232. <view style="padding: 24rpx; color: #666666">{{goodsItem.form.name}}</view>
  233. <view class="goods-list" v-if="mch.diff_goods_form_count !== 1">
  234. <view v-for="(subGoodsItem, subGoodsIndex) in mch.goods_list"
  235. :key="subGoodsIndex"
  236. v-if="subGoodsItem.form && subGoodsItem.form.id == goodsItem.form.id"
  237. class="dir-left-nowrap goods-item">
  238. <view class="box-grow-0">
  239. <image class="goods-image"
  240. :src="subGoodsItem.goods_attr.pic_url ? subGoodsItem.goods_attr.pic_url : subGoodsItem.cover_pic"></image>
  241. </view>
  242. <view class="box-grow-1">
  243. <view class="goods-name">{{subGoodsItem.name}}</view>
  244. <view class="dir-left-wrap attr-list">
  245. <view v-for="(attrItem,attrIndex) in subGoodsItem.attr_list"
  246. :key="attrIndex"
  247. class="attr-item">
  248. {{attrItem.attr_group_name}}:{{attrItem.attr_name}}
  249. </view>
  250. </view>
  251. <view class="dir-left-nowrap">
  252. <view class="box-grow-1 goods-num">×{{subGoodsItem.num}}</view>
  253. <view class="box-grow-0 goods-price-info" :class="[`${theme}-color`]">
  254. <view>
  255. <text v-for="(customCurrency,customCurrencyIndex) in subGoodsItem.custom_currency"
  256. :key="customCurrencyIndex">
  257. {{customCurrency}}+
  258. </text>
  259. <text class="goods-price-unit">¥</text>
  260. <text>{{subGoodsItem.total_original_price}}</text>
  261. </view>
  262. <view v-for="(discount,discountIndex) in subGoodsItem.discounts"
  263. :key="discountIndex">
  264. {{discount.name}}: {{discount.value}}
  265. </view>
  266. </view>
  267. </view>
  268. </view>
  269. </view>
  270. </view>
  271. <app-diy-form
  272. :list="goodsItem.form.value"
  273. @input="handleGoodsFormInput"
  274. @validate="handleGoodsFormValidate"
  275. :sign="`${mchIndex},${goodsIndex},${goodsItem.form.id}`"></app-diy-form>
  276. </view>
  277. </template>
  278. </view><!-- mch item end -->
  279. </view>
  280. </view>
  281. <view>
  282. <view class="submit-bar dir-left-nowrap" v-if="previewData">
  283. <view class="box-grow-1 cross-center order-info" :class="[`${theme}-color`]">
  284. <view style="display: inline-block;">{{totalTitle}}:</view>
  285. <view style="display: inline-block;"
  286. v-for="custom_currency in previewData.custom_currency_all" :key="custom_currency">
  287. {{custom_currency}}+
  288. </view>
  289. <view style="display: inline-block;white-space: nowrap;">¥{{previewData.total_price}}
  290. <view style="content: ' ';display: inline-block;width: 20rpx;"></view>
  291. </view>
  292. </view>
  293. <template v-if="previewData.address_enable && previewData.price_enable">
  294. <view @click="subscribe" class="submit-btn box-grow-0 cross-center"
  295. :class="[`${theme}-background`, submitLock?'lock':'']">
  296. <view style="background-color: transparent;color:#ffffff;">提交</view>
  297. </view>
  298. </template>
  299. <template v-else>
  300. <view v-if="!previewData.address_enable" class="submit-btn box-grow-0 cross-center disabled"
  301. :class="[`${theme}-background`]">
  302. <view style="background-color: transparent;">该地区无货</view>
  303. </view>
  304. <view v-else class="submit-btn box-grow-0 cross-center disabled"
  305. :class="[`${theme}-background`]">
  306. <view style="background-color: transparent;">未达起送要求</view>
  307. </view>
  308. </template>
  309. </view>
  310. </view>
  311. </app-layout>
  312. </template>
  313. <script>
  314. import {mapState} from 'vuex';
  315. import AppRadio from '../../components/basic-component/app-radio/app-radio.vue';
  316. import AppOrderSubmitRow from './app-order-submit-row.vue';
  317. import AppDiyForm from "../../components/page-component/app-diy-form/app-diy-form";
  318. import appSubmitGoods from '../../components/basic-component/app-submit-goods/app-submit-goods.vue';
  319. export default {
  320. name: 'order-submit',
  321. components: {AppDiyForm, AppRadio, AppOrderSubmitRow, appSubmitGoods},
  322. data() {
  323. return {
  324. totalTitle: '合计',
  325. check: false,
  326. previewData: null,
  327. getLocationFail: false,
  328. previewUrl: null,
  329. submitUrl: null,
  330. plugin: null,
  331. orderPageUrl: null,
  332. submitLock: false,
  333. getPayDataTimer: null,
  334. userTheme: null,
  335. payDataUrl: null,
  336. showPayResult: true,
  337. payCancelUrl: null,
  338. };
  339. },
  340. computed: {
  341. ...mapState({
  342. appImg: state => state.mallConfig.__wxapp_img,
  343. }),
  344. theme() {
  345. return this.userTheme ? this.userTheme : this.$store.state.mallConfig.theme;
  346. },
  347. },
  348. onLoad(options) {
  349. if (this.submitLock) return;
  350. this.setFormData(options);
  351. this.$event.on(this.$const.EVENT_USER_LOGIN).then(() => {
  352. this.loadPreviewData();
  353. });
  354. },
  355. onShow() {
  356. if (this.submitLock) return;
  357. // #ifdef MP-BAIDU
  358. setTimeout(() => {
  359. this.loadPreviewData();
  360. }, 50);
  361. // #endif
  362. // #ifndef MP-BAIDU
  363. this.loadPreviewData();
  364. // #endif
  365. },
  366. onHide() {
  367. console.log('onHide');
  368. },
  369. onUnload() {
  370. console.log('onUnload');
  371. if (this.getPayDataTimer) {
  372. clearTimeout(this.getPayDataTimer);
  373. }
  374. },
  375. watch: {
  376. 'previewData.address.name': {
  377. handler() {
  378. this.changeZitiAddress();
  379. },
  380. },
  381. 'previewData.address.mobile': {
  382. handler() {
  383. this.changeZitiAddress();
  384. },
  385. },
  386. },
  387. methods: {
  388. updateList(e,index) {
  389. this.previewData.mch_list[index] = e;
  390. console.log(this.previewData.mch_list)
  391. this.$forceUpdate();
  392. },
  393. setParams(options) {
  394. if (options.total_title) {
  395. this.totalTitle = options.total_title;
  396. }
  397. },
  398. handleOrderFormInput(data, sign) {
  399. const result = [];
  400. for (let i in data) {
  401. result[i] = {
  402. key: data[i].key,
  403. label: data[i].name,
  404. value: data[i].value,
  405. required: data[i].is_required,
  406. };
  407. }
  408. const formData = this.$store.state.orderSubmit.formData;
  409. formData.list[sign].order_form = result;
  410. this.$store.commit('orderSubmit/mutSetFormData', formData);
  411. },
  412. handleOrderFormValidate(result, sign) {
  413. console.log('handleOrderFormValidate:', result, sign);
  414. const formData = this.$store.state.orderSubmit.formData;
  415. formData.list[sign].order_form_validate_result = result;
  416. this.$store.commit('orderSubmit/mutSetFormData', formData);
  417. },
  418. setFormData(options) {
  419. this.previewUrl = decodeURIComponent(options.preview_url || this.$api.order.preview);
  420. this.submitUrl = decodeURIComponent(options.submit_url || this.$api.order.submit);
  421. this.plugin = options.plugin || null;
  422. console.log(options.plugin);
  423. this.orderPageUrl = decodeURIComponent(options.order_page_url || '/pages/order/index/index?status=0');
  424. this.userTheme = options.theme || null;
  425. this.payDataUrl = decodeURIComponent(options.pay_data_url || this.$api.order.pay_data);
  426. this.payCancelUrl = options.pay_cancel_url ? decodeURIComponent(options.pay_cancel_url) : null;
  427. this.showPayResult = options.show_pay_result || true;
  428. if (this.showPayResult === 'true') this.showPayResult = true;
  429. if (this.showPayResult === 'false') this.showPayResult = false;
  430. const list = JSON.parse(options.mch_list);
  431. for (let i in list) {
  432. list[i].distance = 0;
  433. list[i].remark = '';
  434. list[i].order_form = [];
  435. list[i].use_integral = 0;
  436. list[i].user_coupon_id = 0;
  437. for (let j in list[i].goods_list) {
  438. list[i].goods_list[j].cart_id = list[i].goods_list[j].cart_id || 0;
  439. }
  440. }
  441. this.$store.commit('orderSubmit/mutSetFormData', {
  442. list: list,
  443. address_id: 0,
  444. });
  445. },
  446. loadPreviewData() {
  447. uni.showLoading({
  448. mask: true,
  449. title: '加载中',
  450. });
  451. this.$request({
  452. url: this.previewUrl,
  453. method: 'post',
  454. data: {
  455. form_data: JSON.stringify(this.$store.state.orderSubmit.formData),
  456. },
  457. }).then(response => {
  458. uni.hideLoading();
  459. if (response.code === 0) {
  460. if (response.data.allZiti && !response.data.address) {
  461. response.data.address = {
  462. name: '',
  463. mobile: '',
  464. };
  465. }
  466. this.previewData = response.data;
  467. this.setDiyFormScrollStatus();
  468. this.checkCouponError();
  469. this.updateStoreDistance();
  470. } else {
  471. uni.showModal({
  472. title: '提示',
  473. content: response.msg,
  474. showCancel: false,
  475. success: () => {
  476. uni.navigateBack();
  477. },
  478. });
  479. }
  480. }).catch(() => {
  481. uni.hideLoading();
  482. });
  483. },
  484. navigateAddress() {
  485. let url = '/pages/order-submit/address-pick';
  486. url += '?hasCity=' + this.previewData.hasCity;
  487. uni.navigateTo({
  488. url: url,
  489. });
  490. },
  491. navigateStore(mchIndex) {
  492. if (this.previewData.mch_list[mchIndex].mch.id != 0) {
  493. return;
  494. }
  495. let firstGoodsId = '';
  496. if (this.plugin === 'booking') {
  497. firstGoodsId = this.previewData.mch_list[0].goods_list[0].id;
  498. }
  499. let plugin = this.plugin || '';
  500. uni.navigateTo({
  501. url: `/pages/order-submit/store-pick?mchIndex=${mchIndex}&plugin=${plugin}&firstGoodsId=${firstGoodsId}`,
  502. });
  503. },
  504. navigateCoupon(mchIndex) {
  505. uni.navigateTo({
  506. url: `/pages/order-submit/coupon-pick?mchIndex=${mchIndex}`,
  507. });
  508. },
  509. changeZitiAddress() {
  510. const formData = this.$store.state.orderSubmit.formData;
  511. formData.address = {
  512. name: this.previewData.address.name,
  513. mobile: this.previewData.address.mobile,
  514. };
  515. this.$store.commit('orderSubmit/mutSetFormData', formData);
  516. },
  517. changeSendType(mchIndex, value) {
  518. if (this.previewData.mch_list[mchIndex].delivery.send_type == value) return;
  519. const formData = this.$store.state.orderSubmit.formData;
  520. formData.list[mchIndex].send_type = value;
  521. this.$store.commit('orderSubmit/mutSetFormData', formData);
  522. this.previewData.mch_list[mchIndex].delivery.send_type = value;
  523. this.loadPreviewData();
  524. },
  525. updateStoreDistance() {
  526. if (!this.previewData) return;
  527. if (!this.previewData.has_ziti && this.plugin != 'booking') {
  528. return;
  529. }
  530. uni.getLocation({
  531. success: (res) => {
  532. for (let i in this.previewData.mch_list) {
  533. if (!this.previewData.mch_list[i].store) {
  534. continue;
  535. }
  536. if (this.previewData.mch_list[i].store.distance
  537. && this.previewData.mch_list[i].store.distance != '-m') {
  538. continue;
  539. }
  540. const distance = this.$utils.earthDistance({
  541. lat: res.latitude,
  542. lng: res.longitude
  543. }, {
  544. lat: this.previewData.mch_list[i].store.latitude,
  545. lng: this.previewData.mch_list[i].store.longitude
  546. });
  547. let distanceStr = '-m';
  548. if (distance > 1000) {
  549. distanceStr = (distance / 1000).toFixed(2) + 'km';
  550. } else {
  551. distanceStr = distance.toFixed(0) + 'm';
  552. }
  553. this.previewData.mch_list[i].store.distance = distanceStr;
  554. }
  555. },
  556. fail: () => {
  557. this.getLocationFail = true;
  558. },
  559. });
  560. },
  561. openLocationSetting() {
  562. this.getLocationFail = false;
  563. uni.openSetting({});
  564. },
  565. showIntegralTip() {
  566. uni.showModal({
  567. title: '积分抵扣说明',
  568. content: this.$store.state.mallConfig.mall.setting.member_integral_rule,
  569. showCancel: false,
  570. });
  571. },
  572. changeIntegral(mchIndex) {
  573. const formData = this.$store.state.orderSubmit.formData;
  574. const use = !this.previewData.mch_list[mchIndex].integral.use;
  575. formData.list[mchIndex].use_integral = use ? 1 : 0;
  576. this.previewData.mch_list[mchIndex].integral.use = use;
  577. this.loadPreviewData();
  578. },
  579. inputRemark(mchIndex) {
  580. const formData = this.$store.state.orderSubmit.formData;
  581. formData.list[mchIndex].remark = this.previewData.mch_list[mchIndex].remark;
  582. this.$store.commit('orderSubmit/mutSetFormData', formData);
  583. },
  584. submit() {
  585. uni.showLoading({
  586. mask: true,
  587. title: '提交中',
  588. });
  589. this.$request({
  590. url: this.submitUrl,
  591. method: 'post',
  592. data: {
  593. form_data: JSON.stringify(this.$store.state.orderSubmit.formData),
  594. },
  595. }).then(response => {
  596. if (response.code === 0) {
  597. this.getPayOrderId(response.data.queue_id, response.data.token);
  598. } else {
  599. this.submitLock = false;
  600. uni.hideLoading();
  601. uni.showModal({
  602. title: '提示',
  603. content: response.msg,
  604. showCancel: false,
  605. });
  606. }
  607. }).catch(e => {
  608. this.submitLock = false;
  609. uni.hideLoading();
  610. uni.showModal({
  611. title: '提示',
  612. content: e.errMsg,
  613. showCancel: false,
  614. });
  615. });
  616. },
  617. getPayOrderId(queue_id, token) {
  618. this.$request({
  619. url: this.payDataUrl,
  620. method: 'post',
  621. data: {
  622. queue_id: queue_id,
  623. token: token,
  624. },
  625. }).then(response => {
  626. if (response.code === 0) {
  627. if (response.data.retry && response.data.retry === 1) {
  628. this.getPayDataTimer = setTimeout(() => {
  629. this.getPayOrderId(queue_id, token);
  630. }, 1000);
  631. } else {
  632. console.log(response);
  633. uni.hideLoading();
  634. this.pay(response.data);
  635. }
  636. } else {
  637. this.submitLock = false;
  638. uni.hideLoading();
  639. uni.showModal({
  640. title: '提示',
  641. content: response.msg,
  642. showCancel: false,
  643. });
  644. }
  645. }).catch(e => {
  646. this.submitLock = false;
  647. uni.hideLoading();
  648. uni.showModal({
  649. title: '提示',
  650. content: e.errMsg,
  651. showCancel: false,
  652. });
  653. });
  654. },
  655. pay(data) {
  656. this.$payment.pay(data.id).then(res => {
  657. console.log('支付成功', res);
  658. if (this.showPayResult) {
  659. uni.redirectTo({
  660. url: `/pages/order-submit/pay-result?payment_order_union_id=${data.id}&order_page_url=${encodeURIComponent(this.orderPageUrl)}`,
  661. });
  662. } else {
  663. let page_url = this.orderPageUrl;
  664. if (page_url.indexOf('?') === -1) {
  665. page_url += '?'
  666. } else {
  667. page_url += '&';
  668. }
  669. delete data.id;
  670. page_url += `pay_data=${JSON.stringify(data)}`;
  671. uni.redirectTo({
  672. url: page_url,
  673. });
  674. }
  675. }).catch(e => {
  676. console.log('支付失败', e);
  677. if (this.payCancelUrl) {
  678. let page_url = this.payCancelUrl;
  679. if (page_url.indexOf('?') === -1) {
  680. page_url += '?'
  681. } else {
  682. page_url += '&';
  683. }
  684. page_url += `pay_data=${JSON.stringify(data)}`;
  685. uni.redirectTo({
  686. url: page_url,
  687. });
  688. } else {
  689. uni.showModal({
  690. title: '提交失败',
  691. content: e.errMsg,
  692. showCancel: false,
  693. success: () => {
  694. uni.redirectTo({
  695. url: this.orderPageUrl,
  696. });
  697. },
  698. });
  699. }
  700. });
  701. },
  702. jump(mchIndex) {
  703. uni.navigateTo({
  704. url: `/pages/order-submit/map`,
  705. });
  706. },
  707. checkCouponError() {
  708. for (let i in this.previewData.mch_list) {
  709. if (this.previewData.mch_list[i].coupon && this.previewData.mch_list[i].coupon.coupon_error) {
  710. uni.showModal({
  711. title: '',
  712. content: this.previewData.mch_list[i].coupon.coupon_error,
  713. showCancel: false,
  714. });
  715. return;
  716. }
  717. }
  718. },
  719. setDiyFormScrollStatus() {
  720. console.log('this.previewData.mch_list--->', this.previewData.mch_list);
  721. for (let i in this.previewData.mch_list) {
  722. if (
  723. this.previewData.mch_list[i].order_form
  724. ) {
  725. if (
  726. this.previewData.mch_list[i].order_form.value
  727. && this.previewData.mch_list[i].order_form.value.length
  728. && this.previewData.mch_list[i].order_form.value.length >= 5
  729. ) {
  730. this.previewData.mch_list[i].order_form.show_scroll = true;
  731. } else {
  732. this.previewData.mch_list[i].order_form.show_scroll = false;
  733. }
  734. }
  735. }
  736. },
  737. subscribe() {
  738. for (let i in this.$store.state.orderSubmit.formData.list) {
  739. const item = this.$store.state.orderSubmit.formData.list[i];
  740. if (!item.order_form_validate_result) continue;
  741. if (item.order_form_validate_result.hasError) {
  742. uni.showModal({
  743. title: '提示',
  744. content: item.order_form_validate_result.errors[0].msg,
  745. showCancel: false,
  746. });
  747. return;
  748. }
  749. }
  750. for (let i in this.$store.state.orderSubmit.formData.list) {
  751. for (let j in this.$store.state.orderSubmit.formData.list[i].goods_list) {
  752. const item = this.$store.state.orderSubmit.formData.list[i].goods_list[j];
  753. if (!item.goods_form_validate_result) continue;
  754. if (item.goods_form_validate_result.hasError) {
  755. uni.showModal({
  756. title: '提示',
  757. content: item.goods_form_validate_result.errors[0].msg,
  758. showCancel: false,
  759. });
  760. return;
  761. }
  762. }
  763. }
  764. if (this.submitLock) return;
  765. this.submitLock = true;
  766. this.$subscribe(this.previewData.template_message_list).then(res => {
  767. this.submit();
  768. }).catch(res => {
  769. this.submit();
  770. });
  771. },
  772. handleGoodsFormInput(data, sign) {
  773. const signArr = sign.split(',');
  774. const mchIndex = parseInt(signArr[0]);
  775. const goodsIndex = parseInt(signArr[1]);
  776. const formId = parseInt(signArr[2]);
  777. const result = [];
  778. for (let i in data) {
  779. result[i] = {
  780. key: data[i].key,
  781. label: data[i].name,
  782. value: data[i].value,
  783. required: data[i].is_required,
  784. };
  785. }
  786. const formData = this.$store.state.orderSubmit.formData;
  787. formData.list[mchIndex].goods_list[goodsIndex].form_data = result;
  788. this.$store.commit('orderSubmit/mutSetFormData', formData);
  789. },
  790. handleGoodsFormValidate(result, sign) {
  791. const signArr = sign.split(',');
  792. const mchIndex = parseInt(signArr[0]);
  793. const goodsIndex = parseInt(signArr[1]);
  794. const formData = this.$store.state.orderSubmit.formData;
  795. formData.list[mchIndex].goods_list[goodsIndex].goods_form_validate_result = result;
  796. this.$store.commit('orderSubmit/mutSetFormData', formData);
  797. },
  798. },
  799. }
  800. </script>
  801. <style scoped lang="scss">
  802. $submitBarHeight: #{110rpx};
  803. $borderColor: $uni-weak-color-one;
  804. $xWidth: #{24rpx};
  805. $yWidth: #{24rpx};
  806. .felx-three{
  807. display: flex;
  808. align-items: center;
  809. justify-content: space-around;
  810. .box-grow-2, .box-grow-3, .box-grow-4{
  811. font-size: 24rpx;
  812. font-family: Source Han Sans CN;
  813. font-weight: 400;
  814. color: rgba(100,100,100,1);
  815. overflow: hidden;
  816. text-overflow: ellipsis;
  817. white-space: nowrap;
  818. }
  819. .box-grow-2{
  820. width: 30%;
  821. }
  822. .box-grow-3{
  823. width: 30%;
  824. }
  825. .box-grow-4{
  826. width: 40%;
  827. }
  828. .box-grow-5{
  829. width: 100%;
  830. font-size: 24rpx;
  831. font-family: Source Han Sans CN;
  832. font-weight: 400;
  833. color: rgba(100,100,100,1);
  834. overflow: hidden;
  835. text-overflow: ellipsis;
  836. white-space: nowrap;
  837. }
  838. }
  839. .pick-up {
  840. margin-top: #{20rpx};
  841. background: #fff4f3;
  842. height: #{80rpx};
  843. width: 100%;
  844. padding: 0 #{24rpx};
  845. font-size: #{28rpx};
  846. color: #353535;
  847. }
  848. .px-12 {
  849. padding-left: #{12rpx};
  850. padding-right: #{12rpx};
  851. }
  852. .mb-12 {
  853. margin-bottom: #{12rpx};
  854. }
  855. .page {
  856. min-height: 100%;
  857. border-top: #{1rpx} solid $borderColor;
  858. padding-bottom: $submitBarHeight;
  859. .address {
  860. margin-bottom: $yWidth;
  861. .bottom-image {
  862. width: 100%;
  863. height: #{8rpx};
  864. display: block;
  865. }
  866. }
  867. .mch-list {
  868. .mch-name {
  869. padding: $yWidth $xWidth;
  870. }
  871. .delivery {
  872. background: #fff;
  873. padding: $yWidth $xWidth;
  874. .send-type {
  875. display: inline-block;
  876. padding: #{8rpx} #{24rpx};
  877. border-radius: #{100rpx};
  878. margin-right: $xWidth;
  879. font-size: $uni-font-size-general-one;
  880. }
  881. .send-type:last-child {
  882. margin-right: 0;
  883. }
  884. .send-type.active {
  885. color: #fff;
  886. }
  887. }
  888. .store {
  889. .title {
  890. padding: $yWidth $xWidth 0;
  891. }
  892. .store-address {
  893. color: $uni-general-color-two;
  894. }
  895. .location {
  896. padding: 0 #{48rpx};
  897. .icon {
  898. width: #{22rpx};
  899. height: #{26rpx};
  900. margin-right: #{12rpx};
  901. }
  902. .inline-block {
  903. display: inline-block;
  904. vertical-align: top;
  905. }
  906. .open-location-setting {
  907. margin-top: -#{2rpx};
  908. padding-left: #{12rpx};
  909. }
  910. .open-location-btn {
  911. font-size: $uni-font-size-weak-one;
  912. height: #{44rpx};
  913. line-height: #{42rpx};
  914. padding: 0 #{16rpx};
  915. border: #{1rpx} solid;
  916. border-radius: #{1000rpx};
  917. }
  918. }
  919. }
  920. .city {
  921. padding: #{32rpx} #{24rpx};
  922. background-color: #ffffff;
  923. margin-bottom: #{20rpx};
  924. font-size: $uni-font-size-general-one;
  925. .error {
  926. color: #ff4544;
  927. margin-right: #{24rpx};
  928. }
  929. .btn {
  930. padding: #{10rpx} #{20rpx};
  931. border-radius: #{100rpx};
  932. border: #{1rpx} solid #cccccc;
  933. font-size: $uni-font-size-general-two;
  934. color: $uni-general-color-one;
  935. }
  936. }
  937. .goods-list {
  938. border-bottom: #{1rpx} solid $borderColor;
  939. .goods-item {
  940. background: #fff;
  941. padding: #{24rpx};
  942. .goods-image {
  943. width: #{200rpx};
  944. height: #{200rpx};
  945. display: block;
  946. margin-right: #{24rpx};
  947. }
  948. .goods-name {
  949. font-size:24rpx !important;
  950. font-family:Source Han Sans CN;
  951. font-weight:400;
  952. color:rgba(72,72,72,1);
  953. height: #{84rpx};
  954. line-height: #{42rpx};
  955. display: -webkit-box;
  956. -webkit-box-orient: vertical;
  957. -webkit-line-clamp: 2;
  958. overflow: hidden;
  959. margin-bottom: #{22rpx};
  960. }
  961. .attr-list, .goods-num {
  962. font-size: $uni-font-size-weak-one;
  963. color: $uni-general-color-one;
  964. }
  965. .attr-item {
  966. margin-right: #{24rpx};
  967. }
  968. .attr-item:last-child {
  969. margin-right: 0;
  970. }
  971. .goods-price-info {
  972. text-align: right;
  973. font-size: $uni-font-size-general-one;
  974. }
  975. }
  976. }
  977. .express-price {
  978. text-align: right;
  979. .express-price-desc {
  980. font-size: $uni-font-size-weak-one;
  981. }
  982. }
  983. .coupon {
  984. .active {
  985. color: $uni-important-color-red;
  986. }
  987. .tip {
  988. color: $uni-general-color-two;
  989. }
  990. }
  991. .integral {
  992. .tip-btn {
  993. font-size: 0;
  994. padding: #{12rpx};
  995. margin-top: -#{7rpx};
  996. /* #ifdef MP-ALIPAY*/
  997. margin-top: -#{14rpx};
  998. /* #endif*/
  999. }
  1000. .icon {
  1001. width: #{36rpx};
  1002. height: #{36rpx};
  1003. display: block;
  1004. }
  1005. }
  1006. .remark {
  1007. height: 339rpx;
  1008. background: #fff;
  1009. border-bottom: #{1rpx} solid $borderColor;
  1010. padding: 0 #{12rpx};
  1011. }
  1012. }
  1013. }
  1014. .submit-bar {
  1015. background: #fff;
  1016. border-top: #{1rpx} solid $uni-weak-color-two;
  1017. height: $submitBarHeight;
  1018. position: fixed;
  1019. left: 0;
  1020. bottom: 0;
  1021. width: 100%;
  1022. z-index: 1000;
  1023. .order-info {
  1024. padding: 0 #{24rpx};
  1025. }
  1026. .submit-btn {
  1027. height: 100%;
  1028. padding: 0 #{50rpx};
  1029. }
  1030. .submit-btn:active {
  1031. box-shadow: inset 0 0 #{500rpx} rgba(0, 0, 0, .15);
  1032. }
  1033. .submit-btn.lock {
  1034. box-shadow: inset 0 0 #{500rpx} rgba(255, 255, 255, 0.35);
  1035. }
  1036. .submit-btn.disabled {
  1037. background: $uni-general-color-two;
  1038. }
  1039. }
  1040. </style>