lex-xin 4 mesiacov pred
rodič
commit
77974c683e

+ 4 - 0
miniprogram/components/apply-refound/apply-refound.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 105 - 0
miniprogram/components/apply-refound/apply-refound.less

@@ -0,0 +1,105 @@
+/* components/apply-refound/apply-refound.wxss */
+.useRefound-pop {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+
+  .useRefound-mask {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, 0.6);
+  }
+  .useRefound-container {
+    position: absolute;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    width: 100%;
+    background: linear-gradient( 180deg, #FFDEE7 0%, #FFFFFF 12%, #FFFFFF 100%);
+    background-color: #fff;
+    border-radius: 32rpx 32rpx 0rpx 0rpx;
+    .icon-close {
+      position: absolute;
+      width: 38rpx;
+      height: 38rpx;
+      top: 40rpx;
+      right: 40rpx;
+    }
+    .use-title {
+      font-weight: 600;
+      font-size: 36rpx;
+      color: #000000;
+      line-height: 50rpx;
+      padding-top: 34rpx;
+      padding-bottom: 30rpx;
+      text-align: center;
+    }
+    .use-form {
+      background: #F7F8F9;
+      border-radius: 20rpx;
+      padding: 22rpx 24rpx 24rpx 30rpx;
+      textarea {
+        height: 140rpx;
+        font-size: 30rpx;
+        width: 100%;
+        &::placeholder {
+          color: #AAAAAA;
+        }
+      }
+      .num {
+        text-align: right;
+        font-size: 28rpx;
+        color: #AAAAAA;
+        line-height: 40rpx;
+      }
+    }
+    .use-form__input {
+      margin: 0 40rpx 0;
+      background: #FFFFFF;
+      border-radius: 20rpx;
+      margin-bottom: 48rpx;
+      display: flex;
+      flex-direction: column;
+      .title {
+        display: inline;
+        font-size: 30rpx;
+        color: #131415;
+        padding-bottom: 24rpx;
+        .red {
+          color: #F44541;
+        }
+        .sencd {
+          color: #AAAAAA;
+        }
+      }
+      input {
+        padding: 20rpx 16rpx;
+        background: #F7F8F9;
+        border-radius: 16rpx;
+        font-size: 30rpx;
+        &::placeholder {
+          color: #AAAAAA;
+        }
+      }
+    }
+    .btnSection {
+      padding: 0 32rpx 58rpx;
+      button {
+        margin: 0;
+        width: 100%;
+        background: linear-gradient( 270deg, #FF204B 0%, #FE5B71 100%);
+        border-radius: 78rpx;
+        padding: 22rpx 84rpx;
+        font-weight: 500;
+        font-size: 32rpx;
+        color: #FBEAC9;
+        line-height: 44rpx;
+      }
+    }
+  }
+}

+ 89 - 0
miniprogram/components/apply-refound/apply-refound.ts

@@ -0,0 +1,89 @@
+import { api_userPaymentOrderRefundPayment } from "../../api/login";
+
+// components/apply-refound/apply-refound.ts
+Component({
+
+  /**
+   * 组件的属性列表
+   */
+  properties: {
+    refoundStatus: {
+      type: Boolean,
+      default: false,
+    },
+    goodsInfo: {
+      type: Object,
+      default: {}
+    }
+  },
+
+  /**
+   * 组件的初始数据
+   */
+  data: {
+    refoundValue: "", // 退款内容
+    refoundPhone: ''
+  },
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+    textareaInput(e: { detail: any }) {
+      this.setData({
+        refoundValue: e.detail.value
+      })
+    },
+    phoneInput(e: { detail: any }) {
+      this.setData({
+        refoundPhone: e.detail.value
+      })
+    },
+    onRefoundClose() {
+      this.triggerEvent("changeRefoundStatus", false)
+    },
+    checkPhone(phone: string) {
+      const phoneRule =
+        /^((13[0-9])|(14(0|[5-7]|9))|(15([0-3]|[5-9]))|(16(2|[5-9]))|(17[0-8])|(18[0-9])|(19([0-3]|[5-9])))\d{8}$/;
+      return phoneRule.test(phone);
+    },
+    async onRefound() {
+      const refoundValue = this.data.refoundValue
+      const refoundPhone = this.data.refoundPhone
+      if (!refoundValue) {
+        wx.showToast({ title: '请输入退款原因', icon: 'none' })
+        return
+      }
+      if (!this.checkPhone(refoundPhone)) {
+        wx.showToast({ title: '请输入正确的手机号码', icon: 'none' })
+        return
+      }
+      try {
+        const { goods, orderNo } = this.data.goodsInfo
+        const details: any = []
+        goods.forEach((item: any) => {
+          details.push({
+            num: item.goodsNum,
+            onlyRefund: false,
+            userPaymentOrderDetailId: item.id,
+            refundAmount: item.currentPrice
+          })
+        })
+        const params = {
+          merOrderNo: orderNo,
+          serviceCharge: false,
+          refundReason: refoundValue,
+          phone: refoundPhone, // 手机号
+          serviceChargeFee: 0,
+          userRefundOrderDetails: details
+        }
+        const { data } = await api_userPaymentOrderRefundPayment(params)
+        if (data.code == 200) {
+          wx.showToast({ title: '申请成功', icon: 'none' })
+          this.triggerEvent('onConfirm')
+        } else {
+          wx.showToast({ title: data.message, icon: 'none' })
+        }
+      } catch { }
+    },
+  }
+})

