Bladeren bron

bug修改

喻文俊 3 jaren geleden
bovenliggende
commit
c85fccaae1

+ 1 - 0
.env.development

@@ -17,6 +17,7 @@ VUE_APP_SOCKET_SERVER = 'wss://zplma-b.caimei365.com/websocket?sessionSource=zpl
 # VUE_APP_SOCKET_SERVER = 'ws://192.168.2.68:8012/websocket?sessionSource=zplm_admin'
 
 # 网站地址
+# VUE_APP_LOCAL = 'http://192.168.2.81:9527'
 VUE_APP_LOCAL = 'http://zplm-b.caimei365.com'
 
 

+ 9 - 0
src/api/pay.js

@@ -71,3 +71,12 @@ export function createPayUrl(data) {
     data
   })
 }
+
+/** 初始化支付信息linkLogo */
+export function fetchPayInfoWithLinkLogo(params) {
+  return request({
+    url: '/pay/link/data',
+    method: 'GET',
+    params
+  })
+}

+ 3 - 2
src/api/system.js

@@ -140,9 +140,10 @@ export function updateMenuSelective(id, data) {
 }
 
 /** 获取菜单列表 tree */
-export function sysMenuTree() {
+export function sysMenuTree(params) {
   return request({
     url: '/sys/menu/tree',
-    method: 'get'
+    method: 'get',
+    params
   })
 }

+ 2 - 1
src/layout/components/VipTipDialog/index.vue

@@ -4,6 +4,7 @@
     :visible="allShowVipTip && vipTipVisiable"
     width="24%"
     :close-on-click-modal="false"
+    :show-close="false"
     center
   >
     <div>{{ contentText }}</div>
@@ -30,7 +31,7 @@ export default {
     },
     contentText() {
       const insertText = ['', '账号试用即将到期', '账号试用已到期', '会员账号即将到期', '会员账号已到期']
-      return `对不起,您的账号${insertText[this.vipInfo.freeUseFlag]},请尽快开通会员,以免影响正常使用`
+      return `对不起,您的${insertText[this.vipInfo.freeUseFlag]},请尽快开通会员,以免影响正常使用`
     }
   },
   methods: {

+ 7 - 2
src/permission.js

@@ -10,7 +10,8 @@ if (userInfo) {
 }
 
 // 路由白名单
-const whiteList = ['/login', '/share', '/share/pay', '/share/pay-success', '/share/pay-faild']
+const whiteList = ['/login']
+const shareList = ['/share', '/share/pay', '/share/pay-success', '/share/pay-faild']
 
 // 路由拦截器
 router.beforeEach(async(to, from, next) => {
@@ -19,6 +20,10 @@ router.beforeEach(async(to, from, next) => {
   // 设置页面标题
   document.title = getPageTitle(to.meta.title)
 
+  if (shareList.indexOf(to.path) > -1) {
+    next()
+  }
+
   if (hasToken) {
     // 如果是访问登录页面,强制跳转到首页
     if (to.path === '/login') {
@@ -33,6 +38,7 @@ router.beforeEach(async(to, from, next) => {
         next()
       } else {
         try {
+          console.log(to)
           // 代理状态更换时清空全部页面标签
           if (store.getters.isChangeProxy) {
             store.commit('tagsView/CLEAR_ALL_VIEW')
@@ -44,7 +50,6 @@ router.beforeEach(async(to, from, next) => {
           const accessRoutes = await store.dispatch('permission/generateRoutes')
           // 添加路由配置
           router.addRoutes(accessRoutes)
-          console.log(accessRoutes)
           // 放行
           next({ ...to, replace: true })
         } catch (err) {

+ 1 - 1
src/router/module/share.js

@@ -12,7 +12,7 @@ const vipRoutes = [
     hidden: true,
     children: [
       {
-        path: 'pay',
+        path: 'pay/:linkLogo',
         component: () => import('@/views/common/share/pay/pay'),
         name: 'PayVip',
         meta: { title: '支付会员' },

+ 0 - 0
src/utils/format-routes-to-modules.js


+ 41 - 0
src/utils/index.js

@@ -366,3 +366,44 @@ export function removeClass(ele, cls) {
     ele.className = ele.className.replace(reg, ' ')
   }
 }
+
+/**
+ * 倒计时
+ * @param diff 倒计时时间/s
+ * @param loadTime 运行时的当前时间
+ * @param item 倒计时对象
+ * @param callback 回调
+ */
+export function countDown(diff, loadTime, item, callback) {
+  function round($diff) {
+    const dd = parseInt($diff / 1000 / 60 / 60 / 24, 10) // 计算剩余的天数
+    const hh = parseInt(($diff / 1000 / 60 / 60) % 24, 10) // 计算剩余的小时数
+    const mm = parseInt(($diff / 1000 / 60) % 60, 10) // 计算剩余的分钟数
+    const ss = parseInt(($diff / 1000) % 60, 10) // 计算剩余的秒数
+
+    function checkTime(_a) {
+      let a = _a
+      if (a < 10) {
+        a = '0' + a
+      }
+      return a.toString()
+    }
+
+    item.conttainer = {
+      dd: checkTime(dd),
+      hh: checkTime(hh),
+      mm: checkTime(mm),
+      ss: checkTime(ss)
+    }
+
+    if (item.conttainer.dd > 0 || item.conttainer.hh > 0 || item.conttainer.mm > 0 || item.conttainer.ss > 0) {
+      item.t = setTimeout(() => {
+        callback && callback(item)
+        round($diff - 1000)
+      }, 1000)
+    } else {
+      callback && callback(item)
+    }
+  }
+  round(diff - loadTime)
+}

+ 26 - 0
src/views/admin/member/settings/combo-edit.vue

@@ -80,10 +80,36 @@ export default {
       fetchConfigureList().then(res => {
         this.packageList = res.data.packageList
         this.serviceList = res.data.serviceList
+        if (this.packageList.length === 0) {
+          this.insertOnePackage()
+        }
+        if (this.serviceList.length === 0) {
+          this.insertOneSerivice()
+        }
       })
     },
+    // 校验文本框内容
+    validateInputContent() {
+      const hasEmptyPackage = this.packageList.some(item => {
+        for (const key in item) {
+          if (!item[key]) return false
+        }
+        return true
+      })
+      const hasEmptyService = this.serviceList.some(item => {
+        for (const key in item) {
+          if (!item[key]) return false
+        }
+        return true
+      })
+      return hasEmptyService && hasEmptyPackage
+    },
     // 更新套餐 服务配置列表
     updateConfigure() {
+      if (!this.validateInputContent()) {
+        this.$message.warning('已添加项不能为空')
+        return
+      }
       updateConfigure({ packageList: this.packageList, serviceList: this.serviceList }).then(res => {
         console.log(res)
         this.$message.success('套餐配置保存成功')

+ 1 - 1
src/views/admin/settings/roles/edit.vue

@@ -72,7 +72,7 @@ export default {
     },
     // 获取菜单权限列表
     getMenuTree() {
-      sysMenuTree().then(res => {
+      sysMenuTree({ menuType: 1 }).then(res => {
         this.menuTree = res.data
       })
     },

+ 24 - 6
src/views/common/helper/document/index.vue

@@ -10,7 +10,8 @@
         <span>所属模块:</span>
         <el-cascader
           v-model="listQuery.fileModule"
-          :options="modules"
+          :options="menuTree"
+          :props="props"
           placeholder="所属模块"
           clearable
           @change="getList"
@@ -104,7 +105,8 @@
           <el-cascader
             v-if="dialogVisible"
             v-model="dialogFormData.fileModule"
-            :options="modules"
+            :options="menuTree"
+            :props="props"
             placeholder="所属模块"
             clearable
           />
@@ -131,8 +133,9 @@ import openWindow from '@/utils/open-window'
 import { formatDate } from '@/utils'
 import { mapGetters } from 'vuex'
 import { fetchCourseList, saveCourse, removeCourse } from '@/api/helper'
-import { getToutesTree, getModuleType } from '@/utils/formatRoutesToModule'
+// import { getToutesTree, getModuleType } from '@/utils/formatRoutesToModule'
 import { debounce } from '@/utils/tools'
+import { sysMenuTree } from '@/api/system'
 export default {
   components: { Pagination, FileUpload },
   filters: {
@@ -158,9 +161,15 @@ export default {
         pageSize: 10
       },
       modules: [],
+      menuTree: [],
       list: [],
       uploadFileList: [],
       dialogFormData: {},
+      props: {
+        value: 'id',
+        label: 'title',
+        children: 'subMenus'
+      },
       rules: {
         fileTitle: [
           {
@@ -194,7 +203,8 @@ export default {
   },
   created() {
     this.dialogFormData = this.resetDialogFormData()
-    this.modules = getToutesTree(this.routes)
+    // this.modules = getToutesTree(this.routes)
+    this.getMenuTree()
     this.getList()
   },
   methods: {
@@ -207,6 +217,7 @@ export default {
         fileName: '',
         fileType: 2,
         fileModule: []
+
       }
     },
 
@@ -315,7 +326,7 @@ export default {
       fetchCourseList(params)
         .then((res) => {
           if (res.code !== 0) return
-          this.list = this.formatFileModuleType(res.data.list)
+          // this.list = this.formatFileModuleType(res.data.list)
           this.total = res.data.total
         })
         .finally(() => {
@@ -358,10 +369,17 @@ export default {
     // 获取模块文本
     formatFileModuleType(list) {
       return list.filter((item) => {
-        item.fileModuleType = getModuleType(item.fileModule)
+        // item.fileModuleType = getModuleType(item.fileModule)
         return item.fileModuleType !== ''
       })
     },
+    // 获取模块列表
+    getMenuTree() {
+      sysMenuTree({ menuType: 2 }).then(res => {
+        this.menuTree = res.data
+        console.log(this.menuTree)
+      })
+    },
     // 表格索引
     indexMethod(index) {
       return index + this.listQuery.pageSize * (this.listQuery.pageNum - 1) + 1

+ 23 - 6
src/views/common/helper/video/index.vue

@@ -10,7 +10,8 @@
         <span>所属模块:</span>
         <el-cascader
           v-model="listQuery.fileModule"
-          :options="modules"
+          :options="menuTree"
+          :props="props"
           placeholder="所属模块"
           clearable
           @change="getList"
@@ -100,7 +101,8 @@
           <el-cascader
             v-if="dialogVisible"
             v-model="dialogFormData.fileModule"
-            :options="modules"
+            :options="menuTree"
+            :props="props"
             placeholder="所属模块"
             clearable
           />
@@ -127,8 +129,9 @@ import openWindow from '@/utils/open-window'
 import { formatDate } from '@/utils'
 import { mapGetters } from 'vuex'
 import { fetchCourseList, saveCourse, removeCourse } from '@/api/helper'
-import { getToutesTree, getModuleType } from '@/utils/formatRoutesToModule'
+// import { getToutesTree, getModuleType } from '@/utils/formatRoutesToModule'
 import { debounce } from '@/utils/tools'
+import { sysMenuTree } from '@/api/system'
 export default {
   components: { Pagination, FileUpload },
   filters: {
@@ -161,9 +164,15 @@ export default {
         pageSize: 10
       },
       modules: [],
+      menuTree: [],
       list: [],
       uploadFileList: [],
       dialogFormData: {},
+      props: {
+        value: 'id',
+        label: 'title',
+        children: 'subMenus'
+      },
       rules: {
         fileTitle: [{ required: true, message: '请输入标题', trigger: ['change', 'blur'] }],
         fileUrl: [{ required: true, message: '请选择文件', trigger: 'change' }],
@@ -179,7 +188,8 @@ export default {
   },
   created() {
     this.dialogFormData = this.resetDialogFormData()
-    this.modules = getToutesTree(this.routes)
+    // this.modules = getToutesTree(this.routes)
+    this.getMenuTree()
     this.getList()
     console.log(this.authUserId)
   },
@@ -302,7 +312,7 @@ export default {
       fetchCourseList(params)
         .then(res => {
           if (res.code !== 0) return
-          this.list = this.formatFileModuleType(res.data.list)
+          // this.list = this.formatFileModuleType(res.data.list)
           this.total = res.data.total
         })
         .finally(() => {
@@ -344,10 +354,17 @@ export default {
     // 获取模块文本
     formatFileModuleType(list) {
       return list.filter(item => {
-        item.fileModuleType = getModuleType(item.fileModule)
+        // item.fileModuleType = getModuleType(item.fileModule)
         return item.fileModuleType !== ''
       })
     },
+    // 获取模块列表
+    getMenuTree() {
+      sysMenuTree({ menuType: 2 }).then(res => {
+        this.menuTree = res.data
+        console.log(this.menuTree)
+      })
+    },
     // 表格索引
     indexMethod(index) {
       return index + this.listQuery.pageSize * (this.listQuery.pageNum - 1) + 1

+ 100 - 12
src/views/common/share/pay/pay.vue

@@ -2,16 +2,16 @@
   <div class="share-pay container">
     <div class="section supplier">
       <div class="info">
-        <span class="name">上海维沙美容美发经营管理有限公司</span>
-        <span class="mobile">15889588265</span>
+        <span class="name">{{ authUser.name }}</span>
+        <span class="mobile">{{ authUser.mobile }}</span>
       </div>
       <div class="current-down">
         <span class="tip">倒计时</span>
-        <span class="bg">72</span>
+        <span class="bg">{{ countDownTime.hh * 1 + countDownTime.dd * 24 * 1 }}</span>
         <span class="exp">:</span>
-        <span class="bg">26</span>
+        <span class="bg">{{ countDownTime.mm }}</span>
         <span class="exp">:</span>
-        <span class="bg">30</span>
+        <span class="bg">{{ countDownTime.ss }}</span>
       </div>
     </div>
     <div class="section package">
@@ -19,11 +19,11 @@
         <span class="vip-icon" />
         <span>购买认证通会员</span>
         <span>套餐</span>
-        <span>1年</span>
+        <span>{{ formatMonth }}</span>
       </div>
       <div class="total">
         <span>支付总额:</span>
-        <span class="price">¥5980.00</span>
+        <span class="price">¥{{ orderPayLink.unpaidAmount | formatPrice }}</span>
       </div>
     </div>
     <div class="section bank">
@@ -33,14 +33,16 @@
       <pay-bank
         :data="orderInfo"
         :show-price="false"
-        :coty-status="false"
+        :copy-status="false"
         :pay-way="3"
-        @pay-confirm="handlePayConfirm"
+        :confirm="confirmVisiable"
+        @change="handleBankChange"
+        @pay-confirm="handleConfirmPay"
       />
     </div>
     <div class="submit">
       <div class="container">
-        <el-button type="danger">立即支付</el-button>
+        <el-button type="danger" @click="onSubmit">立即支付</el-button>
       </div>
     </div>
   </div>
@@ -48,17 +50,103 @@
 
 <script>
 import PayBank from '@/views/components/payment/pay-bank.vue'
+import { checkedOtherPaySuccess, fetchPayInfoWithLinkLogo } from '@/api/pay'
+import { countDown } from '@/utils'
 export default {
   components: {
     PayBank
   },
   data() {
     return {
-      orderInfo: {}
+      confirmVisiable: false,
+      linkLogo: '',
+      orderPayLink: {},
+      authUser: {},
+      submitInfo: {},
+      timer: null,
+      countDownTime: {}
     }
   },
+  computed: {
+    orderInfo() {
+      return {
+        pageType: 4,
+        payAmount: this.orderPayLink.unpaidAmount,
+        vipId: '',
+        vipRecordId: this.orderPayLink.authVipRecordId
+      }
+    },
+    formatMonth() {
+      const vipMonth = this.orderPayLink.vipMonth
+      return vipMonth % 12 ? `${vipMonth}月` : `${vipMonth / 12}年`
+    }
+  },
+  created() {
+    this.init()
+    console.log(this.linkLogo)
+  },
   methods: {
-    handlePayConfirm() {}
+    // 初始化
+    init() {
+      this.linkLogo = this.$route.params.linkLogo
+      this.fetchPayInfoWithLinkLogo()
+    },
+    // 确认支付
+    handleBankChange(e) {
+      console.log(e)
+      console.log(e)
+      this.submitInfo = e
+    },
+    // 获取订单信息
+    fetchPayInfoWithLinkLogo() {
+      fetchPayInfoWithLinkLogo({ linkLogo: this.linkLogo }).then(res => {
+        const result = JSON.parse(res.data)
+        this.orderPayLink = result.orderPayLink
+        this.authUser = result.authUser
+        console.log(result)
+        this.countDown()
+      })
+    },
+    // 确认支付事件
+    handleConfirmPay(e) {
+      this.redirectUrlQuery = {
+        payAmount: e.data.payAmount
+      }
+      checkedOtherPaySuccess({ mbOrderId: e.data.mbOrderId }).then(res => {
+        res = JSON.parse(res.data)
+        if (res.data.status === '1') {
+          this.$router.push({
+            path: '/share/pay-success',
+            query: this.redirectUrlQuery
+          })
+        } else {
+          this.$router.push({
+            path: '/share/pay-faild',
+            query: this.redirectUrlQuery
+          })
+        }
+      })
+    },
+    // 跳转支付
+    onSubmit() {
+      if (this.submitInfo.data && this.submitInfo.data.payUrl) {
+        this.confirmVisiable = true
+        window.open(this.submitInfo.data.payUrl, '_blank')
+      } else {
+        this.$message.warning('请选择银行')
+        return
+      }
+    },
+    // 倒计时
+    countDown() {
+      const diffTime = new Date(this.orderPayLink.effectiveTime).getTime()
+      const loadTime = new Date().getTime()
+      this.timer && clearTimeout(this.timer)
+      countDown(diffTime, loadTime, {}, item => {
+        this.countDownTime = item.conttainer
+        this.timer = item.t
+      })
+    }
   }
 }
 </script>

+ 3 - 1
src/views/components/PermissionButton/index.vue

@@ -12,7 +12,9 @@ export default {
   },
   methods: {
     handleClick() {
-      this.hasPermission = this.$store.getters.vipInfo.vipStatus === 1
+      const { freeUseFlag, vipStatus } = this.$store.getters.vipInfo
+      // (已过期 or 非会员) and 非试用期
+      this.hasPermission = !((vipStatus === 0 || vipStatus === 3) && freeUseFlag === 0)
       if (this.hasPermission) {
         this.$emit('click')
       } else {

+ 1 - 1
src/views/components/payment/pay-alipay.vue

@@ -76,7 +76,7 @@ export default {
             ...this.data
           }
         })
-      }, 1000)
+      }, 3000)
     }
   }
 }

+ 25 - 6
src/views/components/payment/pay-bank.vue

@@ -14,7 +14,7 @@
         <el-image :src="row.bankLogo" class="bank-icon" />
       </template>
     </radio-card>
-    <div v-if="payWay === 3 && cotyStatus" class="pay-submit">
+    <div v-if="payWay === 3 && copyStatus" class="pay-submit">
       <div class="tip">
         <div class="copy-tip">
           若您在公司的职位无法直接使用企业网银付款,请点击右侧“复制支付链接”按钮,将该链接发送给公司财务人员进行企业网银付款
@@ -53,9 +53,13 @@ export default {
       type: Boolean,
       default: true
     },
-    cotyStatus: {
+    copyStatus: {
       type: Boolean,
       default: true
+    },
+    confirm: {
+      type: Boolean,
+      default: false
     }
   },
   data() {
@@ -74,9 +78,16 @@ export default {
       return this.bankList.find(item => item.id === this.checkedBank)
     }
   },
+  watch: {
+    confirm() {
+      this.confirmVisiable = this.confirm
+    }
+  },
   created() {
     this.fetchBankcodeList()
-    this.handleCreatePayUrl()
+    if (this.copyStatus) {
+      this.handleCreatePayUrl()
+    }
   },
   methods: {
     // 获取网银支付列表
@@ -105,19 +116,18 @@ export default {
           payType: 1
         })
         const linkLogo = res.data.slice(res.data.lastIndexOf('=') + 1)
-        this.payUrl = `${process.env.VUE_APP_LOCAL}/#/share/pay?linkLogo=${linkLogo}`
+        this.payUrl = `${process.env.VUE_APP_LOCAL}/#/share/pay/${linkLogo}`
       } catch (error) {
         console.log(error)
       }
     },
     // 复制支付链接
     handleClipboard($event) {
-      this.confirmVisiable = true
+      // this.confirmVisiable = true
       handleClipboard(this.payUrl, '支付链接已复制到剪切板', $event)
     },
     // 提交
     onSubmit() {
-      // this.handlePay()
       this.confirmVisiable = true
       window.open(this.payData.payUrl, '_blank')
     },
@@ -144,6 +154,14 @@ export default {
           const result = JSON.parse(res.data)
           if (result.code === '000000') {
             this.payData = result.data
+            // 触发事件
+            this.$emit('change', {
+              type: this.userType,
+              data: {
+                ...this.payData,
+                ...this.data
+              }
+            })
           } else {
             this.$message.error('支付系统遇到点小问题,请稍后重试')
             this.isLoading = false
@@ -156,6 +174,7 @@ export default {
     // 验证确认支付
     checkedPayConfirm() {
       this.confirmVisiable = false
+      // 触发确认支付事件
       this.$emit('pay-confirm', {
         type: this.userType,
         data: {

+ 1 - 1
src/views/components/payment/pay-wechat.vue

@@ -57,7 +57,7 @@ export default {
             ...this.data
           }
         })
-      }, 1000)
+      }, 3000)
     }
   }
 }

+ 1 - 1
src/views/normal/vip/buy.vue

@@ -250,7 +250,7 @@ export default {
           query: this.redirectUrlQuery
         })
       } else {
-        this.diffScanOverTime(60, () => {
+        this.diffScanOverTime(60 * 5, () => {
           this.$router.push({
             path: '/pay/faild',
             query: this.redirectUrlQuery