建材商城系统20241014
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.

807 lines
20 KiB

1 week ago
  1. <template>
  2. <view class="page">
  3. <!-- 导航栏 -->
  4. <navbar :title="titleMap[type]" leftClick @leftClick="$utils.navigateBack" bgColor="#DC2828" color="#fff" />
  5. <view class="bac"></view>
  6. <view class="box">
  7. <!-- 送礼 -->
  8. <view class="give-type" v-if="type == 'give'">
  9. <view class="tab-box">
  10. <view class="tab-item" :class="{'active': isGive === 1}"
  11. @click="isGive = 1">
  12. <text>单人礼包</text>
  13. <text class="desc">送给1位好友可同时送多件礼品</text>
  14. </view>
  15. <view class="tab-item" :class="{'active': isGive === 2}"
  16. @click="isGive = 2">
  17. <text>多人礼包</text>
  18. <text class="desc">送给多位好友每人1件礼品</text>
  19. </view>
  20. <view class="tab-item" :class="{'active': isGive === 3}"
  21. @click="isGive = 3">
  22. <text>抽奖礼包</text>
  23. <text class="desc">好友抽奖中奖者获得礼品</text>
  24. </view>
  25. </view>
  26. <!-- <view class="tips">
  27. <text>支付后分享给好友收礼</text>
  28. <text class="guide" @click="$refs.popup.open('gift_guide')">指南</text>
  29. </view> -->
  30. </view>
  31. <!-- 多人礼包人数 -->
  32. <view class="cell-item" v-if="type == 'give' && isGive === 2">
  33. <view class="cell-item-left">
  34. <uv-icon name="gift" size="40" color="#E3441A"></uv-icon>
  35. <view class="user-name">礼包份数</view>
  36. </view>
  37. <view class="cell-item-right">
  38. <view class="stepper">
  39. <text class="minus" :class="{disabled: multiNum <= multiMinNum}"
  40. @click="multiNum > multiMinNum && multiNum--">-</text>
  41. <text class="num">{{multiNum}}</text>
  42. <text class="plus" :class="{disabled: multiNum >= multiMaxNum}"
  43. @click="multiNum < multiMaxNum && multiNum++">+</text>
  44. </view>
  45. </view>
  46. </view>
  47. <!-- 抽奖礼包说明 -->
  48. <view class="lucky-box" v-if="type == 'give' && isGive === 3">
  49. <view class="title">抽奖规则</view>
  50. <view class="tips-list">
  51. <view class="tip-item"> 好友参与抽奖</view>
  52. <view class="tip-item"> 系统随机抽取中奖者</view>
  53. <view class="tip-item"> 中奖者填写地址领取礼品</view>
  54. </view>
  55. </view>
  56. <!-- 商品详情 -->
  57. <view class="product-item" v-for="item in payOrderProduct" :key="item.id">
  58. <view class="img-box">
  59. <image :src="item.image && item.image.split(',')[0]" mode="aspectFill"></image>
  60. </view>
  61. <view class="server-info">
  62. <view class="server-title">{{ item.name }}</view>
  63. <view class="texture">
  64. 材质{{ item.material }}
  65. </view>
  66. <view class="stepper">
  67. <uv-number-box button-size="60rpx"
  68. inputWidth="250rpx"
  69. v-model="item.selectNum"
  70. :max="item.num"></uv-number-box>
  71. </view>
  72. <view class="sales-volume">
  73. <view class="desc">已售出 {{ item.payNum }}</view>
  74. </view>
  75. </view>
  76. </view>
  77. <!-- 地址 -->
  78. <view @click="openAddress" class="cell-item">
  79. <view class="cell-item-left">
  80. <image src="@/pages_order/static/createOrder/address.png" mode="widthFix" class="cell-icon"></image>
  81. <view class="user-name">{{ address.name }}</view>
  82. <view class="user-address">{{ address.address }}</view>
  83. </view>
  84. <view class="cell-item-right">
  85. <uv-icon name="arrow-right"></uv-icon>
  86. </view>
  87. </view>
  88. <!-- 备注 -->
  89. <!-- <view class="cell-item">
  90. <view class="cell-item-left">
  91. <image src="@/pages_order/static/createOrder/coupon.png" mode="widthFix" class="cell-icon"></image>
  92. <view class="user-name">备注</view>
  93. </view>
  94. <view class="cell-item-right remark-input">
  95. <uv-textarea v-model="remark" border="none" height="40rpx" placeholder="请输入订单备注信息" :count="false" :auto-height="false" />
  96. </view>
  97. </view> -->
  98. <view class="cell-list">
  99. <uv-radio-group v-model="payMethod">
  100. <view style="width: 710rpx;">
  101. <!-- 账户余额 -->
  102. <view class="cell-item">
  103. <view class="cell-item-left">
  104. <image src="@/pages_order/static/createOrder/account.png" mode="widthFix" class="cell-icon">
  105. </image>
  106. <view class="user-name">账户积分</view>
  107. <view class="descript">(积分: {{ userInfo.money }})</view>
  108. </view>
  109. <view class="cell-item-right">
  110. <uv-radio activeColor="#E3441A"
  111. size="40rpx"
  112. icon-size="30rpx"
  113. :name="0"/>
  114. </view>
  115. </view>
  116. <!-- 微信支付 -->
  117. <view class="cell-item">
  118. <view class="cell-item-left">
  119. <image src="@/pages_order/static/createOrder/wx.png" mode="widthFix" class="cell-icon">
  120. </image>
  121. <view class="user-name">微信支付</view>
  122. <view class="descript"></view>
  123. </view>
  124. <view class="cell-item-right">
  125. <uv-radio
  126. activeColor="#E3441A"
  127. size="40rpx"
  128. icon-size="30rpx"
  129. :name="1"/>
  130. </view>
  131. </view>
  132. </view>
  133. </uv-radio-group>
  134. </view>
  135. <!-- 优惠券 -->
  136. <!-- <view @click="openCoupon" class="cell-item">
  137. <view class="cell-item-left">
  138. <image src="@/pages_order/static/createOrder/coupon.png" mode="widthFix" class="cell-icon"></image>
  139. <view class="user-name">优惠券</view>
  140. <view class="descript">({{ coupon.money || 0}})</view>
  141. </view>
  142. <view class="cell-item-right">
  143. <radio color="#E3441A" :value="2" :checked="coupon.id" />
  144. </view>
  145. </view> -->
  146. <!-- 提示 -->
  147. <view class="hint"
  148. v-if="payOrderProduct[0] && payOrderProduct[0].orderDetails">
  149. {{ payOrderProduct[0].orderDetails }}
  150. </view>
  151. <!-- 用户协议 -->
  152. <view class="agreement">
  153. <radio color="#E3441A" @click="agreement = !agreement" :checked="agreement" />
  154. 本人已同意<text @click="$refs.popup.open('user_xy')">用户使用协议</text>
  155. </view>
  156. <!-- 下单 -->
  157. <view class="submit">
  158. <view class="price">
  159. <view>
  160. <text style="color: #000;">合计</text>
  161. <text style="font-size: 18px;
  162. font-weight: 600;">{{ totalPrice }}</text>
  163. </view>
  164. </view>
  165. <view class="btn" @click="submit">
  166. 立即支付
  167. </view>
  168. </view>
  169. </view>
  170. <!-- 地址选择 -->
  171. <uv-popup ref="addressPopup" :round="30" style="padding-bottom: 90rpx;">
  172. <addressList ref="addressList" height="60vh" @select="selectAddress" />
  173. <view class="add-btn">
  174. <view @click="$utils.navigateTo('/pages_order/mine/address?type=back')" class="button-submit">新增地址</view>
  175. </view>
  176. </uv-popup>
  177. <!-- 优惠券选择-->
  178. <!-- <uv-popup ref="couponPopup" :round="30">
  179. <couponList ref="couponList" height="60vh" @select="selectCoupon" />
  180. </uv-popup> -->
  181. <configPopup ref="popup"></configPopup>
  182. <!-- <kefu></kefu> -->
  183. <kefu/>
  184. </view>
  185. </template>
  186. <script>
  187. import addressList from '../components/address/addressList.vue'
  188. // import couponList from '@/components/couponList/couponList.vue'
  189. import {
  190. mapState
  191. } from 'vuex'
  192. export default {
  193. components: {
  194. addressList,
  195. // couponList
  196. },
  197. data() {
  198. return {
  199. address: {
  200. name: '请选择地址',
  201. address: '',
  202. },
  203. addressTotal: 0,
  204. remark: '',
  205. agreement: false,
  206. coupon: {},
  207. payMethod : 1,
  208. isGive : 0,
  209. type : '',
  210. titleMap : {
  211. def : '确认订单',
  212. give : '送礼清单',
  213. },
  214. multiNum: 2, // 多人礼包人数
  215. multiMinNum: 2, // 最小人数
  216. multiMaxNum: 100, // 最大人数
  217. }
  218. },
  219. computed: {
  220. totalPrice() {
  221. let price = 0
  222. this.payOrderProduct.forEach(n => {
  223. price += n.price * (n.selectNum || 1)
  224. })
  225. if (this.coupon.id) {
  226. price -= this.coupon.money
  227. }
  228. return Number(price).toFixed(2)
  229. },
  230. ...mapState(['userInfo', 'payOrderProduct']),
  231. },
  232. onLoad(args) {
  233. this.type = args.type || 'def'
  234. if(this.type == 'give'){
  235. this.isGive = 1
  236. }
  237. this.$store.commit('getUserInfo')
  238. },
  239. onShow() {
  240. this.getAddressList()
  241. // this.getCouponList()
  242. },
  243. methods: {
  244. // 打开
  245. getAddressList() {
  246. // 获取地址列表
  247. this.$refs.addressList.getAddressList().then(res => {
  248. this.addressTotal = res.total
  249. if (this.addressTotal != 0) {
  250. this.address = res.records[0]
  251. }
  252. })
  253. },
  254. //获取优惠券列表
  255. getCouponList() {
  256. this.$refs.couponList.getCouponList()
  257. },
  258. // 打开选择地址
  259. openAddress() {
  260. if (this.addressTotal == 0) {
  261. return uni.navigateTo({
  262. url: '/pages_order/mine/address?type=back'
  263. })
  264. }
  265. this.$refs.addressPopup.open('bottom')
  266. },
  267. // 选择地址
  268. selectAddress(e) {
  269. this.address = e
  270. this.$refs.addressPopup.close()
  271. },
  272. // 打开优惠券选择
  273. openCoupon() {
  274. if (this.addressTotal == 0) {
  275. return uni.navigateTo({
  276. url: '/pages_order/mine/address?type=back'
  277. })
  278. }
  279. this.$refs.couponPopup.open('bottom')
  280. },
  281. // 选择优惠券
  282. selectCoupon(e) {
  283. //判断优惠券限制
  284. let {
  285. useMoney
  286. } = e
  287. let productTotalPrice = 0
  288. this.payOrderProduct.forEach(item => {
  289. productTotalPrice += item.price
  290. })
  291. if (productTotalPrice < useMoney) {
  292. return uni.showToast({
  293. title: `此优惠券需要满${useMoney}使用`,
  294. icon: "none"
  295. })
  296. }
  297. this.coupon = e
  298. this.$refs.couponPopup.close()
  299. },
  300. submit() {
  301. let addressId = this.address.id
  302. if (!addressId) {
  303. uni.showToast({
  304. title: '请选择地址',
  305. icon: 'none'
  306. })
  307. return
  308. }
  309. if (!this.agreement) {
  310. uni.showToast({
  311. title: '请先同意使用协议',
  312. icon: 'none'
  313. })
  314. return
  315. }
  316. let data = {}
  317. let api = ''
  318. // if(this.type != 'give'){
  319. let list = []
  320. this.payOrderProduct.forEach(n => {
  321. list.push({
  322. num: n.selectNum || 1,
  323. shopId: n.id,
  324. })
  325. })
  326. data = {
  327. addressId,
  328. payType : this.payMethod,
  329. list: JSON.stringify(list),
  330. // remark: this.remark || '', // 添加备注字段
  331. }
  332. api = 'createSumOrder'
  333. this.deleteCart(this.payOrderProduct.map(n => n.cartId).join(','))
  334. // } else {
  335. // data = {
  336. // addressId,
  337. // num: this.payOrderProduct[0].selectNum || 1,
  338. // productId: this.payOrderProduct[0].id,
  339. // payType : this.payMethod,
  340. // // isGive : this.isGive,
  341. // // memberNum : 1,
  342. // // remark: this.remark || '', // 添加备注字段
  343. // }
  344. // api = 'createOrder'
  345. // }
  346. if(this.coupon.id){
  347. data.couponId = this.coupon.id
  348. }
  349. // if(this.isGive == 2){
  350. // data.memberNum = this.multiNum
  351. // }
  352. this.$api(api, data, res => {
  353. if (res.code == 200) {
  354. if(this.payMethod == 0){
  355. // uni.showToast({
  356. // title: '下单成功',
  357. // icon: 'none'
  358. // })
  359. this.paySuccess(res)
  360. return
  361. }
  362. uni.requestPaymentWxPay(res)
  363. .then(e => {
  364. uni.showToast({
  365. title: '下单成功',
  366. icon: 'none'
  367. })
  368. this.paySuccess(res)
  369. }).catch(n => {
  370. setTimeout(uni.redirectTo, 700, {
  371. url: '/pages/index/order'
  372. })
  373. })
  374. }
  375. })
  376. },
  377. paySuccess(res){
  378. if(this.type == 'def'){
  379. setTimeout(uni.redirectTo, 700, {
  380. url: '/pages/index/order'
  381. })
  382. }else{
  383. setTimeout(uni.redirectTo, 700, {
  384. url: `/pages_order/order/instantGift?id=${res.message}`
  385. })
  386. }
  387. },
  388. // 删除购物车
  389. deleteCart(ids) {
  390. this.$api('deleteCart', {
  391. ids
  392. })
  393. },
  394. }
  395. }
  396. </script>
  397. <style scoped lang="scss">
  398. .page {
  399. overflow: auto;
  400. padding-bottom: 300rpx;
  401. .bac {
  402. width: 100%;
  403. height: 100px;
  404. background: $uni-color;
  405. }
  406. .give-type {
  407. background: #fff;
  408. border-radius: 20rpx;
  409. padding: 30rpx;
  410. margin-bottom: 20rpx;
  411. .tab-box {
  412. display: flex;
  413. justify-content: space-between;
  414. .tab-item {
  415. width: 30%;
  416. background: #F8F8F8;
  417. border-radius: 20rpx;
  418. padding: 20rpx;
  419. text-align: center;
  420. text {
  421. display: block;
  422. &.desc {
  423. font-size: 24rpx;
  424. color: #999;
  425. margin-top: 10rpx;
  426. }
  427. }
  428. &.active {
  429. background: rgba($uni-color, 0.1);
  430. color: $uni-color;
  431. .desc {
  432. color: $uni-color;
  433. }
  434. }
  435. }
  436. }
  437. .tips {
  438. margin-top: 20rpx;
  439. font-size: 26rpx;
  440. color: #999;
  441. display: flex;
  442. align-items: center;
  443. justify-content: space-between;
  444. .guide {
  445. color: $uni-color;
  446. text-decoration: underline;
  447. }
  448. }
  449. }
  450. .box {
  451. padding: 20rpx;
  452. margin-top: -150rpx;
  453. // 商品详情
  454. .product-item {
  455. display: flex;
  456. flex-wrap: wrap;
  457. align-items: center;
  458. justify-content: space-between;
  459. background: white;
  460. border-radius: 15rpx;
  461. box-sizing: border-box;
  462. padding: 25rpx;
  463. margin: 20rpx 0rpx;
  464. .img-box {
  465. width: 200rpx;
  466. height: 200rpx;
  467. background: #ccc;
  468. border-radius: 10rpx;
  469. overflow: hidden;
  470. image {
  471. width: 100%;
  472. height: 100%;
  473. }
  474. }
  475. .server-info {
  476. width: calc(100% - 200rpx);
  477. box-sizing: border-box;
  478. padding: 10rpx 20rpx;
  479. display: flex;
  480. flex-direction: column;
  481. justify-content: space-around;
  482. .server-title {
  483. font-size: 34rpx;
  484. }
  485. .texture {
  486. color: #B8B8B8;
  487. margin: 10rpx 0rpx;
  488. }
  489. .stepper {
  490. margin-bottom: 10rpx;
  491. &::v-deep .uv-number-box__input {
  492. color: $uni-color !important;
  493. width: 200rpx !important;
  494. }
  495. }
  496. .sales-volume {
  497. display: flex;
  498. align-items: center;
  499. color: #B8B8B8;
  500. font-size: 26rpx;
  501. image {
  502. width: 25rpx;
  503. height: 25rpx;
  504. }
  505. }
  506. }
  507. }
  508. //cell单元格(地址)
  509. .cell-item {
  510. display: flex;
  511. justify-content: space-between;
  512. align-items: center;
  513. background: white;
  514. border-radius: 20rpx;
  515. padding: 20rpx;
  516. box-sizing: border-box;
  517. .cell-item-left {
  518. display: flex;
  519. align-items: center;
  520. width: 90%;
  521. .cell-icon {
  522. width: 40rpx;
  523. }
  524. .user-name,
  525. .user-address {
  526. white-space: nowrap;
  527. overflow: hidden;
  528. text-overflow: ellipsis;
  529. width: 150rpx;
  530. padding-left: 20rpx;
  531. box-sizing: border-box;
  532. }
  533. .descript {
  534. color: #888888;
  535. }
  536. .user-address {
  537. width: calc(100% - 230rpx);
  538. }
  539. }
  540. .cell-item-right {
  541. width: 10%;
  542. display: flex;
  543. justify-content: flex-end;
  544. &.remark-input {
  545. width: 70%;
  546. justify-content: flex-start;
  547. &::v-deep .uv-textarea {
  548. width: 100%;
  549. padding: 0;
  550. background-color: transparent;
  551. }
  552. &::v-deep .uv-textarea__field {
  553. padding: 0;
  554. font-size: 28rpx;
  555. }
  556. }
  557. .stepper {
  558. display: flex;
  559. align-items: center;
  560. text {
  561. display: flex;
  562. align-items: center;
  563. justify-content: center;
  564. width: 44rpx;
  565. height: 44rpx;
  566. &.minus, &.plus {
  567. background: #F8F8F8;
  568. border-radius: 50%;
  569. font-size: 32rpx;
  570. &.disabled {
  571. color: #ccc;
  572. }
  573. }
  574. &.num {
  575. margin: 0 20rpx;
  576. color: $uni-color;
  577. font-size: 28rpx;
  578. }
  579. }
  580. }
  581. }
  582. }
  583. .cell-list {
  584. margin: 20rpx 0rpx;
  585. border-radius: 20rpx;
  586. overflow: hidden;
  587. .cell-item {
  588. border-radius: 0rpx;
  589. }
  590. }
  591. // 提示
  592. .hint {
  593. font-size: 26rpx;
  594. margin-top: 80rpx;
  595. color: #BFBFBF;
  596. }
  597. // 用户协议
  598. .agreement {
  599. display: flex;
  600. justify-content: center;
  601. align-items: center;
  602. padding: 10px 0;
  603. .van-checkbox {
  604. margin-right: 5rpx;
  605. }
  606. text {
  607. color: $uni-color;
  608. }
  609. }
  610. // 下单
  611. .submit {
  612. position: fixed;
  613. bottom: 0;
  614. left: 0;
  615. width: 100%;
  616. height: 60px;
  617. background-color: #fff;
  618. display: flex;
  619. justify-content: space-between;
  620. align-items: center;
  621. .price {
  622. color: #F39637;
  623. padding: 0 20px;
  624. }
  625. .btn {
  626. background: $uni-color;
  627. color: white;
  628. width: 120px;
  629. height: 45px;
  630. border-radius: 23px;
  631. font-size: 16px;
  632. display: flex;
  633. justify-content: center;
  634. align-items: center;
  635. }
  636. }
  637. }
  638. //新增地址按钮
  639. .add-btn {
  640. width: 100%;
  641. .button-submit {
  642. display: flex;
  643. align-items: center;
  644. justify-content: center;
  645. width: 596rpx;
  646. height: 90rpx;
  647. background: #E3441A;
  648. border-radius: 46rpx;
  649. margin: 20rpx auto;
  650. font-size: 28rpx;
  651. font-family: PingFang SC, PingFang SC-Regular;
  652. font-weight: 400;
  653. text-align: center;
  654. color: #ffffff;
  655. }
  656. }
  657. .multi-box, .lucky-box {
  658. background: #fff;
  659. border-radius: 20rpx;
  660. padding: 30rpx;
  661. margin-bottom: 20rpx;
  662. .title {
  663. font-size: 28rpx;
  664. font-weight: 500;
  665. margin-bottom: 20rpx;
  666. }
  667. }
  668. .multi-box {
  669. .stepper {
  670. display: flex;
  671. align-items: center;
  672. justify-content: center;
  673. text {
  674. display: flex;
  675. align-items: center;
  676. justify-content: center;
  677. width: 60rpx;
  678. height: 60rpx;
  679. &.minus, &.plus {
  680. background: #F8F8F8;
  681. border-radius: 50%;
  682. font-size: 36rpx;
  683. &.disabled {
  684. color: #ccc;
  685. }
  686. }
  687. &.num {
  688. margin: 0 40rpx;
  689. color: $uni-color;
  690. font-size: 32rpx;
  691. }
  692. }
  693. }
  694. }
  695. .lucky-box {
  696. .tips-list {
  697. .tip-item {
  698. font-size: 26rpx;
  699. color: #666;
  700. line-height: 2;
  701. }
  702. }
  703. }
  704. }
  705. </style>