+ 22 - 0
miniprogram/components/apply-refound/apply-refound.wxml

@@ -0,0 +1,22 @@
+<!--components/apply-refound/apply-refound.wxml-->
+<view class="useRefound-pop" wx:if="{{ refoundStatus }}">
+    <view class="useRefound-mask"></view>
+    <view class="useRefound-container">
+      <image bind:tap="onRefoundClose" class="icon-close" src="./images/icon-close.png"></image>
+      <view class="use-title">申请退款</view>
+      <view class="use-form__input">
+        <view class="title"><text class="red">*</text>退款原因</view>
+        <view class="use-form">
+          <textarea placeholder="请输入您的退款原因" maxlength="100" bindinput="textareaInput" value="{{ refoundValue }}"></textarea>
+          <view class="num">{{ refoundValue.length }}/100</view>
+        </view>
+      </view>
+      <view class="use-form__input">
+        <view class="title"><text class="red">*</text>联系方式 <text class="sencd">(必填)</text></view>
+        <input placeholder="请输入手机号码" type="number" maxlength="11" bindinput="phoneInput" value="{{ refoundPhone }}"></input>
+      </view>
+      <view class="btnSection">
+        <button type="primary" bind:tap="onRefound">申请退款</button>
+      </view>
+    </view>
+  </view>

BIN
miniprogram/components/apply-refound/images/icon-close.png


+ 2 - 1
miniprogram/pages/orders/order-result.json

@@ -1,6 +1,7 @@
 {
   "usingComponents": {
     "navigation-bar": "/components/navigation-bar/navigation-bar",
-    "service": "/components/service/service"
+    "service": "/components/service/service",
+    "apply-refound": "/components/apply-refound/apply-refound"
   }
 }

+ 25 - 48
miniprogram/pages/orders/order-result.ts

