小程序端工程代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

546 lines
18 KiB

  1. <template>
  2. <view class="order-submission">
  3. <view class="allAddress" :style="systemStore ? '' : 'padding-top: 0.2*100rpx'">
  4. <view class="nav acea-row">
  5. <view class="item font-color-red" :class="shipping_type === 0 ? 'on' : 'on2'" @click="addressType(0)" v-if="systemStore"></view>
  6. <view class="item font-color-red" :class="shipping_type === 1 ? 'on' : 'on2'" @click="addressType(1)" v-if="systemStore && !isIntegral"></view>
  7. </view>
  8. <view class="address acea-row row-between-wrapper" v-if="shipping_type === 0" @click="addressTap">
  9. <view class="addressCon" v-if="addressInfo.realName">
  10. <view class="name">
  11. {{ addressInfo.realName }}
  12. <text class="phone">{{ addressInfo.phone }}</text>
  13. </view>
  14. <view>
  15. <text class="default font-color-red" v-if="addressInfo.isDefault">[默认]</text>
  16. {{ addressInfo.province }}{{ addressInfo.city }}{{ addressInfo.district }}{{ addressInfo.detail }}
  17. </view>
  18. </view>
  19. <view class="addressCon" v-else>
  20. <view class="setaddress">设置收货地址</view>
  21. </view>
  22. <view class="iconfont icon-jiantou"></view>
  23. </view>
  24. <div class="address acea-row row-between-wrapper" v-if="shipping_type === 1" @click="showStoreList">
  25. <div class="addressCon" v-if="storeItems">
  26. <div class="name">
  27. {{ storeItems.name }}
  28. <span class="phone">{{ storeItems.phone }}</span>
  29. </div>
  30. <div>{{ storeItems.address }}</div>
  31. </div>
  32. <div class="addressCon" v-else>
  33. <div class="name">
  34. {{ systemStore.name }}
  35. <span class="phone">{{ systemStore.phone }}</span>
  36. </div>
  37. <div>{{ systemStore.address }}</div>
  38. </div>
  39. <div class="iconfont icon-jiantou"></div>
  40. </div>
  41. <view class="line">
  42. <image :src="`${$VUE_APP_RESOURCES_URL}/images/line.jpg`" />
  43. </view>
  44. </view>
  45. <OrderGoods :evaluate="0" :isIntegral="isIntegral" :cartInfo="orderGroupInfo.cartInfo"></OrderGoods>
  46. <view class="wrapper">
  47. <view class="item acea-row row-between-wrapper" @click="couponTap" v-if="deduction === false && !isIntegral">
  48. <view>优惠券</view>
  49. <view class="discount">
  50. {{ usableCoupon.couponTitle || '请选择' }}
  51. <text class="iconfont icon-jiantou"></text>
  52. </view>
  53. </view>
  54. <view class="item acea-row row-between-wrapper" v-if="!isIntegral && deduction === false && enableIntegral === true">
  55. <view>积分抵扣</view>
  56. <view class="discount">
  57. <view class="select-btn">
  58. <view class="checkbox-wrapper">
  59. <!-- <input type="checkbox" v-model="useIntegral" @click="changeUseIntegral"/> -->
  60. <checkbox-group @change="changeUseIntegral">
  61. <label class="well-check">
  62. <text class="integral">
  63. 当前积分
  64. <text class="num font-color-red">{{ userInfo.integral || 0 }}</text>
  65. </text>
  66. <checkbox value="true" :checked="useIntegral ? true : false"></checkbox>
  67. </label>
  68. </checkbox-group>
  69. </view>
  70. </view>
  71. </view>
  72. </view>
  73. <view class="item acea-row row-between-wrapper" v-if="shipping_type === 0">
  74. <view>快递费用</view>
  75. <view class="discount">
  76. {{ orderGroupInfo.priceGroup.storePostage > 0 ? orderGroupInfo.priceGroup.storePostage : '免运费' }}
  77. </view>
  78. </view>
  79. <view v-if="shipping_type === 1">
  80. <view class="item acea-row row-between-wrapper">
  81. <view>联系人</view>
  82. <view class="discount">
  83. <input type="text" placeholder="请填写您的联系姓名" v-model="contacts" />
  84. </view>
  85. </view>
  86. <view class="item acea-row row-between-wrapper">
  87. <view>联系电话</view>
  88. <view class="discount">
  89. <input type="text" placeholder="请填写您的联系电话" v-model="contactsTel" />
  90. </view>
  91. </view>
  92. </view>
  93. <view class="item">
  94. <view>备注信息150字以内</view>
  95. <textarea v-model="mark"></textarea>
  96. </view>
  97. </view>
  98. <view class="wrapper">
  99. <view class="item">
  100. <view>支付方式</view>
  101. <view class="list">
  102. <view class="payItem acea-row row-middle" v-if="!isIntegral" :class="active === 'weixin' ? 'on' : ''" @click="payItem('weixin')" v-show="isWeixin">
  103. <view class="name acea-row row-center-wrapper"> <view class="iconfont icon-weixin2" :class="active === 'weixin' ? 'bounceIn' : ''"></view>微信支付 </view>
  104. <view class="tip">微信快捷支付</view>
  105. </view>
  106. <view class="payItem acea-row row-middle" v-if="!isIntegral" :class="active === 'weixin' ? 'on' : ''" @click="payItem('weixin')" v-show="!isWeixin">
  107. <view class="name acea-row row-center-wrapper"> <view class="iconfont icon-weixin2" :class="active === 'weixin' ? 'bounceIn' : ''"></view>微信支付 </view>
  108. <view class="tip">微信快捷支付</view>
  109. </view>
  110. <view class="payItem acea-row row-middle" v-if="!isIntegral" :class="active === 'yue' ? 'on' : ''" @click="payItem('yue')">
  111. <view class="name acea-row row-center-wrapper"> <view class="iconfont icon-icon-test" :class="active === 'yue' ? 'bounceIn' : ''"></view>余额支付 </view>
  112. <view class="tip">可用余额{{ userInfo.nowMoney || 0 }}</view>
  113. </view>
  114. <view class="payItem acea-row row-middle" v-if="isIntegral" :class="active === 'integral' ? 'on' : ''" @click="payItem('integral')">
  115. <view class="name acea-row row-center-wrapper"> <view class="iconfont icon-icon-test" :class="active === 'integral' ? 'bounceIn' : ''"></view>积分支付 </view>
  116. <view class="tip">可用积分{{ userInfo.integral || 0 }}</view>
  117. </view>
  118. </view>
  119. </view>
  120. </view>
  121. <view class="moneyList">
  122. <view class="item acea-row row-between-wrapper" v-if="orderPrice.totalPrice !== undefined">
  123. <view>商品总价</view>
  124. <view class="money" v-if="!isIntegral">{{ orderPrice.totalPrice }}</view>
  125. <view class="money" v-if="isIntegral">{{ orderPrice.payIntegral }}积分</view>
  126. </view>
  127. <view class="item acea-row row-between-wrapper" v-if="orderPrice.payPostage > 0 && !isIntegral">
  128. <view>运费</view>
  129. <view class="money">{{ orderPrice.payPostage }}</view>
  130. </view>
  131. <view class="item acea-row row-between-wrapper" v-if="orderPrice.couponPrice > 0 && !isIntegral">
  132. <view>优惠券抵扣</view>
  133. <view class="money">-{{ orderPrice.couponPrice }}</view>
  134. </view>
  135. <view class="item acea-row row-between-wrapper" v-if="orderPrice.deductionPrice > 0 && !isIntegral">
  136. <view>积分抵扣</view>
  137. <view class="money">-{{ orderPrice.deductionPrice }}</view>
  138. </view>
  139. </view>
  140. <view style="height: 120rpx"></view>
  141. <view class="footer acea-row row-between-wrapper">
  142. <view>
  143. 合计:
  144. <text class="font-color-red" v-if="!isIntegral">{{ orderPrice.payPrice }}</text>
  145. <text class="font-color-red" v-if="isIntegral">{{ orderPrice.payIntegral }}积分</text>
  146. </view>
  147. <view class="settlement" @click="createOrder">立即结算</view>
  148. </view>
  149. <CouponListWindow v-on:couponchange="changecoupon($event)" v-model="showCoupon" :price="orderPrice.totalPrice" :checked="usableCoupon.id" @checked="changeCoupon" :cartid="cartid"></CouponListWindow>
  150. <AddressWindow @checked="changeAddress" @redirect="addressRedirect" v-model="showAddress" :checked="addressInfo.id" ref="mychild"></AddressWindow>
  151. </view>
  152. </template>
  153. <style scoped lang="less">
  154. .order-submission .wrapper .shipping select {
  155. color: #999;
  156. padding-right: 0.15 * 100rpx;
  157. }
  158. .order-submission .wrapper .shipping .iconfont {
  159. font-size: 0.3 * 100rpx;
  160. color: #515151;
  161. }
  162. .order-submission .allAddress {
  163. width: 100%;
  164. background-image: linear-gradient(to bottom, #eb3729 0%, #eb3729 100%);
  165. background-image: -webkit-linear-gradient(to bottom, #eb3729 0%, #eb3729 100%);
  166. background-image: -moz-linear-gradient(to bottom, #eb3729 0%, #eb3729 100%);
  167. padding-top: 1 * 100rpx;
  168. }
  169. .order-submission .allAddress .nav {
  170. margin: 0 auto;
  171. padding: 0 30rpx;
  172. width: 100%;
  173. box-sizing: border-box;
  174. }
  175. .order-submission .allAddress .nav .item {
  176. flex: 1;
  177. position: relative;
  178. }
  179. .order-submission .allAddress .nav .item.on {
  180. position: relative;
  181. }
  182. .order-submission .allAddress .nav .item.on:before {
  183. position: absolute;
  184. bottom: 0;
  185. content: '快递配送';
  186. font-size: 0.28 * 100rpx;
  187. display: block;
  188. height: 0;
  189. left: 0;
  190. right: 0;
  191. border-width: 0.4 * 100rpx;
  192. border-style: solid;
  193. border-color: #fff;
  194. z-index: 9;
  195. text-align: center;
  196. line-height: 0.14 * 100rpx;
  197. }
  198. .order-submission .allAddress .nav .item:nth-of-type(2).on:before {
  199. content: '到店自提';
  200. border-width: 0.4 * 100rpx;
  201. }
  202. .order-submission .allAddress .nav .item.on2 {
  203. position: relative;
  204. }
  205. .order-submission .allAddress .nav .item.on2:before {
  206. position: absolute;
  207. bottom: 0;
  208. content: '到店自提';
  209. font-size: 0.28 * 100rpx;
  210. display: block;
  211. height: 0;
  212. left: 0;
  213. right: 0;
  214. border-width: 0.4 * 100rpx;
  215. border-style: solid;
  216. border-color: #d5e6e6;
  217. text-align: center;
  218. line-height: 0.14 * 100rpx;
  219. }
  220. .order-submission .allAddress .nav .item:nth-of-type(1).on2:before {
  221. content: '快递配送';
  222. border-width: 0.4 * 100rpx;
  223. }
  224. .order-submission .allAddress .address {
  225. width: 6.91 * 100rpx;
  226. height: 1.5 * 100rpx;
  227. margin: 0 auto;
  228. box-sizing: border-box;
  229. }
  230. .order-submission .allAddress .line {
  231. width: 7.1 * 100rpx;
  232. margin: 0 auto;
  233. }
  234. .order-submission .wrapper .item .discount input::placeholder {
  235. color: #ccc;
  236. }
  237. </style>
  238. <script>
  239. import OrderGoods from '@/components/OrderGoods'
  240. import CouponListWindow from '@/components/CouponListWindow'
  241. import AddressWindow from '@/components/AddressWindow'
  242. import { postOrderConfirm, postOrderComputed, createOrder } from '@/api/order'
  243. import { mapGetters } from 'vuex'
  244. import { handleOrderPayResults, subscribeMessage } from '@/libs/order'
  245. import { weappPay } from '@/libs/wechat'
  246. import { isWeixin, handleErrorMessage } from '@/utils'
  247. const NAME = 'OrderSubmission',
  248. _isWeixin = isWeixin()
  249. export default {
  250. name: NAME,
  251. components: {
  252. OrderGoods,
  253. CouponListWindow,
  254. AddressWindow,
  255. },
  256. props: {},
  257. data: function() {
  258. return {
  259. offlinePayStatus: 2,
  260. from: this.$deviceType,
  261. deduction: true,
  262. enableIntegral: true,
  263. enableIntegralNum: 0,
  264. isWeixin: _isWeixin,
  265. pinkId: 0,
  266. active: _isWeixin ? 'weixin' : 'yue',
  267. showCoupon: false,
  268. showAddress: false,
  269. addressInfo: {},
  270. couponId: 0,
  271. orderGroupInfo: {
  272. priceGroup: {},
  273. },
  274. usableCoupon: {},
  275. addressLoaded: false,
  276. useIntegral: false,
  277. orderPrice: {
  278. payPrice: '计算中',
  279. },
  280. mark: '',
  281. systemStore: {},
  282. shipping_type: 0,
  283. contacts: '',
  284. contactsTel: '',
  285. storeSelfMention: 0,
  286. cartid: '',
  287. isIntegral: false,
  288. }
  289. },
  290. computed: mapGetters(['userInfo', 'storeItems']),
  291. watch: {
  292. useIntegral() {
  293. this.computedPrice()
  294. },
  295. shipping_type() {
  296. this.computedPrice()
  297. },
  298. },
  299. onLoad: function() {
  300. let that = this
  301. this.$store.dispatch('getUser', true)
  302. that.getCartInfo()
  303. console.log(that.$yroute)
  304. if (that.$yroute.query.pinkid !== undefined) {
  305. that.pinkId = that.$yroute.query.pinkid
  306. }
  307. this.isIntegral = that.$yroute.query.isIntegral == 'true'
  308. this.useIntegral = this.isIntegral
  309. if (this.isIntegral) {
  310. this.active = 'integral'
  311. }
  312. if (that.$yroute.query.id !== undefined) {
  313. that.cartid = that.$yroute.query.id
  314. console.log(that.cartid)
  315. }
  316. },
  317. methods: {
  318. showStoreList() {
  319. this.$store.commit('get_to', 'orders')
  320. this.$yrouter.push({
  321. path: '/pages/shop/StoreList/index',
  322. })
  323. },
  324. addressType: function(index) {
  325. if (index && !this.systemStore.id) {
  326. uni.showToast({
  327. title: '暂无门店信息,您无法选择到店自提!',
  328. icon: 'none',
  329. duration: 2000,
  330. })
  331. return
  332. }
  333. console.log(this)
  334. this.shipping_type = index
  335. },
  336. changeUseIntegral: function(e) {
  337. // this.computedPrice();
  338. if (this.isIntegral) {
  339. return
  340. }
  341. this.useIntegral = e.mp.detail.value[0]
  342. },
  343. // 计算商品价格
  344. computedPrice() {
  345. let shipping_type = this.shipping_type
  346. postOrderComputed(this.orderGroupInfo.orderKey, {
  347. addressId: this.addressInfo.id,
  348. useIntegral: this.useIntegral ? 1 : 0,
  349. couponId: this.usableCoupon.id || 0,
  350. shipping_type: parseInt(shipping_type) + 1,
  351. }).then(res => {
  352. const data = res.data
  353. if (data.status === 'EXTEND_ORDER') {
  354. this.$yrouter.replace({
  355. path: '/pages/order/OrderDetails/index',
  356. query: {
  357. id: data.result.orderId,
  358. },
  359. })
  360. } else {
  361. this.orderPrice = data.result
  362. }
  363. })
  364. },
  365. getCartInfo() {
  366. let cartIds = this.$yroute.query.id
  367. // 拼团id
  368. if (this.$yroute.query.pinkId) {
  369. cartIds = this.$yroute.query.pinkId
  370. }
  371. if (!cartIds) {
  372. uni.showToast({
  373. title: '参数有误',
  374. icon: 'none',
  375. duration: 2000,
  376. })
  377. return this.$yrouter.back()
  378. }
  379. postOrderConfirm(cartIds)
  380. .then(res => {
  381. console.log(res, 999999)
  382. console.log(res.data.systemStore || {}, 999999)
  383. this.offlinePayStatus = res.data.offline_pay_status
  384. this.orderGroupInfo = res.data
  385. this.deduction = res.data.deduction
  386. this.usableCoupon = res.data.usableCoupon || {}
  387. this.addressInfo = res.data.addressInfo || {}
  388. // 用来显示到店自提的店铺地址
  389. this.systemStore = res.data.systemStore || {}
  390. this.storeSelfMention = res.data.storeSelfMention
  391. this.computedPrice()
  392. })
  393. .catch((error) => {
  394. console.log(error)
  395. uni.showToast({
  396. title: '加载订单数据失败',
  397. icon: 'none',
  398. duration: 2000,
  399. })
  400. })
  401. },
  402. addressTap: function() {
  403. this.showAddress = true
  404. if (!this.addressLoaded) {
  405. this.addressLoaded = true
  406. this.$refs.mychild.getAddressList()
  407. }
  408. },
  409. addressRedirect() {
  410. this.addressLoaded = false
  411. this.showAddress = false
  412. },
  413. couponTap: function() {
  414. this.showCoupon = true
  415. },
  416. changeCoupon: function(coupon) {
  417. if (!coupon) {
  418. this.usableCoupon = {
  419. couponTitle: '不使用优惠券',
  420. id: 0,
  421. }
  422. } else {
  423. this.usableCoupon = coupon
  424. }
  425. this.computedPrice()
  426. },
  427. payItem: function(index) {
  428. this.active = index
  429. },
  430. changeAddress(addressInfo) {
  431. this.addressInfo = addressInfo
  432. this.computedPrice()
  433. },
  434. createOrder() {
  435. if (this.isIntegral) {
  436. // 积分支付
  437. if (this.userInfo.integral < this.orderPrice.payIntegral) {
  438. uni.showToast({
  439. title: '积分不足',
  440. icon: 'none',
  441. duration: 2000,
  442. })
  443. return
  444. }
  445. this.active = 'integral'
  446. }
  447. let shipping_type = this.shipping_type
  448. if (!this.isIntegral && !this.active) {
  449. uni.showToast({
  450. title: '请选择支付方式',
  451. icon: 'none',
  452. duration: 2000,
  453. })
  454. return
  455. }
  456. if (!this.addressInfo.id && !this.shipping_type) {
  457. uni.showToast({
  458. title: '请选择收货地址',
  459. icon: 'none',
  460. duration: 2000,
  461. })
  462. return
  463. }
  464. if (this.shipping_type) {
  465. if ((this.contacts === '' || this.contactsTel === '') && this.shipping_type) {
  466. uni.showToast({
  467. title: '请填写联系人或联系人电话',
  468. icon: 'none',
  469. duration: 2000,
  470. })
  471. return
  472. }
  473. if (!/^1(3|4|5|7|8|9|6)\d{9}$/.test(this.contactsTel)) {
  474. uni.showToast({
  475. title: '请填写正确的手机号',
  476. icon: 'none',
  477. duration: 2000,
  478. })
  479. return
  480. }
  481. if (!/^[\u4e00-\u9fa5\w]{2,16}$/.test(this.contacts)) {
  482. uni.showToast({
  483. title: '请填写您的真实姓名',
  484. icon: 'none',
  485. duration: 2000,
  486. })
  487. return
  488. }
  489. }
  490. uni.showLoading({
  491. title: '生成订单中',
  492. })
  493. let from = {}
  494. if (this.$deviceType == 'app') {
  495. from.from = 'app'
  496. }
  497. console.log(this.$deviceType)
  498. // #ifdef MP-WEIXIN
  499. subscribeMessage()
  500. // #endif
  501. createOrder(this.orderGroupInfo.orderKey, {
  502. realName: this.contacts,
  503. phone: this.contactsTel,
  504. addressId: this.addressInfo.id,
  505. useIntegral: this.useIntegral ? 1 : 0,
  506. couponId: this.usableCoupon.id || 0,
  507. payType: this.active,
  508. pinkId: this.pinkId,
  509. seckillId: this.orderGroupInfo.seckill_id,
  510. combinationId: this.orderGroupInfo.combination_id,
  511. bargainId: this.orderGroupInfo.bargain_id,
  512. from: this.from,
  513. mark: this.mark || '',
  514. shippingType: parseInt(shipping_type) + 1,
  515. storeId: this.storeItems ? this.storeItems.id : this.systemStore.id,
  516. ...from,
  517. })
  518. .then(res => {
  519. uni.hideLoading()
  520. handleOrderPayResults.call(this, res.data, 'create', this.active)
  521. })
  522. .catch(err => {
  523. handleErrorMessage(err, '创建订单失败')
  524. })
  525. },
  526. },
  527. }
  528. </script>