推拿小程序前端代码仓库
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.

762 lines
17 KiB

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