order-submit.vue 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471
  1. <template>
  2. <app-layout>
  3. <view class="safe-area-inset-bottom">
  4. <!-- 地址、商户、配送、商品、优惠、费用信息 -->
  5. <view class="page" v-if="previewData">
  6. <view v-if="!previewData.hasCity && previewData.show_address !== false && previewData.hasRecipient" class="group">
  7. <app-address-bar :address="previewData.address" :has-ziti="previewData.has_ziti" :all-ziti="previewData.allZiti" @address-input="handleAddressInput"></app-address-bar>
  8. </view>
  9. <template v-for="(mch, mchIndex) in previewData.mch_list" >
  10. <view v-if="previewData.hasCity && mchIndex === 0" class="group">
  11. <app-address-bar :address="mch.city.error ? null : mch.address" :has-city="true" :city="mch.city"></app-address-bar>
  12. </view>
  13. <view v-if="previewData.hasCity && mchIndex === 1" class="group">
  14. <app-address-bar :address="previewData.address" :has-ziti="previewData.has_ziti" :all-ziti="previewData.allZiti" :city="mch.city"></app-address-bar>
  15. </view>
  16. <!-- 循环商户列表start -->
  17. <view :key="mchIndex" class="group">
  18. <!-- 商铺名 -->
  19. <view style="padding: 26rpx 32rpx;">
  20. <view class="dir-left-nowrap cross-center" style="padding: 10rpx 0;line-height: 1.2;">
  21. <!-- 商户名start -->
  22. <view class="box-grow-0">
  23. <image src="/static/image/icon/store-black.png" class="title-icon mr-12"></image>
  24. </view>
  25. <view class="box-grow-1 font-bold ellipsis-1">{{mch.mch.name}}</view>
  26. <view v-if="mch.mch.id > 0 && mch.delivery && mch.delivery.send_type === 'offline' && mch.store && mch.store.distance != '-m'" class="box-grow-0 dir-left-nowrap cross-center">
  27. <image src="/static/image/icon/location.png" class="mr-12" style="display: block; width: 22rpx;height: 26rpx;"></image>
  28. <view>距您{{mch.store.distance}}</view>
  29. </view>
  30. </view><!-- 商户名end -->
  31. <template v-if="mch.delivery && mch.delivery.send_type === 'offline'">
  32. <!-- 自提门店信息start -->
  33. <view v-if="mch.no_store && mch.no_store === true" :class="[themeTextClass]" :style="{'color': !is_gift ? theme.color : '', 'paddding': '10rpx 0'}">暂无门店,请选择其他配送方式
  34. </view>
  35. <template v-else>
  36. <template v-if="mch.store">
  37. <view v-if="mch.mch.id == 0" class="dir-left-nowrap" style="padding: 10rpx 0;line-height: 1.2;">
  38. <view @click="navigateStore(mchIndex)" class="box-grow-1 dir-left-nowrap cross-center">
  39. <view>
  40. <image src="/static/image/icon/navigation-black.png" class="title-icon mr-12"></image>
  41. </view>
  42. <view class="font-bold ellipsis-1 mr-12">
  43. {{mch.store.name}}
  44. </view>
  45. <view class="mr-12">
  46. <image src="/static/image/icon/right.png" class="mr-12" style="width: 12rpx; height: 22rpx;"></image>
  47. </view>
  48. </view>
  49. <view v-if="mch.store.distance != '-m' || getLocationFail" class="box-grow-0 dir-left-nowrap cross-center">
  50. <view>
  51. <image src="/static/image/icon/location.png" class="mr-12" style="display: block; width: 22rpx;height: 26rpx;"></image>
  52. </view>
  53. <view v-if="getLocationFail" @click.stop="openLocationSetting" :class="[`${theme}-color`, `${theme}-border`]" :style="{'color': !is_gift ? theme.color : '', 'border-color': !is_gift ? theme.border : ''}">获取位置
  54. </view>
  55. <view v-else-if="mch.store.distance != '-m'">距您{{mch.store.distance}}</view>
  56. </view>
  57. </view>
  58. <view style="padding: 10rpx 0;line-height: 1.2;">
  59. <view class="font-gray ellipsis-2" style="line-height: 30rpx; max-height: 60rpx;">
  60. {{mch.store.address}}
  61. </view>
  62. </view>
  63. </template>
  64. <view v-else class="dir-left-nowrap cross-center" @click="navigateStore(mchIndex)" style="padding: 10rpx 0;">
  65. <view class="box-grow-1 dir-left-nowrap">
  66. <image src="/static/image/icon/navigation-black.png" class="title-icon mr-12"></image>
  67. <view class="mr-12 font-bold">选择门店</view>
  68. </view>
  69. <view class="box-grow-0 dir-left-nowrap cross-center">
  70. <view class="mr-12 font-gray">请选择门店</view>
  71. <image src="/static/image/icon/arrow-right.png" class="mr-12" style="width: 12rpx; height: 22rpx;"></image>
  72. </view>
  73. </view>
  74. </template>
  75. </template><!-- 自提门店信息end -->
  76. </view>
  77. <view class="line"></view>
  78. <!-- 配送方式 -->
  79. <view v-if="mch.show_delivery !== false" style="padding: 18rpx 32rpx;">
  80. <!-- 选择配送方式start -->
  81. <view class="dir-left-nowrap cross-center" style="padding: 18rpx 0;">
  82. <view class="box-grow-0">
  83. <image src="/static/image/icon/delivery.png" class="title-icon mr-12"></image>
  84. </view>
  85. <view class="box-grow-1 font-bold">配送方式</view>
  86. </view>
  87. <view class="dir-left-nowrap" style="padding: 18rpx 0;">
  88. <view v-for="(sendType, sendTypeIndex) in mch.delivery.send_type_list" :key="sendTypeIndex" class="send-type"
  89. :style="{'background-color': sendType.value == mch.delivery.send_type && !userTheme ? theme.background : ''}"
  90. :class="sendType.value == mch.delivery.send_type && userTheme ? `${theme}-background theme-color`: sendType.value == mch.delivery.send_type && !userTheme ? 'theme-color' : 'app-light-gray-back' "
  91. @click="changeSendType(mchIndex,sendType.value)">
  92. {{sendType.name}}
  93. </view>
  94. </view>
  95. </view><!-- 选择配送方式end -->
  96. <!-- 同城配送 -->
  97. <template v-if="mch.delivery && mch.delivery.send_type === 'city' && mch.city">
  98. <!-- 同城配送信息start -->
  99. <view class="line"></view>
  100. <view v-if="mch.city.error" class="dir-left-nowrap cross-center" style="padding: 36rpx 32rpx;">
  101. <view class="box-grow-1">{{mch.city.error}}</view>
  102. <view class="box-grow-0 dir-left-nowrap delivery-coverage-btn" @click="jump(mchIndex)" style="margin: -12rpx 0;">查看配送范围
  103. </view>
  104. </view>
  105. <view v-else style="padding: 36rpx 32rpx;">
  106. <view style="padding: 10rpx 0;">发货地址:{{mch.city.address}}</view>
  107. <view class="dir-left-nowrap cross-center" style="padding: 10rpx 0;">
  108. <view class="box-grow-1">
  109. <view v-if="mch.city.explain">{{mch.city.explain}}</view>
  110. </view>
  111. <view class="box-grow-0 dir-left-nowrap delivery-coverage-btn" @click="jump(mchIndex)">查看配送范围
  112. </view>
  113. </view>
  114. </view>
  115. </template><!-- 同城配送信息end -->
  116. <view class="line"></view>
  117. <view v-if="!mch.pick_up_enable" style="height: 80rpx;line-height: 80rpx; background: #fff4f3;padding: 0 24rpx;">
  118. <view>以下商品满{{mch.pick_up_price}}元起送</view>
  119. </view>
  120. <!-- 商品循环 -->
  121. <app-submit-goods :theme="theme" v-on:updateList="updateList" :index="mchIndex" :plugin="plugin" :list="mch"></app-submit-goods>
  122. <view class="line"></view>
  123. <!-- 优惠券 -->
  124. <template v-if="(mch.coupon && mch.coupon.enabled) ||
  125. (mch.member_discount > 0 || mch.member_discount < 0) ||
  126. (mch.integral && mch.integral.can_use) ||
  127. mch.temp_vip_discount ||
  128. (mch.insert_rows && mch.insert_rows.length) ||
  129. (mch.full_reduce_discount > 0 || mch.full_reduce_discount < 0)">
  130. <view style="padding: 20rpx 32rpx;">
  131. <template v-if="mch.coupon && mch.coupon.enabled">
  132. <view @click="showCouponPicker(mchIndex)" style="padding: 16rpx 0;">
  133. <view class="dir-left-nowrap cross-center">
  134. <view class="box-grow-1">优惠券</view>
  135. <view class="box-grow-0 mr-12" v-if="mch.coupon.use" :class="[themeTextClass]" :style="{'color': !is_gift ? theme.color : ''}">
  136. -¥{{mch.coupon.coupon_discount}}
  137. </view>
  138. <view class="box-grow-0 mr-12 font-gray" v-else-if="noCouponStatus(mchIndex)">
  139. 暂无优惠券可用
  140. </view>
  141. <view class="box-grow-0 mr-12 font-gray" v-else>选择优惠券</view>
  142. <view class="box-grow-0">
  143. <image src="/static/image/icon/arrow-right.png" style="width: 12rpx; height: 22rpx; margin-bottom: -2rpx;"></image>
  144. </view>
  145. </view>
  146. </view>
  147. <app-bottom-modal :visible.sync="mch.showCouponPicker" title="优惠券">
  148. <app-coupon-pick :plugin="plugin" :mch-index="mchIndex" @change="loadPreviewData" :no-coupons.sync="mch.noCoupons" :theme="theme"></app-coupon-pick>
  149. </app-bottom-modal>
  150. </template>
  151. <view v-if="mch.member_discount > 0 || mch.member_discount < 0" class="dir-left-nowrap" style="padding: 16rpx 0;">
  152. <view class="box-grow-1">会员价总优惠</view>
  153. <view class="box-grow-0" :class="[themeTextClass]" :style="{'color': !is_gift ? theme.color : ''}">
  154. <template v-if="mch.member_discount>0">-¥{{mch.member_discount}}</template>
  155. <template v-else-if="mch.member_discount<0">+¥{{0-mch.member_discount}}</template>
  156. <template v-else>¥0.00</template>
  157. </view>
  158. </view>
  159. <view v-if="mch.full_reduce_discount > 0 || mch.full_reduce_discount < 0" class="dir-left-nowrap" style="padding: 16rpx 0;">
  160. <view class="box-grow-1">满减总优惠</view>
  161. <view class="box-grow-0" :class="[themeTextClass]" :style="{'color': !is_gift ? theme.color : ''}">
  162. <template v-if="mch.full_reduce_discount>0">-¥{{mch.full_reduce_discount}}</template>
  163. <template v-else-if="mch.full_reduce_discount<0">+¥{{0-mch.full_reduce_discount}}</template>
  164. </view>
  165. </view>
  166. <view v-if="mch.integral && mch.integral.can_use" class="dir-left-nowrap" style="padding: 16rpx 0;">
  167. <view class="box-grow-1 dir-left-nowrap cross-center">
  168. 积分抵扣(使用 {{mch.integral.use_num}}积分)
  169. <image @click="showIntegralTip" style="width: 36rpx;height: 36rpx; margin: -12rpx 0;" src="/static/image/icon/warning.png"></image>
  170. </view>
  171. <view class="box-grow-0 dir-left-nowrap cross-center">
  172. <view class="mr-12" :class="[themeTextClass]" :style="{'color': !is_gift ? theme.color : ''}">
  173. -¥{{mch.integral.deduction_price}}
  174. </view>
  175. <view style="margin: -6rpx 0">
  176. <app-submit-checkbox :round="true" :theme="theme" :value="mch.integral.use" border-color="#999999" @input="changeIntegral(mchIndex)"></app-submit-checkbox>
  177. </view>
  178. </view>
  179. </view>
  180. <view v-if="mch.temp_vip_discount" style="padding: 16rpx 0;">
  181. <view :style="{
  182. backgroundImage: `url(${appImg.order_submit.svip_bg})`,
  183. }" class="svip dir-left-nowrap cross-center">
  184. <view class="box-grow-1">
  185. <view v-if="mch.vip_card_detail">SVIP用户,本单优惠
  186. <text style="color: #ff4544;">{{mch.temp_vip_discount}}</text>
  187. </view>
  188. <template v-else>
  189. <view style="margin-bottom: 10rpx;">现在开卡,本单立减
  190. <text style="color: #ff4544;">{{mch.temp_vip_discount}}
  191. </text>
  192. </view>
  193. <view @click="navigateVipCardPrivilege" class="dir-left-nowrap cross-center">
  194. <view style="margin-right: 10rpx; font-size: 22rpx;">查看权益</view>
  195. <image src="/static/image/icon/order-submit/arrow-right-b.png" style="width: 12rpx;height: 22rpx; display: block;"></image>
  196. </view>
  197. </template>
  198. </view>
  199. <view class="box-grow-0 dir-left-nowrap cross-center" style="padding: 12rpx 22rpx 12rpx 0;" @click="navigateSvip(mchIndex)">
  200. <view class="vip-card-name" style="margin-right: 10rpx; line-height: 1.05;">
  201. <template v-if="mch.vip_card_detail">{{mch.vip_card_detail.name}}</template>
  202. <template v-else>请选择</template>
  203. </view>
  204. <image src="/static/image/icon/order-submit/arrow-right-a.png" style="width: 12rpx;height: 22rpx; display: block;"></image>
  205. </view>
  206. </view>
  207. </view>
  208. <view v-if="mch.insert_rows && mch.insert_rows.length" :class="[mch.showInsertRows?'show':'',]">
  209. <view class="dir-left-nowrap cross-center" @click="reversalShowInsertRows(mchIndex)" style="padding: 16rpx 0;">
  210. <view class="box-grow-1 dir-left-nowrap cross-center">
  211. <view class="mr-12">活动优惠</view>
  212. <image style="width: 22rpx; height: 12rpx;" class="bottom-icon" src="/static/image/icon/bottom.png"></image>
  213. </view>
  214. <view class="box-grow-0" :class="[themeTextClass]" :style="{'color': !is_gift ? theme.color : ''}">
  215. {{mch.insert_total_discount}}
  216. </view>
  217. </view>
  218. <view class="insert-rows">
  219. <view class="font-small more-discount-info">
  220. <view v-for="(insertRow, insertRowIndex) in mch.insert_rows" :key="insertRowIndex" class="row dir-left-nowrap no-px">
  221. <view class="box-grow-1" style="color: #999;">{{insertRow.title}}</view>
  222. <view class="box-grow-0" :class="[themeTextClass]" :style="{'color': !is_gift ? theme.color : ''}">
  223. {{insertRow.value}}
  224. </view>
  225. </view>
  226. </view>
  227. </view>
  228. </view>
  229. </view>
  230. <view class="line"></view>
  231. </template>
  232. <!-- 运费 -->
  233. <template v-if="mch.show_express_price !== false">
  234. <!-- 运费信息start -->
  235. <view class="dir-left-nowrap cross-center" style="height: 84rpx; padding: 0 32rpx;">
  236. <view class="box-grow-1">运费</view>
  237. <view class="box-grow-0" :class="[themeTextClass]" :style="{'color': !is_gift ? theme.color : '','text-align':'right'}">
  238. <template v-if="mch.express_price_origin && mch.express_price_desc">
  239. <view :style="{'color': theme.color}">¥{{mch.express_price_origin}}</view>
  240. <view class="express-price-desc" :style="{'color': theme.color}">{{mch.express_price_desc}}
  241. </view>
  242. </template>
  243. <template v-else>¥{{mch.express_price}}</template>
  244. </view>
  245. </view>
  246. </template><!-- 运费信息end -->
  247. <!-- 买家留言 -->
  248. <template v-if="
  249. !(mch.order_form && mch.order_form.status == '1')
  250. && mch.show_remark !== false
  251. && mch.has_goods_form !== true">
  252. <view class="line"></view>
  253. <view class="row" style="padding-top: 0;padding-bottom: 0;">
  254. <app-input @input="inputRemark(mchIndex)" v-model="mch.remark" placeholder="买家留言" padding-left="0" height="100"></app-input>
  255. </view>
  256. </template>
  257. <view class="line"></view>
  258. <!-- 小计 -->
  259. <view class="dir-right-nowrap cross-center" style="height: 84rpx; padding: 0 32rpx;">
  260. <view class="box-grow-0 dir-left-nowrap">
  261. <view>小计:</view>
  262. <view :class="[themeTextClass]" :style="{'color': !is_gift ? theme.color : ''}">¥{{mch.total_price}}</view>
  263. </view>
  264. <view class="box-grow-0 font-gray mr-12">共{{mch.goods_count}}件</view>
  265. </view>
  266. </view>
  267. <!-- 循环商户列表end -->
  268. </template>
  269. <view v-for="(mch, mchIndex) in previewData.mch_list" :key="mchIndex">
  270. <view v-if="mch.order_form && mch.order_form.status == '1'" class="group">
  271. <view style="padding: 0 12rpx">
  272. <app-diy-form :title="mch.order_form.name" :list="mch.order_form.value" @input="handleOrderFormInput" @validate="handleOrderFormValidate" :sign="mchIndex" label-position="top" :show-scroll-btn="mch.order_form.show_scroll"></app-diy-form>
  273. </view>
  274. </view>
  275. <template v-if="mch.has_goods_form">
  276. <view v-for="(goodsItem, goodsIndex) in mch.goods_list" :key="goodsIndex" v-if="goodsItem.form && !goodsItem.form.same_form" class="group goods-form">
  277. <view style="padding: 36rpx 32rpx;" class="font-bold">{{goodsItem.form.name}}</view>
  278. <view class="line"></view>
  279. <view class="row goods-list" v-if="mch.diff_goods_form_count !== 1 || previewData.mch_list.length > 1">
  280. <view v-for="(subGoodsItem, subGoodsIndex) in mch.goods_list" :key="subGoodsIndex" v-if="subGoodsItem.form && subGoodsItem.form.id == goodsItem.form.id" class="dir-left-nowrap goods-item">
  281. <view class="box-grow-0">
  282. <image class="goods-image" :src="subGoodsItem.goods_attr.pic_url ? subGoodsItem.goods_attr.pic_url : subGoodsItem.cover_pic"></image>
  283. </view>
  284. <view class="box-grow-1">
  285. <view class="goods-name ellipsis-2">
  286. {{subGoodsItem.name}}
  287. </view>
  288. <view class="dir-left-wrap">
  289. <view v-for="(attrItem,attrIndex) in subGoodsItem.attr_list" :key="attrIndex" class="mr-12 font-gray font-small">
  290. {{attrItem.attr_group_name}}:{{attrItem.attr_name}}
  291. </view>
  292. </view>
  293. <view class="dir-left-nowrap">
  294. <view class="box-grow-1 font-gray font-small">×{{subGoodsItem.num}}</view>
  295. <view class="box-grow-0">
  296. <view class="font-small" style="text-align: right" :style="{'color': theme.color}">
  297. <text v-for="(customCurrency,customCurrencyIndex) in subGoodsItem.custom_currency" :key="customCurrencyIndex">
  298. {{customCurrency}}+
  299. </text>
  300. ¥{{subGoodsItem.total_original_price}}
  301. </view>
  302. <view v-for="(discount,discountIndex) in subGoodsItem.discounts" :key="discountIndex" style="text-align: right" :style="{'color': theme.color}">
  303. {{discount.name}}: {{discount.value}}
  304. </view>
  305. </view>
  306. </view>
  307. </view>
  308. </view>
  309. </view>
  310. <view style="padding: 0 12rpx">
  311. <app-diy-form :showRequiredIcon="true" :list="goodsItem.form.value" @input="handleGoodsFormInput" @validate="handleGoodsFormValidate" label-position="top" :label-fs28="true" :sign="`${mchIndex},${goodsIndex},${goodsItem.form.id}`"></app-diy-form>
  312. </view>
  313. </view>
  314. </template>
  315. </view>
  316. </view>
  317. <view class="full-tip" v-if="previewData.next_full_reduce"></view>
  318. </view>
  319. <!-- 结算底栏 -->
  320. <view class="submit-bar u-bottom-fixed dir-top-nowrap safe-area-inset-bottom" v-if="previewData">
  321. <view class="full-tip full-tip-show" v-if="previewData.next_full_reduce">
  322. 还差<span class="full-tip-text">{{previewData.next_full_reduce.diff}}</span>元<span class="full-tip-text">{{previewData.next_full_reduce.text}}</span>
  323. </view>
  324. <view class="bd-bottom dir-left-nowrap">
  325. <view class="box-grow-1 cross-center u-submit-bar-height">
  326. <view class="price-info">
  327. <view :class="[themeTextClass]" :style="{'color': !is_gift ? theme.color : '','font-size': '26rpx'}">
  328. {{totalTitle}}:
  329. <text v-for="(custom_currency, ccIndex) in previewData.custom_currency_all" :key="ccIndex">
  330. {{custom_currency}}+
  331. </text>
  332. <template v-if="previewData.vip_card_discount_total_price">
  333. ¥{{previewData.vip_card_discount_total_price}}
  334. </template>
  335. <template v-else>¥{{previewData.total_price}}</template>
  336. </view>
  337. <view v-if="previewData.vip_card_price > 0" :class="[themeTextClass]" :style="{'color': !is_gift ? theme.color : '','font-size': '20rpx'}">包含SVIP费用:
  338. ¥{{previewData.vip_card_price}}
  339. </view>
  340. </view>
  341. </view>
  342. <template v-if="previewData.address_enable && previewData.price_enable">
  343. <view @click="subscribe" class="submit-btn u-submit-bar-height box-grow-0 main-center cross-center" :class="[ submitLock? ' lock' : '', themeBgClass]" :style="{'background-color': !is_gift ? theme.background : ''}">
  344. <view style="background-color: transparent;color:#ffffff; text-align: center;">提交订单</view>
  345. </view>
  346. </template>
  347. <template v-else>
  348. <view class="submit-btn u-submit-bar-height box-grow-0 main-center cross-center disabled" :class="[themeTextClass]" :style="{'color': !is_gift ? theme.color : ''}">
  349. <view style="background-color: transparent;color: #ffffff; text-align: center;">提交订单</view>
  350. </view>
  351. </template>
  352. </view>
  353. </view>
  354. <app-close v-if="showClose && mchList.length > 0" :toBack="true" :mch_list="mchList" @update="getMall"></app-close>
  355. </app-layout>
  356. </template>
  357. <script>
  358. import {mapGetters, mapState} from 'vuex';
  359. import AppDiyForm from "../../components/page-component/app-diy-form/app-diy-form.vue";
  360. import appSubmitGoods from './app-submit-goods.vue';
  361. import AppCouponPick from "./app-coupon-pick";
  362. import AppBottomModal from "./app-bottom-modal";
  363. import AppAddressBar from "./app-address-bar";
  364. import AppSubmitCheckbox from "./app-submit-checkbox";
  365. import AppClose from '../../components/basic-component/app-close/app-close.vue';
  366. import deepClone from '@/core/deepClone.js'
  367. export default {
  368. name: 'order-submit',
  369. components: {
  370. AppSubmitCheckbox,
  371. AppAddressBar,
  372. AppBottomModal,
  373. AppCouponPick,
  374. AppDiyForm,
  375. appSubmitGoods,
  376. AppClose
  377. },
  378. data() {
  379. return {
  380. totalTitle: '合计',
  381. check: false,
  382. previewData: {
  383. mch_list: [],
  384. total_price: 0,
  385. vip_card_discount_total_price: null,
  386. custom_currency_all: []
  387. },
  388. getLocationFail: false,
  389. previewUrl: null,
  390. submitUrl: null,
  391. plugin: null,
  392. orderPageUrl: null,
  393. submitLock: false,
  394. getPayDataTimer: null,
  395. userTheme: null,
  396. is_gift: false,
  397. payDataUrl: null,
  398. showPayResult: true,
  399. payCancelUrl: null,
  400. loadingPreviewData: true,
  401. showClose: false,
  402. is_open: false,
  403. mchList: '',
  404. p_pay_id: '',//重新提交处理
  405. };
  406. },
  407. computed: {
  408. ...mapState({
  409. appImg: state => state.mallConfig.__wxapp_img,
  410. }),
  411. theme() {
  412. return this.userTheme ? this.userTheme : this.getTheme;
  413. },
  414. ...mapGetters('mallConfig', {
  415. getTheme: 'getTheme',
  416. }),
  417. themeBgClass() {
  418. if (this.userTheme && this.userTheme.indexOf('gift') >= 0) {
  419. return `${this.theme} ${this.theme}-background`;
  420. }
  421. },
  422. themeTextClass() {
  423. if (this.userTheme && this.userTheme.indexOf('gift') >= 0) {
  424. return `${this.theme} ${this.theme}-color`;
  425. }
  426. },
  427. },
  428. onLoad(options) {
  429. this.$commonLoad.onload(options);
  430. let mchList = JSON.parse(options.mch_list);
  431. let list = [];
  432. for(let item of mchList) {
  433. if(item.mch_id > 0) {
  434. list.push(item.mch_id)
  435. }
  436. }
  437. this.is_gift = this.userTheme && this.userTheme.indexOf('gift') >= 0 ? true : false;
  438. this.mchList = list.length > 0 ? JSON.stringify(list) : '0';
  439. if (this.submitLock) return;
  440. this.setFormData(options);
  441. this.$event.on(this.$const.EVENT_USER_LOGIN).then(() => {
  442. this.loadPreviewData();
  443. });
  444. // #ifdef H5
  445. let { hash } = window.location;
  446. if (hash.indexOf('pay_id_weChart') > 0 && hash.indexOf('isWechat=true') > 0) {
  447. let _this = this;
  448. uni.showModal({
  449. content: '确定已完成支付?',
  450. confirmText: '确定',
  451. cancelText: '返回支付',
  452. success(res) {
  453. if (res.confirm) {
  454. let search = hash.split('?')[1];
  455. if (search) {
  456. let str = search.substr(0).match(new RegExp('(^|&)' + 'pay_id_weChart' + '=([^&]*)(&|$)'))
  457. if (unescape(str[2])) {
  458. _this.weChartPay(unescape(str[2]));
  459. }
  460. }
  461. } else if (res.cancel) {
  462. uni.redirectTo({
  463. url: `/pages/order/index/index`
  464. });
  465. }
  466. },
  467. fail() {
  468. }
  469. });
  470. }
  471. // #endif
  472. },
  473. onShow() {
  474. this.showClose = false;
  475. setTimeout(()=>{
  476. this.showClose = true;
  477. // #ifdef H5
  478. document.getElementsByClassName('uni-page-head__title')[0].innerHTML = '确认订单';
  479. // #endif
  480. });
  481. },
  482. onUnload() {
  483. if (this.getPayDataTimer) {
  484. clearTimeout(this.getPayDataTimer);
  485. }
  486. },
  487. watch: {
  488. 'previewData.address.name': {
  489. handler() {
  490. this.changeZitiAddress();
  491. },
  492. },
  493. 'previewData.address.mobile': {
  494. handler() {
  495. this.changeZitiAddress();
  496. },
  497. },
  498. },
  499. methods: {
  500. getMall(e) {
  501. console.log(e)
  502. if(e != undefined) {
  503. this.is_open = e && e.is_open == 1 ? true : false;
  504. if(this.is_open) {
  505. if (this.submitLock) return;
  506. // #ifdef MP-BAIDU
  507. setTimeout(() => {
  508. this.loadPreviewData();
  509. }, 50);
  510. // #endif
  511. // #ifndef MP-BAIDU
  512. this.loadPreviewData();
  513. // #endif
  514. }
  515. }
  516. },
  517. noCouponStatus(mchIndex) {
  518. const mchNoCouponStatusList = this.$store.getters['orderSubmit/getMchNoCouponStatusList'];
  519. if (mchNoCouponStatusList[mchIndex])
  520. return true;
  521. else
  522. return false;
  523. },
  524. navigateVipCardPrivilege() {
  525. uni.navigateTo({
  526. url: '/plugins/vip_card/rights/rights?id=1',
  527. });
  528. },
  529. showCouponPicker(index) {
  530. this.previewData.mch_list[index].showCouponPicker = true;
  531. },
  532. reversalShowInsertRows(index) {
  533. this.previewData.mch_list[index].showInsertRows = !this.previewData.mch_list[index].showInsertRows;
  534. },
  535. updateList(e, index) {
  536. this.previewData.mch_list[index] = e;
  537. this.$forceUpdate();
  538. },
  539. setParams(options) {
  540. if (options.total_title) {
  541. this.totalTitle = options.total_title;
  542. }
  543. },
  544. handleOrderFormInput({data, sign}) {
  545. const result = [];
  546. for (let i in data) {
  547. result[i] = {
  548. key: data[i].key,
  549. label: data[i].name,
  550. value: data[i].value,
  551. required: data[i].is_required,
  552. };
  553. }
  554. const formData = this.$store.state.orderSubmit.formData;
  555. formData.list[sign].order_form = result;
  556. this.$store.commit('orderSubmit/mutSetFormData', formData);
  557. },
  558. handleOrderFormValidate({result, sign}) {
  559. const formData = this.$store.state.orderSubmit.formData;
  560. formData.list[sign].order_form_validate_result = result;
  561. this.$store.commit('orderSubmit/mutSetFormData', formData);
  562. },
  563. setFormData(options) {
  564. console.log(options.preview_url)
  565. this.previewUrl = decodeURIComponent(options.preview_url || this.$api.order.preview);
  566. this.submitUrl = decodeURIComponent(options.submit_url || this.$api.order.submit);
  567. this.plugin = options.plugin || null;
  568. this.orderPageUrl = decodeURIComponent(options.order_page_url || '/pages/order/index/index?status=0');
  569. this.userTheme = options.theme || null;
  570. this.payDataUrl = decodeURIComponent(options.pay_data_url || this.$api.order.pay_data);
  571. this.payCancelUrl = options.pay_cancel_url ? decodeURIComponent(options.pay_cancel_url) : null;
  572. this.showPayResult = options.show_pay_result || true;
  573. if (this.showPayResult === 'true') this.showPayResult = true;
  574. if (this.showPayResult === 'false') this.showPayResult = false;
  575. let list = JSON.parse(options.mch_list);
  576. // console.log('================123===============')
  577. // console.log(list)
  578. // let tempGoods = []
  579. // for (let i = 0; i < list.length; i ++) {
  580. // const goods_list = list[i].goods_list
  581. // if (i === 0) {
  582. // goods_list.forEach(item => { item['is_jingwai'] = 0 })
  583. // } else if (i === 1) {
  584. // goods_list.forEach(item => { item['is_jingwai'] = 1 })
  585. // }
  586. // tempGoods = [...tempGoods, ...goods_list]
  587. // }
  588. // const tempList = [list[0]]
  589. // tempList[0].mch_id = 0
  590. // tempList[0].goods_list = tempGoods
  591. // list = deepClone(tempList)
  592. // 商户列表先做下排序,主商城必须在最前
  593. for (let i in list) {
  594. if (parseInt(list[i].mch_id) === 0) {
  595. const _mchItem = list[i];
  596. list.splice(i, 1);
  597. list.unshift(_mchItem);
  598. break;
  599. }
  600. }
  601. for (let i in list) {
  602. list[i].distance = 0;
  603. list[i].remark = '';
  604. list[i].order_form = [];
  605. list[i].use_integral = 0;
  606. list[i].user_coupon_id = 0;
  607. for (let j in list[i].goods_list) {
  608. list[i].goods_list[j].cart_id = list[i].goods_list[j].cart_id || 0;
  609. }
  610. if (this.plugin === 'booking') {
  611. let store_id = this.bookStorage('get');
  612. list[i]['store_id'] = store_id ? store_id : '';
  613. }
  614. }
  615. this.$store.commit('orderSubmit/mutSetFormData', {
  616. list: list,
  617. address_id: 0,
  618. send_type: options.send_type || ''
  619. });
  620. },
  621. bookStorage(type, store_id = '') {
  622. let key = '_book_storage_order_preview';
  623. if (type === 'get') {
  624. return this.$storage.getStorageSync(key);
  625. }
  626. if (type === 'save') {
  627. this.$storage.setStorageSync(key, store_id ? store_id : 0);
  628. }
  629. },
  630. loadPreviewData() {
  631. this.loadingPreviewData = true;
  632. uni.showLoading({
  633. mask: true,
  634. title: '加载中',
  635. });
  636. this.$request({
  637. url: this.previewUrl,
  638. method: 'post',
  639. data: {
  640. form_data: JSON.stringify(this.$store.state.orderSubmit.formData),
  641. },
  642. }).then(response => {
  643. this.loadingPreviewData = false;
  644. uni.hideLoading();
  645. if (response.code === 0) {
  646. if (response.data.allZiti && !response.data.address) {
  647. response.data.address = {
  648. name: '',
  649. mobile: '',
  650. };
  651. }
  652. for (let i in response.data.mch_list) {
  653. response.data.mch_list[i].showCouponPicker = false;
  654. response.data.mch_list[i].noCoupons = false;
  655. response.data.mch_list[i].showInsertRows = false;
  656. }
  657. this.previewData = response.data;
  658. // const arr = this.$store.state.orderSubmit.formData.list[0].goods_list
  659. // // 添加境内外信息
  660. // console.log(arr)
  661. // this.previewData.mch_list[0].goods_list.forEach(item => {
  662. // const t = arr.find(i => i.id === item.id)
  663. // item.is_jingwai = t.is_jingwai
  664. // })
  665. // console.log('====================================')
  666. // console.log(this.previewData.mch_list[0].goods_list)
  667. this.setDiyFormScrollStatus();
  668. this.checkCouponError();
  669. this.updateStoreDistance();
  670. this.updateGoodsCount();
  671. } else {
  672. uni.showModal({
  673. title: '提示',
  674. content: response.msg,
  675. showCancel: false,
  676. success: () => {
  677. uni.navigateBack();
  678. },
  679. });
  680. }
  681. }).catch(() => {
  682. this.loadingPreviewData = false;
  683. uni.hideLoading();
  684. });
  685. },
  686. navigateStore(mchIndex) {
  687. if (this.previewData.mch_list[mchIndex].mch.id != 0) {
  688. return;
  689. }
  690. let firstGoodsId = '';
  691. if (this.plugin === 'booking') {
  692. firstGoodsId = this.previewData.mch_list[0].goods_list[0].id;
  693. }
  694. let plugin = this.plugin || '';
  695. uni.navigateTo({
  696. url: `/pages/order-submit/store-pick?mchIndex=${mchIndex}&plugin=${plugin}&firstGoodsId=${firstGoodsId}`,
  697. });
  698. },
  699. navigateCoupon(mchIndex) {
  700. uni.navigateTo({
  701. url: `/pages/order-submit/coupon-pick?mchIndex=${mchIndex}`,
  702. });
  703. },
  704. navigateSvip(mchIndex) {
  705. uni.navigateTo({
  706. url: `/pages/order-submit/vip-card?mchIndex=${mchIndex}`,
  707. });
  708. },
  709. changeZitiAddress() {
  710. const formData = this.$store.state.orderSubmit.formData;
  711. formData.address = {
  712. name: this.previewData.address ? this.previewData.address.name : '',
  713. mobile: this.previewData.address ? this.previewData.address.mobile : '',
  714. };
  715. this.$store.commit('orderSubmit/mutSetFormData', formData);
  716. },
  717. changeSendType(mchIndex, value) {
  718. if (this.previewData.mch_list[mchIndex].delivery.send_type == value) return;
  719. const formData = this.$store.state.orderSubmit.formData;
  720. formData.list[mchIndex].send_type = value;
  721. this.$store.commit('orderSubmit/mutSetFormData', formData);
  722. this.previewData.mch_list[mchIndex].delivery.send_type = value;
  723. this.loadPreviewData();
  724. },
  725. updateStoreDistance() {
  726. if (!this.previewData) return;
  727. if (!this.previewData.has_ziti && this.plugin != 'booking') {
  728. return;
  729. }
  730. // #ifdef MP
  731. uni.getLocation({
  732. success: (res) => {
  733. for (let i in this.previewData.mch_list) {
  734. if (!this.previewData.mch_list[i].store) {
  735. continue;
  736. }
  737. if (this.previewData.mch_list[i].store.distance &&
  738. this.previewData.mch_list[i].store.distance != '-m') {
  739. continue;
  740. }
  741. if (
  742. this.previewData.mch_list[i].store.latitude == '' ||
  743. this.previewData.mch_list[i].store.longitude == '' ||
  744. isNaN(this.previewData.mch_list[i].store.latitude) ||
  745. isNaN(this.previewData.mch_list[i].store.longitude)
  746. ) {
  747. continue;
  748. }
  749. const distance = this.$utils.earthDistance({
  750. lat: res.latitude,
  751. lng: res.longitude
  752. }, {
  753. lat: this.previewData.mch_list[i].store.latitude,
  754. lng: this.previewData.mch_list[i].store.longitude
  755. });
  756. let distanceStr = '-m';
  757. if (distance > 1000) {
  758. distanceStr = (distance / 1000).toFixed(2) + 'km';
  759. } else {
  760. distanceStr = distance.toFixed(0) + 'm';
  761. }
  762. this.previewData.mch_list[i].store.distance = distanceStr;
  763. }
  764. },
  765. fail: () => {
  766. this.getLocationFail = true;
  767. },
  768. });
  769. // #endif
  770. // #ifdef H5
  771. if (this.$jwx.isWechat()) {
  772. this.$jwx.getLocation({
  773. success: (res) => {
  774. for (let i in this.previewData.mch_list) {
  775. if (!this.previewData.mch_list[i].store) {
  776. continue;
  777. }
  778. if (this.previewData.mch_list[i].store.distance &&
  779. this.previewData.mch_list[i].store.distance != '-m') {
  780. continue;
  781. }
  782. if (
  783. this.previewData.mch_list[i].store.latitude == '' ||
  784. this.previewData.mch_list[i].store.longitude == '' ||
  785. isNaN(this.previewData.mch_list[i].store.latitude) ||
  786. isNaN(this.previewData.mch_list[i].store.longitude)
  787. ) {
  788. continue;
  789. }
  790. const distance = this.$utils.earthDistance({
  791. lat: res.latitude,
  792. lng: res.longitude
  793. }, {
  794. lat: this.previewData.mch_list[i].store.latitude,
  795. lng: this.previewData.mch_list[i].store.longitude
  796. });
  797. let distanceStr = '-m';
  798. if (distance > 1000) {
  799. distanceStr = (distance / 1000).toFixed(2) + 'km';
  800. } else {
  801. distanceStr = distance.toFixed(0) + 'm';
  802. }
  803. this.previewData.mch_list[i].store.distance = distanceStr;
  804. }
  805. },
  806. fail: () => {
  807. this.getLocationFail = true;
  808. },
  809. });
  810. } else {
  811. uni.getLocation({
  812. success: (res) => {
  813. for (let i in this.previewData.mch_list) {
  814. if (!this.previewData.mch_list[i].store) {
  815. continue;
  816. }
  817. if (this.previewData.mch_list[i].store.distance &&
  818. this.previewData.mch_list[i].store.distance != '-m') {
  819. continue;
  820. }
  821. if (
  822. this.previewData.mch_list[i].store.latitude == '' ||
  823. this.previewData.mch_list[i].store.longitude == '' ||
  824. isNaN(this.previewData.mch_list[i].store.latitude) ||
  825. isNaN(this.previewData.mch_list[i].store.longitude)
  826. ) {
  827. continue;
  828. }
  829. const distance = this.$utils.earthDistance({
  830. lat: res.latitude,
  831. lng: res.longitude
  832. }, {
  833. lat: this.previewData.mch_list[i].store.latitude,
  834. lng: this.previewData.mch_list[i].store.longitude
  835. });
  836. let distanceStr = '-m';
  837. if (distance > 1000) {
  838. distanceStr = (distance / 1000).toFixed(2) + 'km';
  839. } else {
  840. distanceStr = distance.toFixed(0) + 'm';
  841. }
  842. this.previewData.mch_list[i].store.distance = distanceStr;
  843. }
  844. },
  845. fail: () => {
  846. this.getLocationFail = true;
  847. },
  848. });
  849. }
  850. // #endif
  851. },
  852. openLocationSetting() {
  853. this.getLocationFail = false;
  854. uni.openSetting({});
  855. },
  856. showIntegralTip() {
  857. uni.showModal({
  858. title: '积分抵扣说明',
  859. content: this.$store.state.mallConfig.mall.setting.member_integral_rule,
  860. showCancel: false,
  861. });
  862. },
  863. changeIntegral(mchIndex) {
  864. const formData = this.$store.state.orderSubmit.formData;
  865. const use = !this.previewData.mch_list[mchIndex].integral.use;
  866. formData.list[mchIndex].use_integral = use ? 1 : 0;
  867. this.previewData.mch_list[mchIndex].integral.use = use;
  868. this.loadPreviewData();
  869. },
  870. inputRemark(mchIndex) {
  871. const formData = this.$store.state.orderSubmit.formData;
  872. formData.list[mchIndex].remark = this.previewData.mch_list[mchIndex].remark;
  873. this.$store.commit('orderSubmit/mutSetFormData', formData);
  874. },
  875. submit() {
  876. uni.showLoading({
  877. mask: true,
  878. title: '提交中',
  879. });
  880. this.$request({
  881. url: this.submitUrl,
  882. method: 'post',
  883. data: {
  884. form_data: JSON.stringify(this.$store.state.orderSubmit.formData),
  885. },
  886. }).then(response => {
  887. if (response.code === 99) {
  888. // 未实名认证,需要使命认证
  889. uni.hideLoading()
  890. this.submitLock = false;
  891. const _this = this
  892. uni.showModal({
  893. title: '提示',
  894. content: '您的账号尚未实名认证,请前往认证',
  895. success: function (res) {
  896. if (res.confirm) {
  897. _this.$jump({
  898. open_type: 'navigate',
  899. url: '/pages/identify/identify'
  900. })
  901. }
  902. }
  903. })
  904. return
  905. }
  906. if (response.code === 0) {
  907. this.getPayOrderId(response.data.queue_id, response.data.token);
  908. } else {
  909. this.submitLock = false;
  910. uni.hideLoading();
  911. uni.showModal({
  912. title: '',
  913. content: response.msg,
  914. showCancel: false,
  915. });
  916. }
  917. }).catch(e => {
  918. this.submitLock = false;
  919. uni.hideLoading();
  920. uni.showModal({
  921. title: '提示',
  922. content: e.errMsg,
  923. showCancel: false,
  924. });
  925. });
  926. },
  927. getPayOrderId(queue_id, token) {
  928. this.$request({
  929. url: this.payDataUrl,
  930. method: 'post',
  931. data: {
  932. queue_id: queue_id,
  933. token: token,
  934. },
  935. }).then(response => {
  936. if (response.code === 0) {
  937. if (response.data.retry && response.data.retry === 1) {
  938. this.getPayDataTimer = setTimeout(() => {
  939. this.getPayOrderId(queue_id, token);
  940. }, 1000);
  941. } else {
  942. uni.hideLoading();
  943. this.pay(response.data);
  944. }
  945. } else {
  946. this.submitLock = false;
  947. uni.hideLoading();
  948. uni.showModal({
  949. title: '提示',
  950. content: response.msg,
  951. showCancel: false,
  952. });
  953. }
  954. }).catch(e => {
  955. this.submitLock = false;
  956. uni.hideLoading();
  957. uni.showModal({
  958. title: '提示',
  959. content: e.errMsg,
  960. showCancel: false,
  961. });
  962. });
  963. },
  964. pay(data) {
  965. this.p_pay_id = data.id;
  966. this.$payment.pay(data.id).then(res => {
  967. if (this.showPayResult) {
  968. uni.redirectTo({
  969. url: `/pages/order-submit/pay-result?payment_order_union_id=${data.id}&order_page_url=${encodeURIComponent(this.orderPageUrl)}`,
  970. });
  971. } else {
  972. let page_url = this.orderPageUrl;
  973. if (page_url.indexOf('?') === -1) {
  974. page_url += '?'
  975. } else {
  976. page_url += '&';
  977. }
  978. delete data.id;
  979. page_url += `pay_data=${JSON.stringify(data)}`;
  980. uni.redirectTo({
  981. url: page_url,
  982. });
  983. }
  984. }).catch(e => {
  985. if (this.payCancelUrl) {
  986. let page_url = this.payCancelUrl;
  987. if (page_url.indexOf('?') === -1) {
  988. page_url += '?'
  989. } else {
  990. page_url += '&';
  991. }
  992. page_url += `pay_data=${JSON.stringify(data)}`;
  993. uni.redirectTo({
  994. url: page_url,
  995. });
  996. } else {
  997. if (e.errMsg === '5b03b6e009796c698d132908cb635fca') {
  998. //重新发起支付
  999. this.submitLock = false;
  1000. } else {
  1001. uni.showModal({
  1002. title: '提交失败',
  1003. content: e.errMsg,
  1004. showCancel: false,
  1005. success: () => {
  1006. uni.redirectTo({
  1007. url: this.orderPageUrl,
  1008. });
  1009. },
  1010. });
  1011. }
  1012. }
  1013. });
  1014. },
  1015. jump() {
  1016. uni.navigateTo({
  1017. url: `/pages/order-submit/map`,
  1018. });
  1019. },
  1020. checkCouponError() {
  1021. for (let i in this.previewData.mch_list) {
  1022. if (this.previewData.mch_list[i].coupon && this.previewData.mch_list[i].coupon.coupon_error) {
  1023. uni.showModal({
  1024. title: '',
  1025. content: this.previewData.mch_list[i].coupon.coupon_error,
  1026. showCancel: false,
  1027. });
  1028. return;
  1029. }
  1030. }
  1031. },
  1032. setDiyFormScrollStatus() {
  1033. for (let i in this.previewData.mch_list) {
  1034. let order_form = this.previewData.mch_list[i].order_form;
  1035. if (order_form) {
  1036. if (order_form.value && order_form.value.length && order_form.value.length >= 5) {
  1037. order_form.show_scroll = true;
  1038. } else {
  1039. order_form.show_scroll = false;
  1040. }
  1041. }
  1042. }
  1043. },
  1044. subscribe() {
  1045. if (this.p_pay_id) {
  1046. this.pay({
  1047. id: this.p_pay_id
  1048. });
  1049. return true;
  1050. } else {
  1051. this.p_pay_id = '';
  1052. }
  1053. for (let i in this.$store.state.orderSubmit.formData.list) {
  1054. const item = this.$store.state.orderSubmit.formData.list[i];
  1055. if (!item.order_form_validate_result) continue;
  1056. if (item.order_form_validate_result.hasError) {
  1057. uni.showModal({
  1058. title: '提示',
  1059. content: item.order_form_validate_result.errors[0].msg,
  1060. showCancel: false,
  1061. });
  1062. return;
  1063. }
  1064. }
  1065. for (let i in this.$store.state.orderSubmit.formData.list) {
  1066. for (let j in this.$store.state.orderSubmit.formData.list[i].goods_list) {
  1067. const item = this.$store.state.orderSubmit.formData.list[i].goods_list[j];
  1068. if (!item.goods_form_validate_result) continue;
  1069. if (item.goods_form_validate_result.hasError) {
  1070. uni.showModal({
  1071. title: '提示',
  1072. content: item.goods_form_validate_result.errors[0].msg,
  1073. showCancel: false,
  1074. });
  1075. return;
  1076. }
  1077. }
  1078. if (this.plugin === 'booking' && this.$store.state.orderSubmit.formData.list[i]) {
  1079. this.bookStorage('save', this.$store.state.orderSubmit.formData.list[i].store_id);
  1080. }
  1081. }
  1082. if (this.submitLock) return;
  1083. this.submitLock = true;
  1084. this.$subscribe(this.previewData.template_message_list).then(res => {
  1085. this.submit();
  1086. }).catch(() => {
  1087. this.submit();
  1088. });
  1089. },
  1090. handleGoodsFormInput({data, sign}) {
  1091. const signArr = sign.split(',');
  1092. const mchIndex = parseInt(signArr[0]);
  1093. const goodsIndex = parseInt(signArr[1]);
  1094. // const formId = parseInt(signArr[2]);
  1095. const result = [];
  1096. for (let i in data) {
  1097. result[i] = {
  1098. key: data[i].key,
  1099. label: data[i].name,
  1100. value: data[i].value,
  1101. required: data[i].is_required,
  1102. };
  1103. }
  1104. const formData = this.$store.state.orderSubmit.formData;
  1105. formData.list[mchIndex].goods_list[goodsIndex].form_data = result;
  1106. this.$store.commit('orderSubmit/mutSetFormData', formData);
  1107. },
  1108. handleGoodsFormValidate({result, sign}) {
  1109. if (!sign) return;
  1110. const signArr = sign.split(',');
  1111. const mchIndex = parseInt(signArr[0]);
  1112. const goodsIndex = parseInt(signArr[1]);
  1113. const formData = this.$store.state.orderSubmit.formData;
  1114. formData.list[mchIndex].goods_list[goodsIndex].goods_form_validate_result = result;
  1115. this.$store.commit('orderSubmit/mutSetFormData', formData);
  1116. },
  1117. updateGoodsCount() {
  1118. for (let i in this.previewData.mch_list) {
  1119. let count = 0;
  1120. for (let j in this.previewData.mch_list[i].goods_list) {
  1121. count += parseInt(this.previewData.mch_list[i].goods_list[j].num);
  1122. }
  1123. this.previewData.mch_list[i].goods_count = count;
  1124. }
  1125. },
  1126. handleAddressInput(e) {
  1127. if (typeof e.name !== 'undefined') this.previewData.address.name = e.name;
  1128. if (typeof e.mobile !== 'undefined') this.previewData.address.mobile = e.mobile;
  1129. },
  1130. // #ifdef H5
  1131. weChartPay(id) {
  1132. this.$request({
  1133. url: this.$api.registered.pay,
  1134. method: 'get',
  1135. data: {
  1136. payment_order_union_id: id
  1137. }
  1138. }).then((res) => {
  1139. if (res.code === 0) {
  1140. if (res.data.status === 1) {
  1141. uni.redirectTo({
  1142. url: `/pages/order-submit/pay-result?payment_order_union_id=${id}&order_page_url=${encodeURIComponent(this.orderPageUrl)}`,
  1143. });
  1144. } else {
  1145. if (this.orderPageUrl) {
  1146. uni.redirectTo({
  1147. url: this.orderPageUrl
  1148. });
  1149. } else {
  1150. uni.redirectTo({
  1151. url: '/pages/order/index/index'
  1152. });
  1153. }
  1154. }
  1155. }
  1156. })
  1157. }
  1158. // #endif
  1159. },
  1160. }
  1161. </script>
  1162. <style scoped lang="scss">
  1163. $submitBarHeight: #{110rpx};
  1164. $borderColor: $uni-weak-color-one;
  1165. $xWidth: #{24rpx};
  1166. $yWidth: #{24rpx};
  1167. .page {
  1168. padding-bottom: $submitBarHeight;
  1169. font-size: #{28rpx};
  1170. line-height: 1;
  1171. color: #353535;
  1172. }
  1173. .u-submit-bar-height {
  1174. height: 82upx;
  1175. }
  1176. .group {
  1177. margin: #{20rpx} #{26rpx};
  1178. background: #fff;
  1179. border-radius: #{16rpx};
  1180. overflow: hidden;
  1181. box-shadow: 0 0 #{5rpx} rgba(0, 0, 0, 0.025);
  1182. }
  1183. .row {
  1184. padding: #{12rpx} #{32rpx};
  1185. }
  1186. .row.no-px {
  1187. padding-left: 0;
  1188. padding-right: 0;
  1189. }
  1190. .line {
  1191. height: 0;
  1192. width: 100%;
  1193. background: #e2e2e2;
  1194. border-bottom: #{1rpx} solid #e2e2e2;
  1195. }
  1196. .font-bold {
  1197. font-weight: bold;
  1198. }
  1199. .font-small {
  1200. font-size: #{24rpx};
  1201. }
  1202. .font-gray {
  1203. color: #999999;
  1204. }
  1205. .title-icon {
  1206. width: #{28rpx};
  1207. height: #{25rpx};
  1208. display: block;
  1209. }
  1210. .mr-12 {
  1211. margin-right: #{12rpx};
  1212. }
  1213. .ellipsis-1 {
  1214. white-space: nowrap;
  1215. text-overflow: ellipsis;
  1216. overflow: hidden;
  1217. }
  1218. .ellipsis-2 {
  1219. display: -webkit-box;
  1220. -webkit-box-orient: vertical;
  1221. -webkit-line-clamp: 2;
  1222. text-overflow: ellipsis;
  1223. overflow: hidden;
  1224. }
  1225. .send-type {
  1226. display: inline-block;
  1227. padding: 0 0;
  1228. height: #{56rpx};
  1229. line-height: #{56rpx};
  1230. width: #{190rpx};
  1231. text-align: center;
  1232. border-radius: #{100rpx};
  1233. margin: 0 #{32rpx} 0 0;
  1234. font-size: #{28rpx};
  1235. }
  1236. .send-type:last-child {
  1237. margin-right: 0;
  1238. }
  1239. .delivery-coverage-btn {
  1240. display: inline-block;
  1241. padding: 0 #{20rpx};
  1242. height: #{56rpx};
  1243. line-height: #{56rpx};
  1244. text-align: center;
  1245. border-radius: #{100rpx};
  1246. font-size: #{24rpx};
  1247. border: #{1rpx} solid #e5e5e5;
  1248. color: #666;
  1249. }
  1250. .more-discount-info {
  1251. background: #f7f7f7;
  1252. padding: #{6rpx} #{14rpx};
  1253. position: relative;
  1254. border-radius: #{8rpx};
  1255. }
  1256. .more-discount-info:before {
  1257. display: block;
  1258. content: " ";
  1259. width: 0;
  1260. height: 0;
  1261. position: absolute;
  1262. right: #{30rpx};
  1263. top: -#{39rpx};
  1264. border: #{20rpx} solid transparent;
  1265. border-bottom-color: #f7f7f7;
  1266. }
  1267. .insert-rows {
  1268. height: 0;
  1269. overflow: hidden;
  1270. transition: 200ms;
  1271. padding: 0 0;
  1272. visibility: hidden;
  1273. view {
  1274. font-size: #{24rpx};
  1275. }
  1276. }
  1277. .show .insert-rows {
  1278. height: auto;
  1279. padding: #{24rpx} 0;
  1280. visibility: visible;
  1281. }
  1282. .show .bottom-icon,
  1283. .bottom-icon.show {
  1284. transform: rotate(180deg);
  1285. transition: 200ms;
  1286. }
  1287. .svip {
  1288. view {
  1289. color: #e4cdbb;
  1290. }
  1291. height: #{120rpx};
  1292. background-size: 100% 100%;
  1293. background-color: #3c352e;
  1294. padding-left: #{110rpx};
  1295. border-radius: #{12rpx};
  1296. .vip-card-name {
  1297. max-width: #{90rpx};
  1298. overflow: hidden;
  1299. white-space: nowrap;
  1300. text-overflow: ellipsis;
  1301. font-size: #{24rpx};
  1302. color: #f3be94;
  1303. }
  1304. }
  1305. .goods-form {
  1306. .goods-list {
  1307. padding-top: #{12rpx};
  1308. padding-bottom: #{12rpx};
  1309. }
  1310. .goods-item {
  1311. margin: #{12rpx} 0;
  1312. }
  1313. .goods-image {
  1314. width: #{200rpx};
  1315. height: #{200rpx};
  1316. margin-right: #{24rpx};
  1317. }
  1318. .goods-name {
  1319. line-height: #{35rpx};
  1320. height: #{70rpx};
  1321. margin-bottom: #{32rpx};
  1322. }
  1323. }
  1324. /* ---------- */
  1325. .submit-bar {
  1326. //background: #fff;
  1327. //border-top: #{1rpx} solid $uni-weak-color-two;
  1328. //position: fixed;
  1329. //left: 0;
  1330. //bottom: 0;
  1331. //width: 100%;
  1332. //z-index: 1000;
  1333. .price-info {
  1334. padding: 0 0;
  1335. >view {
  1336. margin: #{16rpx} 0;
  1337. }
  1338. }
  1339. .submit-btn {
  1340. width: 240upx;
  1341. text-align: center;
  1342. border-radius: 41upx;
  1343. }
  1344. .submit-btn:active {
  1345. box-shadow: inset 0 0 #{500rpx} rgba(0, 0, 0, .15);
  1346. }
  1347. .submit-btn.lock {
  1348. box-shadow: inset 0 0 #{500rpx} rgba(255, 255, 255, 0.35);
  1349. }
  1350. .submit-btn.disabled {
  1351. background: $uni-general-color-two;
  1352. }
  1353. }
  1354. .theme-color {
  1355. color: #ffffff;
  1356. }
  1357. .u-bottom-fixed {
  1358. position: fixed;
  1359. bottom: 0;
  1360. left: 0;
  1361. width: 100%;
  1362. z-index: 997;
  1363. background-color: #ffffff;
  1364. box-shadow: 0 -1rpx 20rpx -15rpx #353535;
  1365. }
  1366. .bd-bottom {
  1367. width: 750upx;
  1368. height: 110upx;
  1369. padding: 14upx 24upx;
  1370. }
  1371. .full-tip {
  1372. width: 750upx;
  1373. height: 58upx;
  1374. line-height: 58upx;
  1375. }
  1376. .full-tip-show {
  1377. background-color: #ffecec;
  1378. font-size: #{24rpx};
  1379. text-align: center;
  1380. .full-tip-text {
  1381. color: #FF4544;
  1382. }
  1383. }
  1384. .collapse-item-titlebar {
  1385. display: flex;
  1386. align-items: center;
  1387. height: 80rpx;
  1388. .collapse-item-titlebar-txt {
  1389. padding-left: 24rpx;
  1390. font-weight: bold;
  1391. font-size: 30rpx;
  1392. }
  1393. }
  1394. ::v-deep .uni-collapse {
  1395. background-color: transparent !important;
  1396. }
  1397. </style>