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

804 lines
20 KiB

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