@@ -221,12 +221,15 @@ Page({
   async cancelRefound() {
     try {
       const {data} = await api_userPaymentCancelRefund(this.data.goodsInfo.refundOrderId)
-      console.log(data, 'data')
+      // console.log(data, 'data')
       if(data.code == 200) {
         wx.showToast({ title: '取消退款成功', icon: 'none' })
-        wx.navigateBack({
-          delta: 1
-        })
+        // setTimeout(() => {
+        //   wx.navigateBack({
+        //     delta: 1
+        //   })
+        // }, 1000);
+        this.getDetail()
       } else {
         wx.showToast({ title: data.message, icon: 'none' })
       }
@@ -235,58 +238,32 @@ Page({
   /** 申请退款 */
   useRefound() {
     this.setData({
-      refoundStatus: true,
-      refoundValue: ""
+      refoundStatus: true
     })
   },
-  textareaInput(e: { detail: any }) {
+  changeRefoundStatus(e: {detail: any}) {
     this.setData({
-      refoundValue: e.detail.value
+      refoundStatus: e.detail
     })
   },
-  onRefoundClose() {
+  onRefoundComfirm() {
     this.setData({
-      refoundStatus: false,
-      refoundValue: ''
+      refoundStatus: false
     })
+    // wx.navigateBack({
+    //   delta: 1
+    // })
+    this.getDetail()
   },
-  async onRefound() {
-    console.log(this.data.refoundValue, 'value')
-    const refoundValue = this.data.refoundValue
-    if(!refoundValue) {
-      wx.showToast({ title: '请输入退款原因', icon: 'none' })
-      return
-    }
-    try {
-      const { goods, orderNo } = this.data.goodsInfo
-      console.log(this.data.goodsInfo, 'goodsInfo')
-      const details: any = []
-      goods.forEach((item: any) => {
-        details.push({
-          num: item.goodsNum,
-          onlyRefund: false,
-          userPaymentOrderDetailId: item.id,
-          refundAmount: item.currentPrice
-        })
-      })
-      const params = {
-        merOrderNo: orderNo,
-        serviceCharge: false,
-        refundReason: refoundValue,
-        serviceChargeFee: 0,
-        userRefundOrderDetails: details
-      }
-      const {data} = await api_userPaymentOrderRefundPayment(params)
-      if(data.code == 200) {
-        wx.showToast({ title: '申请成功', icon: 'none' })
-        setTimeout(() => {
-          wx.navigateBack({
-            delta: 1
-          })
-        }, 2000);
-      } else {
-        wx.showToast({ title: data.message, icon: 'none' })
+  onCopy(e: { currentTarget: any }) {
+    wx.setClipboardData({
+      data: e.currentTarget.dataset.orderno,
+      success: () => {
+        wx.showToast({title: '复制成功', icon: 'none'})
+      },
+      fail: () => {
+        wx.showToast({title: '复制失败,请稍后再试', icon: 'none'})
       }
-    } catch {}
+    })
   }
 })

+ 2 - 14
miniprogram/pages/orders/order-result.wxml

@@ -75,18 +75,6 @@
 
   <service popShow="{{ showService }}" bind:changePop="changePop"></service>
 
-  <view class="useRefound-pop" wx:if="{{ refoundStatus }}">
-    <view class="useRefound-mask"></view>
-    <view class="useRefound-container">
-      <image bind:tap="onRefoundClose" class="icon-close" src="./images/icon-close.png"></image>
-      <view class="use-title">选择退款原因</view>
-      <view class="use-form">
-        <textarea placeholder="请输入您的退款原因" maxlength="50" bindinput="textareaInput" value="{{ refoundValue }}"></textarea>
-        <view class="num">{{ refoundValue.length }}/50</view>
-      </view>
-      <view class="btnSection">
-        <button type="primary" bind:tap="onRefound">申请退款</button>
-      </view>
-    </view>
-  </view>
+  <!-- 退费 -->
+  <apply-refound refoundStatus="{{ refoundStatus }}" goodsInfo="{{goodsInfo}}" bind:changeRefoundStatus="changeRefoundStatus" bind:onConfirm="onRefoundComfirm"></apply-refound>
 </view>

+ 2 - 1
miniprogram/pages/orders/orders.json

@@ -1,5 +1,6 @@
 {
   "usingComponents": {
-    "navigation-bar": "/components/navigation-bar/navigation-bar"
+    "navigation-bar": "/components/navigation-bar/navigation-bar",
+    "apply-refound": "/components/apply-refound/apply-refound"
   }
 }

+ 166 - 29
miniprogram/pages/orders/orders.ts

@@ -42,6 +42,8 @@ Page({
     rows: 10,
     recordList: [],
     maxPage: 1, // 总分页数
+    refoundStatus: false,
+    goodsInfo: {}, // 选中的数据
   },
 
   /**
@@ -89,7 +91,7 @@ Page({
         openId: app.globalData.userInfo?.liteOpenid,
         page: currentPage,
         rows: this.data.rows,
-        wechatOrderStatus: tabIdx == 0 ? "" : tabIdx == 1 ? "WAIT_PAY" : tabIdx == 2 ? "WAIT_USE" : tabIdx == 3 ? "PAID" : tabIdx == 4 ? "CLOSED" : tabIdx == 5 ? 'REFUNDING' : "",
+        wechatOrderStatus: tabIdx == 0 ? "" : tabIdx == 1 ? "WAIT_PAY" : tabIdx == 2 ? "WAIT_USE" : tabIdx == 3 ? "PAID" : tabIdx == 4 ? "CLOSED" : tabIdx == 5 ? 'SALE_AFTER' : "",
       })
       if (data.code == 200) {
         const { rows, total } = data.data;
@@ -183,33 +185,9 @@ Page({
   onPay(e: any) {
     const { dataset } = e.currentTarget
     const item: any = this.data.recordList.find((item: any) => item.id === dataset.id)
-    console.log(dataset, item, 'item')
     if(item) {
-      const studentPaymentOrderDetails = item.studentPaymentOrderDetails[0]
-      const prices: any = this.formatPrice(item.paymentCashAmount)
-      const params = {
-        // buyNum: "0",
-        decimalPart: prices.decimalPart,
-        // id: "1856596669912584193",
-        integerPart: prices.integerPart,
-        userPaymentOrderDetailId: studentPaymentOrderDetails.userPaymentOrderDetailId,
-        name: studentPaymentOrderDetails.goodsName,
-        num: studentPaymentOrderDetails.goodsNum,
-        originalPrice: studentPaymentOrderDetails.originalPrice,
-        period: studentPaymentOrderDetails.activationCodeInfo.type,
-        pic: studentPaymentOrderDetails.goodsUrl,
-        salePrice: item.paymentCashAmount,
-        // shopId: "1815717514476302337",
-        orderNo: item.orderNo,
-        wechatStatus: item.wechatStatus,
-        // stockNum: "10",
-        typeName: studentPaymentOrderDetails.typeName
-      }
-      let info = JSON.stringify(params);
-      console.log(params, "params")
-      info = encodeURIComponent(info);
-      wx.navigateTo({
-        url: `../orders/order-detail?orderInfo=${info}`,
+      this.onSubmit({
+        orderNo: item.orderNo
       })
     }
   },
@@ -220,8 +198,167 @@ Page({
   },
   onDetail(e: any) {
     const { dataset } = e.currentTarget
-    wx.navigateTo({
-      url: '../orders/order-result?orderNo=' + dataset.orderno
+    if(dataset.wechatstatus === "WAIT_PAY") {
+      console.log()
+      this.onSubmit({orderNo: dataset.orderno})
+    } else {
+      wx.navigateTo({
+        url: '../orders/order-result?orderNo=' + dataset.orderno
+      })
+    }
+  },
+  // 购买
+  async onSubmit(goodsInfo: any) {
+    wx.showLoading({
+      mask: true,
+      title: "订单提交中...",
+    });
+    try {
+      const { orderNo } = goodsInfo
+      const {data} = await api_userPaymentOrderUnpaid({
+        orderNo: orderNo,
+        paymentType: 'WECHAT_MINI'
+      })
+      if (data.code === 200) {
+        const { paymentConfig, paymentType, orderNo } = data.data.paymentConfig
+        this.onExecutePay(paymentConfig, paymentType, orderNo)
+      } else {
+        this.onPayError()
+      }
+    } catch {
+      wx.hideLoading()
+    }
+  },
+  async onExecutePay( paymentConfig: any, paymentType: string, orderNo: string) {
+    wx.login({
+      success: async (wxres: any) => {
+        const res = await api_executePayment({
+          merOrderNo: paymentConfig.merOrderNo,
+          paymentChannel: this.data.paymentChannel || 'wx_lite', 
+          paymentType,
+          userId: app.globalData.userInfo?.id,
+          code: wxres.code,
+          wxMiniAppId: app.globalData.appId
+        })
+        wx.hideLoading()
+        if(res.data.code === 200) {
+          this.onPaying(paymentType, res.data.data.reqParams, orderNo)
+        } else {
+          this.onPayError(res.data.message)
+        }
+      },
+      fail: () => {
+        this.onPayError()
+      }
     })
   },
+  onPaying(paymentType: string, paymentConfig: any, orderNo: string) {
+    const isYeePay = paymentType.indexOf('yeepay') !== -1
+    const prePayInfo = isYeePay ? JSON.parse(paymentConfig.prePayTn)
+      : paymentConfig?.expend
+        ? JSON.parse(paymentConfig?.expend?.pay_info)
+        : paymentConfig
+    const that = this
+    wx.requestPayment({
+      timeStamp: prePayInfo.timeStamp,
+      nonceStr: prePayInfo.nonceStr,
+      package: prePayInfo.package ? prePayInfo.package : prePayInfo.packageValue,
+      paySign: prePayInfo.paySign,
+      signType: prePayInfo.signType ? prePayInfo.signType : 'MD5',
+      success() {
+        wx.showToast({ title: '支付成功', icon: 'success' });
+        // that.onRefoundComfirm()
+      },
+      fail(ressonInfo) {
+        console.log('支付失败', ressonInfo)
+        that.onPayError()
+      }
+    })
+  },
+  // 获取后台配置的支付方式
+  async queryPayType() {
+    try {
+      // wxlite_payment_service_provider
+      const { data } = await api_queryByParamName({
+        paramName: app.globalData.appId
+      });
+      if (data.code == 200) {
+        const paramValue = data.data.paramValue ? JSON.parse(data.data.paramValue) : {}
+        this.setData({
+          paymentType: paramValue.vendor,
+          paymentChannel: paramValue.channel
+        });
+      }
+    } catch (error) {
+      console.log(error, "error");
+    }
+  },
+  onPayError(message?: string) {
+    wx.hideLoading()
+    wx.showToast({
+      title: message || '支付取消',
+      icon: 'none'
+    })
+  },
+  async onRefounded(e: any) {
+    const { dataset } = e.currentTarget
+    const item: any = this.data.recordList.find((item: any) => item.id === dataset.id)
+    console.log(dataset, item, 'item')
+    if(!item) {
+      return
+    }
+
+    if(item.wechatStatus === "REFUNDING") {
+      try {
+        const refundOrderId = item.refundOrderId
+        const {data} = await api_userPaymentCancelRefund(refundOrderId)
+        console.log(data, 'data')
+        if(data.code == 200) {
+          wx.showToast({ title: '取消退款成功', icon: 'none' })
+          this.onRefoundComfirm()
+        } else {
+          wx.showToast({ title: data.message, icon: 'none' })
+        }
+      } catch {}
+    } else {
+      const { orderNo, studentPaymentOrderDetails } = item
+      const goodsInfo: any = {
+        orderNo,
+        goods: []
+      }
+      if(Array.isArray(studentPaymentOrderDetails)) {
+        studentPaymentOrderDetails.forEach((item: any) => {
+          goodsInfo.goods.push({
+            ...item,
+            id: item.userPaymentOrderDetailId,
+            currentPrice: item.paymentCashAmount
+          })
+        })
+      }
+      this.setData({
+        goodsInfo,
+        refoundStatus: true
+      })
+    }
+  },
+  changeRefoundStatus(e: {detail: any}) {
+    this.setData({
+      refoundStatus: e.detail
+    })
+  },
+  onRefoundComfirm() {
+    const that = this
+    this.setData({
+      refoundStatus: false
+    })
+    setTimeout(() => {
+      that.setData({
+        page: 1,
+        maxPage: 1,
+        recordList: [],
+      }, () => {
+        this.getList()
+      })
+    }, 1500);
+  },
 })

+ 10 - 2
miniprogram/pages/orders/orders.wxml

@@ -33,8 +33,14 @@
               <view class="order-price">
                 订单金额:<text class="price">¥ {{item.amount}}</text>
               </view>
-              <button class="sure" type="primary" wx:if="{{ item.wechatStatus == 'WAIT_PAY' }}"  catch:tap="onPay" data-id="{{item.id}}">继续支付</button>
-              <button type="primary" wx:else catch:tap="onOne" data-id="{{item.id}}">再来一单</button>
+              <block wx:if="{{ item.wechatStatus == 'REFUNDING' || item.wechatStatus == 'WAIT_USE' }}" wx:key="block">
+                <button wx:if="{{ item.wechatStatus == 'REFUNDING' }}" type="primary" wx:if="{{ item.wechatStatus == 'REFUNDING' }}"  catch:tap="onRefounded" data-id="{{item.id}}">取消退款</button>
+                <button wx:else type="primary" catch:tap="onRefounded" data-id="{{item.id}}">申请退款</button>
+              </block>
+              <block wx:else wx:key="block">
+                <button class="sure" type="primary" wx:if="{{ item.wechatStatus == 'WAIT_PAY' }}"  catch:tap="onPay" data-id="{{item.id}}">继续支付</button>
+                <button type="primary" wx:else catch:tap="onOne" data-id="{{item.id}}">再来一单</button>
+              </block>
             </view>
           </view>
         </view>
@@ -47,4 +53,6 @@
       </block>
     </scroll-view>
   </view>
+  <!-- 申请退款 -->
+  <apply-refound refoundStatus="{{ refoundStatus }}" goodsInfo="{{goodsInfo}}" bind:changeRefoundStatus="changeRefoundStatus" bind:onConfirm="onRefoundComfirm"></apply-refound>
 </view>