lex-xin 5 ماه پیش
والد
کامیت
5f0823a5de

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

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

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

@@ -0,0 +1,103 @@
+/* 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: #F8F8F8;
+    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 {
+      margin: 0 40rpx 0;
+      background: #FFFFFF;
+      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: 20rpx 40rpx 0;
+      background: #FFFFFF;
+      border-radius: 20rpx;
+      padding: 24rpx;
+      margin-bottom: 180rpx;
+      display: flex;
+      justify-content: space-between;
+      .title {
+        display: inline;
+        font-size: 30rpx;
+        color: #131415;
+        .red {
+          color: #F44541;
+        }
+        .sencd {
+          color: #AAAAAA;
+        }
+      }
+      input {
+        text-align: right;
+        font-size: 30rpx;
+        &::placeholder {
+          color: #AAAAAA;
+        }
+      }
+    }
+    .btnSection {
+      padding: 0 32rpx 58rpx;
+      button {
+        margin: 0;
+        width: 100%;
+        background: linear-gradient( 90deg, #544F4A 0%, #302F2B 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 { }
+    },
+  }
+})

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

@@ -0,0 +1,19 @@
+<!--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">
+        <textarea placeholder="请输入您的退款原因" maxlength="100" bindinput="textareaInput" value="{{ refoundValue }}"></textarea>
+        <view class="num">{{ refoundValue.length }}/100</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


+ 1 - 0
miniprogram/components/service/service.ts

@@ -40,6 +40,7 @@ Component({
       // 
     },
     onShow() {
+      console.log('onShow', '1212')
       this.setData({
         popShow: true
       })

+ 1 - 1
miniprogram/components/service/service.wxml

@@ -8,5 +8,5 @@
       <image src="./images/icon-close.png" catch:tap="onClose" class="iconClose"></image>
     </view>
   </view>
-  <image wx:if="{{ btnShow }}" src="./images/icon-service.png" bind:tap="onShow" style="top: {{top}}px; right: 4px;" bindtouchstart="onTouchStart" bindtouchmove="onTouchMove" bindtouchend="onTouchEnd" class="iconSerivce"></image>
+  <image wx:if="{{ btnShow }}" src="./images/icon-service.png" catch:tap="onShow" style="top: {{top}}px; right: 4px;" bind:touchstart="onTouchStart" catch:touchmove="onTouchMove" bind:touchend="onTouchEnd" class="iconSerivce"></image>
 </view>

+ 21 - 0
miniprogram/pages/index/index.less

@@ -299,6 +299,27 @@ page {
   }
 }
 
+
+.scroll-current-item {
+  position: fixed;
+  bottom: 162rpx;
+  left: 0;
+  width: 100%;
+  margin-top: 24rpx;
+  font-size: 24rpx;
+  color: #502F00;
+  line-height: 40rpx;
+  background: #FFF3E1;
+  border: 2rpx solid #FBE9CE;
+  padding: 12rpx 16rpx;
+  text-align: center;
+
+  text {
+    color: #FF0047;
+    font-weight: bold;
+  }
+}
+
 .goodsSection {
   // margin-bottom: 156rpx;
   margin-top: 12rpx;

+ 60 - 14
miniprogram/pages/index/index.ts

@@ -22,13 +22,26 @@ Page({
     isOverSaled: false, // 是否所有商品都没有库存
     selected: {} as any,
     opacity: 0,
+    scrolIntoViewStr: '',
+    scrolIntoView: '',
+    scrollDiscount: false, // 是否扣减启
+    scrollIntoViewType: false,
+    headerHeight: 0, // 头部的高度
   },
 
   /**
    * 生命周期函数--监听页面加载
    */
   onLoad() {
-    this.onInit()
+    // this.onInit()
+  },
+  onReady() {
+    const that = this
+    wx.createSelectorQuery().select('#scroll-header').boundingClientRect(function (rect) {
+      that.setData({
+        headerHeight: rect.height
+      })
+    }).exec();
   },
   /**
    * 获取基础信息
@@ -157,7 +170,7 @@ Page({
       let info = JSON.stringify({
         ...that.data.selected
       });
-      console.log(that.data.selected, "that.data.selected")
+      // console.log(that.data.selected, "that.data.selected")
       info = encodeURIComponent(info);
       wx.navigateTo({
         url: `../orders/order-detail?orderInfo=${info}`,
@@ -187,21 +200,54 @@ Page({
   // },
   // 页面滚动时颜色变化
   onScrollView(e: { detail: any }) {
-    const top = e.detail.scrollTop || 0
+    const top = e.detail.scrollTop || 0 
+    // 从100开始显示
     this.setData({
-      opacity: top > 150 ? 1 : top / 150
+      opacity: top < 100 ? 0 : (top - 100) > 150 ? 1 : (top - 100) / 150
     })
+    if(this.data.scrollIntoViewType) {
+      this.setData({
+        scrollTop: this.data.scrollDiscount ? top - this.data.headerHeight : top,
+        scrollIntoViewType: false,
+        scrollDiscount: false,
+      })
+    } else {
+      this.onChangeScroll()
+    }
+  },
+  onChangeScroll() {
+    const that = this;
+    debounce(function() {
+      wx.createSelectorQuery().select('#type3').boundingClientRect(function (rect) {
+        if(rect.top > 0 &&  rect.top <= that.data.headerHeight) {
+         that.setData({
+           scrolIntoViewStr: 'type3',
+         })
+        }
+      }).exec();
+      wx.createSelectorQuery().select('#type2').boundingClientRect(function (rect) {
+        if(rect.top > 0 &&  rect.top <= that.data.headerHeight) {
+          that.setData({
+            scrolIntoViewStr: 'type2'
+          })
+        }
+        if(rect.top > 0 && rect.top > that.data.headerHeight) {
+          that.setData({
+            scrolIntoViewStr: 'type1'
+          })
+        }
+      }).exec();
+    }, 600)()
+    
+    
   },
   onTapAnchor(e: { currentTarget: { dataset: any } }) {
-    console.log(e, 'e')
-    const scrollView = this.selectComponent('.scrollarea');
-    console.log(scrollView, 'scrollView')
-    const that = this
-    wx.createSelectorQuery().select('#' + e.currentTarget.dataset.type).boundingClientRect(function (rect) {
-      console.log(rect)
-      that.setData({
-          scrollTop: rect.top
-      });
-    }).exec();
+    const type = e.currentTarget.dataset.type
+    this.setData({
+      scrolIntoView: type,
+      scrolIntoViewStr: type,
+      scrollDiscount: type !== 'type3' ? true : false,
+      scrollIntoViewType: true,
+    })
   }
 })

+ 9 - 5
miniprogram/pages/index/index.wxml

@@ -1,5 +1,5 @@
 <!--index.wxml-->
-<scroll-view class="scrollarea" id="scroll-view" scroll-y="{{popupShow ? false : true}}" type="list" bindscroll="onScrollView" scroll-top="{{scrollTop}}">
+<scroll-view class="scrollarea" id="scroll-view" scroll-y="{{popupShow ? false : true}}" type="list" bindscroll="onScrollView" scroll-into-view="{{scrolIntoView}}" scroll-top="{{ scrollTop }}">
   <view class="container">
     <!-- <view class="topShadow"></view> -->
     <view class="slider-count">{{current + 1}}/{{8}}</view>
@@ -98,15 +98,19 @@
     </view>
 
 
-    <view class="scroll-header" style="opacity: {{opacity}}">
+    <view id="scroll-header" class="scroll-header" style="opacity: {{opacity}}">
       <navigation-bar back="{{false}}" title="商品详情"></navigation-bar>
       <view class="product-catagory">
-        <view class="item selected" bind:tap="onTapAnchor" data-type="type1">产品介绍</view>
-        <view class="item" bind:tap="onTapAnchor" data-type="type2">互通案例</view>
-        <view class="item" bind:tap="onTapAnchor" data-type="type3">购买流程</view>
+        <view class="item {{ scrolIntoViewStr == 'type1' || !scrolIntoViewStr ? 'selected' : '' }}" bind:tap="onTapAnchor" data-type="type1">产品介绍</view>
+        <view class="item {{ scrolIntoViewStr == 'type2' ? 'selected' : '' }}" bind:tap="onTapAnchor" data-type="type2">互通案例</view>
+        <view class="item {{ scrolIntoViewStr == 'type3' ? 'selected' : '' }}" bind:tap="onTapAnchor" data-type="type3">购买流程</view>
       </view>
     </view>
 
+    <view class="scroll-current-item" wx:if="{{!isOverSaled && selected.id && opacity >= 1}}">
+      您已选中:<text>{{ selected.typeName }}</text> ,合计:<text>¥ {{ selected.showSalePrice }}</text>,已优惠:<text>¥ {{ selected.discountPrice }}</text>
+    </view>
+
     <view class="goodsSection">
       <view class="title">
         <view class="before"></view>

BIN
miniprogram/pages/login/images/radio-active.png


+ 16 - 13
miniprogram/pages/login/login.less

@@ -9,44 +9,47 @@
   flex-direction: column;
   padding-top: 150rpx;
   image {
-    width: 160rpx;
-    height: 160rpx;
-    border-radius: 50%;
+    width: 148rpx;
+    height: 148rpx;
     overflow: hidden;
   }
   .appname {
-    padding-top: 40rpx;
+    padding-top: 46rpx;
     font-weight: 600;
-    font-size: 40rpx;
+    font-size: 44rpx;
     color: #333333;
+    line-height: 60rpx;
     line-height: 56rpx;
   }
 }
 
 .login-section {
-  padding-top: 180rpx;
-  padding: 180rpx 40rpx 0;
+  padding: 128rpx 40rpx 0;
   button {
     width: 100%;
     line-height: 88rpx;
-    background: linear-gradient( 270deg, #FF204B 0%, #FE5B71 100%);
+    background: linear-gradient( 90deg, #544F4A 0%, #302F2B 100%);
     border-radius: 44rpx;
     font-weight: 500;
     font-size: 32rpx;
-    color: #FFFFFF;
+    color: #FBEAC9;
     padding-top: 0;
     padding-bottom: 0;
     &[disabled][type=primary] {
       color: #fff;
-      background: linear-gradient( 270deg, #FF204B 0%, #FE5B71 100%);
+      background: linear-gradient( 90deg, #544F4A 0%, #302F2B 100%);
       opacity: 0.7;
     }
   }
 
   .protocol-section {
-    padding-top: 80rpx;
+    position: absolute;
+    bottom: 100rpx;
+    left: 0;
+    width: 100%;
+    text-align: center;
     font-size: 26rpx;
-    color: #3C3C3C;
+    color: #777777;
     line-height: 36rpx;
     .radioSection {
       height: 36rpx;
@@ -61,7 +64,7 @@
       transform: translateY(4rpx)
     }
     .protocol {
-      color: #FE2451;
+      color: #A76D1C;
     }
   } 
 

+ 0 - 7
miniprogram/pages/login/login.ts

@@ -15,13 +15,6 @@ Page({
   onLoad() {},
   getLogin(e: any) {
     const { detail } = e
-    // if(!this.data.isAgree) {
-    //   wx.showToast({
-    //     title: '请先阅读并勾选协议',
-    //     icon: 'none'
-    //   })
-    //   return
-    // }
     wx.login({
       success: (res) => {
         const params = {

+ 2 - 2
miniprogram/pages/login/login.wxml

@@ -2,12 +2,12 @@
 <view class="container">
   <navigation-bar title="登录" ></navigation-bar>
   <view class="appInfo">
-    <image src="https://oss.dayaedu.com/gyt/basic/1690793313834.png"></image>
+    <image src="https://oss.dayaedu.com/ktyq/1732255278268.png"></image>
     <text class="appname">音乐数字AI</text>
   </view>
   <view class="login-section">
     <view class="btnSection">
-      <button type="primary" disabled="{{ !isAgree }}" open-type="getPhoneNumber" bindgetphonenumber="getLogin">微信一键登录</button>
+      <button type="primary" disabled="{{ !isAgree }}" open-type="getUserInfo" bindgetuserinfo="getLogin">微信一键登录</button>
     </view>
     <view class="protocol-section">
       <image wx:if="{{isAgree}}" bind:tap="onAgree" src="./images/radio-active.png" class="radio"></image>

+ 8 - 9
miniprogram/pages/orders/order-detail.ts

@@ -65,10 +65,10 @@ Page({
       console.log(error, "error");
     }
   },
-  onPayError() {
+  onPayError(message?: string) {
     wx.hideLoading()
     wx.showToast({
-      title: '支付失败',
+      title: message || '支付取消',
       icon: 'none'
     })
   },
@@ -131,19 +131,17 @@ Page({
       success: async (wxres: any) => {
         const res = await api_executePayment({
           merOrderNo: paymentConfig.merOrderNo,
-          paymentChannel: this.data.paymentChannel || 'wx_lite', // 'wx_pub', //
+          paymentChannel: this.data.paymentChannel || 'wx_lite', 
           paymentType,
           userId: app.globalData.userInfo?.id,
           code: wxres.code,
           wxMiniAppId: app.globalData.appId
-          // code: '011yjYkl289aye4q2zml24UEWT3yjYkn',
-          // wxPubAppId: 'wxbde13f59d40cb4f2'
         })
         wx.hideLoading()
         if(res.data.code === 200) {
           this.onPay(paymentType, res.data.data.reqParams, orderNo)
         } else {
-          this.onPayError()
+          this.onPayError(res.data.message)
         }
       },
       fail: () => {
@@ -172,10 +170,11 @@ Page({
       },
       fail(ressonInfo) {
         console.log('支付失败', ressonInfo)
-        // wx.showToast({ title: '支付失败!', icon: 'none' });
         that.onPayError()
-        wx.redirectTo({
-          url: '/pages/orders/order-result?orderNo=' + orderNo
+        const goodsInfo = that.data.goodsInfo
+        goodsInfo.orderNo = orderNo
+        that.setData({
+          goodsInfo
         })
       }
     })

+ 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"
   }
 }

+ 9 - 102
miniprogram/pages/orders/order-result.less

@@ -142,6 +142,13 @@ page {
     right: -44rpx;
   }
 }
+.only_canvas {
+  position: absolute;
+  left: -300rpx;
+  top: 0;
+  width: 202rpx;
+  height: 202rpx;
+}
 .qrcode-section {
   margin-top: 20rpx;
   padding-bottom: 32rpx;
@@ -167,11 +174,13 @@ page {
     }
   } 
   .qrcode-wrap {
+    position: relative;
     margin: 32rpx auto;
     border: 2rpx solid #EDEDED;
     padding: 6rpx;
     border-radius: 8rpx;
     display: inline-block;
+    font-size: 0;
   }
   .my_draw_canvas {
     width: 202rpx;
@@ -314,105 +323,3 @@ page {
   }
 }
 
-.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: #F8F8F8;
-    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 {
-      margin: 0 40rpx 0;
-      background: #FFFFFF;
-      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: 20rpx 40rpx 0;
-      background: #FFFFFF;
-      border-radius: 20rpx;
-      padding: 24rpx;
-      margin-bottom: 180rpx;
-      display: flex;
-      justify-content: space-between;
-      .title {
-        display: inline;
-        font-size: 30rpx;
-        color: #131415;
-        .red {
-          color: #F44541;
-        }
-        .sencd {
-          color: #AAAAAA;
-        }
-      }
-      input {
-        text-align: right;
-        font-size: 30rpx;
-        &::placeholder {
-          color: #AAAAAA;
-        }
-      }
-    }
-    .btnSection {
-      padding: 0 32rpx 58rpx;
-      button {
-        margin: 0;
-        width: 100%;
-        background: linear-gradient( 90deg, #544F4A 0%, #302F2B 100%);
-        border-radius: 78rpx;
-        padding: 22rpx 84rpx;
-        font-weight: 500;
-        font-size: 32rpx;
-        color: #FBEAC9;
-        line-height: 44rpx;
-      }
-    }
-  }
-}

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

@@ -1,6 +1,6 @@
 // pages/orders/order-detail.ts
 import drawQrcode from "../../utils/weapp.qrcode.esm";
-import { api_userPaymentCancelRefund, api_userPaymentOrderDetail, api_userPaymentOrderRefundPayment } from "../../api/login";
+import { api_userPaymentCancelRefund, api_userPaymentOrderDetail } from "../../api/login";
 
 // 获取应用实例
 Page({
@@ -49,8 +49,6 @@ Page({
     showCanvas: false, // 是否显示二维码
     canvasImg: "" as string,
     refoundStatus: false,
-    refoundValue: "", // 退款内容
-    refoundPhone: ''
   },
 
   /**
@@ -156,26 +154,26 @@ Page({
       url: '../index/index'
     })
   },
-  setCanvasSize: function () {
-    var size = {} as any;
-    try {
-      const res = wx.getWindowInfo()
-      var scale = 750 / 262; //不同屏幕下canvas的适配比例;设计稿是750宽
-      var width = res.windowWidth / scale;
-      var height = width; //canvas画布为正方形
-      size.w = width;
-      size.h = height;
-    } catch (e) {
-      // Do something when catch error
-      console.log("获取设备信息失败" + e);
-    }
-    return size;
-  },
+  // setCanvasSize: function () {
+  //   var size = {} as any;
+  //   try {
+  //     const res = wx.getWindowInfo()
+  //     var scale = 750 / 262; //不同屏幕下canvas的适配比例;设计稿是750宽
+  //     var width = res.windowWidth / scale;
+  //     var height = width; //canvas画布为正方形
+  //     size.w = width;
+  //     size.h = height;
+  //   } catch (e) {
+  //     // Do something when catch error
+  //     console.log("获取设备信息失败" + e);
+  //   }
+  //   return size;
+  // },
   createQrCode(content: any, canvasId: any) {
-    const size = this.setCanvasSize();
+    // const size = this.setCanvasSize();
     drawQrcode({
-      width: size.w,
-      height: size.h,
+      width: 101,
+      height: 101,
       canvasId: canvasId,
       text: content,
       callback: () => {
@@ -237,79 +235,20 @@ 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
     })
   },
-  phoneInput(e: {detail: any}) {
-    this.setData({
-      refoundPhone: e.detail.value
-    })
-  },
-  onRefoundClose() {
-    this.setData({
-      refoundStatus: false,
-      refoundValue: ''
+  onRefoundComfirm() {
+    wx.navigateBack({
+      delta: 1
     })
   },
-  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.setData({
-          refoundStatus: false
-        })
-        setTimeout(() => {
-          wx.navigateBack({
-            delta: 1
-          })
-        }, 1000);
-      } else {
-        wx.showToast({ title: data.message, icon: 'none' })
-      }
-    } catch {}
-  },
   onCopy(e: { currentTarget: any }) {
-    console.log(e, 'e')
     wx.setClipboardData({
       data: e.currentTarget.dataset.orderno,
       success: () => {

+ 9 - 24
miniprogram/pages/orders/order-result.wxml

@@ -50,20 +50,20 @@
         <view class="qrcode-block">
           <view class="left-text">待使用</view>
           <view class="qrcode-wrap">
-            <canvas class='my_draw_canvas' data-type="image" canvas-id='canvasCode' id="canvasCode"></canvas>
+            <image src="{{canvasImg}}" class='my_draw_canvas' show-menu-by-longpress="true"></image>
           </view>
         </view>
       </view>
     </view>
 
-    <view class="order-time" wx:if="{{ goodsInfo.wechatStatus == 'REFUNDED' }}">
+    <view class="order-time" wx:if="{{ goodsInfo.wechatStatus == 'REFUNDED' || goodsInfo.wechatStatus == 'REFUNDING' }}">
       <view class="order-item">
         <view class="title">{{ goodsInfo.wechatStatus == 'REFUNDED' ? '退款时间' : '申请退款时间' }}</view>
-        <view class="value">{{ goodsInfo.refundTime }}</view>
+        <view class="value">{{ goodsInfo.refundTime || '' }}</view>
       </view>
       <view class="order-item">
         <view class="title">退款金额</view>
-        <view class="value red">¥{{ goodsInfo.refundAmount }}</view>
+        <view class="value">¥{{ goodsInfo.refundAmount }}</view>
       </view>
       <view class="order-item">
         <view class="title">退款路径</view>
@@ -72,6 +72,8 @@
     </view>
   </scroll-view>
 
+  <canvas class='my_draw_canvas only_canvas' data-type="image" canvas-id='canvasCode' id="canvasCode"></canvas>
+
   <view class="order-btn" wx:if="{{ goodsInfo.wechatStatus != 'WAIT_PAY' }}">
     <button type="primary" bind:tap="useRefound" wx:if="{{ goodsInfo.wechatStatus == 'WAIT_USE' }}">申请退款</button>
     <block wx:else>
@@ -79,25 +81,8 @@
       <button type="primary" wx:else bind:tap="onSubmit">再次购买</button>
     </block>
   </view>
-
+  <!-- 客服 -->
   <service wx:if="{{serviceShow}}"></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="100" bindinput="textareaInput" value="{{ refoundValue }}"></textarea>
-        <view class="num">{{ refoundValue.length }}/100</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>
+  <!-- 退费 -->
+  <apply-refound refoundStatus="{{ refoundStatus }}" goodsInfo="{{goodsInfo}}" bind:changeRefoundStatus="changeRefoundStatus" bind:onConfirm="onRefoundComfirm"></apply-refound>
 </view>

+ 2 - 1
miniprogram/pages/orders/orders.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"
   }
 }

+ 165 - 33
miniprogram/pages/orders/orders.ts

@@ -1,4 +1,4 @@
-import { api_studentOrderPage } from "../../api/login";
+import { api_executePayment, api_queryByParamName, api_studentOrderPage, api_userPaymentCancelRefund, api_userPaymentOrderUnpaid } from "../../api/login";
 // 获取应用实例
 const app = getApp<IAppOption>()
 Page({
@@ -33,16 +33,16 @@ Page({
         id: 5,
         label: "售后",
       },
-      // {
-      //   id: 6,
-      //   label: "已退款",
-      // },
     ],
+    paymentType: null as any, // 支付类型
+    paymentChannel: null as any,
     tabIdx: 0, // 当前选中的tab索引
     page: 1,
     rows: 10,
     recordList: [],
     maxPage: 1, // 总分页数
+    refoundStatus: false,
+    goodsInfo: {}, // 选中的数据
   },
 
   /**
@@ -190,33 +190,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
       })
     }
   },
@@ -227,8 +203,164 @@ 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() {
+    setTimeout(() => {
+      this.setData({
+        refoundStatus: false,
+        page: 1,
+        maxPage: 1,
+        recordList: [],
+      }, () => {
+        this.getList()
+      })
+    }, 15000);
+  },
 })

+ 11 - 3
miniprogram/pages/orders/orders.wxml

@@ -11,7 +11,7 @@
     <scroll-view class="record-list" type="list" scroll-y bindscrolltolower="loadMore">
       <block wx:if="{{ recordList.length }}">
         <view class="list-item-group">
-          <view class="list-item" wx:for="{{recordList}}" wx:key="index" data-orderno="{{item.orderNo}}" bind:tap="onDetail">
+          <view class="list-item" wx:for="{{recordList}}" wx:key="index" data-orderno="{{item.orderNo}}"  data-wechatstatus="{{item.wechatStatus}}" bind:tap="onDetail">
             <view class="item-top">
               <view class="item-mid">订单号:{{ item.orderNo }}</view>
               <text class="{{ item.wechatStatus == 'WAIT_PAY' || item.wechatStatus == 'WAIT_USE' || item.wechatStatus == 'REFUNDING' ? 'red' : '' }}">{{ item.statusName }}</text>
@@ -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>
@@ -50,4 +56,6 @@
 
   <!-- 客服 -->
   <service wx:if="{{ serviceShow }}"></service>
+  <!-- 申请退款 -->
+  <apply-refound refoundStatus="{{ refoundStatus }}" goodsInfo="{{goodsInfo}}" bind:changeRefoundStatus="changeRefoundStatus" bind:onConfirm="onRefoundComfirm"></apply-refound>
 </view>

+ 14 - 1
project.private.config.json

@@ -4,5 +4,18 @@
   "setting": {
     "compileHotReLoad": true
   },
-  "libVersion": "3.5.8"
+  "libVersion": "3.5.8",
+  "condition": {
+    "miniprogram": {
+      "list": [
+        {
+          "name": "pages/orders/orders",
+          "pathName": "pages/orders/orders",
+          "query": "",
+          "launchMode": "default",
+          "scene": null
+        }
+      ]
+    }
+  }
 }