submit-integral-order.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <template>
  2. <div class="submit-order">
  3. <div class="content">
  4. <div class="step-box">
  5. <div class="left">
  6. <span class="img"></span>
  7. <span class="text">{{$t('submitOrder.submitOrder')}}</span>
  8. </div>
  9. <div class="steps">
  10. <div class="item">
  11. <div class="number">step 01.</div>
  12. <div class="text">{{$t('submitOrder.selectProductToBuy')}}</div>
  13. </div>
  14. <div class="item active">
  15. <div class="number">step 02.</div>
  16. <div class="text">{{$t('submitOrder.confirmOrderInformation')}}</div>
  17. </div>
  18. <div class="item">
  19. <div class="number">step 03.</div>
  20. <div class="text">{{$t('submitOrder.payToCompleteTheOrder')}}</div>
  21. </div>
  22. </div>
  23. </div>
  24. <div class="submit-con">
  25. <!-- 收货地址 -->
  26. <div class="submit-box">
  27. <div class="tit">
  28. <span class="text">{{$t('address.receivingAddress')}}</span>
  29. <!-- <span class="action">显示全部地址</span> -->
  30. </div>
  31. <div class="con address-box">
  32. <div
  33. :class="['item', address.commonAddr?'default-address':'',selectedAddrId==address.addrId?'active':'']"
  34. v-for="address in addressList"
  35. :key="address.addrId"
  36. @click="changeAddress(address.addrId)"
  37. >
  38. <div class="name-phone">
  39. <span class="name">{{address.receiver}}</span>
  40. <span class="phone">{{address.mobile}}</span>
  41. <span
  42. class="set-default"
  43. v-if="!address.commonAddr"
  44. @click="setDefaultAddr(address.addrId)"
  45. >{{$t('address.setDefault')}}</span>
  46. <span class="default-tag" v-if="address.commonAddr">{{$t('address.default')}}</span>
  47. </div>
  48. <div
  49. class="address-detail"
  50. >{{address.province+address.city+address.area+address.addr}}</div>
  51. <div class="del-edit">
  52. <span class="edit" @click.stop="editAddr(address.addrId)"></span>
  53. <span class="del" @click.stop="toggleDelAddr(true,address.addrId)"></span>
  54. </div>
  55. </div>
  56. <div class="item add-address" @click="toggleAddrPop(true)">
  57. <div class="add-box">
  58. <div class="img">+</div>
  59. <div class="text">{{$t('address.addAddress')}}</div>
  60. </div>
  61. </div>
  62. </div>
  63. <div class="popup-mask" v-if="showDelAddr"></div>
  64. <div class="fix-transform-blur">
  65. <div class="popup-box" v-if="showDelAddr">
  66. <div class="tit" style="padding:10px;">
  67. <div class="text">{{$t('tips')}}</div>
  68. <div class="close" @click="toggleDelAddr(false)"></div>
  69. </div>
  70. <div class="con">
  71. <div class="tip">
  72. <div class="tip-icon warning"></div>
  73. <div class="tip-info">
  74. <div class="result">{{$t('address.deleteShippingAddress')}}</div>
  75. <div class="date">{{$t('address.deleteShippingTips')}}</div>
  76. <div class="btns">
  77. <a href="javascrip:void(0);" @click="delAddr()" class="btn-r">{{$t('delete')}}</a>
  78. <a href="javascrip:void(0);" @click="toggleDelAddr(flase)" class="btn-g">{{$t('cancel')}}</a>
  79. </div>
  80. </div>
  81. </div>
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. <!-- 收货地址 -->
  87. <!-- 支付方式 -->
  88. <div class="submit-box">
  89. <div class="tit">
  90. <span class="text">{{$t('commonFoot.paymentMethod')}}</span>
  91. </div>
  92. <div class="con pay-way">
  93. <div class="item active">{{$t('submitOrder.payOnline')}}</div>
  94. <!-- <div class="item">货到付款</div>
  95. <div class="item">线下支付</div>-->
  96. </div>
  97. </div>
  98. <!-- 支付方式 -->
  99. <!-- 配送方式 -->
  100. <div class="submit-box">
  101. <div class="tit">
  102. <span class="text">{{$t('submitOrder.deliveryMethod')}}</span>
  103. </div>
  104. <div class="con delivery-way">
  105. <div class="item active">{{$t('submitOrder.courierDelivery')}}</div>
  106. <!-- <div class="item">到店自提</div> -->
  107. <!-- <div class="description">(该商品不支持自提)</div> -->
  108. </div>
  109. </div>
  110. <!-- /配送方式 -->
  111. <!-- 商品信息 -->
  112. <div class="submit-box goods-info">
  113. <div class="tit">
  114. <span class="text">{{$t('applyReturn.productInformation')}}</span>
  115. </div>
  116. <div class="goods-msg">
  117. <div class="msg-tab">
  118. <div class="img">&nbsp;</div>
  119. <div class="info">{{$t('products')}}</div>
  120. <div class="unit-price">{{$t('priceOne')}}</div>
  121. <div class="number">{{$t('quantity')}}</div>
  122. <div class="total">{{$t('subtotal')}}</div>
  123. </div>
  124. <div class="msg-con">
  125. <!-- 店铺中的商品 -->
  126. <div class="goods-box">
  127. <div class="prod-row">
  128. <div class="img">
  129. <nuxt-link :to="'/member-center/integral-det/'+productItemDto.prodId" class="img-box">
  130. <img :src="productItemDto.pic" alt />
  131. </nuxt-link>
  132. </div>
  133. <div class="info">
  134. <nuxt-link :to="'/member-center/integral-det/'+productItemDto.prodId" class="name">{{productItemDto.prodName}}</nuxt-link>
  135. <span class="sku">{{productItemDto.skuName}}</span>
  136. </div>
  137. <div class="unit-price" >
  138. <span v-if="productItemDto.price > 0">¥{{parsePrice(productItemDto.price)[0]}}.{{parsePrice(productItemDto.price)[1]}} +</span> {{productItemDto.scorePrice/productItemDto.prodCount}}&nbsp;{{$t('submitOrder.points')}}
  139. </div>
  140. <div class="number">{{productItemDto.prodCount}}</div>
  141. <div class="total"><span v-if="productItemDto.productTotalAmount > 0">¥{{parsePrice(productItemDto.productTotalAmount)[0]}}.{{parsePrice(productItemDto.productTotalAmount)[1]}} +</span> {{productItemDto.scorePrice}}&nbsp;{{$t('submitOrder.points')}}</div>
  142. </div>
  143. </div>
  144. <!-- 留言 -->
  145. <div class="submit-box">
  146. <div class="remakes">
  147. {{$t('submitOrder.noteMessage')}}:<input type="text" maxlength="100" class="text" v-model="remarks" :placeholder="$t('submitOrder.numberLength100')" />
  148. </div>
  149. </div>
  150. <!-- /留言 -->
  151. </div>
  152. </div>
  153. </div>
  154. <!-- 商品信息 -->
  155. </div>
  156. <div class="submit-bottom">
  157. <div class="statistic-box">
  158. <div class="item">
  159. <div class="tit">
  160. <span class="number">{{orderInfo.totalCount}}</span>{{$t('submitOrder.totalItems')}}:
  161. </div>
  162. <div class="con">
  163. <span v-if="orderInfo.total > 0">¥{{parsePrice(orderInfo.total)[0]}}.{{parsePrice(orderInfo.total)[1]}} +</span> {{productItemDto.scorePrice}}&nbsp;{{$t('submitOrder.points')}}
  164. </div>
  165. </div>
  166. <div class="item">
  167. <div class="tit">{{$t('submitOrder.freightPayable')}}:</div>
  168. <div
  169. class="con"
  170. >¥{{ parsePrice(transfee)[0] }}.{{
  171. parsePrice(transfee)[1]
  172. }}</div>
  173. </div>
  174. <!-- 平台开启会员包邮(运费减免) -->
  175. <div v-if="orderInfo.freeTransfee" class="item">
  176. <div class="tit">{{$t('submitOrder.memberPackage')}}:</div>
  177. <div class="con bright">
  178. <p>
  179. -¥{{ parsePrice(orderInfo.freeTransfee)[0] }}.{{
  180. parsePrice(orderInfo.freeTransfee)[1]
  181. }}
  182. </p>
  183. </div>
  184. </div>
  185. <div class="item" v-if="orderInfo.orderReduce">
  186. <div class="tit">{{$t('submitOrder.offerAmount')}}:</div>
  187. <div
  188. class="con bright"
  189. >-¥{{parsePrice(orderInfo.orderReduce)[0]}}.{{parsePrice(orderInfo.orderReduce)[1]}}</div>
  190. </div>
  191. </div>
  192. <div class="detail-box">
  193. <div class="item">
  194. <div class="tit">{{$t('submitOrder.totalPayable')}}:</div>
  195. <div class="con">
  196. <span v-if="orderInfo.actualTotal > 0">¥{{parsePrice(orderInfo.actualTotal)[0]}}.{{parsePrice(orderInfo.actualTotal)[1]}} +</span> {{productItemDto.scorePrice}}&nbsp;{{$t('submitOrder.points')}}
  197. </div>
  198. </div>
  199. <div class="item" v-if="currentAddr.addrId">
  200. <span
  201. class="text"
  202. >{{$t('submitOrder.sendTo')}}:{{currentAddr.province+' '+currentAddr.city +' '+currentAddr.area+' '+currentAddr.addr}}</span>
  203. <span class="text">{{$t('submitOrder.consignee')}}:{{currentAddr.receiver}} {{currentAddr.mobile}}</span>
  204. </div>
  205. </div>
  206. <div class="btn-box">
  207. <a href="javascript:void(0)" class="btn" @click="submitOrder">{{$t('submitOrder.submitOrder')}}</a>
  208. </div>
  209. </div>
  210. </div>
  211. <!-- 地址弹窗 -->
  212. <AddressPop
  213. :editAddrId="editAddrId"
  214. v-if="showAddrPop"
  215. @getAddrList="getAddrList"
  216. @reloadOrderInfo="loadOrderInfo"
  217. @toggleAddrPop="toggleAddrPop"
  218. />
  219. <!-- /地址弹窗 -->
  220. </div>
  221. </template>
  222. <script>
  223. import AddressPop from '~/components/add-or-edit-address'
  224. import CouponSelect from '~/components/coupon-select'
  225. export default {
  226. components: {
  227. AddressPop, CouponSelect
  228. },
  229. data () {
  230. return {
  231. addressList: [],
  232. selectedAddrId: 0,
  233. orderInfo: {},
  234. productItemDto: [],
  235. remarks: '', //留言
  236. // 积分相关
  237. totalScoreAmount: 0, // 积分抵扣金额
  238. totalUsableScore: 0, // 整个订单可以使用的积分数
  239. isScorePay: 0, // 用户是否选择积分抵现(0不使用 1使用 默认不使用)
  240. isChecked: true, // 是否选择会员积分抵现
  241. isProhibit: false, // (积分抵现)checkbox是否禁止
  242. // 地址数据
  243. currentAddr: {}, // 当前选择的地址
  244. showAddrPop: false, // 地址弹窗显隐
  245. editAddrId: 0, // 要修改的地址id
  246. showDelAddr: false,
  247. // 券
  248. orderEntry: 0, //订单入口 0购物车 1立即购买
  249. uuid: '',
  250. // 应付运费
  251. transfee: 0,
  252. }
  253. },
  254. mounted () {
  255. if (this.$route.query.orderEntry) {
  256. this.orderEntry = this.$route.query.orderEntry
  257. }
  258. this.uuid = this.genUUID();
  259. this.getAddrList()
  260. this.loadOrderInfo()
  261. },
  262. methods: {
  263. /**
  264. * 获取地址列表
  265. */
  266. getAddrList () {
  267. this.$axios.get('/p/address/list').then(({ data }) => {
  268. this.addressList = data
  269. })
  270. },
  271. /**
  272. * 选择地址
  273. */
  274. changeAddress (addrId) {
  275. this.addressList.forEach(element => {
  276. if (element.addrId == addrId) {
  277. this.currentAddr = element
  278. }
  279. });
  280. this.selectedAddrId = addrId
  281. this.loadOrderInfo()
  282. },
  283. /**
  284. * 设置为默认地址
  285. */
  286. setDefaultAddr (addrId) {
  287. this.$axios.put('/p/address/defaultAddr/' + addrId).then(({ data }) => {
  288. this.$message({
  289. message: data,
  290. type: 'success',
  291. duration: 1000
  292. })
  293. this.getAddrList()
  294. })
  295. },
  296. /**
  297. * 显示/隐藏确认删除弹窗
  298. */
  299. toggleDelAddr (sts, addrId) {
  300. this.showDelAddr = sts
  301. this.editAddrId = addrId
  302. },
  303. /**
  304. * 显示/隐藏地址弹窗
  305. */
  306. toggleAddrPop (sts) {
  307. this.showAddrPop = sts
  308. this.editAddrId = 0
  309. },
  310. /**
  311. * 修改地址 (弹窗传地址id)
  312. */
  313. editAddr (addrId) {
  314. this.showAddrPop = true
  315. this.editAddrId = addrId
  316. },
  317. /**
  318. * 删除地址
  319. */
  320. delAddr () {
  321. let reload = false
  322. if (this.selectedAddrId == this.editAddrId) {
  323. this.selectedAddrId = 0
  324. reload = true
  325. }
  326. this.$axios.delete('/p/address/deleteAddr/' + this.editAddrId).then(({ data }) => {
  327. this.$message({
  328. message: data,
  329. type: 'success',
  330. duration: 1000
  331. })
  332. this.toggleDelAddr(false)
  333. this.getAddrList()
  334. if (reload) {
  335. this.loadOrderInfo()
  336. }
  337. })
  338. },
  339. /**
  340. * 价格处理
  341. */
  342. parsePrice: (value) => {
  343. var val = Number(value)
  344. if (!val) {
  345. val = 0;
  346. }
  347. // 截取小数点后两位,并以小数点为切割点将val转化为数组
  348. return val.toFixed(2).split(".");
  349. },
  350. /**
  351. * 加载订单数据
  352. */
  353. loadOrderInfo () {
  354. // const loading = this.$loading({
  355. // lock: true,
  356. // text: '加载中...',
  357. // background: 'rgba(255, 255, 255, 0.8)'
  358. // });
  359. var orderParam = {
  360. addrId: this.selectedAddrId,
  361. orderItem: this.orderEntry == 1 ? JSON.parse(sessionStorage.getItem("orderItem")) : undefined,
  362. basketIds: this.orderEntry == 0 ? JSON.parse(sessionStorage.getItem("basketIds")) : undefined,
  363. // isScorePay: this.isScorePay,
  364. userChangeCoupon: 1,
  365. uuid: this.uuid
  366. }
  367. this.$axios.post('/p/score/confirm', orderParam).then(({ data }) => {
  368. this.orderInfo = data
  369. this.productItemDto = data.productItemDto
  370. if (data.userAddr) {
  371. this.currentAddr = data.userAddr
  372. this.selectedAddrId = data.userAddr.addrId
  373. }
  374. if (data.totalTransfee && data.freeTransfee) {
  375. this.transfee = accuracyCount(data.totalTransfee, data.freeTransfee, 1)
  376. } else {
  377. this.transfee = data.totalTransfee
  378. }
  379. // loading.close();
  380. }).catch(() => {
  381. // loading.close();
  382. })
  383. },
  384. /**
  385. * 提交订单
  386. */
  387. submitOrder () {
  388. if (!this.addressList.length) {
  389. this.$message({
  390. message: this.$t('submitOrder.pleaseAddTheAddressFirst'),
  391. type: 'success',
  392. duration: 1000
  393. })
  394. this.showAddrPop = true
  395. return
  396. }
  397. if (this.selectedAddrId == 0) {
  398. this.$message({
  399. message: this.$t('submitOrder.pleaseAddTheAddressFirst'),
  400. type: 'success',
  401. duration: 1000
  402. })
  403. document.body.scrollTop = document.documentElement.scrollTop = 0
  404. return
  405. }
  406. this.$axios.post('/p/score/submit', {
  407. remarks: this.remarks,
  408. uuid: this.uuid
  409. }).then(({ data }) => {
  410. sessionStorage.setItem("pay_total", this.orderInfo.actualTotal)
  411. sessionStorage.setItem("pay_orderNumber", data.orderNumbers)
  412. this.$router.push({
  413. path: '/payment'
  414. })
  415. })
  416. },
  417. /**
  418. * 生成uuid
  419. */
  420. genUUID () {
  421. var s = [];
  422. var hexDigits = "0123456789abcdef";
  423. for (var i = 0; i < 36; i++) {
  424. s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
  425. }
  426. s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
  427. s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
  428. s[8] = s[13] = s[18] = s[23] = "-";
  429. var uuid = s.join("");
  430. return uuid;
  431. }
  432. }
  433. }
  434. </script>
  435. <style scoped src='~/assets/css/submit-order.css'></style>
  436. <style scoped>
  437. .fix-transform-blur {
  438. z-index: 10000;
  439. position: fixed;
  440. top: 40%;
  441. left: 50%;
  442. transform: translate(-50%, -40%);
  443. }
  444. .submit-order .submit-box {
  445. padding-left: 20px;
  446. }
  447. .submit-order .submit-box .goods-msg .msg-con {
  448. background: #f9f9f9;
  449. margin-top: 0;
  450. padding-bottom: 30px;
  451. border-bottom: 1px solid #eee;
  452. }
  453. .submit-order .statistic-box .item .con,
  454. .submit-order .detail-box .item .con {
  455. min-width: 120px;
  456. width: auto;
  457. }
  458. .submit-order .submit-box .goods-msg .msg-con .goods-box {
  459. margin: 0 15px;
  460. }
  461. .submit-order .submit-box .goods-msg .msg-con .goods-box::after {
  462. left: 0;
  463. right: 0;
  464. }
  465. .submit-order .submit-box .goods-msg .msg-tab .img,
  466. .submit-order .submit-box .goods-msg .msg-con .img {
  467. padding: 0 15px 0 0;
  468. }
  469. .submit-order .submit-box .remakes {
  470. margin-top: 15px;
  471. }
  472. .submit-order .submit-box .remakes .text {
  473. margin-left: 0;
  474. }
  475. .submit-order .statistic-box .item {
  476. min-height: 33px;
  477. line-height: 33px;
  478. }
  479. .score-pri {
  480. line-height: 1.5em!important;
  481. }
  482. </style>