Sfoglia il codice sorgente

【模版目录】更新模版源码

吴昊天 3 anni fa
parent
commit
998ddc717a
100 ha cambiato i file con 12654 aggiunte e 13534 eliminazioni
  1. 8 9
      template/admin/src/api/common.js
  2. 0 1
      template/admin/src/api/index.js
  3. 30 30
      template/admin/src/api/marketing.js
  4. 2 2
      template/admin/src/api/product.js
  5. 15 15
      template/admin/src/api/setting.js
  6. 71 0
      template/admin/src/api/system.js
  7. 2 2
      template/admin/src/api/systemOutAccount.js
  8. 1 1
      template/admin/src/components/copyright/index.vue
  9. 1 1
      template/admin/src/components/couponList/index.vue
  10. 1 2
      template/admin/src/components/diyComponents/c_upload_img.vue
  11. 3 3
      template/admin/src/components/main/components/user/user.vue
  12. 1 1
      template/admin/src/components/main/main.less
  13. 2 2
      template/admin/src/components/modelSure/modelSure.vue
  14. 1 1
      template/admin/src/components/sendCoupons/index.vue
  15. 30 23
      template/admin/src/components/upGrade/index.vue
  16. 127 121
      template/admin/src/components/verifition/Verify/VerifyPoints.vue
  17. 209 192
      template/admin/src/components/verifition/Verify/VerifySlide.vue
  18. 5 5
      template/admin/src/components/verifition/utils/ase.js
  19. 77 15
      template/admin/src/components/verifition/utils/util.js
  20. 3 2
      template/admin/src/components/wangEditor/index.vue
  21. 3 3
      template/admin/src/main.js
  22. 4 5
      template/admin/src/pages/account/login/index.vue
  23. 1 1
      template/admin/src/pages/finance/components/commissionDetails/index.vue
  24. 6 1
      template/admin/src/pages/finance/financialRecords/recharge/index.vue
  25. 2 3
      template/admin/src/pages/index/index.vue
  26. 3 1
      template/admin/src/pages/marketing/live/add_goods.vue
  27. 5 1
      template/admin/src/pages/marketing/lottery/create.vue
  28. 4 2
      template/admin/src/pages/marketing/storeBargain/create.vue
  29. 10 9
      template/admin/src/pages/marketing/storeCombination/create.vue
  30. 1 8
      template/admin/src/pages/marketing/storeCombination/statistics.vue
  31. 23 4
      template/admin/src/pages/marketing/storeCouponIssue/create.vue
  32. 4 1
      template/admin/src/pages/marketing/storeSeckill/create.vue
  33. 2 2
      template/admin/src/pages/order/orderList/components/tableList.vue
  34. 7 4
      template/admin/src/pages/order/orderList/handle/orderDetails.vue
  35. 2 2
      template/admin/src/pages/order/orderList/handle/orderRecord.vue
  36. 2 2
      template/admin/src/pages/order/orderList/orderlistDetails.vue
  37. 1 1
      template/admin/src/pages/order/refund/index.vue
  38. 0 1
      template/admin/src/pages/product/list_wait.vue
  39. 1 7
      template/admin/src/pages/product/productAdd/index.vue
  40. 1 1
      template/admin/src/pages/setting/devise/list.vue
  41. 36 18
      template/admin/src/pages/setting/multiLanguage/langList.vue
  42. 1 1
      template/admin/src/pages/setting/multiLanguage/list.vue
  43. 40 41
      template/admin/src/pages/setting/systemMenus/components/menusFrom.vue
  44. 10 10
      template/admin/src/pages/setting/userFile/index.vue
  45. 1 1
      template/admin/src/pages/setting/verifyOrder/index.vue
  46. 5 5
      template/admin/src/pages/statistic/user/index.vue
  47. 1 2
      template/admin/src/pages/system/auth/index.vue
  48. 1 5
      template/admin/src/pages/system/configTab/list.vue
  49. 315 0
      template/admin/src/pages/system/crontab/createModal.vue
  50. 167 0
      template/admin/src/pages/system/crontab/index.vue
  51. 10 12
      template/admin/src/pages/system/file/index.vue
  52. 1 5
      template/admin/src/pages/system/group/list.vue
  53. 4 4
      template/admin/src/pages/system/maintain/systemCleardata/index.vue
  54. 3 10
      template/admin/src/pages/system/maintain/systemFile/components/loginFrom.vue
  55. 7 1
      template/admin/src/pages/system/maintain/systemFile/login.vue
  56. 5 5
      template/admin/src/pages/user/level/index.vue
  57. 15 7
      template/admin/src/pages/user/list/handle/userDetails.vue
  58. 27 19
      template/admin/src/pages/user/list/index.vue
  59. 42 43
      template/admin/src/plugin/emoji-awesome/css/google.min.css
  60. 2 2
      template/admin/src/router/modules/finance.js
  61. 9 0
      template/admin/src/router/modules/system.js
  62. 9 9
      template/admin/src/router/routers.js
  63. 2 2
      template/admin/src/store/index.js
  64. 0 1
      template/admin/src/styles/style.css
  65. 25 26
      template/admin/src/utils/download.js
  66. 2 6
      template/admin/src/utils/public.js
  67. 285 268
      template/uni-app/components/couponListWindow/index.vue
  68. 226 0
      template/uni-app/components/easy-loadimage/easy-loadimage.vue
  69. 314 0
      template/uni-app/components/eidtUserModal/index.vue
  70. 154 150
      template/uni-app/components/guide/index.vue
  71. 2 0
      template/uni-app/components/home/index.vue
  72. 188 184
      template/uni-app/components/indexGoods/index.vue
  73. 83 82
      template/uni-app/components/kefuIcon/index.vue
  74. 64 24
      template/uni-app/components/pageFooter/index.vue
  75. 119 109
      template/uni-app/components/promotionGood/index.vue
  76. 134 117
      template/uni-app/components/recommend/index.vue
  77. 0 11
      template/uni-app/components/verify/utils/ase.js
  78. 0 6191
      template/uni-app/components/verify/utils/crypto-js.js
  79. 920 1198
      template/uni-app/components/zb-code/qrcode.js
  80. 32 32
      template/uni-app/config/app.js
  81. 352 0
      template/uni-app/libs/uniApi.js
  82. 2 1
      template/uni-app/main.js
  83. 17 11
      template/uni-app/manifest.json
  84. 12 11
      template/uni-app/pages.json
  85. 1802 1796
      template/uni-app/pages/activity/goods_combination_details/index.vue
  86. 1642 1636
      template/uni-app/pages/activity/goods_seckill_details/index.vue
  87. 7 0
      template/uni-app/pages/annex/components/verify/utils/ase.js
  88. 3077 0
      template/uni-app/pages/annex/components/verify/utils/crypto-js.js
  89. 30 0
      template/uni-app/pages/annex/components/verify/utils/util.js
  90. 11 1
      template/uni-app/components/verify/verify.vue
  91. 0 0
      template/uni-app/pages/annex/components/verify/verifyPoint/verifyPoint.vue
  92. 0 0
      template/uni-app/pages/annex/components/verify/verifySlider/verifySlider.vue
  93. 745 0
      template/uni-app/pages/annex/components/verify/verifySlider/verifySliderPc.vue
  94. 11 4
      template/uni-app/pages/annex/offline_pay/index.vue
  95. 6 5
      template/uni-app/pages/annex/settled/index.vue
  96. 992 974
      template/uni-app/pages/extension/customer_list/chat.vue
  97. 4 6
      template/uni-app/pages/extension/news_list/index.vue
  98. 7 1
      template/uni-app/pages/goods/goods_list/index.vue
  99. 5 0
      template/uni-app/pages/goods/goods_logistics/index.vue
  100. 0 0
      template/uni-app/pages/goods/order_confirm/index.vue

+ 8 - 9
template/admin/src/api/common.js

@@ -10,20 +10,19 @@
 
 import request from '@/libs/request';
 
-
-export function ajCaptcha(params){
+export function ajCaptcha(params) {
   return request({
-    url:'ajcaptcha',
-    method:'get',
-    params:params
+    url: 'ajcaptcha',
+    method: 'get',
+    params: params,
   });
 }
 
-export function ajCaptchaCheck(data){
+export function ajCaptchaCheck(data) {
   return request({
-    url:'ajcheck',
-    method:'post',
-    data:data
+    url: 'ajcheck',
+    method: 'post',
+    data: data,
   });
 }
 

+ 0 - 1
template/admin/src/api/index.js

@@ -49,4 +49,3 @@ export function rankApi() {
     method: 'get',
   });
 }
-

+ 30 - 30
template/admin/src/api/marketing.js

@@ -741,9 +741,9 @@ export function getType(params) {
 
 /**
  * 秒杀统计
- * @param {*} id 
- * @param {*} params 
- * @returns 
+ * @param {*} id
+ * @param {*} params
+ * @returns
  */
 export function getseckillStatistics(id, params) {
   return request({
@@ -755,9 +755,9 @@ export function getseckillStatistics(id, params) {
 
 /**
  * 秒杀参与人
- * @param {*} id 
- * @param {*} params 
- * @returns 
+ * @param {*} id
+ * @param {*} params
+ * @returns
  */
 export function getseckillStatisticsPeople(id, params) {
   return request({
@@ -769,9 +769,9 @@ export function getseckillStatisticsPeople(id, params) {
 
 /**
  * 秒杀订单
- * @param {*} id 
- * @param {*} params 
- * @returns 
+ * @param {*} id
+ * @param {*} params
+ * @returns
  */
 export function getseckillStatisticsOrder(id, params) {
   return request({
@@ -783,11 +783,11 @@ export function getseckillStatisticsOrder(id, params) {
 
 /**
  * 拼团统计
- * @param {*} id 
- * @param {*} params 
- * @returns 
+ * @param {*} id
+ * @param {*} params
+ * @returns
  */
- export function getcombinationStatistics(id, params) {
+export function getcombinationStatistics(id, params) {
   return request({
     url: `marketing/combination/statistics/head/${id}`,
     method: 'get',
@@ -797,9 +797,9 @@ export function getseckillStatisticsOrder(id, params) {
 
 /**
  * 拼团列表
- * @param {*} id 
- * @param {*} params 
- * @returns 
+ * @param {*} id
+ * @param {*} params
+ * @returns
  */
 export function getcombinationStatisticsPeople(id, params) {
   return request({
@@ -811,9 +811,9 @@ export function getcombinationStatisticsPeople(id, params) {
 
 /**
  * 拼团订单
- * @param {*} id 
- * @param {*} params 
- * @returns 
+ * @param {*} id
+ * @param {*} params
+ * @returns
  */
 export function getcombinationStatisticsOrder(id, params) {
   return request({
@@ -825,11 +825,11 @@ export function getcombinationStatisticsOrder(id, params) {
 
 /**
  * 砍价统计
- * @param {*} id 
- * @param {*} params 
- * @returns 
+ * @param {*} id
+ * @param {*} params
+ * @returns
  */
- export function getbargainStatistics(id, params) {
+export function getbargainStatistics(id, params) {
   return request({
     url: `marketing/bargain/statistics/head/${id}`,
     method: 'get',
@@ -839,9 +839,9 @@ export function getcombinationStatisticsOrder(id, params) {
 
 /**
  * 砍价列表
- * @param {*} id 
- * @param {*} params 
- * @returns 
+ * @param {*} id
+ * @param {*} params
+ * @returns
  */
 export function getbargainStatisticsPeople(id, params) {
   return request({
@@ -853,9 +853,9 @@ export function getbargainStatisticsPeople(id, params) {
 
 /**
  * 砍价订单
- * @param {*} id 
- * @param {*} params 
- * @returns 
+ * @param {*} id
+ * @param {*} params
+ * @returns
  */
 export function getbargainStatisticsOrder(id, params) {
   return request({
@@ -863,4 +863,4 @@ export function getbargainStatisticsOrder(id, params) {
     method: 'get',
     params,
   });
-}
+}

+ 2 - 2
template/admin/src/api/product.js

@@ -394,10 +394,10 @@ export function importCard(data) {
  * @param {Number} param id {Number} 属性id
  * @param {Object} param data {Object} 传值参数
  */
- export function batchSetting(data) {
+export function batchSetting(data) {
   return request({
     url: `product/batch/setting`,
     method: 'POST',
     data,
   });
-}
+}

+ 15 - 15
template/admin/src/api/setting.js

@@ -1016,7 +1016,7 @@ export function saveType(type) {
 /**
  * @description 多语言-语言类型列表
  */
- export function langTypeList(data) {
+export function langTypeList(data) {
   return request({
     url: `setting/lang_type/list`,
     method: 'get',
@@ -1026,9 +1026,9 @@ export function saveType(type) {
 
 /**
  * @description 多语言-语言类型新增编辑
- * @param {Number} param id {Number} 
+ * @param {Number} param id {Number}
  */
- export function langTypeForm(id) {
+export function langTypeForm(id) {
   return request({
     url: `setting/lang_type/form/${id}`,
     method: 'get',
@@ -1038,7 +1038,7 @@ export function saveType(type) {
 /**
  * @description 多语言-语言详情列表
  */
- export function langCodeList(data) {
+export function langCodeList(data) {
   return request({
     url: `setting/lang_code/list`,
     method: 'get',
@@ -1049,7 +1049,7 @@ export function saveType(type) {
 /**
  * @description 获取语言信息
  */
- export function langCodeInfo(data) {
+export function langCodeInfo(data) {
   return request({
     url: `setting/lang_code/info`,
     method: 'get',
@@ -1060,7 +1060,7 @@ export function saveType(type) {
 /**
  * @description 修改语言详情
  */
- export function langCodeSettingSave(data) {
+export function langCodeSettingSave(data) {
   return request({
     url: `setting/lang_code/save`,
     method: 'post',
@@ -1071,7 +1071,7 @@ export function saveType(type) {
 /**
  * @description 国家列表
  */
- export function langCountryList(data) {
+export function langCountryList(data) {
   return request({
     url: `setting/lang_country/list`,
     method: 'get',
@@ -1080,10 +1080,10 @@ export function saveType(type) {
 }
 /**
  * 添加语言地区表单
- * @param {*} id 
- * @returns 
+ * @param {*} id
+ * @returns
  */
- export function langCountryForm(id) {
+export function langCountryForm(id) {
   return request({
     url: `setting/lang_country/form/${id}`,
     method: 'get',
@@ -1091,10 +1091,10 @@ export function saveType(type) {
 }
 /**
  * 添加语言地区表单
- * @param {*} id 
- * @returns 
+ * @param {*} id
+ * @returns
  */
- export function langTypeStatus(id,status) {
+export function langTypeStatus(id, status) {
   return request({
     url: `setting/lang_type/status/${id}/${status}`,
     method: 'put',
@@ -1104,10 +1104,10 @@ export function saveType(type) {
 /**
  * @description 一键翻译
  */
- export function langCodeTranslate(data) {
+export function langCodeTranslate(data) {
   return request({
     url: `setting/lang_code/translate`,
     method: 'post',
     data,
   });
-}
+}

+ 71 - 0
template/admin/src/api/system.js

@@ -715,3 +715,74 @@ export function upgradeableListApi(params) {
     params,
   });
 }
+
+/**
+ * 定时任务列表
+ * @param {*} params
+ * @returns
+ */
+export function timerIndex(params) {
+  return request({
+    url: `system/timer/list`,
+    params,
+  });
+}
+
+/**
+ * 修改定时任务状态
+ * @param {*} params
+ * @returns
+ */
+export function showTimer(id, is_open) {
+  return request({
+    url: `system/timer/set_open/${id}/${is_open}`,
+  });
+}
+
+/**
+ * 获取定时任务信息
+ * @param {*} params
+ * @returns
+ */
+export function timerInfo(id) {
+  return request({
+    url: `system/timer/info/${id}`,
+  });
+}
+
+/**
+ * 保存定时任务
+ * @param {*} data
+ * @returns
+ */
+export function saveTimer(data) {
+  return request({
+    url: `system/timer/save`,
+    method: 'post',
+    data,
+  });
+}
+
+/**
+ * 更新定时任务
+ * @param {*} id
+ * @param {*} data
+ * @returns
+ */
+export function updateTimer(id, data) {
+  return request({
+    url: `system/timer/update/${id}`,
+    method: 'post',
+    data,
+  });
+}
+
+/**
+ * 定时任务名称及标识
+ * @returns
+ */
+export function timerTask() {
+  return request({
+    url: `/system/timer/mark`,
+  });
+}

+ 2 - 2
template/admin/src/api/systemOutAccount.js

@@ -144,10 +144,10 @@ export function interfaceDel(id) {
  * @param {*} data
  * @returns
  */
- export function textOutUrl(data) {
+export function textOutUrl(data) {
   return request({
     url: `setting/system_out_account/text_out_url`,
     method: 'post',
-    data
+    data,
   });
 }

+ 1 - 1
template/admin/src/components/copyright/index.vue

@@ -5,7 +5,7 @@
     </div>
     <div class="ivu-global-footer-copyright" v-if="copyright">{{ copyright }}</div>
     <div class="ivu-global-footer-copyright" v-else>
-      Copyright © 2014-2022 
+      Copyright © 2014-2022
       <a href="https://www.crmeb.com" target="_blank">{{ version }}</a>
     </div>
   </div>

+ 1 - 1
template/admin/src/components/couponList/index.vue

@@ -81,7 +81,7 @@ export default {
       isTemplate: false,
       loading: false,
       tableFrom: {
-        receive_type: 3,
+        receive_type: 1,
         page: 1,
         limit: 10,
       },

+ 1 - 2
template/admin/src/components/diyComponents/c_upload_img.vue

@@ -92,8 +92,7 @@ export default {
       deep: true,
     },
   },
-  mounted() {
-  },
+  mounted() {},
   methods: {
     // 点击图文封面
     modalPicTap(title) {

+ 3 - 3
template/admin/src/components/main/components/user/user.vue

@@ -11,7 +11,7 @@
         <!--消息中心<Badge style="margin-left: 10px" :count="messageUnreadCount"></Badge>-->
         <!--</DropdownItem>-->
         <DropdownItem name="userCenter"><Icon type="ios-contact-outline" class="iconImg" />个人中心</DropdownItem>
-		    <!-- <DropdownItem v-show = "info.level === 0" name="fileEdit"><Icon type="ios-document-outline" class="iconImg" />文件管理</DropdownItem> -->
+        <!-- <DropdownItem v-show = "info.level === 0" name="fileEdit"><Icon type="ios-document-outline" class="iconImg" />文件管理</DropdownItem> -->
         <DropdownItem name="logout"><Icon type="ios-log-out" class="iconImg" />退出登录</DropdownItem>
       </DropdownMenu>
     </Dropdown>
@@ -76,7 +76,7 @@ export default {
     userCenter() {
       this.$router.push('/admin/system/user');
     },
-    fileEdit(){
+    fileEdit() {
       this.$router.push('/admin/system/files');
     },
     message() {
@@ -97,7 +97,7 @@ export default {
           break;
         case 'fileEdit':
           this.fileEdit();
-        break;
+          break;
       }
     },
   },

+ 1 - 1
template/admin/src/components/main/main.less

@@ -14,7 +14,7 @@
     padding: 0 20px;
     width: 100%;
   }
-  .ivu-layout-header{
+  .ivu-layout-header {
     height: 50px;
     line-height: 50px;
   }

+ 2 - 2
template/admin/src/components/modelSure/modelSure.vue

@@ -6,13 +6,13 @@
     </p>
     <div>
       <p>{{ `您确定要${delfromData.title}吗?` }}</p>
-      <p>{{ `${delfromData.title}后将无法恢复,请谨慎操作!` }}</p>
+      <p v-if="delfromData.info !== undefined">{{ `${delfromData.info}` }}</p>
     </div>
     <div slot="footer" class="acea-row row-right">
       <Button type="warning" :loading="modal_loading" @click="ok">确定</Button>
       <Button type="primary" @click="cancel">取消</Button>
     </div>
-  </Modal>
+  </Modal> 
 </template>
 
 <script>

+ 1 - 1
template/admin/src/components/sendCoupons/index.vue

@@ -97,7 +97,7 @@ export default {
         page: 1, // 当前页
         limit: 15,
         coupon_title: '',
-        receive_type: 3,
+        receive_type: 1,
       },
       total: 0, // 总条数
     };

+ 30 - 23
template/admin/src/components/upGrade/index.vue

@@ -1,39 +1,46 @@
 <template>
-    <div>
+  <div>
     <!-- 修复升级 -->
-    <Modal v-model="upgrade" width="390" height="96" :closable="false" class-name="vertical-center-modal" :mask-closable="false">
+    <Modal
+      v-model="upgrade"
+      width="390"
+      height="96"
+      :closable="false"
+      class-name="vertical-center-modal"
+      :mask-closable="false"
+    >
       <p slot="header" class="header-modal3">
-        <img src="../../assets/images/bg3.png" alt="">
+        <img src="../../assets/images/bg3.png" alt="" />
       </p>
       <div class="describe">
         <h2>您有新的修复版本可升级</h2>
         <p>更多惊喜内容等你来探索,快来看看吧~</p>
       </div>
       <div slot="footer" class="footer">
-          <Button class="cancel" shape="circle" @click="upgrade = false">暂不升级</Button>
-          <Button shape="circle" type="primary" @click="upgradeNow()">立即升级</Button>
+        <Button class="cancel" shape="circle" @click="upgrade = false">暂不升级</Button>
+        <Button shape="circle" type="primary" @click="upgradeNow()">立即升级</Button>
       </div>
     </Modal>
-    </div>
+  </div>
 </template>
 <script>
 export default {
-    data() {
-        return {
-            upgrade: true,
-        }
+  data() {
+    return {
+      upgrade: true,
+    };
+  },
+  methods: {
+    upgradeNow() {
+      this.$router.push({
+        path: '/admin/system/onlineUpgrade/index',
+        params: { items: true },
+      });
+      this.$store.commit('upgrade/TOGGLE_STATUS', true);
+      sessionStorage.setItem('status', true);
     },
-    methods: {
-        upgradeNow() {
-          this.$router.push({
-            path: "/admin/system/onlineUpgrade/index",
-            params: {items: true},
-          })
-          this.$store.commit("upgrade/TOGGLE_STATUS",true)
-          sessionStorage.setItem("status",true)
-        }
-    },
-}
+  },
+};
 </script>
 <style scoped lang="stylus">
   .ivu-modal-content {
@@ -201,7 +208,7 @@ export default {
     display: flex;
     align-items: center;
     justify-content: center;
-  
+
     .ivu-modal {
       top: 0;
     }
@@ -285,4 +292,4 @@ export default {
   .vertical-center-modal .ivu-modal {
     top: 0;
   }
-</style>
+</style>

+ 127 - 121
template/admin/src/components/verifition/Verify/VerifyPoints.vue

@@ -1,42 +1,42 @@
 <template>
-  <div
-    style="position: relative"
-  >
+  <div style="position: relative">
     <div class="verify-img-out">
       <div
         class="verify-img-panel"
-        :style="{'width': setSize.imgWidth,
-                 'height': setSize.imgHeight,
-                 'background-size' : setSize.imgWidth + ' '+ setSize.imgHeight,
-                 'margin-bottom': vSpace + 'px'}"
+        :style="{
+          width: setSize.imgWidth,
+          height: setSize.imgHeight,
+          'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
+          'margin-bottom': vSpace + 'px',
+        }"
       >
-        <div v-show="showRefresh" class="verify-refresh" style="z-index:3" @click="refresh">
+        <div v-show="showRefresh" class="verify-refresh" style="z-index: 3" @click="refresh">
           <i class="iconfont icon-refresh" />
         </div>
         <img
           ref="canvas"
-          :src="pointBackImgBase?('data:image/png;base64,'+pointBackImgBase):defaultImg"
+          :src="pointBackImgBase ? 'data:image/png;base64,' + pointBackImgBase : defaultImg"
           alt=""
-          style="width:100%;height:100%;display:block"
-          @click="bindingClick?canvasClick($event):undefined"
-        >
+          style="width: 100%; height: 100%; display: block"
+          @click="bindingClick ? canvasClick($event) : undefined"
+        />
 
         <div
           v-for="(tempPoint, index) in tempPoints"
           :key="index"
           class="point-area"
           :style="{
-            'background-color':'#1abd6c',
-            color:'#fff',
-            'z-index':9999,
-            width:'20px',
-            height:'20px',
-            'text-align':'center',
-            'line-height':'20px',
+            'background-color': '#1abd6c',
+            color: '#fff',
+            'z-index': 9999,
+            width: '20px',
+            height: '20px',
+            'text-align': 'center',
+            'line-height': '20px',
             'border-radius': '50%',
-            position:'absolute',
-            top:parseInt(tempPoint.y-10) + 'px',
-            left:parseInt(tempPoint.x-10) + 'px'
+            position: 'absolute',
+            top: parseInt(tempPoint.y - 10) + 'px',
+            left: parseInt(tempPoint.x - 10) + 'px',
           }"
         >
           {{ index + 1 }}
@@ -46,10 +46,12 @@
     <!-- 'height': this.barSize.height, -->
     <div
       class="verify-bar-area"
-      :style="{'width': setSize.imgWidth,
-               'color': this.barAreaColor,
-               'border-color': this.barAreaBorderColor,
-               'line-height':this.barSize.height}"
+      :style="{
+        width: setSize.imgWidth,
+        color: this.barAreaColor,
+        'border-color': this.barAreaBorderColor,
+        'line-height': this.barSize.height,
+      }"
     >
       <span class="verify-msg">{{ text }}</span>
     </div>
@@ -57,12 +59,12 @@
 </template>
 <script type="text/babel">
 /**
-     * VerifyPoints
-     * @description 点选
-     * */
-import { resetSize, _code_chars, _code_color1, _code_color2 } from './../utils/util'
-import { aesEncrypt } from './../utils/ase'
-import {ajCaptcha, ajCaptchaCheck} from "../../../api/common";
+ * VerifyPoints
+ * @description 点选
+ * */
+import { resetSize, _code_chars, _code_color1, _code_color2 } from './../utils/util';
+import { aesEncrypt } from './../utils/ase';
+import { ajCaptcha, ajCaptchaCheck } from '../../../api/common';
 
 export default {
   name: 'VerifyPoints',
@@ -70,7 +72,7 @@ export default {
     // 弹出式pop,固定fixed
     mode: {
       type: String,
-      default: 'fixed'
+      default: 'fixed',
     },
     captchaType: {
       type: String,
@@ -78,30 +80,30 @@ export default {
     // 间隔
     vSpace: {
       type: Number,
-      default: 5
+      default: 5,
     },
     imgSize: {
       type: Object,
       default() {
         return {
           width: '310px',
-          height: '155px'
-        }
-      }
+          height: '155px',
+        };
+      },
     },
     barSize: {
       type: Object,
       default() {
         return {
           width: '310px',
-          height: '40px'
-        }
-      }
+          height: '40px',
+        };
+      },
     },
     defaultImg: {
       type: String,
-      default: ''
-    }
+      default: '',
+    },
   },
   data() {
     return {
@@ -117,116 +119,120 @@ export default {
         imgHeight: 0,
         imgWidth: 0,
         barHeight: 0,
-        barWidth: 0
+        barWidth: 0,
       },
       tempPoints: [],
       text: '',
       barAreaColor: undefined,
       barAreaBorderColor: undefined,
       showRefresh: true,
-      bindingClick: true
-    }
+      bindingClick: true,
+    };
   },
   computed: {
     resetSize() {
-      return resetSize
-    }
+      return resetSize;
+    },
   },
   watch: {
     // type变化则全面刷新
     type: {
       immediate: true,
       handler() {
-        this.init()
-      }
-    }
+        this.init();
+      },
+    },
   },
   mounted() {
     // 禁止拖拽
-    this.$el.onselectstart = function() {
-      return false
-    }
+    this.$el.onselectstart = function () {
+      return false;
+    };
   },
   methods: {
     init() {
       // 加载页面
-      this.fontPos.splice(0, this.fontPos.length)
-      this.checkPosArr.splice(0, this.checkPosArr.length)
-      this.num = 1
-      this.getPictrue()
+      this.fontPos.splice(0, this.fontPos.length);
+      this.checkPosArr.splice(0, this.checkPosArr.length);
+      this.num = 1;
+      this.getPictrue();
       this.$nextTick(() => {
-        this.setSize = this.resetSize(this)	// 重新设置宽度高度
-        this.$parent.$emit('ready', this)
-      })
+        this.setSize = this.resetSize(this); // 重新设置宽度高度
+        this.$parent.$emit('ready', this);
+      });
     },
     canvasClick(e) {
-      this.checkPosArr.push(this.getMousePos(this.$refs.canvas, e))
+      this.checkPosArr.push(this.getMousePos(this.$refs.canvas, e));
       if (this.num == this.checkNum) {
-        this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e))
+        this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e));
         // 按比例转换坐标值
-        this.checkPosArr = this.pointTransfrom(this.checkPosArr, this.setSize)
+        this.checkPosArr = this.pointTransfrom(this.checkPosArr, this.setSize);
         // 等创建坐标执行完
         setTimeout(() => {
           // var flag = this.comparePos(this.fontPos, this.checkPosArr);
           // 发送后端请求
-          var captchaVerification = this.secretKey ? aesEncrypt(this.backToken + '---' + JSON.stringify(this.checkPosArr), this.secretKey) : this.backToken + '---' + JSON.stringify(this.checkPosArr)
+          var captchaVerification = this.secretKey
+            ? aesEncrypt(this.backToken + '---' + JSON.stringify(this.checkPosArr), this.secretKey)
+            : this.backToken + '---' + JSON.stringify(this.checkPosArr);
           const data = {
             captchaType: this.captchaType,
-            'pointJson': this.secretKey ? aesEncrypt(JSON.stringify(this.checkPosArr), this.secretKey) : JSON.stringify(this.checkPosArr),
-            'token': this.backToken
-          }
-          ajCaptchaCheck(data).then(res => {
+            pointJson: this.secretKey
+              ? aesEncrypt(JSON.stringify(this.checkPosArr), this.secretKey)
+              : JSON.stringify(this.checkPosArr),
+            token: this.backToken,
+          };
+          ajCaptchaCheck(data).then((res) => {
             if (res.repCode == '0000') {
-              this.barAreaColor = '#4cae4c'
-              this.barAreaBorderColor = '#5cb85c'
-              this.text = '验证成功'
-              this.bindingClick = false
+              this.barAreaColor = '#4cae4c';
+              this.barAreaBorderColor = '#5cb85c';
+              this.text = '验证成功';
+              this.bindingClick = false;
               if (this.mode == 'pop') {
                 setTimeout(() => {
-                  this.$parent.clickShow = false
-                  this.refresh()
-                }, 1500)
+                  this.$parent.clickShow = false;
+                  this.refresh();
+                }, 1500);
               }
-              this.$parent.$emit('success', { captchaVerification })
+              this.$parent.$emit('success', { captchaVerification });
             } else {
-              this.$parent.$emit('error', this)
-              this.barAreaColor = '#d9534f'
-              this.barAreaBorderColor = '#d9534f'
-              this.text = '验证失败'
+              this.$parent.$emit('error', this);
+              this.barAreaColor = '#d9534f';
+              this.barAreaBorderColor = '#d9534f';
+              this.text = '验证失败';
               setTimeout(() => {
-                this.refresh()
-              }, 700)
+                this.refresh();
+              }, 700);
             }
-          })
-        }, 400)
+          });
+        }, 400);
       }
       if (this.num < this.checkNum) {
-        this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e))
+        this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e));
       }
     },
 
     // 获取坐标
-    getMousePos: function(obj, e) {
-      var x = e.offsetX
-      var y = e.offsetY
-      return { x, y }
+    getMousePos: function (obj, e) {
+      var x = e.offsetX;
+      var y = e.offsetY;
+      return { x, y };
     },
     // 创建坐标点
-    createPoint: function(pos) {
-      this.tempPoints.push(Object.assign({}, pos))
-      return ++this.num
+    createPoint: function (pos) {
+      this.tempPoints.push(Object.assign({}, pos));
+      return ++this.num;
     },
-    refresh: function() {
-      this.tempPoints.splice(0, this.tempPoints.length)
-      this.barAreaColor = '#000'
-      this.barAreaBorderColor = '#ddd'
-      this.bindingClick = true
-      this.fontPos.splice(0, this.fontPos.length)
-      this.checkPosArr.splice(0, this.checkPosArr.length)
-      this.num = 1
-      this.getPictrue()
-      this.text = '验证失败'
-      this.showRefresh = true
+    refresh: function () {
+      this.tempPoints.splice(0, this.tempPoints.length);
+      this.barAreaColor = '#000';
+      this.barAreaBorderColor = '#ddd';
+      this.bindingClick = true;
+      this.fontPos.splice(0, this.fontPos.length);
+      this.checkPosArr.splice(0, this.checkPosArr.length);
+      this.num = 1;
+      this.getPictrue();
+      this.text = '验证失败';
+      this.showRefresh = true;
     },
 
     // 请求背景图片和验证图片
@@ -235,34 +241,34 @@ export default {
         captchaType: this.captchaType,
         clientUid: localStorage.getItem('point'),
         ts: Date.now(), // 现在的时间戳
-      }
-      ajCaptcha(data).then(res => {
+      };
+      ajCaptcha(data).then((res) => {
         if (res.repCode == '0000') {
-          this.pointBackImgBase = res.repData.originalImageBase64
-          this.backToken = res.repData.token
-          this.secretKey = res.repData.secretKey
-          this.poinTextList = res.repData.wordList
-          this.text = '请依次点击【' + this.poinTextList.join(',') + '】'
+          this.pointBackImgBase = res.repData.originalImageBase64;
+          this.backToken = res.repData.token;
+          this.secretKey = res.repData.secretKey;
+          this.poinTextList = res.repData.wordList;
+          this.text = '请依次点击【' + this.poinTextList.join(',') + '】';
         } else {
-          this.text = res.repMsg
+          this.text = res.repMsg;
         }
 
         // 判断接口请求次数是否失效
         if (res.repCode == '6201') {
-          this.pointBackImgBase = null
+          this.pointBackImgBase = null;
         }
-      })
+      });
     },
     // 坐标转换函数
     pointTransfrom(pointArr, imgSize) {
-      var newPointArr = pointArr.map(p => {
-        const x = Math.round(310 * p.x / parseInt(imgSize.imgWidth))
-        const y = Math.round(155 * p.y / parseInt(imgSize.imgHeight))
-        return { x, y }
-      })
+      var newPointArr = pointArr.map((p) => {
+        const x = Math.round((310 * p.x) / parseInt(imgSize.imgWidth));
+        const y = Math.round((155 * p.y) / parseInt(imgSize.imgHeight));
+        return { x, y };
+      });
       // console.log(newPointArr,"newPointArr");
-      return newPointArr
-    }
+      return newPointArr;
+    },
   },
-}
+};
 </script>

+ 209 - 192
template/admin/src/components/verifition/Verify/VerifySlide.vue

@@ -1,56 +1,62 @@
 <template>
-  <div style="position: relative;">
-    <div
-      v-if="type === '2'"
-      class="verify-img-out"
-      :style="{height: (parseInt(setSize.imgHeight) + vSpace) + 'px'}"
-    >
-      <div
-        class="verify-img-panel"
-        :style="{width: setSize.imgWidth,
-                 height: setSize.imgHeight,}"
-      >
-        <img :src="backImgBase?('data:image/png;base64,'+backImgBase):defaultImg" alt="" style="width:100%;height:100%;display:block">
-        <div v-show="showRefresh" class="verify-refresh" @click="refresh"><i class="iconfont icon-refresh" />
-        </div>
+  <div style="position: relative">
+    <div v-if="type === '2'" class="verify-img-out" :style="{ height: parseInt(setSize.imgHeight) + vSpace + 'px' }">
+      <div class="verify-img-panel" :style="{ width: setSize.imgWidth, height: setSize.imgHeight }">
+        <img
+          :src="backImgBase ? 'data:image/png;base64,' + backImgBase : defaultImg"
+          alt=""
+          style="width: 100%; height: 100%; display: block"
+        />
+        <div v-show="showRefresh" class="verify-refresh" @click="refresh"><i class="iconfont icon-refresh" /></div>
         <transition name="tips">
-          <span v-if="tipWords" class="verify-tips" :class="passFlag ?'suc-bg':'err-bg'">{{ tipWords }}</span>
+          <span v-if="tipWords" class="verify-tips" :class="passFlag ? 'suc-bg' : 'err-bg'">{{ tipWords }}</span>
         </transition>
       </div>
     </div>
     <!-- 公共部分 -->
     <div
       class="verify-bar-area"
-      :style="{width: setSize.imgWidth,
-               height: barSize.height,
-               'line-height':barSize.height}"
+      :style="{ width: setSize.imgWidth, height: barSize.height, 'line-height': barSize.height }"
     >
       <span class="verify-msg" v-text="text" />
       <div
         class="verify-left-bar"
-        :style="{width: (leftBarWidth!==undefined)?leftBarWidth: barSize.height, height: barSize.height, 'border-color': leftBarBorderColor, transaction: transitionWidth}"
+        :style="{
+          width: leftBarWidth !== undefined ? leftBarWidth : barSize.height,
+          height: barSize.height,
+          'border-color': leftBarBorderColor,
+          transaction: transitionWidth,
+        }"
       >
         <span class="verify-msg" v-text="finishText" />
         <div
           class="verify-move-block"
-          :style="{width: barSize.height, height: barSize.height, 'background-color': moveBlockBackgroundColor, left: moveBlockLeft, transition: transitionLeft}"
+          :style="{
+            width: barSize.height,
+            height: barSize.height,
+            'background-color': moveBlockBackgroundColor,
+            left: moveBlockLeft,
+            transition: transitionLeft,
+          }"
           @touchstart="start"
           @mousedown="start"
         >
-          <i
-            :class="['verify-icon iconfont', iconClass]"
-            :style="{color: iconColor}"
-          />
+          <i :class="['verify-icon iconfont', iconClass]" :style="{ color: iconColor }" />
           <div
             v-if="type === '2'"
             class="verify-sub-block"
-            :style="{'width':Math.floor(parseInt(setSize.imgWidth)*47/310)+ 'px',
-                     'height': setSize.imgHeight,
-                     'top':'-' + (parseInt(setSize.imgHeight) + vSpace) + 'px',
-                     'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
+            :style="{
+              width: Math.floor((parseInt(setSize.imgWidth) * 47) / 310) + 'px',
+              height: setSize.imgHeight,
+              top: '-' + (parseInt(setSize.imgHeight) + vSpace) + 'px',
+              'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
             }"
           >
-            <img :src="'data:image/png;base64,'+blockBackImgBase" alt="" style="width:100%;height:100%;display:block">
+            <img
+              :src="'data:image/png;base64,' + blockBackImgBase"
+              alt=""
+              style="width: 100%; height: 100%; display: block"
+            />
           </div>
         </div>
       </div>
@@ -59,12 +65,12 @@
 </template>
 <script type="text/babel">
 /**
-     * VerifySlide
-     * @description 滑块
-     * */
-import { aesEncrypt } from './../utils/ase'
-import { resetSize } from './../utils/util'
-import {ajCaptcha, ajCaptchaCheck} from "../../../api/common";
+ * VerifySlide
+ * @description 滑块
+ * */
+import { aesEncrypt } from './../utils/ase';
+import { resetSize } from './../utils/util';
+import { ajCaptcha, ajCaptchaCheck } from '../../../api/common';
 
 //  "captchaType":"blockPuzzle",
 export default {
@@ -75,52 +81,52 @@ export default {
     },
     type: {
       type: String,
-      default: '1'
+      default: '1',
     },
     // 弹出式pop,固定fixed
     mode: {
       type: String,
-      default: 'fixed'
+      default: 'fixed',
     },
     vSpace: {
       type: Number,
-      default: 5
+      default: 5,
     },
     explain: {
       type: String,
-      default: '向右滑动完成验证'
+      default: '向右滑动完成验证',
     },
     imgSize: {
       type: Object,
       default() {
         return {
           width: '310px',
-          height: '155px'
-        }
-      }
+          height: '155px',
+        };
+      },
     },
     blockSize: {
       type: Object,
       default() {
         return {
           width: '50px',
-          height: '50px'
-        }
-      }
+          height: '50px',
+        };
+      },
     },
     barSize: {
       type: Object,
       default() {
         return {
           width: '310px',
-          height: '40px'
-        }
-      }
+          height: '40px',
+        };
+      },
     },
     defaultImg: {
       type: String,
-      default: ''
-    }
+      default: '',
+    },
   },
   data() {
     return {
@@ -139,7 +145,7 @@ export default {
         imgHeight: 0,
         imgWidth: 0,
         barHeight: 0,
-        barWidth: 0
+        barWidth: 0,
       },
       top: 0,
       left: 0,
@@ -151,198 +157,208 @@ export default {
       iconColor: undefined,
       iconClass: 'icon-right',
       status: false, // 鼠标状态
-      isEnd: false,		// 是够验证完成
+      isEnd: false, // 是够验证完成
       showRefresh: true,
       transitionLeft: '',
-      transitionWidth: ''
-    }
+      transitionWidth: '',
+    };
   },
   computed: {
     barArea() {
-      return this.$el.querySelector('.verify-bar-area')
+      return this.$el.querySelector('.verify-bar-area');
     },
     resetSize() {
-      return resetSize
-    }
+      return resetSize;
+    },
   },
   watch: {
     // type变化则全面刷新
     type: {
       immediate: true,
       handler() {
-        this.init()
-      }
-    }
+        this.init();
+      },
+    },
   },
   mounted() {
     // 禁止拖拽
-    this.$el.onselectstart = function() {
-      return false
-    }
-    console.log(this.defaultImg)
+    this.$el.onselectstart = function () {
+      return false;
+    };
+    console.log(this.defaultImg);
   },
   methods: {
     init() {
-      this.text = this.explain
-      this.getPictrue()
+      this.text = this.explain;
+      this.getPictrue();
       this.$nextTick(() => {
-        const setSize = this.resetSize(this)	// 重新设置宽度高度
+        const setSize = this.resetSize(this); // 重新设置宽度高度
         for (const key in setSize) {
-          this.$set(this.setSize, key, setSize[key])
+          this.$set(this.setSize, key, setSize[key]);
         }
-        this.$parent.$emit('ready', this)
-      })
+        this.$parent.$emit('ready', this);
+      });
 
-      var _this = this
+      var _this = this;
 
-      window.removeEventListener('touchmove', function(e) {
-        _this.move(e)
-      })
-      window.removeEventListener('mousemove', function(e) {
-        _this.move(e)
-      })
+      window.removeEventListener('touchmove', function (e) {
+        _this.move(e);
+      });
+      window.removeEventListener('mousemove', function (e) {
+        _this.move(e);
+      });
 
       // 鼠标松开
-      window.removeEventListener('touchend', function() {
-        _this.end()
-      })
-      window.removeEventListener('mouseup', function() {
-        _this.end()
-      })
+      window.removeEventListener('touchend', function () {
+        _this.end();
+      });
+      window.removeEventListener('mouseup', function () {
+        _this.end();
+      });
 
-      window.addEventListener('touchmove', function(e) {
-        _this.move(e)
-      })
-      window.addEventListener('mousemove', function(e) {
-        _this.move(e)
-      })
+      window.addEventListener('touchmove', function (e) {
+        _this.move(e);
+      });
+      window.addEventListener('mousemove', function (e) {
+        _this.move(e);
+      });
 
       // 鼠标松开
-      window.addEventListener('touchend', function() {
-        _this.end()
-      })
-      window.addEventListener('mouseup', function() {
-        _this.end()
-      })
+      window.addEventListener('touchend', function () {
+        _this.end();
+      });
+      window.addEventListener('mouseup', function () {
+        _this.end();
+      });
     },
 
     // 鼠标按下
-    start: function(e) {
-      e = e || window.event
-      if (!e.touches) { // 兼容PC端
-        var x = e.clientX
-      } else { // 兼容移动端
-        var x = e.touches[0].pageX
+    start: function (e) {
+      e = e || window.event;
+      if (!e.touches) {
+        // 兼容PC端
+        var x = e.clientX;
+      } else {
+        // 兼容移动端
+        var x = e.touches[0].pageX;
       }
-      this.startLeft = Math.floor(x - this.barArea.getBoundingClientRect().left)
-      this.startMoveTime = +new Date() // 开始滑动的时间
+      this.startLeft = Math.floor(x - this.barArea.getBoundingClientRect().left);
+      this.startMoveTime = +new Date(); // 开始滑动的时间
       if (this.isEnd == false) {
-        this.text = ''
-        this.moveBlockBackgroundColor = '#337ab7'
-        this.leftBarBorderColor = '#337AB7'
-        this.iconColor = '#fff'
-        e.stopPropagation()
-        this.status = true
+        this.text = '';
+        this.moveBlockBackgroundColor = '#337ab7';
+        this.leftBarBorderColor = '#337AB7';
+        this.iconColor = '#fff';
+        e.stopPropagation();
+        this.status = true;
       }
     },
     // 鼠标移动
-    move: function(e) {
-      e = e || window.event
+    move: function (e) {
+      e = e || window.event;
       if (this.status && this.isEnd == false) {
-        if (!e.touches) { // 兼容PC端
-          var x = e.clientX
-        } else { // 兼容移动端
-          var x = e.touches[0].pageX
+        if (!e.touches) {
+          // 兼容PC端
+          var x = e.clientX;
+        } else {
+          // 兼容移动端
+          var x = e.touches[0].pageX;
         }
-        var bar_area_left = this.barArea.getBoundingClientRect().left
-        var move_block_left = x - bar_area_left // 小方块相对于父元素的left值
+        var bar_area_left = this.barArea.getBoundingClientRect().left;
+        var move_block_left = x - bar_area_left; // 小方块相对于父元素的left值
         if (move_block_left >= this.barArea.offsetWidth - parseInt(parseInt(this.blockSize.width) / 2) - 2) {
-          move_block_left = this.barArea.offsetWidth - parseInt(parseInt(this.blockSize.width) / 2) - 2
+          move_block_left = this.barArea.offsetWidth - parseInt(parseInt(this.blockSize.width) / 2) - 2;
         }
         if (move_block_left <= 0) {
-          move_block_left = parseInt(parseInt(this.blockSize.width) / 2)
+          move_block_left = parseInt(parseInt(this.blockSize.width) / 2);
         }
         // 拖动后小方块的left值
-        this.moveBlockLeft = (move_block_left - this.startLeft) + 'px'
-        this.leftBarWidth = (move_block_left - this.startLeft) + 'px'
+        this.moveBlockLeft = move_block_left - this.startLeft + 'px';
+        this.leftBarWidth = move_block_left - this.startLeft + 'px';
       }
     },
 
     // 鼠标松开
-    end: function() {
-      this.endMovetime = +new Date()
-      var _this = this
+    end: function () {
+      this.endMovetime = +new Date();
+      var _this = this;
       // 判断是否重合
       if (this.status && this.isEnd == false) {
-        var moveLeftDistance = parseInt((this.moveBlockLeft || '').replace('px', ''))
-        moveLeftDistance = moveLeftDistance * 310 / parseInt(this.setSize.imgWidth)
+        var moveLeftDistance = parseInt((this.moveBlockLeft || '').replace('px', ''));
+        moveLeftDistance = (moveLeftDistance * 310) / parseInt(this.setSize.imgWidth);
         const data = {
           captchaType: this.captchaType,
-          'pointJson': this.secretKey ? aesEncrypt(JSON.stringify({ x: moveLeftDistance, y: 5.0 }), this.secretKey) : JSON.stringify({ x: moveLeftDistance, y: 5.0 }),
-          'token': this.backToken
-        }
-        ajCaptchaCheck(data).then(res => {
-            this.moveBlockBackgroundColor = '#5cb85c'
-            this.leftBarBorderColor = '#5cb85c'
-            this.iconColor = '#fff'
-            this.iconClass = 'icon-check'
-            this.showRefresh = false
-            this.isEnd = true
+          pointJson: this.secretKey
+            ? aesEncrypt(JSON.stringify({ x: moveLeftDistance, y: 5.0 }), this.secretKey)
+            : JSON.stringify({ x: moveLeftDistance, y: 5.0 }),
+          token: this.backToken,
+        };
+        ajCaptchaCheck(data)
+          .then((res) => {
+            this.moveBlockBackgroundColor = '#5cb85c';
+            this.leftBarBorderColor = '#5cb85c';
+            this.iconColor = '#fff';
+            this.iconClass = 'icon-check';
+            this.showRefresh = false;
+            this.isEnd = true;
             if (this.mode == 'pop') {
               setTimeout(() => {
-                this.$parent.clickShow = false
-                this.refresh()
-              }, 1500)
+                this.$parent.clickShow = false;
+                this.refresh();
+              }, 1500);
             }
-            this.passFlag = true
-            this.tipWords = `${((this.endMovetime - this.startMoveTime) / 1000).toFixed(2)}s验证成功`
-            var captchaVerification = this.secretKey ? aesEncrypt(this.backToken + '---' + JSON.stringify({ x: moveLeftDistance, y: 5.0 }), this.secretKey) : this.backToken + '---' + JSON.stringify({ x: moveLeftDistance, y: 5.0 })
+            this.passFlag = true;
+            this.tipWords = `${((this.endMovetime - this.startMoveTime) / 1000).toFixed(2)}s验证成功`;
+            var captchaVerification = this.secretKey
+              ? aesEncrypt(this.backToken + '---' + JSON.stringify({ x: moveLeftDistance, y: 5.0 }), this.secretKey)
+              : this.backToken + '---' + JSON.stringify({ x: moveLeftDistance, y: 5.0 });
             setTimeout(() => {
-              this.tipWords = ''
-              this.$parent.closeBox()
-              this.$parent.$emit('success', { captchaVerification })
-            }, 1000)
-        }).catch(res=>{
-          this.moveBlockBackgroundColor = '#d9534f'
-          this.leftBarBorderColor = '#d9534f'
-          this.iconColor = '#fff'
-          this.iconClass = 'icon-close'
-          this.passFlag = false
-          setTimeout(function() {
-            _this.refresh()
-          }, 1000)
-          this.$parent.$emit('error', this)
-          this.tipWords = '验证失败'
-          setTimeout(() => {
-            this.tipWords = ''
-          }, 1000)
-        })
-        this.status = false
+              this.tipWords = '';
+              this.$parent.closeBox();
+              this.$parent.$emit('success', { captchaVerification });
+            }, 1000);
+          })
+          .catch((res) => {
+            this.moveBlockBackgroundColor = '#d9534f';
+            this.leftBarBorderColor = '#d9534f';
+            this.iconColor = '#fff';
+            this.iconClass = 'icon-close';
+            this.passFlag = false;
+            setTimeout(function () {
+              _this.refresh();
+            }, 1000);
+            this.$parent.$emit('error', this);
+            this.tipWords = '验证失败';
+            setTimeout(() => {
+              this.tipWords = '';
+            }, 1000);
+          });
+        this.status = false;
       }
     },
 
-    refresh: function() {
-      this.showRefresh = true
-      this.finishText = ''
+    refresh: function () {
+      this.showRefresh = true;
+      this.finishText = '';
 
-      this.transitionLeft = 'left .3s'
-      this.moveBlockLeft = 0
+      this.transitionLeft = 'left .3s';
+      this.moveBlockLeft = 0;
 
-      this.leftBarWidth = undefined
-      this.transitionWidth = 'width .3s'
+      this.leftBarWidth = undefined;
+      this.transitionWidth = 'width .3s';
 
-      this.leftBarBorderColor = '#ddd'
-      this.moveBlockBackgroundColor = '#fff'
-      this.iconColor = '#000'
-      this.iconClass = 'icon-right'
-      this.isEnd = false
+      this.leftBarBorderColor = '#ddd';
+      this.moveBlockBackgroundColor = '#fff';
+      this.iconColor = '#000';
+      this.iconClass = 'icon-right';
+      this.isEnd = false;
 
-      this.getPictrue()
+      this.getPictrue();
       setTimeout(() => {
-        this.transitionWidth = ''
-        this.transitionLeft = ''
-        this.text = this.explain
-      }, 300)
+        this.transitionWidth = '';
+        this.transitionLeft = '';
+        this.text = this.explain;
+      }, 300);
     },
 
     // 请求背景图片和验证图片
@@ -351,19 +367,20 @@ export default {
         captchaType: this.captchaType,
         clientUid: localStorage.getItem('slider'),
         ts: Date.now(), // 现在的时间戳
-      }
-      ajCaptcha(data).then(res => {
-          this.backImgBase = res.data.originalImageBase64
-          this.blockBackImgBase = res.data.jigsawImageBase64
-          this.backToken = res.data.token
-          this.secretKey = res.data.secretKey
-      }).catch(res =>{
-        this.tipWords = res.msg
-        this.backImgBase = null
-        this.blockBackImgBase = null
-      })
+      };
+      ajCaptcha(data)
+        .then((res) => {
+          this.backImgBase = res.data.originalImageBase64;
+          this.blockBackImgBase = res.data.jigsawImageBase64;
+          this.backToken = res.data.token;
+          this.secretKey = res.data.secretKey;
+        })
+        .catch((res) => {
+          this.tipWords = res.msg;
+          this.backImgBase = null;
+          this.blockBackImgBase = null;
+        });
     },
   },
-}
+};
 </script>
-

+ 5 - 5
template/admin/src/components/verifition/utils/ase.js

@@ -1,11 +1,11 @@
-import CryptoJS from 'crypto-js'
+import CryptoJS from 'crypto-js';
 /**
  * @word 要加密的内容
  * @keyWord String  服务器随机返回的关键字
  *  */
 export function aesEncrypt(word, keyWord = 'XwKsGlMcdPMEhR1B') {
-  var key = CryptoJS.enc.Utf8.parse(keyWord)
-  var srcs = CryptoJS.enc.Utf8.parse(word)
-  var encrypted = CryptoJS.AES.encrypt(srcs, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
-  return encrypted.toString()
+  var key = CryptoJS.enc.Utf8.parse(keyWord);
+  var srcs = CryptoJS.enc.Utf8.parse(word);
+  var encrypted = CryptoJS.AES.encrypt(srcs, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 });
+  return encrypted.toString();
 }

+ 77 - 15
template/admin/src/components/verifition/utils/util.js

@@ -1,36 +1,98 @@
 export function resetSize(vm) {
-  var img_width, img_height, bar_width, bar_height	// 图片的宽度、高度,移动条的宽度、高度
+  var img_width, img_height, bar_width, bar_height; // 图片的宽度、高度,移动条的宽度、高度
 
-  var parentWidth = vm.$el.parentNode.offsetWidth || window.offsetWidth
-  var parentHeight = vm.$el.parentNode.offsetHeight || window.offsetHeight
+  var parentWidth = vm.$el.parentNode.offsetWidth || window.offsetWidth;
+  var parentHeight = vm.$el.parentNode.offsetHeight || window.offsetHeight;
 
   if (vm.imgSize.width.indexOf('%') != -1) {
-    img_width = parseInt(this.imgSize.width) / 100 * parentWidth + 'px'
+    img_width = (parseInt(this.imgSize.width) / 100) * parentWidth + 'px';
   } else {
-    img_width = this.imgSize.width
+    img_width = this.imgSize.width;
   }
 
   if (vm.imgSize.height.indexOf('%') != -1) {
-    img_height = parseInt(this.imgSize.height) / 100 * parentHeight + 'px'
+    img_height = (parseInt(this.imgSize.height) / 100) * parentHeight + 'px';
   } else {
-    img_height = this.imgSize.height
+    img_height = this.imgSize.height;
   }
 
   if (vm.barSize.width.indexOf('%') != -1) {
-    bar_width = parseInt(this.barSize.width) / 100 * parentWidth + 'px'
+    bar_width = (parseInt(this.barSize.width) / 100) * parentWidth + 'px';
   } else {
-    bar_width = this.barSize.width
+    bar_width = this.barSize.width;
   }
 
   if (vm.barSize.height.indexOf('%') != -1) {
-    bar_height = parseInt(this.barSize.height) / 100 * parentHeight + 'px'
+    bar_height = (parseInt(this.barSize.height) / 100) * parentHeight + 'px';
   } else {
-    bar_height = this.barSize.height
+    bar_height = this.barSize.height;
   }
 
-  return { imgWidth: img_width, imgHeight: img_height, barWidth: bar_width, barHeight: bar_height }
+  return { imgWidth: img_width, imgHeight: img_height, barWidth: bar_width, barHeight: bar_height };
 }
 
-export const _code_chars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
-export const _code_color1 = ['#fffff0', '#f0ffff', '#f0fff0', '#fff0f0']
-export const _code_color2 = ['#FF0033', '#006699', '#993366', '#FF9900', '#66CC66', '#FF33CC']
+export const _code_chars = [
+  1,
+  2,
+  3,
+  4,
+  5,
+  6,
+  7,
+  8,
+  9,
+  'a',
+  'b',
+  'c',
+  'd',
+  'e',
+  'f',
+  'g',
+  'h',
+  'i',
+  'j',
+  'k',
+  'l',
+  'm',
+  'n',
+  'o',
+  'p',
+  'q',
+  'r',
+  's',
+  't',
+  'u',
+  'v',
+  'w',
+  'x',
+  'y',
+  'z',
+  'A',
+  'B',
+  'C',
+  'D',
+  'E',
+  'F',
+  'G',
+  'H',
+  'I',
+  'J',
+  'K',
+  'L',
+  'M',
+  'N',
+  'O',
+  'P',
+  'Q',
+  'R',
+  'S',
+  'T',
+  'U',
+  'V',
+  'W',
+  'X',
+  'Y',
+  'Z',
+];
+export const _code_color1 = ['#fffff0', '#f0ffff', '#f0fff0', '#fff0f0'];
+export const _code_color2 = ['#FF0033', '#006699', '#993366', '#FF9900', '#66CC66', '#FF33CC'];

+ 3 - 2
template/admin/src/components/wangEditor/index.vue

@@ -135,7 +135,8 @@ export default {
       let _this = this;
       _this.modalVideo = false;
       this.video = data;
-      let videoHTML = '<video src="' + this.video + '" controls style="max-width:100%;min-height:500rpx"></video>';
+      let videoHTML =
+        '<video src="' + this.video + '" controls style="max-width:100%;min-height:500rpx"></video><p><br></p>';
       this.editor.cmd.do('insertHTML', videoHTML);
     },
 
@@ -181,7 +182,7 @@ export default {
       ];
       // 配置全屏功能按钮是否展示
       //   this.editor.config.showFullScreen = false
-      this.editor.config.uploadImgShowBase64 = true;
+      this.editor.config.uploadImgShowBase64 = false;
       //   this.editor.config.uploadImgAccept = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']
       this.editor.config.zIndex = 0;
       //   this.editor.config.uploadImgMaxSize = this.uploadSize * 1024 * 1024

+ 3 - 3
template/admin/src/main.js

@@ -67,10 +67,10 @@ import scroll from '@/libs/loading';
 import * as tools from '@/libs/tools';
 import VueTreeList from 'vue-tree-list';
 // 复制到粘贴板插件
-import VueClipboard from 'vue-clipboard2'
+import VueClipboard from 'vue-clipboard2';
 
-VueClipboard.config.copyText = true
-Vue.use(VueClipboard)
+VueClipboard.config.copyText = true;
+Vue.use(VueClipboard);
 Vue.use(VueTreeList);
 // 版本升级
 import upgrade from '@/components/upGrade/index.vue';

+ 4 - 5
template/admin/src/pages/account/login/index.vue

@@ -3,7 +3,7 @@
     <div class="container" :class="[fullWidth > 768 ? 'containerSamll' : 'containerBig']">
       <swiper :options="swiperOption" class="swiperPross" v-if="fullWidth > 768">
         <swiper-slide class="swiperPic" v-for="(item, index) in swiperList" :key="index">
-          <img :src="item.slide" />
+          <img :src="item.slide" alt="" />
         </swiper-slide>
         <div class="swiper-pagination" slot="pagination"></div>
       </swiper>
@@ -70,7 +70,6 @@
 <script>
 import { AccountLogin, loginInfoApi } from '@/api/account';
 import { getWorkermanUrl } from '@/api/kefu';
-import Setting from '@/setting';
 import { setCookies } from '@/libs/util';
 import '@/assets/js/canvas-nest.min';
 import Verify from '@/components/verifition/Verify';
@@ -109,9 +108,8 @@ export default {
     };
   },
   created() {
-    var _this = this;
-    top != window && (top.location.href = location.href);
-    document.onkeydown = function (e) {
+    const _this = this;
+    document.onkeydown = function () {
       if (_this.$route.name === 'login') {
         let key = window.event.keyCode;
         if (key === 13) {
@@ -183,6 +181,7 @@ export default {
     // 关闭模态框
     closeModel(params) {
       this.isShow = false;
+      // noinspection JSVoidFunctionReturnValueUsed
       let msg = this.$Message.loading({
         content: '登录中...',
         duration: 0,

+ 1 - 1
template/admin/src/pages/finance/components/commissionDetails/index.vue

@@ -35,7 +35,7 @@
         <div>{{ row.extract_price }}</div>
       </template>
       <template slot-scope="{ row }" slot="pay_type">
-          <span > {{ row.pay_type_name }} </span>
+        <span> {{ row.pay_type_name }} </span>
       </template>
       <template slot-scope="{ row }" slot="price">
         <div v-if="row.price >= 0" class="z-price">+{{ row.price }}</div>

+ 6 - 1
template/admin/src/pages/finance/financialRecords/recharge/index.vue

@@ -75,7 +75,12 @@
         no-filtered-data-text="暂无筛选结果"
       >
         <template slot-scope="{ row, index }" slot="right">
-          <a href="javascript:void(0);" v-if="row.refund_price <= 0 && row.paid && row.recharge_type != 'system'" @click="refund(row)">退款</a>
+          <a
+            href="javascript:void(0);"
+            v-if="row.refund_price <= 0 && row.paid && row.recharge_type != 'system'"
+            @click="refund(row)"
+            >退款</a
+          >
           <!--                    <Divider type="vertical"  v-if="row.paid"/>-->
           <a href="javascript:void(0);" v-if="row.paid === 0" @click="del(row, '此条充值记录', index)">删除</a>
         </template>

+ 2 - 3
template/admin/src/pages/index/index.vue

@@ -9,7 +9,7 @@
     <!--用户-->
     <user-chart ref="userChart" />
     <!--版本升级-->
-    <upgrade v-if="force_reminder == 1"/>
+    <upgrade v-if="force_reminder == 1" />
   </div>
 </template>
 
@@ -25,7 +25,6 @@ import { Notice } from 'iview';
 import { getCookies, setCookies } from '@/libs/util';
 import { upgradeStatusApi } from '@/api/system';
 
-
 export default {
   name: 'index',
   components: {
@@ -51,7 +50,7 @@ export default {
       auth()
         .then((res) => {
           let data = res.data || {};
-          this.force_reminder = data.force_reminder
+          this.force_reminder = data.force_reminder;
           if (data.auth_code && data.auth) {
             this.authCode = data.auth_code;
             this.auth = true;

+ 3 - 1
template/admin/src/pages/marketing/live/add_goods.vue

@@ -59,7 +59,9 @@
         </Table>
 
         <div class="sub_btn">
-          <Button type="primary" style="width: 8%" @click="bindSub" :disabled="disabled" :loading="loadings">提交</Button>
+          <Button type="primary" style="width: 8%" @click="bindSub" :disabled="disabled" :loading="loadings"
+            >提交</Button
+          >
         </div>
       </div>
     </Card>

+ 5 - 1
template/admin/src/pages/marketing/lottery/create.vue

@@ -964,7 +964,11 @@ export default {
       let sum = 0;
       sum = this.sumArr(this.specsData, 'chance');
       for (let j = 0; j < this.specsData.length; j++) {
-        this.$set(this.specsData[j], 'probability', ((this.specsData[j].chance / sum) * 100).toFixed(2) + '%');
+        if (sum == 0) {
+          this.$set(this.specsData[j], 'probability', '0%');
+        } else {
+          this.$set(this.specsData[j], 'probability', ((this.specsData[j].chance / sum) * 100).toFixed(2) + '%');
+        }
       }
     },
     //修改排序

+ 4 - 2
template/admin/src/pages/marketing/storeBargain/create.vue

@@ -141,7 +141,10 @@
                   </RadioGroup>
                 </FormItem>
               </Col>
-              <Col span="24" v-if="formValidate.freight != 3 && formValidate.freight != 1 && formValidate.virtual_type == 0">
+              <Col
+                span="24"
+                v-if="formValidate.freight != 3 && formValidate.freight != 1 && formValidate.virtual_type == 0"
+              >
                 <FormItem label="">
                   <div class="acea-row">
                     <InputNumber
@@ -838,7 +841,6 @@ export default {
     // 下一步
     next(name) {
       if (this.current === 3) {
-
         this.formValidate.description = this.description;
         this.formValidate.rule = this.rule;
         this.$refs[name].validate((valid) => {

+ 10 - 9
template/admin/src/pages/marketing/storeCombination/create.vue

@@ -140,7 +140,10 @@
                   </RadioGroup>
                 </FormItem>
               </Col>
-              <Col span="24" v-if="formValidate.freight != 3 && formValidate.freight != 1 && formValidate.virtual_type == 0">
+              <Col
+                span="24"
+                v-if="formValidate.freight != 3 && formValidate.freight != 1 && formValidate.virtual_type == 0"
+              >
                 <FormItem label="">
                   <div class="acea-row">
                     <InputNumber
@@ -281,13 +284,11 @@
               <Col span="24">
                 <FormItem label="拼团是否参与分销:" props="is_commission" label-for="is_commission">
                   <div class="acea-row row-middle">
-                  <RadioGroup element-id="is_commission" v-model="formValidate.is_commission">
-                    <Radio :label="1" class="radio">开启</Radio>
-                    <Radio :label="0">关闭</Radio>
-                  </RadioGroup>
-                  <div class="ml10 grey">
-                      拼团商品是否参与商城分销返佣
-                  </div>
+                    <RadioGroup element-id="is_commission" v-model="formValidate.is_commission">
+                      <Radio :label="1" class="radio">开启</Radio>
+                      <Radio :label="0">关闭</Radio>
+                    </RadioGroup>
+                    <div class="ml10 grey">拼团商品是否参与商城分销返佣</div>
                   </div>
                 </FormItem>
               </Col>
@@ -783,7 +784,7 @@ export default {
           postage: row.postage, //设置运费金额
           custom_form: row.custom_form, //自定义表单数据
           virtual_type: row.virtual_type, //虚拟商品类型
-          head_commission: 0
+          head_commission: 0,
         };
         this.productAttrs(row);
       }, 500);

+ 1 - 8
template/admin/src/pages/marketing/storeCombination/statistics.vue

@@ -311,14 +311,7 @@ export default {
     getStatistics(id) {
       console.log(id);
       getcombinationStatistics(id).then((res) => {
-        let arr = [
-          'people_count',
-          'spread_count',
-          'start_count',
-          'success_count',
-          'pay_price',
-          'pay_count',
-        ];
+        let arr = ['people_count', 'spread_count', 'start_count', 'success_count', 'pay_price', 'pay_count'];
         this.cardLists.map((i, index) => {
           i.count = res.data[arr[index]];
         });

+ 23 - 4
template/admin/src/pages/marketing/storeCouponIssue/create.vue

@@ -20,9 +20,9 @@
         </FormItem>
         <FormItem label="发送方式">
           <RadioGroup v-model="formData.receive_type">
-            <Radio :label="1">手动领取</Radio>
+            <Radio :label="1">普通券</Radio>
             <Radio :label="2">新人券</Radio>
-            <Radio :label="3">赠送券</Radio>
+            <!-- <Radio :label="3">赠送券</Radio> -->
             <Radio :label="4">会员券</Radio>
           </RadioGroup>
         </FormItem>
@@ -45,7 +45,7 @@
           <div class="info">选择商品</div>
         </FormItem>
         <FormItem v-show="formData.type === 1">
-          <Select v-model="formData.category_id" style="width: 320px">
+          <Select v-model="formData.category_id" style="width: 320px" multiple>
             <Option v-for="item in categoryList" :value="item.id" :key="item.id">{{ item.cate_name }}</Option>
           </Select>
           <div class="info">选择商品的品类</div>
@@ -96,7 +96,7 @@
             @on-change="timeChange"
           ></DatePicker>
         </FormItem>
-        <FormItem label="是否限量" v-if="formData.receive_type != 2 && formData.receive_type != 3">
+        <FormItem label="优惠券发布数量" v-if="formData.receive_type != 2 && formData.receive_type != 3">
           <RadioGroup v-model="formData.is_permanent">
             <Radio :label="0">限量</Radio>
             <Radio :label="1">不限量</Radio>
@@ -110,6 +110,10 @@
           <InputNumber :min="1" :max="100000000" v-model="formData.total_count" :precision="0"></InputNumber>
           <div class="info">填写优惠券的发布数量</div>
         </FormItem>
+        <FormItem label="用户领取数量" v-if="formData.receive_type != 2 && formData.receive_type != 3">
+          <InputNumber :min="1" :max="100000000" v-model="formData.receive_limit" :precision="0"></InputNumber>
+          <div class="info">填写每个用户可以领取多少张</div>
+        </FormItem>
         <!--                <FormItem label="排序">-->
         <!--                    <InputNumber-->
         <!--                        :min="0"-->
@@ -172,6 +176,7 @@ export default {
         status: 1,
         product_id: '',
         category_id: 0,
+        receive_limit: 1,
       },
       categoryList: [],
       productList: [],
@@ -224,6 +229,7 @@ export default {
           this.formData.end_time = data.end_time;
           this.formData.total_count = data.total_count;
           this.formData.sort = data.sort;
+          this.formData.receive_limit = data.receive_limit;
           if ('productInfo' in data) {
             this.productList = data.productInfo;
           }
@@ -309,6 +315,19 @@ export default {
           return this.$Message.error('发布数量不能小于1');
         }
       }
+      if (this.formData.receive_limit < 1) {
+        return this.$Message.error('每个用户可以领取数量不能小于1');
+      }
+      if (this.formData.type == 0) {
+        this.formData.product_id = '';
+        this.formData.category_id = '';
+        this.productList = [];
+      } else if (this.formData.type == 1) {
+        this.formData.product_id = '';
+        this.productList = [];
+      } else if (this.formData.type == 2) {
+        this.formData.category_id = '';
+      }
 
       this.disabled = false;
       couponSaveApi(this.formData)

+ 4 - 1
template/admin/src/pages/marketing/storeSeckill/create.vue

@@ -144,7 +144,10 @@
                   </RadioGroup>
                 </FormItem>
               </Col>
-              <Col span="24" v-if="formValidate.freight != 3 && formValidate.freight != 1 && formValidate.virtual_type == 0">
+              <Col
+                span="24"
+                v-if="formValidate.freight != 3 && formValidate.freight != 1 && formValidate.virtual_type == 0"
+              >
                 <FormItem label="">
                   <div class="acea-row">
                     <InputNumber

+ 2 - 2
template/admin/src/pages/order/orderList/components/tableList.vue

@@ -158,7 +158,7 @@
     <!-- 编辑 退款 退积分 不退款-->
     <edit-from ref="edits" :FromData="FromData" @submitFail="submitFail"></edit-from>
     <!-- 详情 -->
-    <details-from ref="detailss" :orderDatalist="orderDatalist" :orderId="orderId"></details-from>
+    <details-from ref="details" :orderDatalist="orderDatalist" :orderId="orderId"></details-from>
     <!-- 备注 -->
     <order-remark ref="remarks" :orderId="orderId" @submitFail="submitFail"></order-remark>
     <!-- 记录 -->
@@ -580,7 +580,7 @@ export default {
     getData(id) {
       getDataInfo(id)
         .then(async (res) => {
-          this.$refs.detailss.modals = true;
+          this.$refs.details.modals = true;
           this.orderDatalist = res.data;
           if (this.orderDatalist.orderInfo.refund_reason_wap_img) {
             try {

+ 7 - 4
template/admin/src/pages/order/orderList/handle/orderDetails.vue

@@ -1,6 +1,6 @@
 <template>
   <div v-if="orderDatalist">
-    <Modal v-model="modals" scrollable title="订单信息" width="700" class="order_box" footer-hide>
+    <Drawer title="订单详情" :closable="false" width="700" v-model="modals" scrollable>
       <Card :bordered="false" dis-hover class="i-table-no-border">
         <div class="ivu-description-list-title">收货信息</div>
         <Row class="mb10">
@@ -26,11 +26,14 @@
           <Col span="12">优惠券金额:{{ orderDatalist.orderInfo.coupon_price }}</Col>
         </Row>
         <Row class="mb10">
-          <Col span="12">会员商品优惠:{{ orderDatalist.orderInfo.vip_true_price || 0.0 }}</Col>
+          <Col span="12">用户等级优惠:{{ orderDatalist.orderInfo.levelPrice || 0.0 }}</Col>
+          <Col span="12">付费会员优惠:{{ orderDatalist.orderInfo.memberPrice || 0.0 }}</Col>
+        </Row>
+        <Row class="mb10">
           <Col span="12">积分抵扣:{{ orderDatalist.orderInfo.deduction_price || 0.0 }}</Col>
+          <Col span="12">实际支付:{{ orderDatalist.orderInfo.pay_price }}</Col>
         </Row>
         <Row class="mb10">
-          <Col span="12" class="mb10">实际支付:{{ orderDatalist.orderInfo.pay_price }}</Col>
           <Col span="12" class="fontColor3 mb10" v-if="parseFloat(orderDatalist.orderInfo.refund_price)"
             >退款金额:{{ parseFloat(orderDatalist.orderInfo.refund_price) }}</Col
           >
@@ -123,7 +126,7 @@
           </Row>
         </div>
       </Card>
-    </Modal>
+    </Drawer>
     <Modal v-model="modal2" scrollable title="物流查询" width="350" class="order_box2">
       <div class="logistics acea-row row-top">
         <div class="logistics_img">

+ 2 - 2
template/admin/src/pages/order/orderList/handle/orderRecord.vue

@@ -1,5 +1,5 @@
 <template>
-  <Modal v-model="modals" scrollable title="订单记录" width="700" class="order_box" footer-hide>
+  <Drawer title="订单记录" :closable="false" width="700" scrollable v-model="modals">
     <Card :bordered="false" dis-hover>
       <Table
         :columns="columns"
@@ -15,7 +15,7 @@
       <!--                      :page-size="page.limit"/>-->
       <!--            </div>-->
     </Card>
-  </Modal>
+  </Drawer>
 </template>
 
 <script>

+ 2 - 2
template/admin/src/pages/order/orderList/orderlistDetails.vue

@@ -4,8 +4,8 @@
       :cardLists="cardLists"
       v-if="cardLists.length >= 0"
     ></cards-data> -->
-      <table-form @getList="getData" />
-      <table-list ref="table" @on-changeCards="getCards" @changeGetTabs="changeGetTabs" />
+    <table-form @getList="getData" />
+    <table-list ref="table" @on-changeCards="getCards" @changeGetTabs="changeGetTabs" />
   </div>
 </template>
 

+ 1 - 1
template/admin/src/pages/order/refund/index.vue

@@ -534,7 +534,7 @@ export default {
     getRefundData(id, refund_type) {
       if (refund_type == 2) {
         this.delfromData = {
-          title: '立即退货退款',
+          title: '同意退货退款',
           url: `/refund/agree/${id}`,
           method: 'get',
         };

+ 0 - 1
template/admin/src/pages/product/list_wait.vue

@@ -73,7 +73,6 @@
                 更多
                 <Icon type="ios-arrow-down"></Icon>
               </a>
-              
             </Dropdown>
           </template>
         </template>

+ 1 - 7
template/admin/src/pages/product/productAdd/index.vue

@@ -1258,13 +1258,7 @@
               </div>
               <div class="add-more" v-if="disk_type == 2">
                 <Button type="primary" @click="handleAdd" icon="md-add">新增</Button>
-                <Upload
-                  class="ml10"
-                  :action="cardUrl"
-                  :data="uploadData"
-                  :headers="header"
-                  :on-success="upFile"
-                >
+                <Upload class="ml10" :action="cardUrl" :data="uploadData" :headers="header" :on-success="upFile">
                   <Button icon="ios-cloud-upload-outline">导入卡密</Button>
                 </Upload>
               </div>

+ 1 - 1
template/admin/src/pages/setting/devise/list.vue

@@ -56,7 +56,7 @@
                   <div class="font-blue">首页</div>
                 </template>
                 <template slot-scope="{ row, index }" slot="type_name">
-                  <Tag color="primary" v-if="row.is_diy">{{ row.type_name }}{{row.id}}</Tag>
+                  <Tag color="primary" v-if="row.is_diy">{{ row.type_name }}{{ row.id }}</Tag>
                   <Tag color="warning" v-else>{{ row.type_name }}</Tag>
                   <Tag color="success" v-if="row.status == 1">首页</Tag>
                 </template>

+ 36 - 18
template/admin/src/pages/setting/multiLanguage/langList.vue

@@ -13,18 +13,18 @@
           <Col span="24">
             <FormItem label="语言分类:">
               <RadioGroup type="button" v-model="formValidate.is_admin" class="mr15" @on-change="selChange">
-                <Radio :label="item.value" v-for="(item, index) in langType.isAdmin" :key="index">{{
-                  item.title
-                }}</Radio>
+                <Radio :label="item.value" v-for="(item, index) in langType.isAdmin" :key="index"
+                  >{{ item.title }}
+                </Radio>
               </RadioGroup>
             </FormItem>
           </Col>
           <Col span="24">
             <FormItem label="语言类型:">
               <RadioGroup type="button" v-model="formValidate.type_id" class="mr15" @on-change="selChange">
-                <Radio :label="item.value" v-for="(item, index) in langType.langType" :key="index">{{
-                  item.title
-                }}</Radio>
+                <Radio :label="item.value" v-for="(item, index) in langType.langType" :key="index"
+                  >{{ item.title }}
+                </Radio>
               </RadioGroup>
             </FormItem>
           </Col>
@@ -50,8 +50,8 @@
       使用说明
       <template slot="desc"
         >添加用户端页面语言,添加完成之后状态码为中文文字,前端页面使用 $t(`xxxx`),js文件中使用 this.t(`xxxx`) 或者使用
-        that.t(`xxxx`)<br />添加后端接口语言,添加完成之后状态码为6位数字,后台抛错或者控制器返回文字的时候直接填写状态码数字</template
-      >
+        that.t(`xxxx`)<br />添加后端接口语言,添加完成之后状态码为6位数字,后台抛错或者控制器返回文字的时候直接填写状态码数字
+      </template>
     </Alert>
     <Card :bordered="false" dis-hover>
       <Row type="flex">
@@ -89,6 +89,7 @@
       v-model="addlangModal"
       width="750"
       title="添加语言"
+      :loading="FormLoading"
       @on-ok="ok"
       @on-cancel="addlangModal = false"
       @on-visible-change="modalChange"
@@ -131,6 +132,7 @@
 <script>
 import { mapState } from 'vuex';
 import { langCodeList, langCodeInfo, langCodeSettingSave, langCodeTranslate } from '@/api/setting';
+
 export default {
   data() {
     return {
@@ -145,6 +147,7 @@ export default {
         limit: 20,
       },
       total: 0,
+      FormLoading: true,
       loading: false,
       ruleValidate: {
         code: [{ required: true, message: '请输入状态码/文字', trigger: 'blur' }],
@@ -231,15 +234,14 @@ export default {
         text: this.langFormData.remarks,
       })
         .then((res) => {
-          console.log(this.langFormData.list);
-
           this.langFormData.list.map((e) => {
             e.lang_explain = res.data[e.type_id];
           });
           this.traTabLoading = false;
         })
         .catch((err) => {
-          this.$Message.error(err);
+          this.traTabLoading = false;
+          this.$Message.error(err.msg);
         });
     },
     add() {
@@ -254,11 +256,26 @@ export default {
       this.addlangModal = true;
     },
     ok() {
-      console.log(this.langFormData);
-      langCodeSettingSave(this.langFormData).then((res) => {
-        this.$Message.success(res.msg);
-        this.getList();
-      });
+      if (!this.langFormData.remarks.trim()) {
+        this.FormLoading = false;
+        this.$nextTick(() => {
+          this.FormLoading = true;
+        });
+        return this.$Message.error('请先输入语言说明');
+      }
+      langCodeSettingSave(this.langFormData)
+        .then((res) => {
+          this.addlangModal = false;
+          this.$Message.success(res.msg);
+          this.getList();
+        })
+        .catch((err) => {
+          this.FormLoading = false;
+          this.$nextTick(() => {
+            this.FormLoading = true;
+          });
+          this.$Message.error(err.msg);
+        });
     },
     edit(row) {
       this.langFormData.is_admin = this.formValidate.is_admin;
@@ -352,7 +369,7 @@ export default {
   margin-bottom: 10px;
 }
 
-.status >>> .item~.item {
+.status >>> .item ~ .item {
   margin-left: 6px;
 }
 
@@ -378,7 +395,8 @@ export default {
     height: 100%;
   }
 }
-.mb20 /deep/ .ivu-table-wrapper > .ivu-spin-fix{
+
+.mb20 /deep/ .ivu-table-wrapper > .ivu-spin-fix {
   border: none;
 }
 </style>

+ 1 - 1
template/admin/src/pages/setting/multiLanguage/list.vue

@@ -23,7 +23,7 @@
         </template>
         <template slot-scope="{ row, index }" slot="language_name">
           <div class="acea-row row-middle">
-            <span>{{row.language_name}}</span>
+            <span>{{ row.language_name }}</span>
             <Tag class="ml10" color="default" v-if="row.is_default">默认</Tag>
           </div>
         </template>

+ 40 - 41
template/admin/src/pages/setting/systemMenus/components/menusFrom.vue

@@ -162,32 +162,32 @@
 </template>
 
 <script>
-import { addMenusApi, addMenus, getRuleList } from "@/api/systemMenus";
-import icon from "@/utils/icon";
+import { addMenusApi, addMenus, getRuleList } from '@/api/systemMenus';
+import icon from '@/utils/icon';
 
 export default {
-  name: "menusFrom",
+  name: 'menusFrom',
   props: {
     formValidate: {
       type: Object,
-      default: null
+      default: null,
     },
     titleFrom: {
       type: String,
-      default: ""
-    }
+      default: '',
+    },
   },
   data() {
     return {
       arrs: [],
-      searchRule: "",
-      iconVal: "",
+      searchRule: '',
+      iconVal: '',
       grid: {
         xl: 12,
         lg: 12,
         md: 12,
         sm: 24,
-        xs: 24
+        xs: 24,
       },
       modals: false,
       modal12: false,
@@ -198,28 +198,27 @@ export default {
       authType: true,
       search: icon,
       ruleModal: false,
-      ruleList: []
+      ruleList: [],
     };
   },
   watch: {
-    "formValidate.header": function(n) {
+    'formValidate.header': function (n) {
       this.formValidate.is_header = n ? 1 : 0;
     },
-    "formValidate.auth_type": function(n) {
+    'formValidate.auth_type': function (n) {
       if (n === undefined) {
         n = 1;
       }
       this.authType = n === 1;
     },
-    "formValidate.data": function(n) {
-    }
+    'formValidate.data': function (n) {},
   },
   computed: {
     /* eslint-disable */
     optionsList() {
       let a = [];
       this.FromData.map((item) => {
-        if ("pid" === item.field) {
+        if ('pid' === item.field) {
           a = item.options;
         }
       });
@@ -228,7 +227,7 @@ export default {
     headerOptionsList() {
       let a = [];
       this.FromData.map((item) => {
-        if ("header" === item.field) {
+        if ('header' === item.field) {
           a = item.options;
         }
       });
@@ -237,7 +236,7 @@ export default {
     optionsListmodule() {
       let a = [];
       this.FromData.map((item) => {
-        if ("module" === item.field) {
+        if ('module' === item.field) {
           a = item.options;
         }
       });
@@ -246,7 +245,7 @@ export default {
     optionsRadio() {
       let a = [];
       this.FromData.map((item) => {
-        if ("auth_type" === item.field) {
+        if ('auth_type' === item.field) {
           a = item.options;
         }
       });
@@ -255,7 +254,7 @@ export default {
     isheaderRadio() {
       let a = [];
       this.FromData.map((item) => {
-        if ("is_header" === item.field) {
+        if ('is_header' === item.field) {
           a = item.options;
         }
       });
@@ -264,7 +263,7 @@ export default {
     isShowRadio() {
       let a = [];
       this.FromData.map((item) => {
-        if ("is_show" === item.field) {
+        if ('is_show' === item.field) {
           a = item.options;
         }
       });
@@ -273,7 +272,7 @@ export default {
     isShowPathRadio() {
       let a = [];
       this.FromData.map((item) => {
-        if ("is_show_path" === item.field) {
+        if ('is_show_path' === item.field) {
           a = item.options;
         }
       });
@@ -282,12 +281,12 @@ export default {
     menuList() {
       let a = [];
       this.FromData.map((item) => {
-        if ("menu_list" === item.field) {
+        if ('menu_list' === item.field) {
           a = item.props.data;
         }
       });
       return a;
-    }
+    },
   },
   methods: {
     // 获取权限列表
@@ -300,7 +299,7 @@ export default {
     modalchange(type) {
       if (!type) {
         this.arrs = [];
-        this.ruleModal = "";
+        this.ruleModal = '';
         this.ruleModal = false;
       }
     },
@@ -310,7 +309,7 @@ export default {
       }
     },
     selectRule(data) {
-      this.$emit("selectRule", data);
+      this.$emit('selectRule', data);
       this.$nextTick((e) => {
         this.ruleModal = false;
       });
@@ -342,13 +341,13 @@ export default {
       }
     },
     init() {
-      this.searchRule = "";
+      this.searchRule = '';
       this.arrs = [];
     },
     handleCreate1(val) {
       this.headerOptionsList.push({
         value: val,
-        label: val
+        label: val,
       });
     },
     // 获取新增表单
@@ -376,26 +375,26 @@ export default {
         this.formValidate.pid = this.formValidate.path[length - 1] || 0;
       }
       let data = {
-        url: this.formValidate.id ? `/setting/menus/${this.formValidate.id}` : "/setting/menus",
-        method: this.formValidate.id ? "put" : "post",
-        datas: this.formValidate
+        url: this.formValidate.id ? `/setting/menus/${this.formValidate.id}` : '/setting/menus',
+        method: this.formValidate.id ? 'put' : 'post',
+        datas: this.formValidate,
       };
       if (this.authType) {
         if (!this.formValidate.menu_name) {
-          return this.$Message.warning("请填写按钮名称");
+          return this.$Message.warning('请填写按钮名称');
         }
         if (!this.formValidate.menu_path) {
-          return this.$Message.warning("请填写路由地址");
+          return this.$Message.warning('请填写路由地址');
         }
       } else {
         if (!this.formValidate.menu_name) {
-          return this.$Message.warning("请填写接口名称");
+          return this.$Message.warning('请填写接口名称');
         }
         if (!this.formValidate.methods) {
-          return this.$Message.warning("请选择请求方式");
+          return this.$Message.warning('请选择请求方式');
         }
         if (!this.formValidate.api_url) {
-          return this.$Message.warning("请选择接口地址");
+          return this.$Message.warning('请选择接口地址');
         }
       }
       this.valids = true;
@@ -403,9 +402,9 @@ export default {
         .then(async (res) => {
           this.$Message.success(res.msg);
           this.modals = false;
-          this.$emit("getList");
+          this.$emit('getList');
           this.getAddFrom();
-          this.$store.dispatch("admin/menus/getMenusNavList");
+          this.$store.dispatch('admin/menus/getMenusNavList');
         })
         .catch((res) => {
           this.valids = false;
@@ -415,14 +414,14 @@ export default {
     handleReset() {
       this.modals = false;
       this.authType = true;
-      this.$refs["formValidate"].resetFields();
-      this.$emit("clearFrom");
-    }
+      this.$refs['formValidate'].resetFields();
+      this.$emit('clearFrom');
+    },
   },
   created() {
     this.list = this.search;
     this.getAddFrom();
-  }
+  },
 };
 </script>
 

+ 10 - 10
template/admin/src/pages/setting/userFile/index.vue

@@ -5,12 +5,12 @@
         <FormItem label="账号" prop="">
           <Input type="text" v-model="account" :disabled="true" class="input"></Input>
         </FormItem>
-		<FormItem label="文件管理新密码" prop="file_pwd">
-		  <Input type="password" v-model="formValidate.file_pwd" class="input"></Input>
-		</FormItem>
-		<FormItem label="文件管理确认新密码" prop="conf_file_pwd">
-		  <Input type="password" v-model="formValidate.conf_file_pwd" class="input"></Input>
-		</FormItem>
+        <FormItem label="文件管理新密码" prop="file_pwd">
+          <Input type="password" v-model="formValidate.file_pwd" class="input"></Input>
+        </FormItem>
+        <FormItem label="文件管理确认新密码" prop="conf_file_pwd">
+          <Input type="password" v-model="formValidate.conf_file_pwd" class="input"></Input>
+        </FormItem>
         <FormItem>
           <Button type="primary" @click="handleSubmit('formValidate')">提交</Button>
         </FormItem>
@@ -38,12 +38,12 @@ export default {
     return {
       account: '',
       formValidate: {
-		file_pwd: '',
-		conf_file_pwd: '',
+        file_pwd: '',
+        conf_file_pwd: '',
       },
       ruleValidate: {
-		file_pwd: [{ required: true, message: '请输入您的文件管理新密码', trigger: 'blur' }],
-		conf_file_pwd: [{ required: true, message: '请确认您的文件管理新密码', trigger: 'blur' }],
+        file_pwd: [{ required: true, message: '请输入您的文件管理新密码', trigger: 'blur' }],
+        conf_file_pwd: [{ required: true, message: '请确认您的文件管理新密码', trigger: 'blur' }],
       },
     };
   },

+ 1 - 1
template/admin/src/pages/setting/verifyOrder/index.vue

@@ -54,7 +54,7 @@
           </Col>
         </Row>
       </Form>
-       <Table
+      <Table
         :columns="columns"
         :data="orderList"
         ref="table"

+ 5 - 5
template/admin/src/pages/statistic/user/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="article-manager">
-    <div class="i-layout-page-header  pt10">
+    <div class="i-layout-page-header pt10">
       <Form ref="formInline" :model="formInline" inline>
         <FormItem class="mr20">
           用户渠道:
@@ -109,14 +109,14 @@ export default {
 </script>
 
 <style scoped>
-.pt10{
+.pt10 {
   padding-top: 10px;
 }
-.i-layout-page-header{
+.i-layout-page-header {
   margin: 10px 0 10px 0;
 }
-.ivu-form-item{
+.ivu-form-item {
   padding-bottom: 10px;
   margin-bottom: 0;
 }
-  </style>
+</style>

+ 1 - 2
template/admin/src/pages/system/auth/index.vue

@@ -97,7 +97,7 @@ import { auth, getVersion, crmebProduct, saveCrmebCopyRight, getCrmebCopyRight }
 import { mapState } from 'vuex';
 import { formatDate } from '@/utils/validate';
 import QRCode from 'qrcodejs2';
-import Vcode from 'vue-puzzle-vcode';
+// import Vcode from 'vue-puzzle-vcode';
 
 export default {
   name: 'system_auth',
@@ -163,7 +163,6 @@ export default {
     },
   },
   components: {
-    Vcode,
     uploadPictures,
   },
   mounted() {

+ 1 - 5
template/admin/src/pages/system/configTab/list.vue

@@ -6,11 +6,7 @@
           ><Button icon="ios-arrow-back" size="small" type="text">返回</Button></router-link
         >
         <Divider type="vertical" />
-        <span
-          class="ivu-page-header-title mr20"
-          style="padding: 0"
-          v-text="$route.meta.title"
-        ></span>
+        <span class="ivu-page-header-title mr20" style="padding: 0" v-text="$route.meta.title"></span>
       </div>
     </div>
     <Card :bordered="false" dis-hover class="ivu-mt">

+ 315 - 0
template/admin/src/pages/system/crontab/createModal.vue

@@ -0,0 +1,315 @@
+<template>
+  <div>
+    <Modal
+      v-model="modal"
+      :title="formValidate.id ? '编辑定时任务' : '添加定时任务'"
+      width="900"
+      @on-ok="handleSubmit"
+      @on-cancel="modal = true"
+      @on-visible-change="initData"
+    >
+      <Form ref="formValidate" :model="formValidate" :label-width="97" label-colon>
+        <FormItem label="任务名称" required>
+          <Row :gutter="16">
+            <Col span="20">
+              <Select v-model="formValidate.mark" label-in-value @on-change="taskChange">
+                <Option v-for="(value, name) in task" :key="name" :value="name">{{ value }}</Option>
+              </Select>
+            </Col>
+          </Row>
+        </FormItem>
+        <FormItem label="执行周期" required>
+          <Row :gutter="14">
+            <Col span="4">
+              <Select v-model="formValidate.type">
+                <Option v-for="item in typeList" :key="item.value" :value="item.value">{{ item.name }}</Option>
+              </Select>
+            </Col>
+            <Col v-if="formValidate.type == 6" span="4">
+              <Select v-model="formValidate.week">
+                <Option v-for="item in 7" :key="item" :value="item">{{ item | formatWeek }}</Option>
+              </Select>
+            </Col>
+            <Col v-if="[4, 7].includes(formValidate.type)" span="4">
+              <div class="input-number-wrapper">
+                <InputNumber
+                  v-model="formValidate.day"
+                  :max="formValidate.type === 4 ? 10000 : 31"
+                  :min="1"
+                ></InputNumber>
+                <span class="suffix">日</span>
+              </div>
+            </Col>
+            <Col v-if="[3, 5, 6, 7].includes(formValidate.type)" span="4">
+              <div class="input-number-wrapper">
+                <InputNumber v-model="formValidate.hour" :max="23" :min="0"></InputNumber>
+                <span class="suffix">时</span>
+              </div>
+            </Col>
+            <Col span="4" v-if="[2, 5, 6, 7].includes(formValidate.type)">
+              <div class="input-number-wrapper">
+                <InputNumber
+                  v-model="formValidate.minute"
+                  :max="formValidate.type === 2 ? 36000 : 59"
+                  :min="0"
+                ></InputNumber>
+                <span class="suffix">分</span>
+              </div>
+            </Col>
+            <Col span="4" v-if="[1, 5, 6, 7].includes(formValidate.type)">
+              <div class="input-number-wrapper">
+                <InputNumber
+                  v-model="formValidate.second"
+                  :max="formValidate.type === 1 ? 36000 : 59"
+                  :min="0"
+                ></InputNumber>
+                <span class="suffix">秒</span>
+              </div>
+            </Col>
+          </Row>
+          <Row :gutter="12">
+            <div class="trip">{{ trip }}</div>
+          </Row>
+        </FormItem>
+        <FormItem label="任务说明">
+          <Row :gutter="10">
+            <Col span="20">
+              <Input
+                v-model="formValidate.content"
+                type="textarea"
+                :autosize="{ minRows: 5, maxRows: 5 }"
+                placeholder="请输入任务说明"
+              ></Input>
+            </Col>
+          </Row>
+        </FormItem>
+        <FormItem label="是否开启">
+          <Row :gutter="10">
+            <Col span="12">
+              <i-switch v-model="formValidate.is_open" :true-value="1" :false-value="0" size="large">
+                <span slot="open">开启</span>
+                <span slot="close">关闭</span>
+              </i-switch>
+            </Col>
+          </Row>
+        </FormItem>
+      </Form>
+    </Modal>
+  </div>
+</template>
+
+<script>
+import { mapMutations } from 'vuex';
+import { timerTask, timerInfo, saveTimer, updateTimer } from '@/api/system';
+export default {
+  filters: {
+    formatWeek(value) {
+      return ['周一', '周二', '周三', '周四', '周五', '周六', '周日'][value - 1];
+    },
+  },
+  data() {
+    return {
+      modal: false,
+      typeList: [
+        {
+          name: '每隔N秒',
+          value: 1,
+        },
+        {
+          name: '每隔N分钟',
+          value: 2,
+        },
+        {
+          name: '每隔N小时',
+          value: 3,
+        },
+        {
+          name: '每隔N天',
+          value: 4,
+        },
+        {
+          name: '每天',
+          value: 5,
+        },
+        {
+          name: '每星期',
+          value: 6,
+        },
+        {
+          name: '每月',
+          value: 7,
+        },
+      ],
+      task: {},
+      loading: false,
+      formValidate: {
+        mark: '', //键
+        content: '',
+        is_open: 0,
+        type: 6,
+        week: 1,
+        day: 1,
+        hour: 1,
+        minute: 30,
+        second: 0,
+      },
+      trip: '',
+    };
+  },
+  created() {
+    this.timerTask();
+  },
+  watch: {
+    formValidate: {
+      handler(nVal, oVal) {
+        switch (nVal.type) {
+          case 1:
+            this.trip = `每隔${nVal.second}秒执行一次`;
+            break;
+          case 2:
+            this.trip = `每隔${nVal.minute}分钟执行一次`;
+            break;
+          case 3:
+            this.trip = `每隔${nVal.hour}小时执行一次`;
+            break;
+          case 4:
+            this.trip = `每隔${nVal.day}天执行一次`;
+            break;
+          case 5:
+            this.trip = `每天${nVal.hour}时${nVal.minute}分${nVal.second}秒执行一次`;
+            break;
+          case 6:
+            this.trip = `每个星期${nVal.week}的${nVal.hour}时${nVal.minute}分${nVal.second}秒执行一次`;
+            break;
+          case 7:
+            this.trip = `每月${nVal.day}日的${nVal.hour}时${nVal.minute}分${nVal.second}秒执行一次`;
+            break;
+        }
+      },
+      immediate: true,
+      deep: true,
+    },
+  },
+  methods: {
+    ...mapMutations('admin/layout', ['setCopyrightShow']),
+    timerTask() {
+      timerTask().then((res) => {
+        this.task = res.data;
+      });
+    },
+    initData(status) {
+      if (!status) {
+        this.formValidate = {
+          mark: '',
+          content: '',
+          is_open: 0,
+          type: 6,
+          week: 1,
+          day: 1,
+          hour: 1,
+          minute: 30,
+          second: 0,
+        };
+        this.modal = false;
+      }
+    },
+    timerInfo(id) {
+      console.log(id);
+
+      timerInfo(id).then((res) => {
+        this.modal = true;
+        this.formValidate = res.data;
+        // this.formValidate.name = name;
+        // this.formValidate.mark = mark;
+        // this.formValidate.content = content;
+        // this.formValidate.is_open = is_open;
+        // this.formValidate.type = type;
+      });
+    },
+    // 提交
+    handleSubmit() {
+      console.log(this.formValidate);
+      if (!this.formValidate.mark) {
+        return this.$Message.error({
+          content: '请选择任务名称',
+          onClose: () => {
+            // this.loading = false;
+          },
+        });
+      }
+      this.saveTimer(this.formValidate);
+    },
+    taskChange(task) {
+      this.formValidate.mark = task.value;
+    },
+    saveTimer(data) {
+      saveTimer(data)
+        .then((res) => {
+          this.$Message.success({
+            content: res.msg,
+            onClose: () => {
+              this.$emit('submitAsk');
+            },
+          });
+        })
+        .catch((err) => {
+          this.$Message.error(err.msg);
+        });
+    },
+  },
+};
+</script>
+
+<style lang="stylus" scoped>
+.form-card {
+  margin-bottom: 74px;
+
+  >>> .ivu-card-body {
+    padding: 30px 0;
+  }
+}
+
+.btn-card {
+  position: fixed;
+  right: 0;
+  bottom: 0;
+  left: 200px;
+  z-index: 2;
+  text-align: center;
+}
+
+.input-number-wrapper {
+  position: relative;
+  display: inline-block;
+  width: 100%;
+  vertical-align: middle;
+  line-height: normal;
+
+  .ivu-input-number {
+    width: 100%;
+    padding-right: 35px;
+  }
+
+  >>> .ivu-input-number-handler-wrap {
+    right: 35px;
+  }
+
+  .suffix {
+    position: absolute;
+    top: 0;
+    right: 0;
+    z-index: 1;
+    width: 35px;
+    height: 100%;
+    text-align: center;
+    font-size: 12px;
+    line-height: 33px;
+    color: #333333;
+  }
+
+}
+ .trip{
+    padding-left 15px
+    color #aaa
+  }
+</style>

+ 167 - 0
template/admin/src/pages/system/crontab/index.vue

@@ -0,0 +1,167 @@
+<template>
+  <Card :bordered="false" dis-hover>
+    <Button type="primary" @click="addTask">添加定时任务</Button>
+    <Table :columns="columns" :data="tableData" :loading="loading" class="ivu-mt">
+      <template slot-scope="{ row }" slot="execution_cycle">
+        <span>{{ taskTrip(row) }}</span>
+      </template>
+      <template slot-scope="{ row }" slot="is_open">
+        <i-switch v-model="row.is_open" :true-value="1" :false-value="0" size="large" @on-change="handleChange(row)">
+          <span slot="open">开启</span>
+          <span slot="close">关闭</span>
+        </i-switch>
+      </template>
+      <template slot-scope="{ row }" slot="action">
+        <a @click="edit(row.id)">编辑</a>
+
+        <Divider type="vertical" />
+        <a @click="handleDelete(row, '删除秒杀商品', index)">删除</a>
+      </template>
+    </Table>
+    <div class="acea-row row-right page">
+      <Page :total="total" :current="page" show-elevator show-total @on-change="pageChange" :page-size="limit" />
+    </div>
+    <creatTask ref="addTask" @submitAsk="getList"></creatTask>
+  </Card>
+</template>
+
+<script>
+import { timerIndex, showTimer } from '@/api/system';
+import creatTask from './createModal.vue';
+export default {
+  name: 'system_crontab',
+  components: { creatTask },
+  data() {
+    return {
+      loading: false,
+      columns: [
+        {
+          title: '名称',
+          key: 'name',
+          minWidth: 150,
+        },
+        {
+          title: '任务说明',
+          key: 'content',
+          minWidth: 120,
+        },
+        // {
+        //   title: '最后执行时间',
+        //   key: 'last_execution_time',
+        //   minWidth: 120,
+        // },
+        // {
+        //   title: '下次执行时间',
+        //   key: 'next_execution_time',
+        //   minWidth: 120,
+        // },
+        {
+          title: '执行周期',
+          slot: 'execution_cycle',
+          minWidth: 160,
+        },
+        {
+          title: '是否开启',
+          slot: 'is_open',
+          minWidth: 100,
+        },
+        {
+          title: '操作',
+          slot: 'action',
+          align: 'center',
+          fixed: 'right',
+          minWidth: 100,
+        },
+      ],
+      tableData: [],
+      page: 1,
+      limit: 15,
+      total: 1,
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    taskTrip(row) {
+      switch (row.type) {
+        case 1:
+          return `每隔${row.second}秒执行一次`;
+        case 2:
+          return `每隔${row.minute}分钟执行一次`;
+        case 3:
+          return `每隔${row.hour}小时执行一次`;
+        case 4:
+          return `每隔${row.day}天执行一次`;
+        case 5:
+          return `每天${row.hour}时${row.minute}分${row.second}秒执行一次`;
+        case 6:
+          return `每个星期${row.week}的${row.hour}时${row.minute}分${row.second}秒执行一次`;
+        case 7:
+          return `每月${row.day}日的${row.hour}时${row.minute}分${row.second}秒执行一次`;
+      }
+    },
+    // 列表
+    getList() {
+      this.loading = true;
+      timerIndex({
+        page: this.page,
+        limit: this.limit,
+      })
+        .then((res) => {
+          this.loading = false;
+          let { count, list } = res.data;
+          this.total = count;
+          this.tableData = list;
+        })
+        .catch((res) => {
+          this.loading = false;
+          this.$Message.error(res.msg);
+        });
+    },
+    addTask() {
+      console.log(this.$refs.addTask);
+      this.$refs.addTask.modal = true;
+    },
+    edit(id) {
+      console.log(id);
+      this.$refs.addTask.timerInfo(id);
+    },
+    // 删除
+    handleDelete(row, tit, num) {
+      let delfromData = {
+        title: tit,
+        num: num,
+        url: `system/timer/del/${row.id}`,
+        method: 'delete',
+        ids: '',
+      };
+      this.$modalSure(delfromData)
+        .then((res) => {
+          this.$Message.success(res.msg);
+          this.getList();
+        })
+        .catch((res) => {
+          this.$Message.error(res.msg);
+        });
+    },
+    // 是否开启
+    handleChange({ id, is_open }) {
+      showTimer(id, is_open)
+        .then((res) => {
+          this.$Message.success(res.msg);
+          this.getList();
+        })
+        .catch((res) => {
+          this.$Message.error(res.msg);
+        });
+    },
+    pageChange(index) {
+      this.page = index;
+      this.getList();
+    },
+  },
+};
+</script>
+
+<style lang="stylus" scoped></style>

+ 10 - 12
template/admin/src/pages/system/file/index.vue

@@ -22,24 +22,22 @@ export default {
     console.log(this.$refs.picBox.clientWidth);
 
     this.$nextTick(() => {
-      let winwidth = this.$refs.picBox.clientWidth;
+      let winWidth = this.$refs.picBox.clientWidth;
       let winHeight = document.body.clientHeight - 170;
-      console.log(winwidth,winHeight);
-      if (winwidth < 1018) {
+      if (winWidth < 1018) {
         this.pageLimit = 18;
         this.pageLimit = winHeight > 790 ? 24 : 18;
-
-      } else if (winwidth < 1185) {
-        this.pageLimit = winHeight > 790 ? 30  : 18;
-      } else if (winwidth < 1222) {
+      } else if (winWidth < 1185) {
+        this.pageLimit = winHeight > 790 ? 30 : 18;
+      } else if (winWidth < 1222) {
         this.pageLimit = 30;
-      } else if (winwidth < 1327) {
+      } else if (winWidth < 1327) {
         this.pageLimit = 32;
-      } else if (winwidth < 1750) {
+      } else if (winWidth < 1750) {
         this.pageLimit = 40;
-      } else if (winwidth < 2100) {
-          this.pageLimit = winHeight > 790 ? 60 : 48;
-      } else if (winwidth > 2100) {
+      } else if (winWidth < 2100) {
+        this.pageLimit = winHeight > 790 ? 60 : 48;
+      } else if (winWidth > 2100) {
         this.pageLimit = winHeight > 790 ? 75 : 60;
       }
       this.uploadShow = true;

+ 1 - 5
template/admin/src/pages/system/group/list.vue

@@ -6,11 +6,7 @@
           ><Button icon="ios-arrow-back" size="small" type="text">返回</Button></router-link
         >
         <Divider type="vertical" />
-        <span
-          class="ivu-page-header-title mr20"
-          style="padding: 0"
-          v-text="$route.meta.title"
-        ></span>
+        <span class="ivu-page-header-title mr20" style="padding: 0" v-text="$route.meta.title"></span>
       </div>
     </div>
     <Card :bordered="false" dis-hover class="ivu-mt">

+ 4 - 4
template/admin/src/pages/system/maintain/systemCleardata/index.vue

@@ -74,10 +74,10 @@ export default {
           type: 'recycle',
         },
         {
-            title: '清除用户数据',
-            tlt: '用户相关的所有表都将被清除,谨慎操作',
-            typeName: 'error',
-            type: 'user'
+          title: '清除用户数据',
+          tlt: '用户相关的所有表都将被清除,谨慎操作',
+          typeName: 'error',
+          type: 'user',
         },
         {
           title: '清除商城数据',

+ 3 - 10
template/admin/src/pages/system/maintain/systemFile/components/loginFrom.vue

@@ -5,12 +5,7 @@
         <div class="page-account-top">
           <span class="page-account-top-tit">文件管理登录</span>
         </div>
-        <Form
-          ref="formInline"
-          :model="formInline"
-          :rules="ruleInline"
-          @submit.native.prevent
-        >
+        <Form ref="formInline" :model="formInline" :rules="ruleInline" @submit.native.prevent>
           <!-- <FormItem prop="sms_account" class="maxInpt">
             <Input type="text" v-model="formInline.account" prefix="ios-contact-outline" placeholder="请输入手机号" />
           </FormItem> -->
@@ -27,9 +22,7 @@
 </template>
 
 <script>
-import {
-		opendirLoginApi
-	} from '@/api/system';
+import { opendirLoginApi } from '@/api/system';
 export default {
   name: 'file_login',
   data() {
@@ -69,7 +62,7 @@ export default {
           opendirLoginApi(this.formInline)
             .then(async (res) => {
               this.$Message.success('登录成功!');
-              this.$emit('on-Login',res.data);
+              this.$emit('on-Login', res.data);
             })
             .catch((res) => {
               this.$Message.error(res.msg);

+ 7 - 1
template/admin/src/pages/system/maintain/systemFile/login.vue

@@ -16,7 +16,13 @@
             <Input type="text" v-model="formInline.account" prefix="ios-contact-outline" placeholder="请输入手机号" />
           </FormItem> -->
             <FormItem prop="sms_token" class="maxInpt">
-              <Input type="password" size="large" v-model="formInline.password" prefix="ios-lock-outline" placeholder="请输入密码" />
+              <Input
+                type="password"
+                size="large"
+                v-model="formInline.password"
+                prefix="ios-lock-outline"
+                placeholder="请输入密码"
+              />
               <div class="trip">提示:config/filesystem.php中手动配置password后使用,不能为空</div>
             </FormItem>
             <FormItem class="maxInpt">

+ 5 - 5
template/admin/src/pages/user/level/index.vue

@@ -201,11 +201,11 @@ export default {
           slot: 'is_shows',
           minWidth: 120,
         },
-        {
-          title: '等级说明',
-          key: 'explain',
-          minWidth: 120,
-        },
+        // {
+        //   title: '等级说明',
+        //   key: 'explain',
+        //   minWidth: 120,
+        // },
         {
           title: '操作',
           slot: 'action',

+ 15 - 7
template/admin/src/pages/user/list/handle/userDetails.vue

@@ -1,6 +1,6 @@
 <template>
   <div style="width: 100%">
-    <Modal v-model="modals" scrollable footer-hide closable title="用户详情" :mask-closable="false" width="900">
+    <Drawer title="用户详情" :closable="false" width="900" scrollable v-model="modals">
       <Spin size="large" fix v-if="spinShow"></Spin>
       <div class="acea-row">
         <div class="avatar mr15"><img :src="psInfo.avatar" /></div>
@@ -13,15 +13,22 @@
           </div>
         </div>
       </div>
+
       <Row type="flex" justify="space-between" class="mt25">
-        <Col span="4" class="user_menu">
+        <!-- <Col span="4" class="user_menu">
           <Menu :theme="theme2" :active-name="activeName" @on-select="changeType">
             <MenuItem :name="item.val" v-for="(item, index) in list" :key="index">
-              {{ item.label }}
+              
             </MenuItem>
           </Menu>
+        </Col> -->
+        <Col span="24">
+          <Tabs class="mb20" :value="activeName" @on-click="changeType">
+            <TabPane :name="item.val" v-for="(item, index) in list" :key="index" :label="item.label"></TabPane>
+          </Tabs>
         </Col>
-        <Col span="20">
+
+        <Col span="24">
           <Table
             :columns="columns"
             :data="userLists"
@@ -49,7 +56,7 @@
           </div>
         </Col>
       </Row>
-    </Modal>
+    </Drawer>
   </div>
 </template>
 
@@ -380,6 +387,7 @@ export default {
 }
 </style>
 <style scoped lang="stylus">
-.user_menu >>> .ivu-menu
-    width 100% !important
+.user_menu >>> .ivu-menu {
+  width: 100% !important;
+}
 </style>

+ 27 - 19
template/admin/src/pages/user/list/index.vue

@@ -133,21 +133,19 @@
                   </RadioGroup>
                 </FormItem>
               </Col>
-              <Col v-bind="grid">
-                <FormItem label="身份:" label-for="is_promoter">
-                  <RadioGroup v-model="userFrom.is_promoter" type="button">
-                    <Radio label="">
-                      <span>全部</span>
-                    </Radio>
-                    <Radio label="1">
-                      <span>推广员</span>
-                    </Radio>
-                    <Radio label="0">
-                      <span>普通用户</span>
-                    </Radio>
-                  </RadioGroup>
-                </FormItem>
-              </Col>
+              <FormItem label="身份:" label-for="is_promoter">
+                <RadioGroup v-model="userFrom.is_promoter" type="button">
+                  <Radio label="">
+                    <span>全部</span>
+                  </Radio>
+                  <Radio label="1">
+                    <span>推广员</span>
+                  </Radio>
+                  <Radio label="0">
+                    <span>普通用户</span>
+                  </Radio>
+                </RadioGroup>
+              </FormItem>
             </Col>
             <Col span="18">
               <Col v-bind="grid">
@@ -355,13 +353,13 @@
         @onceGetList="onceGetList"
       ></userLabel>
     </Modal>
-    <Modal v-model="modals" title="用户信息填写" class="order_box" :closable="false" width="600" :z-index="50">
+    <Drawer :closable="false" width="700" v-model="modals" title="用户信息填写">
       <userEdit ref="userEdit" v-if="modals" :userData="userData"></userEdit>
-      <div slot="footer">
-        <Button @click="modals = false">取消</Button>
+      <div class="demo-drawer-footer">
+        <Button style="margin-right: 8px" @click="modals = false">取消</Button>
         <Button type="primary" @click="setUser">提交</Button>
       </div>
-    </Modal>
+    </Drawer>
     <!-- 用户标签 -->
     <Modal
       v-model="selectLabelShow"
@@ -1290,4 +1288,14 @@ img {
     color: #808695;
   }
 }
+.demo-drawer-footer{
+        width: 100%;
+        position: absolute;
+        bottom: 0;
+        left: 0;
+        border-top: 1px solid #e8e8e8;
+        padding: 10px 16px;
+        text-align: right;
+        background: #fff;
+    }
 </style>

+ 42 - 43
template/admin/src/plugin/emoji-awesome/css/google.min.css

@@ -10,7 +10,7 @@
   color: transparent !important;
   background-size: 4100%;
   background-image: url(../img/look.png) !important;
- }
+}
 .em.em-tlj-1 {
   background-position: 0% 0%;
 }
@@ -258,45 +258,44 @@
   background-position: 2.5% 100%;
 }
 .em.em-tlj-83 {
-  background-position: 5% 0%
- }
- .em.em-tlj-84 {
-  background-position: 5% 2.5%
- }
- .em.em-tlj-85 {
-  background-position: 5% 5%
- }
- .em.em-tlj-86 {
-  background-position: 5% 7.5%
- }
- .em.em-tlj-87 {
-  background-position: 5% 10%
- }
- .em.em-tlj-88 {
-  background-position: 5% 12.5%
- }
- .em.em-tlj-89 {
-  background-position: 5% 15%
- }
- .em.em-tlj-90 {
-  background-position: 5% 17.5%
- }
- .em.em-tlj-91 {
-  background-position: 5% 20%
- }
- .em.em-tlj-92 {
-  background-position: 5% 22.5%
- }
- .em.em-tlj-93 {
-  background-position: 5% 25%
- }
- .em.em-tlj-94 {
-  background-position: 5% 27.5%
- }
- .em.em-tlj-95 {
-  background-position: 5% 30%
- }
- .em.em-tlj-96 {
-  background-position: 5% 32.5%
- }
-
+  background-position: 5% 0%;
+}
+.em.em-tlj-84 {
+  background-position: 5% 2.5%;
+}
+.em.em-tlj-85 {
+  background-position: 5% 5%;
+}
+.em.em-tlj-86 {
+  background-position: 5% 7.5%;
+}
+.em.em-tlj-87 {
+  background-position: 5% 10%;
+}
+.em.em-tlj-88 {
+  background-position: 5% 12.5%;
+}
+.em.em-tlj-89 {
+  background-position: 5% 15%;
+}
+.em.em-tlj-90 {
+  background-position: 5% 17.5%;
+}
+.em.em-tlj-91 {
+  background-position: 5% 20%;
+}
+.em.em-tlj-92 {
+  background-position: 5% 22.5%;
+}
+.em.em-tlj-93 {
+  background-position: 5% 25%;
+}
+.em.em-tlj-94 {
+  background-position: 5% 27.5%;
+}
+.em.em-tlj-95 {
+  background-position: 5% 30%;
+}
+.em.em-tlj-96 {
+  background-position: 5% 32.5%;
+}

+ 2 - 2
template/admin/src/router/modules/finance.js

@@ -28,7 +28,7 @@ export default {
       path: 'billing_records/index',
       name: `${pre}billingRecords`,
       meta: {
-        auth: ['finance-user_extract'],
+        auth: ['finance-billing_records-index'],
         title: '账单记录',
       },
       component: () => import('@/pages/finance/billingRecords/index'),
@@ -37,7 +37,7 @@ export default {
       path: 'capital_flow/index',
       name: `${pre}capitalFlow`,
       meta: {
-        auth: ['finance-user_extract'],
+        auth: ['finance-capital_flow-index'],
         title: '资金流水',
       },
       component: () => import('@/pages/finance/capitalFlow/index'),

+ 9 - 0
template/admin/src/router/modules/system.js

@@ -150,5 +150,14 @@ export default {
       },
       component: () => import('@/pages/system/onlineUpgrade/index'),
     },
+    {
+      path: 'crontab',
+      name: `${pre}crontab`,
+      meta: {
+        auth: ['system-crontab-index'],
+        title: '定时任务',
+      },
+      component: () => import('@/pages/system/crontab/index'),
+    },
   ],
 };

+ 9 - 9
template/admin/src/router/routers.js

@@ -57,15 +57,15 @@ const frameIn = [
         },
         component: () => import('@/pages/setting/user/index'),
       },
-	  {
-	    path: '/admin/system/files',
-	    name: `systemFiles`,
-	    meta: {
-	      auth: ['admin-setting-files'],
-	      title: '文件管理',
-	    },
-	    component: () => import('@/pages/setting/userFile/index'),
-	  },
+      {
+        path: '/admin/system/files',
+        name: `systemFiles`,
+        meta: {
+          auth: ['admin-setting-files'],
+          title: '文件管理',
+        },
+        component: () => import('@/pages/setting/userFile/index'),
+      },
       // 刷新页面 必须保留
       {
         path: 'refresh',

+ 2 - 2
template/admin/src/store/index.js

@@ -26,7 +26,7 @@ import fresh from './module/fresh';
 import kefu from './module/kefu';
 import integralOrder from './module/integralOrder';
 import mobildConfig from './module/mobildConfig';
-import upgrade from "./module/upgrade"
+import upgrade from './module/upgrade';
 
 Vue.use(Vuex);
 // 持久化储存
@@ -78,6 +78,6 @@ export default new Vuex.Store({
     kefu,
     mobildConfig,
     integralOrder,
-    upgrade
+    upgrade,
   },
 });

+ 0 - 1
template/admin/src/styles/style.css

@@ -678,4 +678,3 @@ body {
 .paddingBox {
   padding: 0 10px 10px;
 }
-

+ 25 - 26
template/admin/src/utils/download.js

@@ -1,63 +1,63 @@
-import axios from 'axios'
-import { Message } from 'element-ui'
-import { saveAs } from 'file-saver'
-import { getToken } from '@/utils/auth'
-import errorCode from '@/utils/errorCode'
-import { blobValidate } from "@/utils/ruoyi";
+import axios from 'axios';
+import { Message } from 'element-ui';
+import { saveAs } from 'file-saver';
+import { getToken } from '@/utils/auth';
+import errorCode from '@/utils/errorCode';
+import { blobValidate } from '@/utils/ruoyi';
 
-const baseURL = process.env.VUE_APP_BASE_API
+const baseURL = process.env.VUE_APP_BASE_API;
 
 export default {
   name(name, isDelete = true) {
-    var url = baseURL + "/common/download?fileName=" + encodeURI(name) + "&delete=" + isDelete
+    var url = baseURL + '/common/download?fileName=' + encodeURI(name) + '&delete=' + isDelete;
     axios({
       method: 'get',
       url: url,
       responseType: 'blob',
-      headers: { 'Authorization': 'Bearer ' + getToken() }
+      headers: { Authorization: 'Bearer ' + getToken() },
     }).then(async (res) => {
       const isLogin = await blobValidate(res.data);
       if (isLogin) {
-        const blob = new Blob([res.data])
-        this.saveAs(blob, decodeURI(res.headers['download-filename']))
+        const blob = new Blob([res.data]);
+        this.saveAs(blob, decodeURI(res.headers['download-filename']));
       } else {
         this.printErrMsg(res.data);
       }
-    })
+    });
   },
   resource(resource) {
-    var url = baseURL + "/common/download/resource?resource=" + encodeURI(resource);
+    var url = baseURL + '/common/download/resource?resource=' + encodeURI(resource);
     axios({
       method: 'get',
       url: url,
       responseType: 'blob',
-      headers: { 'Authorization': 'Bearer ' + getToken() }
+      headers: { Authorization: 'Bearer ' + getToken() },
     }).then(async (res) => {
       const isLogin = await blobValidate(res.data);
       if (isLogin) {
-        const blob = new Blob([res.data])
-        this.saveAs(blob, decodeURI(res.headers['download-filename']))
+        const blob = new Blob([res.data]);
+        this.saveAs(blob, decodeURI(res.headers['download-filename']));
       } else {
         this.printErrMsg(res.data);
       }
-    })
+    });
   },
   zip(url, name) {
-    var url = baseURL + url
+    var url = baseURL + url;
     axios({
       method: 'get',
       url: url,
       responseType: 'blob',
-      headers: { 'Authorization': 'Bearer ' + getToken() }
+      headers: { Authorization: 'Bearer ' + getToken() },
     }).then(async (res) => {
       const isLogin = await blobValidate(res.data);
       if (isLogin) {
-        const blob = new Blob([res.data], { type: 'application/zip' })
-        this.saveAs(blob, name)
+        const blob = new Blob([res.data], { type: 'application/zip' });
+        this.saveAs(blob, name);
       } else {
         this.printErrMsg(res.data);
       }
-    })
+    });
   },
   saveAs(text, name, opts) {
     saveAs(text, name, opts);
@@ -65,8 +65,7 @@ export default {
   async printErrMsg(data) {
     const resText = await data.text();
     const rspObj = JSON.parse(resText);
-    const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
+    const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'];
     Message.error(errMsg);
-  }
-}
-
+  },
+};

+ 2 - 6
template/admin/src/utils/public.js

@@ -11,13 +11,9 @@
 import { tableDelApi } from '@/api/common';
 export function modalSure(delfromData) {
   return new Promise((resolve, reject) => {
-    let content = '';
+    let content = `<p>确定要${delfromData.title}吗?</p>`;
     if (delfromData.info !== undefined) {
-      content = `<p>${delfromData.title}</p><p>${delfromData.info}</p>`;
-    } else if (delfromData.un !== undefined) {
-      content = `<p>确定要${delfromData.title}吗?</p>`;
-    } else {
-      content = `<p>确定要${delfromData.title}吗?</p><p>${delfromData.title}后将无法恢复,请谨慎操作!</p>`;
+      content = content + `<p>${delfromData.info}</p>`;
     }
     this.$Modal.confirm({
       title: delfromData.title,

+ 285 - 268
template/uni-app/components/couponListWindow/index.vue

@@ -1,269 +1,286 @@
-<template>
-	<view>
-		<view class='coupon-list-window' :class='coupon.coupon==true?"on":""'>
-			<view v-if="coupon.count" class="nav acea-row row-around">
-				<view v-if="coupon.count[2]" :class="['acea-row', 'row-middle', coupon.type === 2 ? 'on' : '']" @click="setType(2)">{{$t(`商品券`)}}</view>
-				<view v-if="coupon.count[1]" :class="['acea-row', 'row-middle', coupon.type === 1 ? 'on' : '']" @click="setType(1)">{{$t(`品类券`)}}</view>
-				<view v-if="coupon.count[0]" :class="['acea-row', 'row-middle', coupon.type === 0 ? 'on' : '']" @click="setType(0)">{{$t(`通用券`)}}</view>
-			</view>
-			<view class='title' v-else>{{$t(`优惠券`)}}<text class='iconfont icon-guanbi' @click='close'></text></view>
-			<view v-if="coupon.count" class="occupy"></view>
-			<view class='coupon-list' v-if="coupon.list.length">
-				<view class='item acea-row row-center-wrapper' v-for="(item,index) in coupon.list" @click="getCouponUser(index,item.id)"
-				 :key='index' :class="{svip: item.receive_type === 4}">
-				  <view class="moneyCon acea-row row-center-wrapper">
-						<view class='money acea-row row-column row-center-wrapper' :class='item.is_use && coupon.count?"moneyGray":""'>
-							<view>{{$t(`¥`)}}<text class='num'>{{item.coupon_price}}</text></view>
-							<view class="pic-num" v-if="item.use_min_price > 0">{{$t(`满`)}}{{item.use_min_price}}{{$t(`元可用`)}}</view>
-							<view class="pic-num" v-else>{{$t(`无门槛券`)}}</view>
-						</view>
-					</view>
-					<view class='text'>
-						<view class='condition line2' :class="coupon.count?'':'order'">
-							<span class='line-title' :class='item.is_use && coupon.count?"gray":""' v-if='item.type===0'>{{$t(`通用券`)}}</span>
-							<span class='line-title' :class='item.is_use && coupon.count?"gray":""' v-else-if='item.type===1'>{{$t(`品类券`)}}</span>
-							<span class='line-title' :class='item.is_use && coupon.count?"gray":""' v-else>{{$t(`商品券`)}}</span>
-							<image src='../../static/images/fvip.png' class="pic" v-if="item.receive_type===4"></image>
-							<span class='name'>{{$t(item.title)}}</span>
-						</view>
-						<view class='data acea-row row-between-wrapper'>
-							<view v-if="item.coupon_time">{{$t(`领取后`)}}{{item.coupon_time}}{{$t(`天内可用`)}}</view>
-							<view v-else>{{ item.start_time ? item.start_time + "-" : ""}}{{ item.end_time }}</view>
-							<view v-if="coupon.count">
-								<view class='bnt gray' v-if="item.is_use">{{item.use_title || $t(`已领取`)}}</view>
-								<view class='bnt bg-color' v-else>{{coupon.statusTile || $t(`立即领取`)}}</view>
-							</view>
-							<view v-else class="orderCou">
-								<view class="iconfont icon-xuanzhong11" :class="item.receive_type === 4?'svip':'font-num'" v-if="item.is_use"></view>
-								<view class="iconfont icon-weixuan" v-else></view>
-							</view>
-						</view>
-					</view>
-				</view>
-			</view>
-			<!-- 无优惠券 -->
-			<view class='pictrue' v-else>
-				<image :src="imgHost + '/statics/images/noCoupon.png'"></image>
-			</view>
-		</view>
-		<view class='mask' catchtouchmove="true" :hidden='coupon.coupon==false' @click='close'></view>
-	</view>
-</template>
-
-<script>
-	import {
-		setCouponReceive
-	} from '@/api/api.js';
-	import {HTTP_REQUEST_URL} from '@/config/app';
-	export default {
-		props: {
-			//打开状态 0=领取优惠券,1=使用优惠券
-			openType: {
-				type: Number,
-				default: 0,
-			},
-			coupon: {
-				type: Object,
-				default: function() {
-					return {};
-				}
-			}
-		},
-		data() {
-			return {
-				imgHost:HTTP_REQUEST_URL,
-				type: 0
-			};
-		},
-		methods: {
-			close: function() {
-				this.$emit('ChangCouponsClone');
-				this.type = 0;
-			},
-			getCouponUser: function(index, id) {
-				let that = this;
-				let list = that.coupon.list;
-				if (list[index].is_use == true && this.openType == 0) return true;
-				switch (this.openType) {
-					case 0:
-						//领取优惠券
-						setCouponReceive(id).then(res => {
-							that.$emit('ChangCouponsUseState', index);
-							that.$util.Tips({
-								title: "领取成功"
-							});
-							// that.$emit('ChangCoupons', list[index]);
-						}).catch(err => {
-							uni.showToast({
-								title: err,
-								icon: 'none'
-							});
-						})
-						break;
-					case 1:
-						that.$emit('ChangCoupons', index);
-						break;
-				}
-			},
-			setType: function(type) {
-				this.type = type;
-				this.$emit('tabCouponType', type);
-			}
-		}
-	}
-</script>
-
-<style scoped lang="scss">
-	.orderCou{
-		position: absolute;
-		right: 20rpx;
-		top:50%;
-		margin-top: -20rpx;
-	}
-	.orderCou .iconfont{
-		font-size: 40rpx;
-	}
-	.orderCou .svip{
-		color:#EDBB75;
-	}
-	.coupon-list .item .text{
-		position: relative;
-	}
-	.coupon-list .item .text .condition.order{
-		width: 350rpx;
-	}
-	.coupon-list-window .coupon-list .text .condition .pic {
-		width: 30rpx;
-		height: 30rpx;
-		margin-right: 10rpx;
-		vertical-align: middle;
-	}
-
-	.coupon-list-window .coupon-list .text .condition .name {
-		vertical-align: middle;
-		font-size: 26rpx;
-		font-weight: 500;
-	}
-
-	.coupon-list-window {
-		position: fixed;
-		bottom: 0;
-		left: 0;
-		width: 100%;
-		background-color: #FFFFFF;
-		border-radius: 16rpx 16rpx 0 0;
-		z-index: 999;
-		transform: translate3d(0, 100%, 0);
-		transition: all .3s cubic-bezier(.25, .5, .5, .9);
-	}
-
-	.coupon-list-window.on {
-		transform: translate3d(0, 0, 0);
-	}
-
-	.coupon-list-window .title {
-		height: 124rpx;
-		width: 100%;
-		text-align: center;
-		line-height: 124rpx;
-		font-size: 32rpx;
-		font-weight: bold;
-		position: relative;
-	}
-
-	.coupon-list-window .title .iconfont {
-		position: absolute;
-		right: 30rpx;
-		top: 50%;
-		transform: translateY(-50%);
-		font-size: 35rpx;
-		color: #8a8a8a;
-		font-weight: normal;
-	}
-
-	.coupon-list-window .coupon-list {
-		margin: 0 0 50rpx 0;
-		height: 721rpx;
-		padding-top: 28rpx;
-		overflow: auto;
-	}
-
-	.coupon-list-window .pictrue {
-		width: 414rpx;
-		height: 336rpx;
-		margin: 192rpx auto 243rpx auto;
-	}
-
-	.coupon-list-window .pictrue image {
-		width: 100%;
-		height: 100%;
-	}
-
-	.pic-num {
-		color: #fff;
-		font-size: 24rpx;
-	}
-
-	.line-title {
-		width: 70rpx;
-		height: 32rpx !important;
-		padding: 0 10rpx;
-		line-height: 30rpx;
-		text-align: center;
-		background: var(--view-minorColorT);
-		border: 1px solid var(--view-theme);
-		opacity: 1;
-		border-radius: 20rpx;
-		font-size: 18rpx;
-		color: var(--view-theme);
-		margin-right: 12rpx;
-		box-sizing: border-box;
-	}
-
-	.line-title.gray {
-		border-color: #C1C1C1!important;
-		color: #C1C1C1!important;
-		background-color: #F7F7F7!important;
-	}
-
-	.nav {
-		position: absolute;
-		top: 0;
-		left: 0;
-		width: 100%;
-		height: 106rpx;
-		border-bottom: 2rpx solid #F5F5F5;
-		border-top-left-radius: 16rpx;
-		border-top-right-radius: 16rpx;
-		background-color: #FFFFFF;
-		font-size: 30rpx;
-		color: #999999;
-	}
-
-	.nav .acea-row {
-		border-top: 5rpx solid transparent;
-		border-bottom: 5rpx solid transparent;
-	}
-
-	.nav .acea-row.on {
-		border-bottom-color: var(--view-theme);
-		color: #282828;
-	}
-
-	.nav .acea-row:only-child {
-		border-bottom-color: transparent;
-	}
-
-	.occupy {
-		height: 106rpx;
-	}
-
-	.coupon-list .item {
-		margin-bottom: 18rpx;
-		box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.06);
-	}
-
-	.coupon-list .item .money {
-		font-weight: normal;
-	}
+<template>
+	<view>
+		<view class='coupon-list-window' :class='coupon.coupon==true?"on":""'>
+			<view v-if="coupon.count" class="nav acea-row row-around">
+				<view v-if="coupon.count[2]" :class="['acea-row', 'row-middle', coupon.type === 2 ? 'on' : '']"
+					@click="setType(2)">{{$t(`商品券`)}}</view>
+				<view v-if="coupon.count[1]" :class="['acea-row', 'row-middle', coupon.type === 1 ? 'on' : '']"
+					@click="setType(1)">{{$t(`品类券`)}}</view>
+				<view v-if="coupon.count[0]" :class="['acea-row', 'row-middle', coupon.type === 0 ? 'on' : '']"
+					@click="setType(0)">{{$t(`通用券`)}}</view>
+			</view>
+			<view class='title' v-else>{{$t(`优惠券`)}}<text class='iconfont icon-guanbi' @click='close'></text></view>
+			<view v-if="coupon.count" class="occupy"></view>
+			<view class='coupon-list' v-if="coupon.list.length">
+				<view class='item acea-row row-center-wrapper' v-for="(item,index) in coupon.list"
+					@click="getCouponUser(index,item.id)" :key='index' :class="{svip: item.receive_type === 4}">
+					<view class="moneyCon acea-row row-center-wrapper">
+						<view class='money acea-row row-column row-center-wrapper'
+							:class='item.is_use >= item.receive_limit && coupon.count?"moneyGray":""'>
+							<view>{{$t(`¥`)}}<text class='num'>{{item.coupon_price}}</text></view>
+							<view class="pic-num" v-if="item.use_min_price > 0">
+								{{$t(`满`)}}{{item.use_min_price}}{{$t(`元可用`)}}</view>
+							<view class="pic-num" v-else>{{$t(`无门槛券`)}}</view>
+						</view>
+					</view>
+					<view class='text'>
+						<view class='condition line2' :class="coupon.count?'':'order'">
+							<span class='line-title' :class='item.is_use >= item.receive_limit && coupon.count?"gray":""'
+								v-if='item.type===0'>{{$t(`通用券`)}}</span>
+							<span class='line-title' :class='item.is_use >= item.receive_limit && coupon.count?"gray":""'
+								v-else-if='item.type===1'>{{$t(`品类券`)}}</span>
+							<span class='line-title' :class='item.is_use >= item.receive_limit && coupon.count?"gray":""'
+								v-else>{{$t(`商品券`)}}</span>
+							<image src='../../static/images/fvip.png' class="pic" v-if="item.receive_type===4"></image>
+							<span class='name'>{{$t(item.title)}}</span>
+						</view>
+						<view class='data acea-row row-between-wrapper'>
+							<view v-if="item.coupon_time">{{$t(`领取后`)}}{{item.coupon_time}}{{$t(`天内可用`)}}</view>
+							<view v-else>{{ item.start_time ? item.start_time + "-" : ""}}{{ item.end_time }}</view>
+							<view v-if="coupon.count">
+								<view class='bnt gray' v-if="item.is_use >= item.receive_limit">
+									{{item.use_title || $t(`已领取`)}}</view>
+								<view class='bnt bg-color' v-else>{{coupon.statusTile || $t(`立即领取`)}}</view>
+							</view>
+							<view v-else class="orderCou">
+								<view class="iconfont icon-xuanzhong11"
+									:class="item.receive_type === 4?'svip':'font-num'" v-if="item.is_use"></view>
+								<view class="iconfont icon-weixuan" v-else></view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<!-- 无优惠券 -->
+			<view class='pictrue' v-else>
+				<image :src="imgHost + '/statics/images/noCoupon.png'"></image>
+			</view>
+		</view>
+		<view class='mask' catchtouchmove="true" :hidden='coupon.coupon==false' @click='close'></view>
+	</view>
+</template>
+
+<script>
+	import {
+		setCouponReceive
+	} from '@/api/api.js';
+	import {
+		HTTP_REQUEST_URL
+	} from '@/config/app';
+	export default {
+		props: {
+			//打开状态 0=领取优惠券,1=使用优惠券
+			openType: {
+				type: Number,
+				default: 0,
+			},
+			coupon: {
+				type: Object,
+				default: function() {
+					return {};
+				}
+			}
+		},
+		data() {
+			return {
+				imgHost: HTTP_REQUEST_URL,
+				type: 0
+			};
+		},
+		methods: {
+			close: function() {
+				this.$emit('ChangCouponsClone');
+				this.type = 0;
+			},
+			getCouponUser: function(index, id) {
+				let that = this;
+				let list = that.coupon.list;
+				if (list[index].is_use >= list[index].receive_limit && this.openType == 0) return true;
+				switch (this.openType) {
+					case 0:
+						//领取优惠券
+						setCouponReceive(id).then(res => {
+							that.$emit('ChangCouponsUseState', index);
+							that.$util.Tips({
+								title: "领取成功"
+							});
+							// that.$emit('ChangCoupons', list[index]);
+						}).catch(err => {
+							uni.showToast({
+								title: err,
+								icon: 'none'
+							});
+						})
+						break;
+					case 1:
+						that.$emit('ChangCoupons', index);
+						break;
+				}
+			},
+			setType: function(type) {
+				this.type = type;
+				this.$emit('tabCouponType', type);
+			}
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+	.orderCou {
+		position: absolute;
+		right: 20rpx;
+		top: 50%;
+		margin-top: -20rpx;
+	}
+
+	.orderCou .iconfont {
+		font-size: 40rpx;
+	}
+
+	.orderCou .svip {
+		color: #EDBB75;
+	}
+
+	.coupon-list .item .text {
+		position: relative;
+	}
+
+	.coupon-list .item .text .condition.order {
+		width: 350rpx;
+	}
+
+	.coupon-list-window .coupon-list .text .condition .pic {
+		width: 30rpx;
+		height: 30rpx;
+		margin-right: 10rpx;
+		vertical-align: middle;
+	}
+
+	.coupon-list-window .coupon-list .text .condition .name {
+		vertical-align: middle;
+		font-size: 26rpx;
+		font-weight: 500;
+	}
+
+	.coupon-list-window {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		width: 100%;
+		background-color: #FFFFFF;
+		border-radius: 16rpx 16rpx 0 0;
+		z-index: 999;
+		transform: translate3d(0, 100%, 0);
+		transition: all .3s cubic-bezier(.25, .5, .5, .9);
+	}
+
+	.coupon-list-window.on {
+		transform: translate3d(0, 0, 0);
+	}
+
+	.coupon-list-window .title {
+		height: 124rpx;
+		width: 100%;
+		text-align: center;
+		line-height: 124rpx;
+		font-size: 32rpx;
+		font-weight: bold;
+		position: relative;
+	}
+
+	.coupon-list-window .title .iconfont {
+		position: absolute;
+		right: 30rpx;
+		top: 50%;
+		transform: translateY(-50%);
+		font-size: 35rpx;
+		color: #8a8a8a;
+		font-weight: normal;
+	}
+
+	.coupon-list-window .coupon-list {
+		margin: 0 0 50rpx 0;
+		height: 721rpx;
+		padding-top: 28rpx;
+		overflow: auto;
+	}
+
+	.coupon-list-window .pictrue {
+		width: 414rpx;
+		height: 336rpx;
+		margin: 192rpx auto 243rpx auto;
+	}
+
+	.coupon-list-window .pictrue image {
+		width: 100%;
+		height: 100%;
+	}
+
+	.pic-num {
+		color: #fff;
+		font-size: 24rpx;
+	}
+
+	.line-title {
+		width: 70rpx;
+		height: 32rpx !important;
+		padding: 0 10rpx;
+		line-height: 30rpx;
+		text-align: center;
+		background: var(--view-minorColorT);
+		border: 1px solid var(--view-theme);
+		opacity: 1;
+		border-radius: 20rpx;
+		font-size: 18rpx;
+		color: var(--view-theme);
+		margin-right: 12rpx;
+		box-sizing: border-box;
+	}
+
+	.line-title.gray {
+		border-color: #C1C1C1 !important;
+		color: #C1C1C1 !important;
+		background-color: #F7F7F7 !important;
+	}
+
+	.nav {
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 106rpx;
+		border-bottom: 2rpx solid #F5F5F5;
+		border-top-left-radius: 16rpx;
+		border-top-right-radius: 16rpx;
+		background-color: #FFFFFF;
+		font-size: 30rpx;
+		color: #999999;
+	}
+
+	.nav .acea-row {
+		border-top: 5rpx solid transparent;
+		border-bottom: 5rpx solid transparent;
+	}
+
+	.nav .acea-row.on {
+		border-bottom-color: var(--view-theme);
+		color: #282828;
+	}
+
+	.nav .acea-row:only-child {
+		border-bottom-color: transparent;
+	}
+
+	.occupy {
+		height: 106rpx;
+	}
+
+	.coupon-list .item {
+		margin-bottom: 18rpx;
+		box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.06);
+	}
+
+	.coupon-list .item .money {
+		font-weight: normal;
+	}
 </style>

+ 226 - 0
template/uni-app/components/easy-loadimage/easy-loadimage.vue

@@ -0,0 +1,226 @@
+<template>
+	<view class="easy-loadimage" :id="uid">
+		<image class="origin-img" :src="imageSrc" mode="aspectFill" v-if="loadImg&&!isLoadError" v-show="showImg"
+			:class="{'no-transition':!openTransition,'show-transition':showTransition&&openTransition}"
+			@load="handleImgLoad" @error="handleImgError">
+		</image>
+		<view class="loadfail-img" v-else-if="isLoadError"></view>
+		<view :class="['loading-img','spin-circle',loadingMode]" v-show="!showImg&&!isLoadError"></view>
+	</view>
+</template>
+<script>
+	import {
+		throttle
+	} from '@/libs/uniApi';
+
+	// 生成全局唯一id
+	function generateUUID() {
+		return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+			let r = Math.random() * 16 | 0,
+				v = c == 'x' ? r : (r & 0x3 | 0x8);
+			return v.toString(16);
+		})
+	}
+	export default {
+		props: {
+			imageSrc: {
+				type: String,
+				default: ""
+			},
+			mode: {
+				type: String,
+				default: ""
+			},
+			loadingMode: {
+				type: String,
+				default: 'looming-gray'
+			},
+			openTransition: {
+				type: Boolean,
+				default: true,
+			},
+			viewHeight: {
+				type: Number,
+				default () {
+					return uni.getSystemInfoSync().windowHeight;
+				}
+			}
+		},
+		data() {
+			const that = this;
+			return {
+				// uid:'',
+				uid: 'uid-' + generateUUID(),
+				loadImg: false,
+				showImg: false,
+				isLoadError: false,
+				showTransition: false,
+				scrollFn: throttle(function() {
+					// 加载img时才执行滚动监听判断是否可加载
+					if (that.loadImg || that.isLoadError) return;
+					const id = that.uid
+					const query = uni.createSelectorQuery().in(that);
+					query.select('#' + id).boundingClientRect(data => {
+						if (!data) return;
+						if (data.top - that.viewHeight < 0) {
+							that.loadImg = !!that.imageSrc;
+							that.isLoadError = !that.loadImg;
+						}
+					}).exec()
+				}, 200)
+			}
+		},
+		methods: {
+			init() {
+				this.$nextTick(this.onScroll)
+			},
+			handleImgLoad(e) {
+				// console.log('success');
+				this.showImg = true;
+				// this.$nextTick(function(){
+				//     this.showTransition = true
+				// })
+				setTimeout(() => {
+					this.showTransition = true
+				}, 50)
+			},
+			handleImgError(e) {
+				// console.log('fail');
+				this.isLoadError = true;
+			},
+			onScroll() {
+				this.scrollFn();
+			},
+		},
+		mounted() {
+			this.init()
+			uni.$on('scroll', this.scrollFn);
+			this.onScroll()
+		},
+		beforeDestroy() {
+			uni.$off('scroll', this.scrollFn);
+		}
+	}
+</script>
+
+<style scoped>
+	.easy-loadimage {
+		position: relative;
+
+	}
+
+	.border-img {
+		position: absolute;
+		width: 100%;
+		height: 100%;
+		max-height: 360rpx;
+		top: 0;
+		left: 0;
+	}
+
+	/* 官方优化图片tips */
+	image {
+		will-change: transform
+	}
+
+	/* 渐变过渡效果处理 */
+	image.origin-img {
+		width: 100%;
+		height: 100%;
+		opacity: 0.3;
+		max-height: 360rpx;
+	}
+
+	image.origin-img.show-transition {
+		transition: opacity .5s;
+		opacity: 1;
+	}
+
+	image.origin-img.no-transition {
+		opacity: 1;
+	}
+
+	/* 渐变过渡效果处理 */
+	image.border-img {
+		width: 100%;
+		height: 100%;
+		opacity: 0.3;
+		max-height: 360rpx;
+	}
+
+	image.border-img.show-transition {
+		transition: opacity .5s;
+		opacity: 1;
+	}
+
+	image.border-img.no-transition {
+		opacity: 1;
+	}
+
+	/* 加载失败、加载中的占位图样式控制 */
+	.loadfail-img {
+		height: 100%;
+		background: url('~@/static/easy-loadimage/loadfail.png') no-repeat center;
+		background-size: 50%;
+	}
+
+	.loading-img {
+		height: 100%;
+	}
+
+	/* 转圈 */
+	.spin-circle {
+		background: url('~@/static/easy-loadimage/loading.gif') no-repeat center;
+		background-size: 60%;
+	}
+
+	/* 动态灰色若隐若现 */
+	.looming-gray {
+		animation: looming-gray 1s infinite linear;
+		background-color: #e3e3e3;
+	}
+
+	@keyframes looming-gray {
+		0% {
+			background-color: #e3e3e3aa;
+		}
+
+		50% {
+			background-color: #e3e3e3;
+		}
+
+		100% {
+			background-color: #e3e3e3aa;
+		}
+	}
+
+	/* 骨架屏1 */
+	.skeleton-1 {
+		background-color: #e3e3e3;
+		background-image: linear-gradient(100deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0) 80%);
+		background-size: 100rpx 100%;
+		background-repeat: repeat-y;
+		background-position: 0 0;
+		animation: skeleton-1 .6s infinite;
+	}
+
+	@keyframes skeleton-1 {
+		to {
+			background-position: 200% 0;
+		}
+	}
+
+	/* 骨架屏2 */
+	.skeleton-2 {
+		background-image: linear-gradient(-90deg, #fefefe 0%, #e6e6e6 50%, #fefefe 100%);
+		background-size: 400% 400%;
+		background-position: 0 0;
+		animation: skeleton-2 1.2s ease-in-out infinite;
+	}
+
+	@keyframes skeleton-2 {
+		to {
+			background-position: -135% 0;
+		}
+	}
+</style>

+ 314 - 0
template/uni-app/components/eidtUserModal/index.vue

@@ -0,0 +1,314 @@
+<template>
+	<view :style="colorStyle">
+		<view class="product-window" :class="{'on':isShow}">
+			<view class="iconfont icon-guanbi" @click="closeAttr"></view>
+			<view class="mp-data">
+				<image :src="mpData.siteLogo" mode=""></image>
+				<text class="mp-name">{{mpData.siteName}} 申请</text>
+			</view>
+			<view class="trip-msg">
+				<view class="title">
+					{{$t(`获取您的昵称、头像`)}}
+				</view>
+				<view class="trip">
+					{{$t(`提供具有辨识度的用户中心界面`)}}
+				</view>
+			</view>
+			<form @submit="formSubmit">
+				<view class="edit">
+					<view class="avatar edit-box">
+						<view class="left">
+							<view class="head">{{$t(`头像`)}}</view>
+							<!-- <image :src="userInfo.avatar || defaultAvatar" mode=""></image> -->
+							<view class="avatar-box" v-if="!mp_is_new" @click.stop='uploadpic'>
+								<image :src="userInfo.avatar || defHead"></image>
+							</view>
+							<button v-else class="avatar-box" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
+								<image :src="userInfo.avatar || defHead"></image>
+							</button>
+						</view>
+						<!-- <view class="iconfont icon-xiangyou"></view> -->
+					</view>
+					<view class="nickname edit-box">
+						<view class="left">
+							<view class="head">{{$t(`昵称`)}}</view>
+							<view class='input'><input type='nickname' placeholder-class="pl-sty"
+									:placeholder="$t(`请输入昵称`)" name='nickname' :maxlength="16"
+									:value='userInfo.nickname'></input>
+							</view>
+						</view>
+						<!-- <view class="iconfont icon-xiangyou"></view> -->
+					</view>
+
+				</view>
+
+				<view class="bottom">
+					<button class="save" formType="submit" :class="{'open': userInfo.avatar}">
+						{{$t(`保存`)}}
+					</button>
+				</view>
+			</form>
+		</view>
+		<canvas canvas-id="canvas" v-if="canvasStatus"
+			:style="{width: canvasWidth + 'px', height: canvasHeight + 'px',position: 'absolute',left:'-100000px',top:'-100000px'}"></canvas>
+		<view class="mask" @touchmove.prevent v-if="isShow" @click="closeAttr"></view>
+	</view>
+	</uni-popup>
+
+</template>
+
+<script>
+	import colors from "@/mixins/color";
+	import Cache from '@/utils/cache';
+	import {
+		userEdit,
+	} from '@/api/user.js';
+	export default {
+		mixins: [colors],
+		props: {
+			isShow: {
+				type: Number,
+				value: 0
+			}
+		},
+		data() {
+			return {
+				defHead: require('@/static/images/def_avatar.png'),
+				mp_is_new: this.$Cache.get('MP_VERSION_ISNEW') || false,
+				userInfo: {
+					avatar: '',
+					nickname: '',
+				},
+				mpData: uni.getStorageSync('copyRight'),
+				canvasStatus: false,
+			};
+		},
+		mounted() {
+
+		},
+		methods: {
+			/**
+			 * 上传文件
+			 * 
+			 */
+			uploadpic: function() {
+				let that = this;
+				this.canvasStatus = true
+				that.$util.uploadImageChange('upload/image', (res) => {
+					let userInfo = that.userInfo;
+					if (userInfo !== undefined) {
+						that.userInfo.avatar = res.data.url;
+					}
+					this.canvasStatus = false
+				}, (res) => {
+					this.canvasStatus = false
+				}, (res) => {
+					this.canvasWidth = res.w
+					this.canvasHeight = res.h
+				});
+			},
+			// 微信头像获取
+			onChooseAvatar(e) {
+				const {
+					avatarUrl
+				} = e.detail
+				this.$util.uploadImgs('upload/image', avatarUrl, (res) => {
+					this.userInfo.avatar = res.data.url
+				}, (err) => {
+					console.log(err)
+				})
+			},
+			closeAttr: function() {
+				this.$emit('closeEdit');
+			},
+			/**
+			 * 提交修改
+			 */
+			formSubmit(e) {
+				console.log(e, 'eeeeee')
+				let that = this
+				if (!this.userInfo.avatar) return that.$util.Tips({
+					title: that.$t(`请上传头像`)
+				});
+				if (!e.detail.value.nickname) return that.$util.Tips({
+					title: that.$t(`请输入昵称`)
+				});
+				this.userInfo.nickname = e.detail.value.nickname
+				userEdit(this.userInfo).then(res => {
+					this.$emit('editSuccess')
+					return that.$util.Tips({
+						title: res.msg,
+						icon: 'success'
+					}, {
+						tab: 3
+					});
+				}).catch(msg => {
+					return that.$util.Tips({
+						title: msg || that.$t(`保存失败`)
+					}, {
+						tab: 3,
+						url: 1
+					});
+				});
+			}
+		}
+	}
+</script>
+<style>
+	.pl-sty {
+		color: #999999;
+		font-size: 30rpx;
+	}
+</style>
+<style scoped lang="scss">
+	.product-window.on {
+		transform: translate3d(0, 0, 0);
+	}
+
+	.mask {
+		z-index: 99;
+	}
+
+	.product-window {
+		position: fixed;
+		bottom: 0;
+		width: 100%;
+		left: 0;
+		background-color: #fff;
+		z-index: 1000;
+		border-radius: 20rpx 20rpx 0 0;
+		transform: translate3d(0, 100%, 0);
+		transition: all .3s cubic-bezier(.25, .5, .5, .9);
+		padding: 38rpx 40rpx;
+		padding-bottom: 80rpx;
+		padding-bottom: calc(80rpx+ constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
+		padding-bottom: calc(80rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
+
+		.icon-guanbi {
+			position: absolute;
+			top: 40rpx;
+			right: 40rpx;
+			font-size: 24rpx;
+			font-weight: bold;
+			color: #999;
+		}
+
+		.mp-data {
+			display: flex;
+			align-items: center;
+			margin-bottom: 30rpx;
+
+			.mp-name {
+				font-size: 28rpx;
+				font-weight: bold;
+				color: #000000;
+			}
+
+			image {
+				width: 48rpx;
+				height: 48rpx;
+				border-radius: 50%;
+				margin-right: 16rpx;
+			}
+		}
+
+		.trip-msg {
+			padding-bottom: 32rpx;
+			border-bottom: 1px solid #F5F5F5;
+
+			.title {
+				font-size: 30rpx;
+				font-weight: bold;
+				color: #000;
+				margin-bottom: 6rpx;
+			}
+
+			.trip {
+				font-size: 26rpx;
+				color: #777777;
+			}
+		}
+
+		.edit {
+			border-bottom: 1px solid #F5F5F5;
+
+			.avatar {
+				border-bottom: 1px solid #F5F5F5;
+			}
+
+			.nickname {
+				.input {
+					width: 100%;
+
+				}
+
+				input {
+					height: 80rpx;
+				}
+			}
+
+			.edit-box {
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				font-size: 30rpx;
+				padding: 22rpx 0;
+
+				.left {
+					display: flex;
+					align-items: center;
+					flex: 1;
+
+					.head {
+						color: rgba(0, 0, 0, 0.9);
+						white-space: nowrap;
+						margin-right: 60rpx;
+					}
+
+					button {
+						flex: 1;
+						display: flex;
+						align-items: center;
+					}
+				}
+
+				image {
+					width: 80rpx;
+					height: 80rpx;
+					border-radius: 6rpx;
+				}
+			}
+
+			.icon-xiangyou {
+				color: #cfcfcf;
+			}
+		}
+
+		.bottom {
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+			.save {
+				border: 1px solid #F5F5F5;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				width: 368rpx;
+				height: 80rpx;
+				border-radius: 12rpx;
+				margin-top: 52rpx;
+				background-color: #F5F5F5;
+				color: #ccc;
+				font-size: 30rpx;
+				font-weight: bold;
+			}
+
+			.save.open {
+				border: 1px solid #fff;
+				background-color: #07C160;
+				color: #fff;
+			}
+		}
+	}
+</style>

+ 154 - 150
template/uni-app/components/guide/index.vue

@@ -1,152 +1,156 @@
-<template>
-	<view class="content">
-		<swiper class="swiper" :autoplay="autoplay" indicator-dots="true" indicator-color="rgba(255,255,255,0.6)" :duration="duration"
-			v-if="advData.type == 'pic' && advData.value.length">
-			<swiper-item v-for="(item,index) in advData.value" :key="index" @click="jump(item.link)">
-				<view class="swiper-item">
-					<view class="swiper-item-img">
-						<image :src="item.img" mode="scaleToFill"></image>
-					</view>
-				</view>
-			</swiper-item>
-		</swiper>
-		<view class="video-box" v-else-if="advData.type == 'video' && advData.video_link">
-			<video class="vid" :src="advData.video_link" :autoplay="true" :loop="true" :muted="true"
-				:controls="false"></video>
-		</view>
-		<view class="jump-over" @click.stop="launchFlag()">{{$t(`跳过`)}}<text v-if="closeType == 1">{{times}}</text></view>
-	</view>
-</template>
-
-<script>
-	export default {
-		data() {
-			return {
-				autoplay: false,
-				duration: 500,
-				jumpover: this.$t(`跳过`),
-				experience: this.$t(`立即体验`),
-				timecount: undefined,
-				times: 0
-			}
+<template>
+	<view class="content">
+		<swiper class="swiper" :autoplay="autoplay" indicator-dots="true" indicator-color="rgba(255,255,255,0.6)"
+			:duration="duration" v-if="advData.type == 'pic' && advData.value.length">
+			<swiper-item v-for="(item,index) in advData.value" :key="index" @click="jump(item.link)">
+				<view class="swiper-item">
+					<view class="swiper-item-img">
+						<image :src="item.img" mode="scaleToFill"></image>
+					</view>
+				</view>
+			</swiper-item>
+		</swiper>
+		<view class="video-box" v-else-if="advData.type == 'video' && advData.video_link">
+			<video class="vid" :src="advData.video_link" :autoplay="true" :loop="true" :muted="true"
+				:controls="false"></video>
+		</view>
+		<view class="jump-over" @click.stop="launchFlag()">{{$t(`跳过`)}}<text v-if="closeType == 1">{{times}}</text>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				autoplay: false,
+				duration: 500,
+				jumpover: this.$t(`跳过`),
+				experience: this.$t(`立即体验`),
+				timecount: undefined,
+				times: 0
+			}
+		},
+		props: {
+			advData: {
+				type: Object,
+				default: () => {}
+			},
+			// 1 倒计时 2 手动关闭(预留)
+			closeType: {
+				type: Number,
+				default: 1
+			},
+		},
+		mounted() {
+			this.timer()
 		},
-		props: {
-			advData: {
-				type: Object,
-				default: () => {}
-			},
-			// 1 倒计时 2 手动关闭(预留)
-			closeType: {
-				type: Number,
-				default: 1
-			},
-		},
-		mounted() {
-			this.timer()
-		},
-		methods: {
-			timer() {
-				this.times = this.advData.time
-				let t = this.advData.time || 5
-				this.timecount = setInterval(() => {
-					t--
-					this.times = t
-					if (t <= 0) {
-						clearInterval(this.timecount)
-						this.launchFlag()
-					}
-				}, 1000)
-			},
-			launchFlag() {
-				clearInterval(this.timecount)
-				uni.switchTab({
-					url: '/pages/index/index'
-				});
-			},
-			jump(url) {
-				if (url) {
-					if (url.indexOf("http") != -1) {
-						uni.navigateTo({
-							url: `/pages/annex/web_view/index?url=${url}`
-						});
-					} else {
-						uni.navigateTo({
-							url: url,
-							fail: () => {
-								uni.switchTab({
-									url
-								})
-							}
-						})
-					}
-					clearInterval(this.timecount)
-				}
-
-			},
-		}
-	}
-</script>
-<style lang="scss" scoped>
-	page,
-	.content {
-		width: 100%;
-		height: 100%;
-		background-size: 100% auto;
-		padding: 0;
-	}
-
-	.swiper {
-		width: 100%;
-		height: 100vh;
-		background: #FFFFFF;
-	}
-
-	.swiper-item {
-		width: 100%;
-		height: 100%;
-		text-align: center;
-		position: relative;
-		display: flex;
-		/* justify-content: center; */
-		align-items: flex-end;
-		flex-direction: column-reverse
-	}
-
-	.swiper-item-img {
-		width: 100%;
-		height: 100vh;
-		margin: 0 auto;
-	}
-
-	.swiper-item-img image {
-		width: 100%;
-		height: 100%;
-	}
-
-	.jump-over {
-		position: absolute;
-		height: 45rpx;
-		line-height: 45rpx;
-		padding: 0 15rpx;
-		border-radius: 30rpx;
-		font-size: 24rpx;
-		color: #b09e9a;
-		border: 1px solid #b09e9a;
-		z-index: 999;
-	}
-
-	.jump-over {
-		right: 30rpx;
-		top: 80rpx;
-	}
-
-	.video-box {
-		width: 100vw;
-		height: 100vh;
-
-		.vid {
-			width: 100%;
-			height: 100%;
-		}
-	}
+		onHide() {
+			clearInterval(this.timecount)
+		},
+		methods: {
+			timer() {
+				this.times = this.advData.time
+				let t = this.advData.time || 5
+				this.timecount = setInterval(() => {
+					t--
+					this.times = t
+					if (t <= 0) {
+						clearInterval(this.timecount)
+						this.launchFlag()
+					}
+				}, 1000)
+			},
+			launchFlag() {
+				clearInterval(this.timecount)
+				uni.switchTab({
+					url: '/pages/index/index'
+				});
+			},
+			jump(url) {
+				if (url) {
+					clearInterval(this.timecount)
+					if (url.indexOf("http") != -1) {
+						uni.navigateTo({
+							url: `/pages/annex/web_view/index?url=${url}`
+						});
+					} else {
+						uni.reLaunch({
+							url: url,
+							fail: () => {
+								uni.switchTab({
+									url
+								})
+							}
+						})
+					}
+				}
+
+			},
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	page,
+	.content {
+		width: 100%;
+		height: 100%;
+		background-size: 100% auto;
+		padding: 0;
+	}
+
+	.swiper {
+		width: 100%;
+		height: 100vh;
+		background: #FFFFFF;
+	}
+
+	.swiper-item {
+		width: 100%;
+		height: 100%;
+		text-align: center;
+		position: relative;
+		display: flex;
+		/* justify-content: center; */
+		align-items: flex-end;
+		flex-direction: column-reverse
+	}
+
+	.swiper-item-img {
+		width: 100%;
+		height: 100vh;
+		margin: 0 auto;
+	}
+
+	.swiper-item-img image {
+		width: 100%;
+		height: 100%;
+	}
+
+	.jump-over {
+		position: absolute;
+		height: 45rpx;
+		line-height: 45rpx;
+		padding: 0 15rpx;
+		border-radius: 30rpx;
+		font-size: 24rpx;
+		color: #b09e9a;
+		border: 1px solid #b09e9a;
+		z-index: 999;
+	}
+
+	.jump-over {
+		right: 30rpx;
+		top: 80rpx;
+	}
+
+	.video-box {
+		width: 100vw;
+		height: 100vh;
+
+		.vid {
+			width: 100%;
+			height: 100%;
+		}
+	}
 </style>

+ 2 - 0
template/uni-app/components/home/index.vue

@@ -99,6 +99,8 @@
 		justify-content: center;
 		align-items: center;
 		background: var(--view-theme) !important;
+		opacity: 0.8;
+		backdrop-filter: blur(10px);
 	}
 
 	.home .homeCon .iconfont {

+ 188 - 184
template/uni-app/components/indexGoods/index.vue

@@ -1,185 +1,189 @@
-<template>
-	<view>
-		<view class="list">
-			<view class="product-box">
-				<view class="product-list" v-for="(item, i1) in tmp_data" :key="i1" @click="goGoodsDetail(item)">
-					<view class="product-item">
-						<image :src="item.image" mode="scaleToFill" fade-show style="width: 100%;"></image>
-						<view class="info">
-							<view class="title line2">
-								<text class="tag" v-if="item.activity && item.activity.type === '1'">{{$t(`秒杀`)}}</text>
-								<text class="tag" v-if="item.activity && item.activity.type === '2'">{{$t(`砍价`)}}</text>
-								<text class="tag" v-if="item.activity && item.activity.type === '3'">{{$t(`拼团`)}}</text>
-								<text class="tag" v-if="item.checkCoupon">{{$t(`券`)}}</text>
-								{{ item.store_name }}
-							</view>
-
-							<view class="price-box">
-								<view>
-									<text>{{$t(`¥`)}}</text>
-									{{ item.price }}
-								</view>
-								<view class="sales">
-									{{$t(`已售`)}} {{item.sales}}
-								</view>
-							</view>
-						</view>
-					</view>
-				</view>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	import {
-		goShopDetail,
-		goPage
-	} from '@/libs/order.js'
-	export default {
-		name: 'goodsWaterfall',
-		props: {
-			dataLists: {
-				default: []
-			}
-		},
-		data() {
-			return {
-				lists: [],
-				showLoad: false,
-				tmp_data: []
-			};
-		},
-		methods: {
-			goGoodsDetail(item) {
-				goPage().then(res => {
-					goShopDetail(item, this.uid).then(res => {
-						uni.navigateTo({
-							url: `/pages/goods_details/index?id=${item.id}`
-						})
-					})
-				})
-			},
-		},
-		mounted() {
-			const that = this
-			that.tmp_data = that.dataLists
-			// that.showLoadFlag()
-		},
-		watch: {
-			dataLists() {
-				this.loaded = []
-				this.loadErr = []
-				this.tmp_data = this.dataLists
-			},
-		}
-	};
-</script>
-
-<style lang="scss" scoped>
-	.list {
-		display: flex;
-		margin: 0 30rpx;
-	}
-
-	.product-box {
-		display: flex;
-		flex: 1;
-		flex-wrap: wrap;
-		width: 100%;
-	}
-
-	.flow_item {
-		margin: 15upx;
-		border-radius: 20upx;
-		background: #f4f4f4;
-		overflow: hidden;
-	}
-
-	.flow_item_con {
-		padding: 10upx 20upx 20upx;
-	}
-
-	.flow_item_title {
-		position: relative;
-		font-size: 32upx;
-		font-weight: 700;
-		margin-bottom: 5upx;
-	}
-
-	.flow_item_des {
-		font-size: 24upx;
-	}
-
-	.pl10 {
-		padding-left: 10rpx;
-	}
-
-	.product-list {
-		display: flex;
-		width: calc(50% - 16rpx);
-		margin: 2rpx 8rpx;
-
-		.product-item {
-			position: relative;
-			width: 100%;
-			background: #fff;
-			border-radius: 10rpx;
-			margin-bottom: 8rpx;
-			display: flex;
-			flex-direction: column;
-			justify-content: space-between;
-
-			image {
-				width: 100%;
-				height: 330rpx;
-				border-radius: 10rpx 10rpx 0 0;
-			}
-
-			.info {
-				flex: 1;
-				padding: 14rpx 16rpx;
-				display: flex;
-				flex-direction: column;
-				justify-content: space-between;
-
-				.title {
-					font-size: 28rpx;
-					height: 76rpx;
-				}
-
-				.tag {
-					border-radius: 4rpx;
-					border: 1px solid var(--view-theme);
-					color: var(--view-theme);
-					font-size: 20rpx;
-					padding: 0rpx 4rpx;
-					margin: 10rpx 0;
-					margin-right: 10rpx;
-					width: max-content;
-				}
-
-				.price-box {
-					font-size: 34rpx;
-					font-weight: 700;
-					margin-top: 8px;
-					color: var(--view-priceColor);
-					display: flex;
-					justify-content: space-between;
-					// align-items: flex-end;
-					align-items: center;
-
-					text {
-						font-size: 28rpx;
-					}
-
-					.sales {
-						color: #999999;
-						font-size: 24rpx;
-						font-weight: 400;
-					}
-				}
-			}
-		}
-	}
+<template>
+	<view>
+		<view class="list">
+			<view class="product-box">
+				<view class="product-list" v-for="(item, i1) in tmp_data" :key="i1" @click="goGoodsDetail(item)">
+					<view class="product-item">
+						<!-- <image :src="item.image" mode="scaleToFill" fade-show style="width: 100%;"></image> -->
+						<easy-loadimage mode="widthFix" :image-src="item.image"></easy-loadimage>
+						<view class="info">
+							<view class="title line2">
+								<text class="tag" v-if="item.activity && item.activity.type === '1'">{{$t(`秒杀`)}}</text>
+								<text class="tag" v-if="item.activity && item.activity.type === '2'">{{$t(`砍价`)}}</text>
+								<text class="tag" v-if="item.activity && item.activity.type === '3'">{{$t(`拼团`)}}</text>
+								<text class="tag" v-if="item.checkCoupon">{{$t(`券`)}}</text>
+								{{ item.store_name }}
+							</view>
+
+							<view class="price-box">
+								<view>
+									<text>{{$t(`¥`)}}</text>
+									{{ item.price }}
+								</view>
+								<view class="sales">
+									{{$t(`已售`)}} {{item.sales}}
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		goShopDetail,
+		goPage
+	} from '@/libs/order.js'
+	export default {
+		name: 'goodsWaterfall',
+		props: {
+			dataLists: {
+				default: []
+			}
+		},
+		data() {
+			return {
+				lists: [],
+				showLoad: false,
+				tmp_data: []
+			};
+		},
+		methods: {
+			goGoodsDetail(item) {
+				goPage().then(res => {
+					goShopDetail(item, this.uid).then(res => {
+						uni.navigateTo({
+							url: `/pages/goods_details/index?id=${item.id}`
+						})
+					})
+				})
+			},
+		},
+		mounted() {
+			const that = this
+			that.tmp_data = that.dataLists
+			// that.showLoadFlag()
+		},
+		watch: {
+			dataLists() {
+				this.loaded = []
+				this.loadErr = []
+				this.tmp_data = this.dataLists
+			},
+		},
+	};
+</script>
+
+<style lang="scss" scoped>
+	.list {
+		display: flex;
+		margin: 0 30rpx;
+	}
+
+	.product-box {
+		display: flex;
+		flex: 1;
+		flex-wrap: wrap;
+		width: 100%;
+	}
+
+	.flow_item {
+		margin: 15upx;
+		border-radius: 20upx;
+		background: #f4f4f4;
+		overflow: hidden;
+	}
+
+	.flow_item_con {
+		padding: 10upx 20upx 20upx;
+	}
+
+	.flow_item_title {
+		position: relative;
+		font-size: 32upx;
+		font-weight: 700;
+		margin-bottom: 5upx;
+	}
+
+	.flow_item_des {
+		font-size: 24upx;
+	}
+
+	.pl10 {
+		padding-left: 10rpx;
+	}
+
+	.product-list {
+		display: flex;
+		width: calc(50% - 16rpx);
+		margin: 2rpx 8rpx;
+
+		.product-item {
+			position: relative;
+			width: 100%;
+			background: #fff;
+			border-radius: 10rpx;
+			margin-bottom: 8rpx;
+			display: flex;
+			flex-direction: column;
+			justify-content: space-between;
+
+			/deep/,
+			/deep/image,
+			/deep/.easy-loadimage,
+			/deep/uni-image {
+				width: 100%;
+				height: 330rpx;
+				border-radius: 10rpx 10rpx 0 0;
+			}
+
+			.info {
+				flex: 1;
+				padding: 14rpx 16rpx;
+				display: flex;
+				flex-direction: column;
+				justify-content: space-between;
+
+				.title {
+					font-size: 28rpx;
+					height: 76rpx;
+				}
+
+				.tag {
+					border-radius: 4rpx;
+					border: 1px solid var(--view-theme);
+					color: var(--view-theme);
+					font-size: 20rpx;
+					padding: 0rpx 4rpx;
+					margin: 10rpx 0;
+					margin-right: 10rpx;
+					width: max-content;
+				}
+
+				.price-box {
+					font-size: 34rpx;
+					font-weight: 700;
+					margin-top: 8px;
+					color: var(--view-priceColor);
+					display: flex;
+					justify-content: space-between;
+					// align-items: flex-end;
+					align-items: center;
+
+					text {
+						font-size: 28rpx;
+					}
+
+					.sales {
+						color: #999999;
+						font-size: 24rpx;
+						font-weight: 400;
+					}
+				}
+			}
+		}
+	}
 </style>

+ 83 - 82
template/uni-app/components/kefuIcon/index.vue

@@ -1,83 +1,84 @@
-<template>
-	<!-- #ifdef APP-PLUS || H5 -->
-	<text class="acea-row row-center-wrapper cartf iconfont icon-kefu3" :style="{ top: top + 'px'}" @click="goCustomer"
-		@touchmove.stop.prevent="setTouchMove"></text>
-	<!-- #endif -->
-	<!-- #ifdef MP -->
-	<view v-if="routineContact == 0" class="acea-row row-center-wrapper cartf iconfont icon-kefu3"
-		:style="{ top: top + 'px'}" @touchmove.stop.prevent="setTouchMove" @click="goCustomer"></view>
-	<button class="acea-row row-center-wrapper cartf iconfont icon-kefu3" open-type='contact'
-		:style="{ top: top + 'px'}" @touchmove.stop.prevent="setTouchMove"
-		v-else-if="routineContact==1 && !goodsCon"></button>
-	<button class="acea-row row-center-wrapper cartf iconfont icon-kefu3" open-type='contact'
-		:send-message-title="storeInfo.store_name" :send-message-img="storeInfo.image"
-		:send-message-path="`/pages/goods_details/index?id=${storeInfo.id}`" show-message-card
-		:style="{ top: top + 'px'}" @touchmove.stop.prevent="setTouchMove"
-		v-else-if="routineContact==1 && goodsCon"></button>
-	<!-- #endif -->
-</template>
-
-<script>
-	import {
-		getCustomer
-	} from '@/utils/index.js'
-	let app = getApp();
-	export default {
-		name: "kefuIcon",
-		props: {
-			ids: {
-				type: Number,
-				default: 0
-			},
-			routineContact: {
-				type: Number,
-				default: 0
-			},
-			storeInfo: {
-				type: Object,
-				default: () => {}
-			},
-			goodsCon: {
-				type: Number,
-				default: 0
-			}
-		},
-		data: function() {
-			return {
-				top: "480"
-			};
-		},
-		mounted() {
-			// #ifdef H5
-			this.top = parseFloat(window.innerHeight) - 200
-			// #endif
-		},
-		methods: {
-			goCustomer() {
-				getCustomer(`/pages/extension/customer_list/chat?productId=${this.ids}`)
-			},
-			setTouchMove(e) {
-				let that = this;
-				if (e.touches[0].clientY < 480 && e.touches[0].clientY > 66) {
-					that.top = e.touches[0].clientY
-				}
-			}
-		},
-		created() {}
-	};
-</script>
-
-<style lang="scss">
-	.cartf {
-		width: 96rpx;
-		height: 96rpx;
-		background: #FFFFFF;
-		box-shadow: 0 3rpx 16rpx rgba(0, 0, 0, 0.08);
-		border-radius: 50%;
-		font-size: 47rpx;
-		color: #666;
-		position: fixed;
-		right: 15rpx;
-		z-index: 9;
-	}
+<template>
+	<!-- #ifdef APP-PLUS || H5 -->
+	<text class="acea-row row-center-wrapper cartf iconfont icon-kefu3" :style="{ top: top + 'px'}" @click="goCustomer"
+		@touchmove.stop.prevent="setTouchMove"></text>
+	<!-- #endif -->
+	<!-- #ifdef MP -->
+	<view v-if="routineContact == 0" class="acea-row row-center-wrapper cartf iconfont icon-kefu3"
+		:style="{ top: top + 'px'}" @touchmove.stop.prevent="setTouchMove" @click="goCustomer"></view>
+	<button class="acea-row row-center-wrapper cartf iconfont icon-kefu3" open-type='contact'
+		:style="{ top: top + 'px'}" @touchmove.stop.prevent="setTouchMove"
+		v-else-if="routineContact==1 && !goodsCon"></button>
+	<button class="acea-row row-center-wrapper cartf iconfont icon-kefu3" open-type='contact'
+		:send-message-title="storeInfo.store_name" :send-message-img="storeInfo.image"
+		:send-message-path="`/pages/goods_details/index?id=${storeInfo.id}`" show-message-card
+		:style="{ top: top + 'px'}" @touchmove.stop.prevent="setTouchMove"
+		v-else-if="routineContact==1 && goodsCon"></button>
+	<!-- #endif -->
+</template>
+
+<script>
+	import {
+		getCustomer
+	} from '@/utils/index.js'
+	let app = getApp();
+	export default {
+		name: "kefuIcon",
+		props: {
+			ids: {
+				type: Number,
+				default: 0
+			},
+			routineContact: {
+				type: Number,
+				default: 0
+			},
+			storeInfo: {
+				type: Object,
+				default: () => {}
+			},
+			goodsCon: {
+				type: Number,
+				default: 0
+			}
+		},
+		data: function() {
+			return {
+				top: "480"
+			};
+		},
+		mounted() {
+			// #ifdef H5
+			this.top = parseFloat(window.innerHeight) - 200
+			// #endif
+		},
+		methods: {
+			goCustomer() {
+				getCustomer(`/pages/extension/customer_list/chat?productId=${this.ids}`)
+			},
+			setTouchMove(e) {
+				let that = this;
+				if (e.touches[0].clientY < 480 && e.touches[0].clientY > 66) {
+					that.top = e.touches[0].clientY
+				}
+			}
+		},
+		created() {}
+	};
+</script>
+
+<style lang="scss">
+	.cartf {
+		width: 96rpx;
+		height: 96rpx;
+		background: rgba(255, 255, 255, 0.8);
+		box-shadow: 0 3rpx 16rpx rgba(0, 0, 0, 0.08);
+		backdrop-filter: blur(10px);
+		border-radius: 50%;
+		font-size: 47rpx;
+		color: #666;
+		position: fixed;
+		right: 15rpx;
+		z-index: 9;
+	}
 </style>

+ 64 - 24
template/uni-app/components/pageFooter/index.vue

@@ -1,10 +1,10 @@
 <template>
-	<view>
-		<view v-if="newData" class="page-footer" id="target">
+	<view v-if="newData">
+		<view class="page-footer" id="target">
 			<view class="foot-item" v-for="(item,index) in newData.menuList" :key="index" @click="goRouter(item)"
 				:style="{'background-color':newData.bgColor.color[0].item}">
-				<block v-if="item.link == activeRouter">
-					<image :src="item.imgList[0]"></image>
+				<block v-if="item.link == activityTab">
+					<image :src="item.imgList[0]" class="active"></image>
 					<view class="txt" :style="{color:newData.activeTxtColor.color[0].item}">{{item.name}}</view>
 				</block>
 				<block v-else>
@@ -17,6 +17,7 @@
 			</view>
 		</view>
 	</view>
+
 </template>
 
 <script>
@@ -44,16 +45,24 @@
 		},
 		data() {
 			return {
-				newData: undefined
+				newData: undefined,
+				footHeight: 0,
+				isShow: false // 弹出动画
 			}
 		},
 		computed: {
 			...mapState({
-				configData: state => state.app.pageFooter
-			})
+				configData: state => state.app.pageFooter,
+			}),
 		},
-		computed: mapGetters(['isLogin', 'cartNum']),
+		computed: mapGetters(['isLogin', 'cartNum', 'activityTab']),
 		watch: {
+			activityTab: {
+				handler(nVal, oVal) {
+					console.log(nVal, 'nval')
+				},
+				deep: true
+			},
 			configData: {
 				handler(nVal, oVal) {
 					let self = this
@@ -74,10 +83,7 @@
 		created() {
 			let routes = getCurrentPages(); // 获取当前打开过的页面路由数组
 			let curRoute = routes[routes.length - 1].route //获取当前页面路由
-			this.activeRouter = '/' + curRoute
-		},
-		onShow() {
-
+			this.$store.commit('ACTIVITYTAB', '/' + curRoute);
 		},
 		mounted() {
 			getNavigation().then(res => {
@@ -87,24 +93,18 @@
 			})
 			let that = this
 			uni.hideTabBar()
-			console.log(this.cartNum, 'cartNum')
 			this.newData = this.$store.state.app.pageFooter
 			if (this.isLogin) {
 				this.getCartNum()
 			}
 		},
-		data() {
-			return {
-				newData: {},
-				activeRouter: '/',
-				footHeight: 0
-			}
-		},
+
 		methods: {
 			goRouter(item) {
 				var pages = getCurrentPages();
-				var page = (pages[pages.length - 1]).$page.fullPath;
-				if (item.link == page) return
+				var page = pages[pages.length - 1].route;
+				this.$store.commit('ACTIVITYTAB', item.link);
+				if (item.link == '/' + page) return
 				uni.switchTab({
 					url: item.link,
 					fail(err) {
@@ -128,20 +128,26 @@
 <style lang="scss" scoped>
 	.page-footer {
 		position: fixed;
+		left: 0;
 		bottom: 0;
-		z-index: 30;
+		z-index: 999;
 		display: flex;
 		align-items: center;
 		justify-content: space-around;
+		flex-wrap: nowrap;
 		width: 100%;
+		height: 98rpx;
 		height: calc(98rpx+ constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
 		height: calc(98rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
 		box-sizing: border-box;
 		border-top: solid 1rpx #F3F3F3;
+		backdrop-filter: blur(10px);
 		background-color: #fff;
 		box-shadow: 0px 0px 17rpx 1rpx rgba(206, 206, 206, 0.32);
 		padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
 		padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
+		// transform: translate3d(0, 100%, 0);
+		// transition: all .3s cubic-bezier(.25, .5, .5, .9);
 
 		.foot-item {
 			display: flex;
@@ -153,6 +159,7 @@
 			width: 100%;
 			height: 100%;
 
+
 			.count-num {
 				position: absolute;
 				display: flex;
@@ -169,6 +176,39 @@
 				border-radius: 50%;
 				padding: 4rpx;
 			}
+
+			.active {
+				animation: mymove 1s 1;
+			}
+
+			@keyframes mymove {
+				0% {
+					transform: scale(1);
+					/*开始为原始大小*/
+				}
+
+				10% {
+					transform: scale(0.8);
+				}
+
+				30% {
+					transform: scale(1.1);
+					/*放大1.1倍*/
+				}
+
+				50% {
+					transform: scale(0.9);
+					/*放大1.1倍*/
+				}
+
+				70% {
+					transform: scale(1.05);
+				}
+
+				90% {
+					transform: scale(1);
+				}
+			}
 		}
 
 		.foot-item image {
@@ -182,7 +222,7 @@
 			font-size: 24rpx;
 
 
-			&.active {}
+
 		}
 	}
 </style>

+ 119 - 109
template/uni-app/components/promotionGood/index.vue

@@ -1,110 +1,120 @@
-<template>
-	<view class='promotionGood' :style="colorStyle">
-		<block v-for="(item,index) in benefit" :key="index">
-			<view class='item' @tap="goDetail(item)" hover-class="none">
-				<view class='pictrue'>
-					<image :src='item.image'></image>
-				</view>
-				<view class='money'>
-					<text class="rmb">{{$t(`¥`)}} </text><text class="price"> {{item.price}}</text>
-					<!-- <text class="ot-price">{{item.ot_price}}</text> -->
-				</view>
-			</view>
-		</block>
-	</view>
-</template>
-<script>
-	import {
-		mapGetters
-	} from "vuex";
-	import {
-		goPage,
-		goShopDetail
-	} from '@/libs/order.js'
-	import colors from "@/mixins/color";
-	export default {
-		computed: mapGetters(['uid']),
-		mixins: [colors],
-		props: {
-			benefit: {
-				type: Array,
-				default: function() {
-					return [];
-				}
-			}
-		},
-		data() {
-			return {
-
-			};
-		},
-		methods: {
-			goDetail(item) {
-				goPage().then(res => {
-					goShopDetail(item, this.uid).then(res => {
-						uni.navigateTo({
-							url: `/pages/goods_details/index?id=${item.id}`
-						})
-					})
-				})
-			}
-		}
-	}
-</script>
-
-<style scoped lang='scss'>
-	.promotionGood {
-		padding: 0 30rpx;
-		display: flex;
-		flex-wrap: wrap;
-		padding: 15rpx 24rpx;
-
-		.item {
-			width: 215rpx;
-			display: flex;
-			flex-direction: column;
-			justify-content: center;
-			padding: 9rpx;
-
-			.pictrue {
-				height: 198rpx;
-				border-radius: 12rpx;
-
-				image {
-					width: 100%;
-					height: 100%;
-					border-radius: 12rpx;
-				}
-
-			}
-
-			.money {
-				font-size: 30rpx;
-				color: var(--view-priceColor);
-				margin-top: 10rpx;
-				overflow: hidden; //超出的文本隐藏
-				text-overflow: ellipsis; //溢出用省略号显示
-				white-space: nowrap; //溢出不换行
-				margin: 0 auto;
-
-				.rmb {
-					font-weight: bold;
-					color: var(--view-priceColor);
-					font-size: 20rpx;
-					margin-right: 2rpx;
-				}
-
-				.price {
-					font-weight: bold;
-				}
-
-				.ot-price {
-					color: #999;
-					text-decoration: line-through;
-					font-size: 20rpx;
-					margin-left: 4rpx;
-				}
-			}
-		}
-	}
+<template>
+	<view class='promotionGood' :style="colorStyle">
+		<block v-for="(item,index) in benefit" :key="index">
+			<view class='item' @tap="goDetail(item)" hover-class="none">
+				<view class='pictrue'>
+					<easy-loadimage mode="widthFix" :image-src="item.image"></easy-loadimage>
+				</view>
+				<view class='money'>
+					<text class="rmb">{{$t(`¥`)}} </text><text class="price"> {{item.price}}</text>
+					<!-- <text class="ot-price">{{item.ot_price}}</text> -->
+				</view>
+			</view>
+		</block>
+	</view>
+</template>
+<script>
+	import {
+		mapGetters
+	} from "vuex";
+	import {
+		goPage,
+		goShopDetail
+	} from '@/libs/order.js'
+	import colors from "@/mixins/color";
+	export default {
+		computed: mapGetters(['uid']),
+		mixins: [colors],
+		props: {
+			benefit: {
+				type: Array,
+				default: function() {
+					return [];
+				}
+			}
+		},
+		data() {
+			return {
+
+			};
+		},
+		methods: {
+			goDetail(item) {
+				goPage().then(res => {
+					goShopDetail(item, this.uid).then(res => {
+						uni.navigateTo({
+							url: `/pages/goods_details/index?id=${item.id}`
+						})
+					})
+				})
+			}
+		}
+	}
+</script>
+
+<style scoped lang='scss'>
+	.promotionGood {
+		padding: 0 30rpx;
+		display: flex;
+		flex-wrap: wrap;
+		padding: 15rpx 24rpx;
+
+		.item {
+			width: 215rpx;
+			display: flex;
+			flex-direction: column;
+			justify-content: center;
+			padding: 9rpx;
+
+			.pictrue {
+				height: 198rpx;
+				border-radius: 12rpx;
+
+
+
+				/deep/,
+				/deep/image,
+				/deep/.easy-loadimage,
+				/deep/uni-image {
+					width: 100%;
+					height: 198rpx;
+					border-radius: 12rpx;
+				}
+
+				image {
+					width: 100%;
+					height: 100%;
+					border-radius: 12rpx;
+				}
+			}
+
+			.money {
+				font-size: 30rpx;
+				color: var(--view-priceColor);
+				margin-top: 10rpx;
+				overflow: hidden; //超出的文本隐藏
+				text-overflow: ellipsis; //溢出用省略号显示
+				white-space: nowrap; //溢出不换行
+				margin: 0 auto;
+
+				.rmb {
+					font-weight: bold;
+					color: var(--view-priceColor);
+					font-size: 20rpx;
+					margin-right: 2rpx;
+				}
+
+				.price {
+					font-weight: bold;
+				}
+
+				.ot-price {
+					color: #999;
+					text-decoration: line-through;
+					font-size: 20rpx;
+					margin-left: 4rpx;
+				}
+			}
+		}
+	}
 </style>

+ 134 - 117
template/uni-app/components/recommend/index.vue

@@ -1,118 +1,135 @@
-<template>
-	<view class='recommend' :style="colorStyle">
-		<view class='title acea-row row-center-wrapper'>
-			<text class='iconfont icon-zhuangshixian'></text>
-			<text class='name'>{{$t(`热门推荐`)}}</text>
-			<text class='iconfont icon-zhuangshixian lefticon'></text>
-		</view>
-		<view class='recommendList acea-row row-between-wrapper'>
-			<view class='item' v-for="(item,index) in hostProduct" :key="index" hover-class='none' @tap="goDetail(item)">
-				<view class='pictrue'>
-					<image :src='item.image'></image>
-					<span class="pictrue_log_big pictrue_log_class" v-if="item.activity && item.activity.type === '1'">{{$t(`秒杀`)}}</span>
-					<span class="pictrue_log_big pictrue_log_class" v-if="item.activity && item.activity.type === '2'">{{$t(`砍价`)}}</span>
-					<span class="pictrue_log_big pictrue_log_class" v-if="item.activity && item.activity.type === '3'">{{$t(`拼团`)}}</span>
-				</view>
-				<view class='name line1'>{{item.store_name}}</view>
-				<view class='money font-color'>{{$t(`¥`)}}<text class='num'>{{item.price}}</text></view>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	import {mapGetters} from "vuex";
-	import { goShopDetail } from '@/libs/order.js'
-	import colors from "@/mixins/color";
-	export default {
-	computed: mapGetters(['uid']),
-		props: {
-			hostProduct: {
-				type: Array,
-				default: function() {
-					return [];
-				}
-			}
-		},
-		mixins: [colors],
-		data() {
-			return {
-
-			};
-		},
-		methods: {
-			goDetail(item){
-				goShopDetail(item,this.uid).then(res=>{
-					uni.navigateTo({
-						url:`/pages/goods_details/index?id=${item.id}`
-					})
-				})
-			}
-		}
-	}
-</script>
-
-<style scoped lang="scss">
-	.recommend {
-		background-color: #fff;
-	}
-
-	.recommend .title {
-		height: 135rpx;
-		font-size: 28rpx;
-		color: #282828;
-	}
-
-	.recommend .title .name {
-		margin: 0 28rpx;
-	}
-
-	.recommend .title .iconfont {
-		font-size: 170rpx;
-		color: #454545;
-	}
-
-	.recommend .title .iconfont.lefticon {
-		transform: rotate(180deg);
-	}
-
-	.recommend .recommendList {
-		padding: 0 30rpx;
-	}
-
-	.recommend .recommendList .item {
-		width: 335rpx;
-		margin-bottom: 30rpx;
-		border-radius: 20rpx 20rpx 0 0;
-		box-shadow: 0rpx 3rpx 10rpx 2rpx rgba(0, 0, 0, 0.03);;
-	}
-
-	.recommend .recommendList .item .pictrue {
-		position: relative;
-		width: 100%;
-		height: 335rpx;
-	}
-
-	.recommend .recommendList .item .pictrue image {
-		width: 100%;
-		height: 100%;
-		border-radius: 20rpx;
-	}
-
-	.recommend .recommendList .item .name {
-		font-size: 28rpx;
-		color: #282828;
-		margin-top: 20rpx;
-		padding: 0 10rpx;
-	}
-
-	.recommend .recommendList .item .money {
-		font-size: 20rpx;
-		margin-top: 8rpx;
-		padding: 0 10rpx 10rpx 10rpx;
-	}
-
-	.recommend .recommendList .item .money .num {
-		font-size: 28rpx;
-	}
+<template>
+	<view class='recommend' :style="colorStyle">
+		<view class='title acea-row row-center-wrapper'>
+			<text class='iconfont icon-zhuangshixian'></text>
+			<text class='name'>{{$t(`热门推荐`)}}</text>
+			<text class='iconfont icon-zhuangshixian lefticon'></text>
+		</view>
+		<view class='recommendList acea-row row-between-wrapper'>
+			<view class='item' v-for="(item,index) in hostProduct" :key="index" hover-class='none'
+				@tap="goDetail(item)">
+				<view class='pictrue'>
+					<easy-loadimage mode="widthFix" :image-src="item.image"></easy-loadimage>
+					<span class="pictrue_log_big pictrue_log_class"
+						v-if="item.activity && item.activity.type === '1'">{{$t(`秒杀`)}}</span>
+					<span class="pictrue_log_big pictrue_log_class"
+						v-if="item.activity && item.activity.type === '2'">{{$t(`砍价`)}}</span>
+					<span class="pictrue_log_big pictrue_log_class"
+						v-if="item.activity && item.activity.type === '3'">{{$t(`拼团`)}}</span>
+				</view>
+				<view class='name line1'>{{item.store_name}}</view>
+				<view class='money font-color'>{{$t(`¥`)}}<text class='num'>{{item.price}}</text></view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		mapGetters
+	} from "vuex";
+	import {
+		goShopDetail
+	} from '@/libs/order.js'
+	import colors from "@/mixins/color";
+	export default {
+		computed: mapGetters(['uid']),
+		props: {
+			hostProduct: {
+				type: Array,
+				default: function() {
+					return [];
+				}
+			}
+		},
+		mixins: [colors],
+		data() {
+			return {
+
+			};
+		},
+		methods: {
+			goDetail(item) {
+				goShopDetail(item, this.uid).then(res => {
+					uni.navigateTo({
+						url: `/pages/goods_details/index?id=${item.id}`
+					})
+				})
+			}
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+	.recommend {
+		background-color: #fff;
+	}
+
+	.recommend .title {
+		height: 135rpx;
+		font-size: 28rpx;
+		color: #282828;
+	}
+
+	.recommend .title .name {
+		margin: 0 28rpx;
+	}
+
+	.recommend .title .iconfont {
+		font-size: 170rpx;
+		color: #454545;
+	}
+
+	.recommend .title .iconfont.lefticon {
+		transform: rotate(180deg);
+	}
+
+	.recommend .recommendList {
+		padding: 0 30rpx;
+	}
+
+	.recommend .recommendList .item {
+		width: 335rpx;
+		margin-bottom: 30rpx;
+		border-radius: 20rpx 20rpx 0 0;
+		box-shadow: 0rpx 3rpx 10rpx 2rpx rgba(0, 0, 0, 0.03);
+		;
+	}
+
+	.recommend .recommendList .item .pictrue {
+		position: relative;
+		width: 100%;
+		height: 335rpx;
+	}
+
+
+	.recommend .recommendList .item .pictrue {
+
+		/deep/,
+		/deep/image,
+		/deep/.easy-loadimage,
+		/deep/uni-image {
+
+			width: 100%;
+			height: 335rpx;
+			border-radius: 20rpx;
+		}
+	}
+
+	.recommend .recommendList .item .name {
+		font-size: 28rpx;
+		color: #282828;
+		margin-top: 20rpx;
+		padding: 0 10rpx;
+	}
+
+	.recommend .recommendList .item .money {
+		font-size: 20rpx;
+		margin-top: 8rpx;
+		padding: 0 10rpx 10rpx 10rpx;
+	}
+
+	.recommend .recommendList .item .money .num {
+		font-size: 28rpx;
+	}
 </style>

+ 0 - 11
template/uni-app/components/verify/utils/ase.js

@@ -1,11 +0,0 @@
-import CryptoJS from './crypto-js.js'
-/**
- * @word 要加密的内容
- * @keyWord String  服务器随机返回的关键字
- *  */
-export function aesEncrypt(word,keyWord="XwKsGlMcdPMEhR1B"){
-  var key = CryptoJS.enc.Utf8.parse(keyWord);
-  var srcs = CryptoJS.enc.Utf8.parse(word);
-  var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
-  return encrypted.toString();
-}

File diff suppressed because it is too large
+ 0 - 6191
template/uni-app/components/verify/utils/crypto-js.js


File diff suppressed because it is too large
+ 920 - 1198
template/uni-app/components/zb-code/qrcode.js


+ 32 - 32
template/uni-app/config/app.js

@@ -1,33 +1,33 @@
-module.exports = {
-	// 小程序配置
-	// #ifdef MP || APP-PLUS
-	// 请求域名 格式: https://您的域名
-	HTTP_REQUEST_URL: `https://demo.crmeb.com`,
-	// #endif
-	
-	// H5配置
-	// #ifdef H5
-	//H5接口是浏览器地址,非单独部署不用修改
-	HTTP_REQUEST_URL: window.location.protocol + "//" + window.location.host,
-	// #endif 
-
-	// 以下配置在不做二开的前提下,不需要做任何的修改
-	HEADER: {
-		'content-type': 'application/json',
-		//#ifdef H5
-		'Form-type': navigator.userAgent.toLowerCase().indexOf("micromessenger") !== -1 ? 'wechat' : 'h5',
-		//#endif
-		//#ifdef MP
-		'Form-type': 'routine',
-		//#endif
-		//#ifdef APP-VUE
-		'Form-type': 'app',
-		//#endif
-	},
-	// 回话密钥名称 请勿修改此配置
-	TOKENNAME: 'Authori-zation',
-	// 缓存时间 0 永久
-	EXPIRE: 0,
-	//分页最多显示条数
-	LIMIT: 10
+module.exports = {
+	// 小程序配置
+	// #ifdef MP || APP-PLUS
+	// 请求域名 格式: https://您的域名
+	HTTP_REQUEST_URL: `https://demo.crmeb.com`,
+	// #endif
+
+	// H5配置
+	// #ifdef H5
+	//H5接口是浏览器地址,非单独部署不用修改
+	HTTP_REQUEST_URL: window.location.protocol + "//" + window.location.host,
+	// #endif 
+
+	// 以下配置在不做二开的前提下,不需要做任何的修改
+	HEADER: {
+		'content-type': 'application/json',
+		//#ifdef H5
+		'Form-type': navigator.userAgent.toLowerCase().indexOf("micromessenger") !== -1 ? 'wechat' : 'h5',
+		//#endif
+		//#ifdef MP
+		'Form-type': 'routine',
+		//#endif
+		//#ifdef APP-VUE
+		'Form-type': 'app',
+		//#endif
+	},
+	// 回话密钥名称 请勿修改此配置
+	TOKENNAME: 'Authori-zation',
+	// 缓存时间 0 永久
+	EXPIRE: 0,
+	//分页最多显示条数
+	LIMIT: 10
 }

+ 352 - 0
template/uni-app/libs/uniApi.js

@@ -0,0 +1,352 @@
+
+export function navigateTo(type,url,opt){
+let toUrl=url;
+let api='navigateTo';
+toUrl=opt?toUrl+'?'+convertObj(opt):toUrl;
+switch(type){
+case 1:
+api='navigateTo';
+break;
+case 2:
+api='redirectTo';
+break;
+case 3:
+api='reLaunch';
+break;
+case 4:
+api='switchTab';
+break;
+default:
+api='navigateTo'
+break;
+}
+uni[api]({
+url:toUrl,
+animationType:'slide-in-right',
+animationDuration:200
+});
+}
+export function navigateBack(delta){
+uni.navigateBack({
+delta:delta
+});
+}
+export function setStorage(key,val){
+if(typeof val=='string'){
+uni.setStorageSync(key,val);
+return val
+}
+uni.setStorageSync(key,JSON.stringify(val));
+}
+export function getStorage(key){
+let uu=uni.getStorageSync(key);
+try{
+if(typeof JSON.parse(uu)!='number'){
+uu=JSON.parse(uu);
+}
+}catch(e){}
+return uu;
+}
+export function removeStorage(key){
+if(key){
+uni.removeStorageSync(key);
+}
+}
+export function clearStorage(){
+try{
+uni.clearStorageSync();
+}catch(e){
+throw new Error('处理失败');
+}
+}
+export function Toast(title,icon='none',obj={},duration=800){
+let toastData={
+title:title,
+duration:duration,
+position:'center',
+mask:true,
+icon:icon?icon:'none',
+...obj
+};
+uni.showToast(toastData);
+}
+export function Loading(title='正在加载...',obj={}){
+uni.showLoading({
+title:title,
+mask:true,
+...obj
+});
+}
+export function hideLoading(){
+try{
+uni.hideLoading();
+}catch(e){
+throw new Error('处理失败');
+}
+}
+export function Modal(title='提示',content='这是一个模态弹窗!',obj={
+showCancel:true,
+cancelText:'取消',
+confirmText:'确定'
+}){
+obj.cancelText='确定';
+obj.confirmText='取消';
+return new Promise((reslove,reject)=>{
+uni.showModal({
+title:title,
+content:content,
+...obj,
+success:(res)=>{
+if(res.confirm){
+reslove()
+}
+if(res.cancel){
+reject()
+}
+}
+});
+})
+}
+export function ActionSheet(itemList,itemColor="#000000"){
+return new Promise((reslove,reject)=>{
+uni.showActionSheet({
+itemList:itemList,
+itemColor:itemColor,
+success:(res)=>{
+reslove(res.tapIndex);
+},
+fail:function(res){
+reject(res.errMsg);
+}
+});
+})
+}
+export function ScrollTo(ScrollTop){
+uni.pageScrollTo({
+scrollTop:ScrollTop,
+duration:300
+})
+}
+export function GetUserInfo(){
+return new Promise((reslove,reject)=>{
+uni.getUserInfo({
+success(res){
+console.log(res);
+reslove(res);
+},
+fail(rej){
+reject(rej);
+}
+})
+})
+}
+export function Authorize(scoped='scope.userInfo'){
+return new Promise((reslove,reject)=>{
+uni.authorize({
+scope:scoped,
+success(res){
+reslove(res);
+},
+fail(rej){
+reject(rej);
+}
+})
+})
+}
+export function convertObj(opt){
+let str='';
+let arr=[];
+Object.keys(opt).forEach(item=>{
+arr.push(`${item}=${opt[item]}`);
+})
+str=arr.join('&');
+return str;
+}
+export function throttle(fn,delay){
+var lastArgs;
+var timer;
+var delay=delay||200;
+return function(...args){
+lastArgs=args;
+if(!timer){
+timer=setTimeout(()=>{
+timer=null;
+fn.apply(this,lastArgs);
+},delay);
+}
+}
+}
+export function chooseImage(count){
+return new Promise((reslove,reject)=>{
+uni.chooseImage({
+count:count,
+sizeType:['original','compressed'],
+sourceType:['album','camera'],
+success:(res)=>{
+reslove(res);
+},
+fail:(rej)=>{
+reject(rej);
+}
+});
+})
+}
+export function serialize(data){
+if(data!=null&&data!=''){
+try{
+return JSON.parse(JSON.stringify(data));
+}catch(e){
+if(data instanceof Array){
+return[];
+}
+return{};
+}
+}
+return data;
+}
+Date.prototype.format=function(fmt){
+let o={
+'M+':this.getMonth()+1,
+'d+':this.getDate(),
+'h+':this.getHours(),
+'m+':this.getMinutes(),
+'s+':this.getSeconds(),
+'q+':Math.floor((this.getMonth()+3)/3),
+S:this.getMilliseconds()
+};
+if(/(y+)/.test(fmt)){
+fmt=fmt.replace(RegExp.$1,String(this.getFullYear()).substr(4-RegExp.$1.length));
+}
+for(let k in o){
+if(new RegExp('('+k+')').test(fmt)){
+fmt=fmt.replace(RegExp.$1,RegExp.$1.length==1?o[k]:('00'+o[k]).substr(String(o[k]).length));
+}
+}
+return fmt;
+};
+export function formatDate(nS,format){
+if(!nS){
+return'';
+}
+format=format||'yyyy-MM-dd hh:mm:ss';
+return new Date(nS).format(format);
+}
+export function pathToBase64(path){
+return new Promise(function(resolve,reject){
+if(typeof window==='object'&&'document'in window){
+if(typeof FileReader==='function'){
+var xhr=new XMLHttpRequest()
+xhr.open('GET',path,true)
+xhr.responseType='blob'
+xhr.onload=function(){
+if(this.status===200){
+let fileReader=new FileReader()
+fileReader.onload=function(e){
+resolve(e.target.result)
+}
+fileReader.onerror=reject
+fileReader.readAsDataURL(this.response)
+}
+}
+xhr.onerror=reject
+xhr.send()
+return
+}
+var canvas=document.createElement('canvas')
+var c2x=canvas.getContext('2d')
+var img=new Image
+img.onload=function(){
+canvas.width=img.width
+canvas.height=img.height
+c2x.drawImage(img,0,0)
+resolve(canvas.toDataURL())
+canvas.height=canvas.width=0
+}
+img.onerror=reject
+img.src=path
+return
+}
+if(typeof plus==='object'){
+plus.io.resolveLocalFileSystemURL(getLocalFilePath(path),function(entry){
+entry.file(function(file){
+var fileReader=new plus.io.FileReader()
+fileReader.onload=function(data){
+resolve(data.target.result)
+}
+fileReader.onerror=function(error){
+reject(error)
+}
+fileReader.readAsDataURL(file)
+},function(error){
+reject(error)
+})
+},function(error){
+reject(error)
+})
+return
+}
+if(typeof wx==='object'&&wx.canIUse('getFileSystemManager')){
+wx.getFileSystemManager().readFile({
+filePath:path,
+encoding:'base64',
+success:function(res){
+resolve('data:image/png;base64,'+res.data)
+},
+fail:function(error){
+reject(error)
+}
+})
+return
+}
+reject(new Error('not support'))
+})
+}
+export function showWeekFirstDay(){
+var date=new Date();
+var weekday=date.getDay()||7;
+date.setDate(date.getDate()-weekday+1);
+return formatDate(date,'yyyy-MM-dd');
+}
+export function showMonthFirstDay(){
+var MonthFirstDay=new Date().setDate(1);
+return formatDate(new Date(MonthFirstDay).getTime(),'yyyy-MM-dd');
+}
+var now=new Date();
+var nowMonth=now.getMonth();
+var nowYear=now.getYear();
+nowYear+=(nowYear<2000)?1900:0;
+function getQuarterStartMonth(){
+var quarterStartMonth=0;
+if(nowMonth<3){
+quarterStartMonth=0;
+}
+if(2<nowMonth&&nowMonth<6){
+quarterStartMonth=3;
+}
+if(5<nowMonth&&nowMonth<9){
+quarterStartMonth=6;
+}
+if(nowMonth>8){
+quarterStartMonth=9;
+}
+return quarterStartMonth;
+}
+export function getQuarterStartDate(){
+var quarterStartDate=new Date(nowYear,getQuarterStartMonth(),1);
+return formatDate(quarterStartDate,'yyyy-MM-dd');
+}
+export function unique(data){
+data=data||[];
+var n={};
+for(var i=0;i<data.length;i++){
+var v=JSON.stringify(data[i]);
+if(typeof(v)=="undefined"){
+n[v]=1;
+}
+}
+data.length=0;
+for(var i in n){
+data[data.length]=i;
+}
+return data;
+}

+ 2 - 1
template/uni-app/main.js

@@ -24,9 +24,10 @@ Vue.prototype.$socket = new socket();
 Vue.config.productionTip = false
 import pageLoading from './components/pageLoading.vue'
 import skeleton from './components/skeleton/index.vue'
-
+import easyLoadimage from '@/components/easy-loadimage/easy-loadimage.vue'
 Vue.component('skeleton', skeleton)
 Vue.component('pageLoading', pageLoading)
+Vue.component('easyLoadimage', easyLoadimage)
 
 
 // #ifdef H5

+ 17 - 11
template/uni-app/manifest.json

@@ -2,8 +2,8 @@
     "name" : "CRMEB标准版",
     "appid" : "__UNI__A3F1ED4",
     "description" : "CRMEB标准版",
-    "versionName" : "1.0.0",
-    "versionCode" : 100,
+    "versionName" : "4.6.0",
+    "versionCode" : 461,
     "transformPx" : false,
     /* 5+App特有相关 */
     "app-plus" : {
@@ -63,7 +63,12 @@
             "ios" : {
                 "capabilities" : {
                     "entitlements" : {
-                        "com.apple.developer.associated-domains" : [ "applinks:", "applinks:", "applinks:" ]
+                        "com.apple.developer.associated-domains" : [
+                            "applinks:",
+                            "applinks:",
+                            "applinks:",
+                            "applinks:static-679f0930-8f60-425c-9033-8c135f397ea5.bspapp.com"
+                        ]
                     }
                 },
                 "privacyDescription" : {
@@ -74,7 +79,8 @@
                     "NSLocationAlwaysUsageDescription" : "根据客户地理位置推荐最近门店",
                     "NSCameraUsageDescription" : "上传用户头像保存分享海报"
                 },
-                "idfa" : false
+                "idfa" : false,
+                "dSYMs" : false
             },
             /* SDK配置 */
             "sdkConfigs" : {
@@ -84,14 +90,14 @@
                     },
                     "weixin" : {
                         "__platform__" : [ "ios", "android" ],
-                        "appid" : "",
-                        "UniversalLinks" : ""
+                        "appid" : "wx277a269f3d736d67",
+                        "UniversalLinks" : "https://bzapp.crmeb.net/uni-universallinks/__UNI__A3F1ED4/"
                     }
                 },
                 "share" : {
                     "weixin" : {
-                        "appid" : "",
-                        "UniversalLinks" : ""
+                        "appid" : "wx277a269f3d736d67",
+                        "UniversalLinks" : "https://bzapp.crmeb.net/uni-universallinks/__UNI__A3F1ED4/"
                     }
                 },
                 "push" : {},
@@ -104,9 +110,9 @@
                 "oauth" : {
                     "apple" : {},
                     "weixin" : {
-                        "appid" : "",
-                        "appsecret" : "",
-                        "UniversalLinks" : ""
+                        "appid" : "wx277a269f3d736d67",
+                        "appsecret" : "bd08741a055c2ecac5826ff1c048464b",
+                        "UniversalLinks" : "https://bzapp.crmeb.net/uni-universallinks/__UNI__A3F1ED4/"
                     }
                 },
                 "ad" : {},

+ 12 - 11
template/uni-app/pages.json

@@ -61,17 +61,9 @@
 
 			}
 		}
-		//#ifdef H5
-		,
-		{
-			"path": "pages/auth/index",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		}
-		//#endif
+
 	],
-	"subPackages": [{
+	"subPackages": [{  // 模块分包
 			"root": "pages/extension",
 			"name": "extension",
 			"pages": [{
@@ -940,6 +932,15 @@
 						// #endif
 					}
 				}
+				// #ifdef H5
+				,
+				{
+					"path": "auth/index",
+					"style": {
+						"navigationBarTitleText": ""
+					}
+				}
+				// #endif
 			],
 			"plugins": {
 				"live-player-plugin": {
@@ -1526,7 +1527,7 @@
 			]
 		}
 	],
-	"tabBar": {
+	"tabBar": {  // 底部菜单
 		"color": "#282828",
 		"selectedColor": "#ff3366",
 		"borderStyle": "white",

File diff suppressed because it is too large
+ 1802 - 1796
template/uni-app/pages/activity/goods_combination_details/index.vue


File diff suppressed because it is too large
+ 1642 - 1636
template/uni-app/pages/activity/goods_seckill_details/index.vue


+ 7 - 0
template/uni-app/pages/annex/components/verify/utils/ase.js

@@ -0,0 +1,7 @@
+import CryptoJS from'./crypto-js.js'
+export function aesEncrypt(word,keyWord="XwKsGlMcdPMEhR1B"){
+var key=CryptoJS.enc.Utf8.parse(keyWord);
+var srcs=CryptoJS.enc.Utf8.parse(word);
+var encrypted=CryptoJS.AES.encrypt(srcs,key,{mode:CryptoJS.mode.ECB,padding:CryptoJS.pad.Pkcs7});
+return encrypted.toString();
+}

File diff suppressed because it is too large
+ 3077 - 0
template/uni-app/pages/annex/components/verify/utils/crypto-js.js


+ 30 - 0
template/uni-app/pages/annex/components/verify/utils/util.js

@@ -0,0 +1,30 @@
+
+export function resetSize(vm){
+var img_width,img_height,bar_width,bar_height
+var parentWidth=vm.$el.parentNode.offsetWidth||window.offsetWidth
+var parentHeight=vm.$el.parentNode.offsetHeight||window.offsetHeight
+if(vm.imgSize.width.indexOf('%')!=-1){
+img_width=parseInt(this.imgSize.width)/100*parentWidth+'px'
+}else{
+img_width=this.imgSize.width
+}
+if(vm.imgSize.height.indexOf('%')!=-1){
+img_height=parseInt(this.imgSize.height)/100*parentHeight+'px'
+}else{
+img_height=this.imgSize.height
+}
+if(vm.barSize.width.indexOf('%')!=-1){
+bar_width=parseInt(this.barSize.width)/100*parentWidth+'px'
+}else{
+bar_width=this.barSize.width
+}
+if(vm.barSize.height.indexOf('%')!=-1){
+bar_height=parseInt(this.barSize.height)/100*parentHeight+'px'
+}else{
+bar_height=this.barSize.height
+}
+return{imgWidth:img_width,imgHeight:img_height,barWidth:bar_width,barHeight:bar_height}
+}
+export const _code_chars=[1,2,3,4,5,6,7,8,9,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
+export const _code_color1=['#fffff0','#f0ffff','#f0fff0','#fff0f0']
+export const _code_color2=['#FF0033','#006699','#993366','#FF9900','#66CC66','#FF33CC']

+ 11 - 1
template/uni-app/components/verify/verify.vue

@@ -11,9 +11,17 @@
 				<!-- 验证码容器 -->
 				<!-- 滑动 -->
 				<view v-if="componentType=='VerifySlide'">
+					<!-- #ifndef H5 -->
 					<VerifySlide @success="success" :captchaType="captchaType" :type="verifyType" :figure="figure"
 						:arith="arith" :mode="mode" :vSpace="vSpace" :explain="explain" :imgSize="imgSize"
 						:blockSize="blockSize" :barSize="barSize" :defaultImg="defaultImg" ref="instance"></VerifySlide>
+					<!-- #endif -->
+					<!-- #ifdef H5 -->
+					<verifySliderPc @success="success" :captchaType="captchaType" :type="verifyType" :figure="figure"
+						:arith="arith" :mode="mode" :vSpace="vSpace" :explain="explain" :imgSize="imgSize"
+						:blockSize="blockSize" :barSize="barSize" :defaultImg="defaultImg" ref="instance">
+					</verifySliderPc>
+					<!-- #endif -->
 				</view>
 				<!-- 点选 -->
 				<view v-if="componentType=='VerifyPoints'">
@@ -31,6 +39,7 @@
 	 * @description 分发验证码使用
 	 * */
 	import VerifySlide from './verifySlider/verifySlider'
+	import verifySliderPc from './verifySlider/verifySliderPc'
 	import VerifyPoint from "./verifyPoint/verifyPoint"
 
 	export default {
@@ -197,7 +206,8 @@
 		},
 		components: {
 			VerifySlide,
-			VerifyPoint
+			VerifyPoint,
+			verifySliderPc
 		},
 	}
 </script>

template/uni-app/components/verify/verifyPoint/verifyPoint.vue → template/uni-app/pages/annex/components/verify/verifyPoint/verifyPoint.vue


template/uni-app/components/verify/verifySlider/verifySlider.vue → template/uni-app/pages/annex/components/verify/verifySlider/verifySlider.vue


File diff suppressed because it is too large
+ 745 - 0
template/uni-app/pages/annex/components/verify/verifySlider/verifySliderPc.vue


+ 11 - 4
template/uni-app/pages/annex/offline_pay/index.vue

@@ -1,5 +1,5 @@
 <template>
-	<form class="form" @submit="checkForm">
+	<form class="form" @submit="checkForm" :style="colorStyle">
 		<view class="input-section">
 			<view class="section-hd">{{$t(`支付金额`)}}</view>
 			<view class="section-bd">
@@ -15,10 +15,10 @@
 			<radio-group class="section-bd" name="method">
 				<label class="item" v-if="yuePay">
 					<text class="iconfont icon-yue"></text>
-					<text class="name">
-						{{$t(`余额支付`)}}
+					<view class="name">
+						<text>{{$t(`余额支付`)}}</text>
 						<text class="money">{{$t(`可用余额`)}}:{{$t(`¥`)}}{{ now_money || 0 }}</text>
-					</text>
+					</view>
 					<radio value="yue" :checked="payType === 'yue'" />
 				</label>
 				<label v-if="wxpay" class="item">
@@ -45,8 +45,10 @@
 	import {
 		mapGetters
 	} from "vuex";
+		import colors from "@/mixins/color";
 	const app = getApp();
 	export default {
+		mixins: [colors],
 		data() {
 			return {
 				money: '',
@@ -417,6 +419,11 @@
 			padding-right: 30rpx;
 			padding-bottom: 30rpx;
 			border-bottom: 1rpx solid #f5f5f5;
+			.name{
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+			}
 		}
 
 		.iconfont {

+ 6 - 5
template/uni-app/pages/annex/settled/index.vue

@@ -85,8 +85,7 @@
 					</view>
 			</view>
 		</form>
-		<Verify @success="success" :captchaType="'blockPuzzle'" :imgSize="{ width: '330px', height: '155px' }"
-			ref="verify"></Verify>
+
 		<view class="settlementAgreement" v-if="showProtocol">
 			<view class="setAgCount">
 				<i class="icon iconfont icon-cha" @click="showProtocol = false"></i>
@@ -103,7 +102,9 @@
 		</view>
 		<!-- #ifdef MP -->
 		<authorize @onLoadFun="onLoadFun" :isAuto="isAuto" :isShowAuth="isShowAuth" @authColse="authColse"></authorize>
-		<!-- #endif -->
+		<!-- #endif -->
+		<Verify @success="success" :captchaType="'blockPuzzle'" :imgSize="{ width: '330px', height: '155px' }"
+			ref="verify"></Verify>
 	</view>
 	<view class="settledSuccessMain" v-else-if='status == 0'>
 		<view class="settledSuccessful">
@@ -135,7 +136,7 @@
 					{{$t(`返回首页`)}}
 				</view>
 		</view>
-
+		
 	</view>
 </template>
 <script>
@@ -161,7 +162,7 @@
 	import authorize from '@/components/Authorize';
 	// #endif
 	import colors from "@/mixins/color";
-	import Verify from '@/components/verify/verify.vue';
+	import Verify from '../components/verify/verify.vue';
 	import sendVerifyCode from "@/mixins/SendVerifyCode";
 	const app = getApp();
 	export default {

File diff suppressed because it is too large
+ 992 - 974
template/uni-app/pages/extension/customer_list/chat.vue


+ 4 - 6
template/uni-app/pages/extension/news_list/index.vue

@@ -23,10 +23,8 @@
 							<view class='line bg-color' v-if="active==item.id"></view>
 						</view>
 					</block>
-
-
 				</scroll-view>
-				<scroll-view class="scroll-view_x" scroll-x scroll-with-animation style="width:auto;overflow:hidden;">
+				<scroll-view v-if="coutList.length" class="scroll-view_x" scroll-x scroll-with-animation style="width:auto;overflow:hidden;">
 					<view class="coutry-list">
 						<view class="coutry" :class='activeCou==coutry.id?"on":""' v-for="(coutry,index) in coutList"
 							:key="index" @click="getCidArticle(coutry.id,1)">
@@ -386,10 +384,10 @@
 	.coutry-list {
 		display: flex;
 		align-items: center;
-		margin-top: 10rpx;
-		padding-top: 20rpx;
+		margin: 10rpx 0;
+		padding-top: 10rpx;
 		border-top: 1px solid #F2F2F2;
-
+		height: 80rpx;
 		.coutry {
 			// background-color: #F5F5F5;
 			border-radius: 26rpx;

+ 7 - 1
template/uni-app/pages/goods/goods_list/index.vue

@@ -120,6 +120,7 @@
 		},
 		onLoad: function(options) {
 			this.where.cid = options.cid || 0;
+			this.where.coupon_category_id = options.coupon_category_id || '';
 			this.$set(this.where, 'sid', options.sid || 0);
 			this.title = options.title || '';
 			this.$set(this.where, 'keyword', options.searchValue || '');
@@ -240,7 +241,12 @@
 				this.get_host_product();
 			}
 
-		}
+		},
+		// 滚动监听
+		onPageScroll(e) {
+			// 传入scrollTop值并触发所有easy-loadimage组件下的滚动监听事件
+			uni.$emit('scroll');
+		},
 	}
 </script>
 

+ 5 - 0
template/uni-app/pages/goods/goods_logistics/index.vue

@@ -118,6 +118,11 @@
 			});
 			// #endif
 		},
+		// 滚动监听
+		onPageScroll(e) {
+			// 传入scrollTop值并触发所有easy-loadimage组件下的滚动监听事件
+			uni.$emit('scroll');
+		},
 		methods: {
 			/**
 			 * 授权回调

+ 0 - 0
template/uni-app/pages/goods/order_confirm/index.vue


Some files were not shown because too many files changed in this diff