ソースを参照

feat: 完善购买,支付、订单列表、订单详情

zhangyuhan 1 年間 前
コミット
e8507cedcf

+ 19 - 1
project-config/index.js

@@ -18,6 +18,23 @@ const projectInfo = {
   themeColor: '#0ec684'
 }
 
+const projectBuyInfo = {
+  products: [
+    {
+      key: 'now',
+      label: '正在招标+采购意向',
+      tip: '该会员适用于正在招标、采购意向小程序',
+      ad: 'mini-app-buy-order-desc'
+    },
+    {
+      key: 'all',
+      label: '综合服务',
+      tip: '该会员适用于正在招标、采购意向、临期项目、客户目录小程序',
+      ad: 'mini-app-buy-all-order-desc'
+    }
+  ]
+}
+
 // 分享文案相关
 const shareInfo = {
   home: {
@@ -162,7 +179,8 @@ const appConfig = {
   projectInfo,
   shareInfo,
   boxInfo,
-  tabbars
+  tabbars,
+  projectBuyInfo
 }
 
 export default appConfig

+ 20 - 1
src/api/modules/common.js

@@ -19,10 +19,29 @@ export function ajaxGetAppConfig(data) {
 }
 
 
+// 支付信息获取
+export function ajaxGetProductOrderInfo(data) {
+  return request({
+    url: '/debrisproduct/getPriceList',
+    method: 'post',
+    data
+  })
+}
+
 // 支付信息获取
 export function ajaxGetPayConfig(data) {
   return request({
-    url: '/debrisproduct/getPayParam',
+    url: '/jypay/debrisproduct/getWxPayParam',
+    method: 'post',
+    data
+  })
+}
+
+
+// 支付信息获取
+export function ajaxGerOrderCode(data) {
+  return request({
+    url: '/debrisproduct/createOrder',
     method: 'post',
     data
   })

+ 34 - 0
src/api/modules/order.js

@@ -0,0 +1,34 @@
+import request from '../index'
+export function ajaxGetOrderList(data) {
+  return request({
+    url: '/debrisproduct/orderList',
+    method: 'post',
+    data
+  })
+}
+
+// 支付信息获取
+export function ajaxGetOrderDetail(data) {
+  return request({
+    url: '/debrisproduct/orderDetail',
+    method: 'post',
+    data
+  })
+}
+// 支付信息获取
+export function ajaxRemoveOrder(data) {
+  return request({
+    url: '/jypay/debrisproduct/orderDelete',
+    method: 'post',
+    data
+  })
+}
+
+// 支付信息获取
+export function ajaxCancelOrder(data) {
+  return request({
+    url: '/jypay/debrisproduct/orderCancel',
+    method: 'post',
+    data
+  })
+}

+ 2 - 0
src/app.config.js

@@ -16,6 +16,8 @@ export default defineAppConfig({
     // 订单功能
     "pages/order/create/index",
     "pages/order/pay/index",
+    "pages/order/list/index",
+    "pages/order/detail/index",
     // 省份选择
     "pages/select-area/index",
     // 通用页面

+ 44 - 0
src/assets/style/common.scss

@@ -198,3 +198,47 @@ button[disabled] {
     background-repeat: no-repeat;
   }
 }
+
+
+.j-tabs{
+  background-color: #fff;
+  width: 100%;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: flex-start;
+  &.flex-width {
+    .j-tab {
+      flex: 1;
+    }
+  }
+}
+
+.j-tab {
+  line-height: 20px;
+  font-size: 14px;
+  text-align: center;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-shrink: 0;
+  padding: 14px 16px;
+  color: #5f5e64;
+
+  &.active {
+    position: relative;
+    color: $main;
+  }
+  &.active::after{
+    content: "";
+    position: absolute;
+    bottom: 0;
+    left: 50%;
+    transform: translateX(-12px);
+    right: 20px;
+    width: 24px;
+    height: 3px;
+    background-color: $main;
+    border-radius: 1px;
+  }
+}

+ 3 - 2
src/components/create-order/SubmitBar.vue

@@ -50,7 +50,7 @@
           </div>
         </div>
       </transition>
-      <div class="bar-show">
+      <div class="bar-show fix-safe">
         <div class="bar-top">
           <div class="price-group" v-if="showPrice">
             <div class="p-amount">
@@ -311,7 +311,8 @@ export default {
   .bar-hide {
     box-sizing: border-box;
     position: relative;
-    padding: 0 16px;
+    padding-left: 16px;
+    padding-right: 16px;
     background: #fff;
     z-index: 99;
   }

+ 160 - 78
src/pages/order/create/index.vue

@@ -1,10 +1,25 @@
 <template>
   <div class="must-page-class-name create-order-page j-container">
-    <div cl="j-header" v-show="buyTopTip">
+    <div cl="j-header">
       <van-notice-bar-weapp
         left-icon="volume-o"
+        :key="buyTopTip"
         :text="buyTopTip"
+        v-show="buyTopTip"
       ></van-notice-bar-weapp>
+      <view class="tab-list">
+        <view
+          class="tab"
+          :class="activeTabIndex == index ? 'active': ''"
+          v-for="(item, index) in tabs"
+          :key="item.key"
+          @click="tabClick(index, item)"
+        >
+          <view>
+            {{item.label}}
+          </view>
+        </view>
+      </view>
     </div>
     <div class="j-main">
       <section class="module-area-count-selector">
@@ -64,14 +79,21 @@
             <span class="cell-value-text highlight-text">{{buyAreaText}}</span>
           </template>
         </JCell>
-        <spec-list v-if="canShowModule.selectSpec" :list="specList" @change="onChangeSpec" v-model="activeSpec"></spec-list>
+        <spec-list v-if="canShowModule.selectSpec" :list="formatSpecList" @change="onChangeSpec" v-model="activeSpec"></spec-list>
         <JCell
           class="order-cell t-line"
           title="有效日期"
           :value="effectTimeText"
         ></JCell>
       </div>
-      <ad-single class="order-desc-img" :showTag="false" :showCloseIcon="false" ad="mini-app-buy-order-desc"></ad-single>
+      <ad-single
+        class="order-desc-img"
+        :key="buyAD"
+        :showTag="false"
+        :showCloseIcon="false"
+        :ad="buyAD"
+      >
+      </ad-single>
     </div>
     <div class="j-footer">
       <SubmitBar
@@ -93,7 +115,8 @@ import SpecList from "@/components/create-order/SpecList.vue";
 import { JCell } from '@/ui'
 import {mapGetters} from "vuex";
 import SubmitBar from '@/components/create-order/SubmitBar'
-import AdSingle from "../../../components/common/Ad.vue";
+import AdSingle from "@/components/common/Ad.vue";
+import {ajaxGerOrderCode, ajaxGetProductOrderInfo} from "@/api/modules/common";
 export default {
   components: {
     AdSingle,
@@ -121,63 +144,9 @@ export default {
           areaCount: 1
         }
       },
-      activeSpec: 1,
-      specList: [
-        {
-          id: 1,
-          cycleType: 1, // 月
-          label: '1月',
-          value: '1个月',
-          price: 599,
-          desc: '每天仅需19.97元',
-          perDayPrice: 0,
-          productionId: 1012, // 产品id,后台配置
-          tipText: '赠1个月',
-          tipType:"gift",
-          giftLoaded: false,
-          giftInfo: '',
-          giftName: '',
-          discountId: '',
-          activityInfo: ''
-        },
-        {
-          id: 2,
-          cycleType: 2, // 季
-          label: '1季',
-          value: '1季',
-          price: 1499,
-          desc: '每天仅需16.66元',
-          perDayPrice: 0,
-          productionId: 1013,
-          tipText: '7折',
-          tipType: 'discount',
-          giftLoaded: false,
-          giftInfo: '',
-          giftName: '',
-          discountId: '',
-          activityInfo: ''
-        },
-        {
-          id: 3,
-          cycleType: 3, // 年
-          label: '1年',
-          value: '1年',
-          price: 5999,
-          desc: '每天仅需16.44元',
-          perDayPrice: 0,
-          productionId: 1014,
-          tipText: '',
-          giftLoaded: false,
-          giftInfo: '',
-          giftName: '',
-          discountId: '',
-          activityInfo: ''
-        }
-      ],
-      effectTimeInfo: {
-        startTime: '',
-        endTime: ''
-      },
+      activeSpec: 0,
+      specList: [],
+      activeTabIndex: 0,
       // 页面信息验证是否通过(value全为true时验证通过)
       canNextMap: {
         // 是否同意购买协议
@@ -187,8 +156,12 @@ export default {
   },
   computed: {
     ...mapGetters('env', ['canSupportPay']),
+    ...mapGetters('config', ['appConfig']),
     buyTopTip () {
-      return '该会员仅适用于采购意向小程序'
+      return this.activeTabItem?.tip || ''
+    },
+    buyAD () {
+      return this.activeTabItem?.ad || 'mini-app-buy-order-desc'
     },
     buyAreaTitle () {
       return '续费区域'
@@ -201,25 +174,31 @@ export default {
     },
     canShowModule () {
       return {
-        selectArea: false,
+        selectArea: true,
         selectSpec: true
       }
     },
     selectedInfo() {
       return this.selectedInfoMap[this.buyType] || {}
     },
+    activeSpecItem () {
+      return this.specList[this.activeSpec]
+    },
     calcPrice () {
-      return this.specList[this.activeSpec - 1].price * 100
+      return this.specList[this.activeSpec]?.price * 100
+    },
+    calcPriceOrigin () {
+      return this.specList[this.activeSpec]?.origin * 100
     },
     canSubmitOrder() {
       return !Object.values(this.canNextMap).includes(false)
     },
     params() {
-      const { pay = this.calcPrice, origin = this.calcPrice, discount = 0 } = {}
+      const { pay = this.calcPrice, origin = this.calcPriceOrigin } = {}
       return {
         pay,
         origin,
-        discount // 折扣,优惠了多少钱
+        discount: origin - pay
       }
     },
     confirmDisabled() {
@@ -229,23 +208,67 @@ export default {
       return '提交订单'
     },
     effectTimeText() {
-      const { startTime, endTime } = this.effectTimeInfo
-      const formatStr = 'YYYY.MM.DD'
-      if (startTime && endTime) {
-        return `${dayjs(startTime * 1000).format(formatStr)} - ${dayjs(
-          endTime * 1000
-        ).format(formatStr)}`
-      } else {
-        return ' - '
-      }
+      return this.specList[this.activeSpec]?.effectiveTime || '-'
+    },
+    formatSpecList () {
+      const isOneArea = this.canShowModule.selectArea && this.selectedInfo.radio === '1'
+      return this.specList.filter(v => isOneArea ? v.area === 1 : v.area === -1)
     },
+    BuyALL () {
+      return this.activeTabIndex === 1
+    },
+    tabs () {
+      return this.appConfig.projectBuyInfo.products
+    },
+    activeTabItem () {
+      return this.tabs[this.activeTabIndex]
+    }
   },
   created () {
     Taro.setNavigationBarTitle({
       title: '会员续费'
     })
+    this.getOrderInfo()
   },
   methods: {
+    tabClick (index, { key }) {
+      this.activeTabIndex = index
+      this.getOrderInfo()
+    },
+    getOrderInfo () {
+      ajaxGetProductOrderInfo({
+        BuyAll: this.BuyALL
+      }).then(res => {
+        console.log(res)
+        let specList = []
+        if (res.data && Array.isArray(res.data)) {
+          specList = res.data.map((v, index) => {
+            return {
+              id: index,
+              cycleType: 1,
+              label: v.time,
+              value: v.name,
+              price: v.price / 100,
+              origin: v.originalPrice / 100,
+              desc: v.tip,
+              perDayPrice: 0,
+              productionId: v.name,
+              tipText: v.discount ? (v.discount + '折') : '',
+              tipType: v.discount ? "gift" : '',
+              giftLoaded: false,
+              giftInfo: '',
+              giftName: '',
+              discountId: '',
+              activityInfo: '',
+              area: v.area,
+              effectiveTime: v.effectiveTime
+            }
+          })
+        }
+        this.activeSpec = 0
+        this.specList = specList
+      })
+    },
     checkedChange (f) {
       this.canNextMap.read = f
     },
@@ -278,10 +301,25 @@ export default {
       this.selectedInfo.areaCount = count
     },
     onSubmit () {
-      this.doOpenPay({
-        id: 'test-order-' + Date.now(),
-        price: this.calcPrice
+      ajaxGerOrderCode({
+        BuyAll: this.BuyALL,
+        Name: this.activeSpecItem.productionId
+      }).then(res => {
+        if (res.error_code === 0 && res.data) {
+          this.doOpenPay({
+            id: res.data,
+            price: this.calcPrice
+          })
+        } else {
+          Taro.showToast({
+            title: res.error_msg || '创建订单失败',
+            icon: 'error',
+            duration: 2000
+          })
+        }
       })
+      //
+
     },
     doOpenPay ({ id, price }) {
       if (this.canSupportPay) {
@@ -319,6 +357,48 @@ export default {
 .create-order-page {
   background: #F5F5F5;
   height: 100%;
+
+
+  .tab-list{
+    background-color: #fff;
+    width: 100%;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: flex-start;
+  }
+
+  .tab {
+    line-height: 20px;
+    font-size: 14px;
+    text-align: center;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-shrink: 0;
+    padding: 14px 16px;
+    color: #5f5e64;
+
+    &.active {
+      position: relative;
+      color: $main;
+    }
+    &.active::after{
+      content: "";
+      position: absolute;
+      bottom: 0;
+      left: 50%;
+      transform: translateX(-12px);
+      right: 20px;
+      width: 24px;
+      height: 3px;
+      background-color: $main;
+      border-radius: 1px;
+    }
+  }
+
+
+
   .order-desc-img {
     flex-shrink: 0;
     width: 375px;
@@ -336,6 +416,7 @@ export default {
       padding: 0 8px;
     }
     .spec-card {
+      max-width: 106px;
       flex: 1;
       margin: 8px;
     }
@@ -357,6 +438,7 @@ export default {
   }
 
   .module-area-count-selector {
+    margin-top: 8px;
     background: #fff;
     .radio-content {
       display: flex;

+ 4 - 0
src/pages/order/detail/index.config.js

@@ -0,0 +1,4 @@
+export default definePageConfig({
+  navigationBarTitleText: '订单详情',
+  "navigationStyle": "custom",
+})

ファイルの差分が大きいため隠しています
+ 502 - 0
src/pages/order/detail/index.vue


+ 3 - 0
src/pages/order/list/index.config.js

@@ -0,0 +1,3 @@
+export default definePageConfig({
+  navigationBarTitleText: '我的订单'
+})

ファイルの差分が大きいため隠しています
+ 767 - 0
src/pages/order/list/index.vue


+ 78 - 33
src/pages/order/pay/index.vue

@@ -21,17 +21,20 @@
 
 <script>
 import Taro from "@tarojs/taro";
+import { ajaxGetPayConfig } from "@/api/modules/common";
 
 export default {
   data () {
     return {
-      payInfo: {}
+      payInfo: {},
+      payParams: {}
     }
   },
   onShow () {
     console.log('onShow')
     const $instance = Taro.getCurrentInstance()
     this.payInfo = $instance.router.params
+    this.getOrderInfo(this.payInfo.id)
   },
   methods: {
     doBack () {
@@ -48,48 +51,90 @@ export default {
         }
       })
     },
+    getOrderInfo (id) {
+      ajaxGetPayConfig({
+        orderCode: id
+      }).then(res => {
+        if (res.data.price) {
+          this.payInfo.price = res.data.price
+        }
+        if (res.data?.res) {
+          this.payParams = res.data.res
+        }
+      })
+    },
     doPay () {
       try {
-        Taro.cloud
-          .callFunction({
-            name: "createOrder",
-            data: {}
-          }).then(res => {
-          console.log('ccc', JSON.stringify(res))
-          const payment = res.result.payment
-          Taro.requestPayment({
-            ...payment,
-            success: function (res) {
-              console.log('ok', JSON.stringify(res))
-              Taro.showToast({
-                title: '支付成功',
-                duration: 2000
-              })
-            },
-            fail: function (res) {
-              console.log(JSON.stringify(res))
-              Taro.showToast({
-                title: '取消支付',
-                icon: 'error',
-                duration: 2000
-              })
-            }
-          })
-        }).finally(() => {
-          Taro.showToast({
-            title: '获取支付参数失败',
-            icon: 'error',
-            duration: 2000
-          })
+        const payment = this.payParams
+        console.log(payment, 'pay')
+        Taro.requestPayment({
+          ...payment,
+          success: function (res) {
+            console.log('ok', JSON.stringify(res))
+            Taro.showToast({
+              title: '支付成功',
+              duration: 2000
+            })
+          },
+          fail: function (res) {
+            console.log(JSON.stringify(res))
+            Taro.showToast({
+              title: '取消支付',
+              icon: 'error',
+              duration: 2000
+            })
+          }
         })
       } catch (e) {
         console.log(e)
         Taro.showToast({
-          title: '未配置支付',
+          title: '支付异常,请联系客服',
           icon: 'error',
           duration: 2000
         })
       }
+
+      // try {
+      //   Taro.cloud
+      //     .callFunction({
+      //       name: "createOrder",
+      //       data: {}
+      //     }).then(res => {
+      //     console.log('ccc', JSON.stringify(res))
+      //     const payment = res.result.payment
+      //     Taro.requestPayment({
+      //       ...payment,
+      //       success: function (res) {
+      //         console.log('ok', JSON.stringify(res))
+      //         Taro.showToast({
+      //           title: '支付成功',
+      //           duration: 2000
+      //         })
+      //       },
+      //       fail: function (res) {
+      //         console.log(JSON.stringify(res))
+      //         Taro.showToast({
+      //           title: '取消支付',
+      //           icon: 'error',
+      //           duration: 2000
+      //         })
+      //       }
+      //     })
+      //   }).finally(() => {
+      //     Taro.showToast({
+      //       title: '获取支付参数失败',
+      //       icon: 'error',
+      //       duration: 2000
+      //     })
+      //   })
+      // } catch (e) {
+      //   console.log(e)
+      //   Taro.showToast({
+      //     title: '未配置支付',
+      //     icon: 'error',
+      //     duration: 2000
+      //   })
+      // }
     }
   }
 }

+ 9 - 2
src/pages/tabbar/mine/index.vue

@@ -20,7 +20,7 @@
       </div>
       <div v-if="nowUserType === 'is-free'" class="go-buy-item">
         <span>未开通会员</span>
-        <div class="go-buy-item--right-tip">
+        <div class="go-buy-item--right-tip" @click="goBuyPage">
           <span>开通会员</span>
           <span class="iconfont icon-youbian"></span>
         </div>
@@ -153,6 +153,11 @@ export default {
         phoneNumber: phone
       })
     },
+    goBuyPage () {
+      Taro.navigateTo({
+        url: '/pages/order/create/index',
+      })
+    },
     goItem(type) {
       switch (type) {
         case 'customer': {
@@ -161,7 +166,9 @@ export default {
           break
         }
         case 'order': {
-          goToOrderList()
+          Taro.navigateTo({
+            url: '/pages/order/list/index?active=0',
+          })
           break
         }
         case 'area': {

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません