소스 검색

【模版目录】更新v5.3.0

evoxwht 1 년 전
부모
커밋
2512145b01
100개의 변경된 파일19738개의 추가작업 그리고 17519개의 파일을 삭제
  1. 1 1
      template/admin/.env.dev
  2. 0 4
      template/admin/README.md
  3. 17359 16452
      template/admin/package-lock.json
  4. 1 1
      template/admin/package.json
  5. 11 0
      template/admin/src/api/agent.js
  6. 34 0
      template/admin/src/api/app.js
  7. 11 0
      template/admin/src/api/notification.js
  8. 11 0
      template/admin/src/api/order.js
  9. 10 0
      template/admin/src/api/setting.js
  10. 4 2
      template/admin/src/components/copyright/index.vue
  11. 14 44
      template/admin/src/components/customerInfo/index.vue
  12. 15 17
      template/admin/src/components/freightTemplate/city.vue
  13. 37 36
      template/admin/src/components/goodsList/index.vue
  14. 13 5
      template/admin/src/components/linkaddress/index.vue
  15. 1 1
      template/admin/src/components/mobileConfigDiy/c_home_goods_list.vue
  16. 1 1
      template/admin/src/components/mobileConfigRightDiy/c_cascader.vue
  17. 7 0
      template/admin/src/components/mobileConfigRightDiy/c_goods.vue
  18. 3 0
      template/admin/src/components/mobilePageDiy/home_goods_list.vue
  19. 1 1
      template/admin/src/components/mobilePageDiy/home_product.vue
  20. 3 3
      template/admin/src/components/searchFrom/searchFrom.vue
  21. 21 11
      template/admin/src/components/uploadImg/index.vue
  22. 19 16
      template/admin/src/components/uploadVideo/index.vue
  23. 19 16
      template/admin/src/components/uploadVideo2/index.vue
  24. 6 1
      template/admin/src/components/wangEditor/index.vue
  25. 3 2
      template/admin/src/directive/directives.js
  26. 3 1
      template/admin/src/directive/index.js
  27. 38 0
      template/admin/src/directive/module/permission.js
  28. 1 1
      template/admin/src/i18n/lang/zh-cn.js
  29. 2 2
      template/admin/src/layout/component/aside.vue
  30. 1 0
      template/admin/src/layout/component/header.vue
  31. 10 11
      template/admin/src/layout/component/transverseAside.vue
  32. 3 0
      template/admin/src/layout/index.vue
  33. 1 1
      template/admin/src/layout/navBars/breadcrumb/index.vue
  34. 13 2
      template/admin/src/layout/navBars/breadcrumb/search.vue
  35. 54 8
      template/admin/src/layout/navBars/breadcrumb/setings.vue
  36. 6 6
      template/admin/src/layout/navBars/breadcrumb/theme.js
  37. 10 0
      template/admin/src/layout/navBars/breadcrumb/user.vue
  38. 13 1
      template/admin/src/layout/routerView/parent.vue
  39. 18 0
      template/admin/src/libs/permission.js
  40. 20 14
      template/admin/src/pages/account/login/index.vue
  41. 12 0
      template/admin/src/pages/agent/handle/promotersList.vue
  42. 146 0
      template/admin/src/pages/app/routine/link/index.vue
  43. 4 2
      template/admin/src/pages/app/upload/index.vue
  44. 190 167
      template/admin/src/pages/app/wechat/reply/follow.vue
  45. 16 11
      template/admin/src/pages/division/agent/index.vue
  46. 1 6
      template/admin/src/pages/division/list/index.vue
  47. 14 10
      template/admin/src/pages/kefu/appChat/index.vue
  48. 3 1
      template/admin/src/pages/kefu/appChat/mobile/index.vue
  49. 1 1
      template/admin/src/pages/kefu/index.vue
  50. 1 1
      template/admin/src/pages/kefu/mobile/chat_list.vue
  51. 6 2
      template/admin/src/pages/kefu/mobile/index.vue
  52. 14 4
      template/admin/src/pages/kefu/pc/components/delivery.vue
  53. 17 5
      template/admin/src/pages/kefu/pc/components/rightMenu.vue
  54. 7 1
      template/admin/src/pages/kefu/pc/index.vue
  55. 14 12
      template/admin/src/pages/marketing/channelCode/channelCodeIndex.vue
  56. 20 10
      template/admin/src/pages/marketing/channelCode/createCode.vue
  57. 0 2
      template/admin/src/pages/marketing/lottery/create.vue
  58. 1 11
      template/admin/src/pages/marketing/recharge/index.vue
  59. 3 2
      template/admin/src/pages/marketing/storeBargain/create.vue
  60. 2 2
      template/admin/src/pages/marketing/storeBargain/index.vue
  61. 1 1
      template/admin/src/pages/marketing/storeBargain/statistics.vue
  62. 2 2
      template/admin/src/pages/marketing/storeCombination/create.vue
  63. 1 1
      template/admin/src/pages/marketing/storeIntegral/create.vue
  64. 2 2
      template/admin/src/pages/marketing/storeSeckill/create.vue
  65. 1 0
      template/admin/src/pages/notify/smsConfig/index.vue
  66. 53 18
      template/admin/src/pages/order/orderList/components/tableFrom.vue
  67. 65 22
      template/admin/src/pages/order/orderList/components/tableList.vue
  68. 300 0
      template/admin/src/pages/order/orderList/handle/orderRefund.vue
  69. 0 1
      template/admin/src/pages/order/orderList/handle/orderSend.vue
  70. 1 1
      template/admin/src/pages/order/print/index.vue
  71. 1 1
      template/admin/src/pages/order/refund/index.vue
  72. 50 20
      template/admin/src/pages/product/productAdd/index.vue
  73. 1 1
      template/admin/src/pages/product/productList/taoBao.vue
  74. 14 3
      template/admin/src/pages/setting/devise/diyIndex.vue
  75. 56 0
      template/admin/src/pages/setting/notification/components/keysList.vue
  76. 37 4
      template/admin/src/pages/setting/notification/index.vue
  77. 211 33
      template/admin/src/pages/setting/notification/notificationEdit.vue
  78. 11 2
      template/admin/src/pages/setting/setSystem/index.vue
  79. 3 3
      template/admin/src/pages/setting/storage/index.vue
  80. 38 24
      template/admin/src/pages/setting/storeService/index.vue
  81. 0 1
      template/admin/src/pages/setting/systemRole/index.vue
  82. 0 1
      template/admin/src/pages/system/codeGeneration/components/TableForm.vue
  83. 0 1
      template/admin/src/pages/system/crontab/createModal.vue
  84. 1 1
      template/admin/src/pages/system/crontab/index.vue
  85. 0 1
      template/admin/src/pages/system/systemMenus/components/menusFrom.vue
  86. 5 1
      template/admin/src/pages/user/group/index.vue
  87. 1 1
      template/admin/src/pages/user/list/handle/userDetails.vue
  88. 40 23
      template/admin/src/pages/user/list/index.vue
  89. 0 7
      template/admin/src/router/index.js
  90. 9 0
      template/admin/src/router/modules/app.js
  91. 9 0
      template/admin/src/router/modules/marketing.js
  92. 1 1
      template/admin/src/router/modules/setting.js
  93. 33 32
      template/admin/src/store/module/moren.js
  94. 133 6
      template/admin/src/styles/style.scss
  95. 31 0
      template/admin/src/utils/index.js
  96. 2 2
      template/admin/src/utils/modalForm.js
  97. 0 6
      template/admin/src/utils/upload.js
  98. 2 2
      template/admin/vue.config.js
  99. 353 383
      template/uni-app/App.vue
  100. 0 0
      template/uni-app/api/user.js

+ 1 - 1
template/admin/.env.dev

@@ -5,4 +5,4 @@ VUE_APP_ENV='dev'
 VUE_APP_TITLE=CRMEB
 
 # 接口请求地址
-VUE_APP_API_URL='http://192.168.31.239/adminapi'
+VUE_APP_API_URL=''

+ 0 - 4
template/admin/README.md

@@ -292,8 +292,4 @@ $ npm run build
 
 `$ VUE_APP_API_URL=''`
 
-### docker开发调试
-$ docker-compose up -d
 
-### 访问地址
-http://localhost:1617/admin

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 17359 - 16452
template/admin/package-lock.json


+ 1 - 1
template/admin/package.json

@@ -1,6 +1,6 @@
 {
   "name": "from-crmeb-admin",
-  "version": "5.2.1",
+  "version": "5.2.2",
   "author": "sugar1569<763569752@qq.com>",
   "private": false,
   "scripts": {

+ 11 - 0
template/admin/src/api/agent.js

@@ -184,3 +184,14 @@ export function isShowApi(data) {
     method: 'put',
   });
 }
+
+/**
+ * @description 员工添加--表单
+ * @param {Object} param data {Object} 传值参数
+ */
+ export function staffAddFrom(uid) {
+  return request({
+    url: `agent/division/staff/create/${uid}`,
+    method: 'get',
+  });
+}

+ 34 - 0
template/admin/src/api/app.js

@@ -405,3 +405,37 @@ export function cityList() {
     method: 'get',
   });
 }
+
+/**
+ * @description 小程序链接 -- 列表
+ * @param {Object} param data {Object} 传值参数
+ */
+ export function routineSchemeList(data) {
+  return request({
+    url: 'app/routine/scheme_list',
+    method: 'get',
+    params: data,
+  });
+}
+
+/**
+ * @description 小程序链接 -- 创建修改表单
+ * @param {Number} param id {Number} 标签id
+ */
+ export function routineSchemeForm(id) {
+  return request({
+    url: `app/routine/scheme_form/${id}`,
+    method: 'get',
+  });
+}
+
+/**
+ * @description 小程序链接 -- 删除
+ * @param {Number} param id {Number} 标签id
+ */
+ export function routineSchemeDel(id) {
+  return request({
+    url: `app/routine/scheme_del/${id}`,
+    method: 'delete',
+  });
+}

+ 11 - 0
template/admin/src/api/notification.js

@@ -53,3 +53,14 @@ export function noticeStatus(type, status, id) {
     method: 'put',
   });
 }
+
+/**
+ * @description 添加修改消息表单
+ * @param {Number} param id {Number} 传值参数
+ */
+ export function notificationForm(id) {
+  return request({
+    url: `setting/notification/not_form/${id}`,
+    method: 'get',
+  });
+}

+ 11 - 0
template/admin/src/api/order.js

@@ -150,6 +150,17 @@ export function getRefundFrom(id) {
     method: 'get',
   });
 }
+/**
+ * @description 退款
+ * @param {Number} param id {Number} 订单id
+ */
+export function refundPrice(id, data) {
+  return request({
+    url: `/order/refund/${id}`,
+    method: 'put',
+    data,
+  });
+}
 
 /**
  * @description 新版-获取退款表单数据

+ 10 - 0
template/admin/src/api/setting.js

@@ -1168,3 +1168,13 @@ export function scanUpload(data) {
     data,
   });
 }
+/**
+ * 菜单搜索
+ */
+export function menusSearch(data) {
+  return request({
+    url: `menusSearch`,
+    method: 'post',
+    data,
+  });
+}

+ 4 - 2
template/admin/src/components/copyright/index.vue

@@ -1,11 +1,11 @@
 <template>
-  <div class="ivu-global-footer i-copyright">
+  <div class="ivu-global-footer i-copyright" v-if="isShow">
     <div class="ivu-global-footer-links" v-if="!copyright">
       <a :href="item.href" target="_blank" v-for="(item, index) in links" :key="index">{{ item.title }}</a>
     </div>
     <div class="ivu-global-footer-copyright" v-if="copyright">{{ copyright }}</div>
     <div class="ivu-global-footer-copyright" v-else>
-      Copyright © 2014-2023
+      Copyright © 2014-2024
       <a href="https://www.crmeb.com" target="_blank">{{ version }}</a>
     </div>
   </div>
@@ -35,6 +35,7 @@ export default {
       ],
       copyright: '',
       version: '',
+      isShow: false
     };
   },
   created() {
@@ -45,6 +46,7 @@ export default {
       this.version = this.$store.state.userInfo.version;
       getCrmebCopyRight().then((res) => {
         this.copyright = res.data.copyrightContext;
+        this.isShow = true
       });
     },
   },

+ 14 - 44
template/admin/src/components/customerInfo/index.vue

@@ -1,24 +1,10 @@
 <template>
   <div class="customer">
     <el-form ref="formValidate" :model="formValidate" label-width="80px" inline @submit.native.prevent>
-      <el-form-item label="搜索日期:">
-        <el-date-picker
-          :editable="false"
-          @change="onchangeTime"
-          v-model="timeVal"
-          value-format="yyyy/MM/dd"
-          type="daterange"
-          placement="bottom-end"
-          range-separator="-"
-          start-placeholder="开始日期"
-          end-placeholder="结束日期"
-          style="width: 250px"
-        ></el-date-picker>
-      </el-form-item>
-      <el-form-item label="用户名称:">
+      <el-form-item label="搜索用户:">
         <el-input
           clearable
-          placeholder="请输入用户名称"
+          placeholder="请输入用户UID、昵称或手机号"
           v-model="formValidate.nickname"
           class="form_content_width"
         ></el-input>
@@ -48,55 +34,39 @@
           >
         </template>
       </el-table-column>
-      <el-table-column label="ID" width="80">
+      <el-table-column label="UID" width="80">
         <template slot-scope="scope">
           <span>{{ scope.row.uid }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="微信用户名称" min-width="180">
-        <template slot-scope="scope">
-          <div>{{ scope.row.nickname }}</div>
-          <div style="color: red">{{ scope.row.is_del ? '用户已注销' : '' }}</div>
-        </template>
-      </el-table-column>
-      <el-table-column label="客服头像" min-width="90">
+      <el-table-column label="用户头像" min-width="90">
         <template slot-scope="scope">
           <div class="tabBox_img" v-viewer>
             <img v-lazy="scope.row.headimgurl" />
           </div>
         </template>
       </el-table-column>
-
-      <el-table-column label="用户类型" min-width="130">
+      <el-table-column label="用户昵称" min-width="180">
         <template slot-scope="scope">
-          <span v-if="scope.row.user_type === 'wechat'">公众号</span>
-          <span v-else-if="scope.row.user_type === 'routine'">小程序</span>
-          <span v-else-if="scope.row.user_type === 'h5'">H5</span>
-          <span v-else-if="scope.row.user_type === 'pc'">PC</span>
-          <span v-else>--</span>
+          <div>{{ scope.row.nickname }}</div>
+          <div style="color: red">{{ scope.row.is_del ? '用户已注销' : '' }}</div>
         </template>
       </el-table-column>
-      <el-table-column label="性别" min-width="130">
+      <el-table-column label="手机号" min-width="180">
         <template slot-scope="scope">
-          <span v-show="scope.row.sex === 1">男</span>
-          <span v-show="scope.row.sex === 2">女</span>
-          <span v-show="scope.row.sex === 0">保密</span>
-          <span v-show="scope.row.sex === null">--</span>
+          <div>{{ scope.row.phone }}</div>
         </template>
       </el-table-column>
-      <!--      <el-table-column label="地区" min-width="130">-->
-      <!--        <template slot-scope="scope">-->
-      <!--          <span v-if="scope.row.country || scope.row.province || scope.row.city">{{-->
-      <!--            scope.row.country + scope.row.province + scope.row.city-->
-      <!--          }}</span>-->
-      <!--          <span v-else>&#45;&#45;</span>-->
-      <!--        </template>-->
-      <!--      </el-table-column>-->
       <el-table-column label="是否关注公众号" min-width="130">
         <template slot-scope="scope">
           <span v-text="scope.row.subscribe === 1 ? '关注' : '未关注'"></span>
         </template>
       </el-table-column>
+      <el-table-column label="注册时间" min-width="180">
+        <template slot-scope="scope">
+          <div>{{ scope.row.add_time }}</div>
+        </template>
+      </el-table-column>
     </el-table>
     <div class="acea-row row-right page">
       <pagination

+ 15 - 17
template/admin/src/components/freightTemplate/city.vue

@@ -1,7 +1,7 @@
 <template>
   <div>
     <el-dialog :visible.sync="addressModal" title="选择可配送区域" width="50%" class="modal">
-      <el-row :gutter="24" >
+      <el-row :gutter="24">
         <el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24" class="item">
           <div class="acea-row row-right row-middle">
             <el-checkbox v-model="iSselect" @change="allCheckbox">全选</el-checkbox>
@@ -9,7 +9,7 @@
           </div>
         </el-col>
       </el-row>
-      <el-row :gutter="24"  v-loading="loading">
+      <el-row :gutter="24" v-loading="loading">
         <el-col
           :xl="6"
           :lg="6"
@@ -21,33 +21,29 @@
           :key="index"
           v-if="item.isShow"
         >
-          <el-popover
-              placement="top-start"
-              width="600"
-              trigger="hover"
-              :open-delay="600">
+          <el-popover placement="top-start" width="600" trigger="hover" :open-delay="600">
             <div>
               <div class="city">
                 <div class="checkBox">
                   <div class="arrow"></div>
                   <div>
                     <el-checkbox
-                        v-model="city.checked"
-                        :label="city.name"
-                        @change="primary(index, indexn)"
-                        class="itemn"
-                        v-for="(city, indexn) in item.children"
-                        :key="indexn"
-                        v-show="city.isShow"
-                    >{{ city.name }}</el-checkbox
+                      v-model="city.checked"
+                      :label="city.name"
+                      @change="primary(index, indexn)"
+                      class="itemn"
+                      v-for="(city, indexn) in item.children"
+                      :key="indexn"
+                      v-show="city.isShow"
+                      >{{ city.name }}</el-checkbox
                     >
                   </div>
                 </div>
               </div>
             </div>
             <el-checkbox slot="reference" v-model="item.checked" :label="item.name" @change="checkedClick(index)">{{
-                item.name
-              }}</el-checkbox
+              item.name
+            }}</el-checkbox
             ><span class="red">({{ (item.count || 0) + '/' + item.childNum }})</span>
           </el-popover>
         </el-col>
@@ -128,6 +124,7 @@ export default {
           el.childNum = oldNum;
         });
         this.cityList = res.data;
+        this.iSselect = false;
       });
     },
     /**
@@ -245,6 +242,7 @@ export default {
   mounted() {
     // this.getCityList();
   },
+  beforeDestroy() {},
 };
 </script>
 

+ 37 - 36
template/admin/src/components/goodsList/index.vue

@@ -1,19 +1,14 @@
 <template>
   <div class="goodList">
-    <el-form ref="formValidate"
-             :model="formValidate"
-             label-width="80px"
-             label-position="right"
-             inline
-             class="tabform">
+    <el-form ref="formValidate" :model="formValidate" label-width="80px" label-position="right" inline class="tabform">
       <el-form-item label="商品分类:" v-if="!liveStatus">
         <el-cascader
-            v-model="formValidate.cate_id"
-            size="small"
-            :options="treeSelect"
-            :props="{ checkStrictly: true, emitPath: false }"
-            clearable
-            class="form_content_width"
+          v-model="formValidate.cate_id"
+          size="small"
+          :options="treeSelect"
+          :props="{ checkStrictly: true, emitPath: false }"
+          clearable
+          class="form_content_width"
         ></el-cascader>
       </el-form-item>
       <el-form-item label="商品类型:" v-if="!type && diy">
@@ -24,10 +19,10 @@
       </el-form-item>
       <el-form-item label="商品搜索:">
         <el-input
-            clearable
-            placeholder="请输入商品名称/关键字/编号"
-            v-model="formValidate.store_name"
-            class="form_content_width"
+          clearable
+          placeholder="请输入商品名称/关键字/编号"
+          v-model="formValidate.store_name"
+          class="form_content_width"
         />
         <el-button type="primary" @click="userSearchs" class="ml15">查询</el-button>
       </el-form-item>
@@ -189,15 +184,15 @@ export default {
     };
   },
   computed: {},
-  watch:{
-    ischeckbox:{
-      handler(newVal,oldVal) {
-        if(newVal){
+  watch: {
+    ischeckbox: {
+      handler(newVal, oldVal) {
+        if (newVal) {
           this.many = 'many';
         }
       },
-      immediate: true
-    }
+      immediate: true,
+    },
   },
   created() {
     let many = '';
@@ -294,21 +289,26 @@ export default {
         changeListApi(this.formValidate)
           .then(async (res) => {
             let data = res.data;
-            if (this.selectIds.length) {
-              let arr = [];
-              this.selectIds.map((item) => {
-                data.list.map((i) => {
-                  if (i.id == item) {
-                    i._checked = true;
-                    arr.push(i);
-                  }
-                });
-              });
-              this.changeCheckbox(arr);
-            }
+            console.log(this.selectIds);
             this.tableList = data.list;
             this.total = res.data.count;
             this.loading = false;
+            this.$nextTick(() => {
+              if (this.selectIds.length) {
+                let arr = [];
+                this.selectIds.map((item) => {
+                  data.list.map((i) => {
+                    if (i.id == item) {
+                      console.log(i);
+                      this.$refs.table.toggleRowSelection(i, true);
+
+                      arr.push(i);
+                    }
+                  });
+                });
+                this.changeCheckbox(arr);
+              }
+            });
           })
           .catch((res) => {
             this.loading = false;
@@ -332,7 +332,8 @@ export default {
               this.selectIds.map((item) => {
                 data.list.map((i) => {
                   if (i.id == item) {
-                    i._checked = true;
+                    console.log(i);
+                    this.$refs.table.toggleRowSelection(i);
                   }
                 });
               });
@@ -356,7 +357,7 @@ export default {
           form_create_helper.set('image', imageValue.concat(this.images));
           form_create_helper.close('image');
         } else {
-          this.$refs.table.clearSelection()
+          this.$refs.table.clearSelection();
           if (this.isdiy) {
             this.$emit('getProductId', this.diyVal);
           } else {

+ 13 - 5
template/admin/src/components/linkaddress/index.vue

@@ -57,8 +57,8 @@
             </div>
           </div>
         </div>
-        <div class="right_box" v-if="currenType == 'marketing_link'">
-          <div v-if="coupon.length">
+        <div class="right_box" v-if="currenType == 'marketing_link' && coupon.length">
+          <div>
             <div class="cont">优惠券</div>
             <div class="Box">
               <div
@@ -72,7 +72,8 @@
               </div>
             </div>
           </div>
-          <div v-if="basicsList.length">
+          <div >
+          <div v-permission="'seckill'" v-if="basicsList.length">
             <div class="cont">秒杀</div>
             <div class="Box">
               <div
@@ -86,7 +87,10 @@
               </div>
             </div>
           </div>
-          <div v-if="distributionList.length">
+          </div>
+          <div >
+
+          <div v-permission="'bargain'" v-if="distributionList.length">
             <div class="cont">砍价</div>
             <div class="Box">
               <div
@@ -100,7 +104,10 @@
               </div>
             </div>
           </div>
-          <div v-if="userList.length">
+          </div>
+          <div>
+
+          <div v-permission="'combination'" v-if="userList.length">
             <div class="cont">拼团</div>
             <div class="Box">
               <div
@@ -114,6 +121,7 @@
               </div>
             </div>
           </div>
+          </div>
           <div v-if="integral.length">
             <div class="cont">积分</div>
             <div class="Box">

+ 1 - 1
template/admin/src/components/mobileConfigDiy/c_home_goods_list.vue

@@ -216,7 +216,7 @@ export default {
       // }
       let activeValue = this.configObj.selectConfig.activeValue;
       getProduct({
-        id: activeValue[activeValue.length - 1],
+        id: activeValue,
         page: 1,
         limit: this.configObj.numConfig.val,
         priceOrder: this.configObj.goodsSort.type == 2 ? 'desc' : '',

+ 1 - 1
template/admin/src/components/mobileConfigRightDiy/c_cascader.vue

@@ -11,7 +11,7 @@
           v-model="configData.activeValue"
           filterable
           @change="sliderChange"
-          :props="{ multiple: true, checkStrictly: true, emitPath: false }"
+          :props="{ multiple: false, checkStrictly: true, emitPath: false }"
           clearable
         ></el-cascader>
       </el-col>

+ 7 - 0
template/admin/src/components/mobileConfigRightDiy/c_goods.vue

@@ -24,6 +24,7 @@
         :isdiy="true"
         @getProductId="getProductId"
         v-if="modals"
+        :selectIds="selectIds"
       ></goods-list>
     </el-dialog>
   </div>
@@ -47,6 +48,11 @@ export default {
     configObj: {
       handler(nVal, oVal) {
         this.defaults = nVal;
+        let ids =[]
+        this.defaults.goodsList.list.map((i) => {
+          ids.push(i.id);
+        });
+        this.selectIds = ids;
       },
       immediate: true,
       deep: true,
@@ -58,6 +64,7 @@ export default {
       goodsList: [],
       tempGoods: {},
       defaults: {},
+      selectIds: [],
     };
   },
   created() {

+ 3 - 0
template/admin/src/components/mobilePageDiy/home_goods_list.vue

@@ -682,6 +682,9 @@ export default {
                     flex 1
                     margin-left 5px
                     padding: 5px 10px;
+                    .title
+                      height 37px;
+
         &.itemB
             justify-content inherit
             .item

+ 1 - 1
template/admin/src/components/mobilePageDiy/home_product.vue

@@ -34,7 +34,7 @@
           <div class="img-box">
             <img v-if="item.image" :src="item.image" alt="" />
             <div v-else class="empty-box"><span class="iconfont-diy icontupian"></span></div>
-            <div class="label" :style="{ background: labelColor }" v-if="item.activity && item.activity.type === '1'">
+            <div v-permission="'seckill'" class="label" :style="{ background: labelColor }" v-if="item.activity && item.activity.type === '1'">
               秒杀
             </div>
             <div class="label" :style="{ background: labelColor }" v-if="item.activity && item.activity.type === '2'">

+ 3 - 3
template/admin/src/components/searchFrom/searchFrom.vue

@@ -49,9 +49,9 @@
             <el-radio-group v-model="currentTab" type="button" @input="onClickTab(currentTab)">
               <el-radio-button label="">全部</el-radio-button>
               <el-radio-button label="1">普通</el-radio-button>
-              <el-radio-button label="2">拼团</el-radio-button>
-              <el-radio-button label="3">砍价</el-radio-button>
-              <el-radio-button label="4">秒杀</el-radio-button>
+              <el-radio-button v-permission="'combination'" label="2">拼团</el-radio-button>
+              <el-radio-button v-permission="'bargain'" label="3">砍价</el-radio-button>
+              <el-radio-button v-permission="'seckill'" label="4">秒杀</el-radio-button>
             </el-radio-group>
           </el-form-item>
         </el-col>

+ 21 - 11
template/admin/src/components/uploadImg/index.vue

@@ -42,7 +42,6 @@
                   :auto-upload="false"
                   :data="uploadData"
                   :headers="header"
-                  :before-upload="beforeUpload"
                   :multiple="true"
                   :limit="limit"
                 >
@@ -136,7 +135,7 @@ import { getCookies } from '@/libs/util';
 import { fileUpload, scanUploadQrcode, scanUploadGet } from '@/api/setting';
 import QRCode from 'qrcodejs2';
 import compressImg from '@/utils/compressImg.js';
-
+import { isPicUpload } from '@/utils/index';
 export default {
   name: '',
   props: {
@@ -224,6 +223,10 @@ export default {
         this.$message.error('请先输入图片地址');
         return;
       }
+      if (this.webImgUrl.indexOf('.php') != -1) {
+        this.$message.error('请先输入其他图片地址');
+        return;
+      }
       this.ruleForm.imgList.push({
         url: this.webImgUrl,
       });
@@ -306,7 +309,9 @@ export default {
           });
       });
     },
-    beforeUpload(file) {},
+    beforeUpload(file) {
+      console.log(file);
+    },
     creatQrCode(url) {
       this.$refs.qrCodeUrl.innerHTML = '';
       var qrcode = new QRCode(this.$refs.qrCodeUrl, {
@@ -335,17 +340,22 @@ export default {
       console.log(file);
     },
     async fileChange(file, fileList) {
-      if (file.size >= 2097152) {
-        await this.comImg(file.raw).then((res) => {
-          fileList.map((e) => {
-            if (e.uid === file.uid) {
-              e.raw = res;
-            }
+      if (isPicUpload(file)) {
+        if (file.size >= 2097152) {
+          await this.comImg(file.raw).then((res) => {
+            fileList.map((e) => {
+              if (e.uid === file.uid) {
+                e.raw = res;
+              }
+            });
+            this.ruleForm.imgList = fileList;
           });
+        } else {
           this.ruleForm.imgList = fileList;
-        });
+        }
       } else {
-        this.ruleForm.imgList = fileList;
+        // 从ruleForm对象的imgList数组中删除最后一个元素
+        this.ruleForm.imgList.splice(this.ruleForm.imgList.length, 1);
       }
     },
     comImg(file) {

+ 19 - 16
template/admin/src/components/uploadVideo/index.vue

@@ -21,6 +21,7 @@
         :headers="header"
         :multiple="true"
         style="display: inline-block"
+        accept=".mp4"
       >
         <el-button type="primary" icon="ios-cloud-upload-outline">上传视频</el-button>
       </el-upload>
@@ -48,6 +49,7 @@ import { uploadByPieces } from '@/utils/upload'; //引入uploadByPieces方法
 import { productGetTempKeysApi, uploadType } from '@/api/product';
 import Setting from '@/setting';
 import { getCookies } from '@/libs/util';
+import { isVideoUpload } from '@/utils';
 
 // import '../../../public/UEditor/dialogs/internal';
 export default {
@@ -94,22 +96,23 @@ export default {
       }
     },
     videoSaveToUrl(file) {
-      uploadByPieces({
-        file: file, // 视频实体
-        pieceSize: 3, // 分片大小
-        success: (data) => {
-          this.formValidate.video_link = data.file_path;
-          this.progress = 100;
-        },
-        error: (e) => {
-          this.$message.error(e.msg);
-        },
-        uploading: (chunk, allChunk) => {
-          this.videoIng = true;
-          let st = Math.floor((chunk / allChunk) * 100);
-          this.progress = st;
-        },
-      });
+      if (isVideoUpload(filex))
+        uploadByPieces({
+          file: file, // 视频实体
+          pieceSize: 3, // 分片大小
+          success: (data) => {
+            this.formValidate.video_link = data.file_path;
+            this.progress = 100;
+          },
+          error: (e) => {
+            this.$message.error(e.msg);
+          },
+          uploading: (chunk, allChunk) => {
+            this.videoIng = true;
+            let st = Math.floor((chunk / allChunk) * 100);
+            this.progress = st;
+          },
+        });
       return false;
     },
     getToken() {

+ 19 - 16
template/admin/src/components/uploadVideo2/index.vue

@@ -21,6 +21,7 @@
         :headers="header"
         :multiple="true"
         style="display: inline-block"
+        accept=".mp4"
       >
         <el-button type="primary" icon="ios-cloud-upload-outline">上传视频</el-button>
       </el-upload>
@@ -48,6 +49,7 @@ import { uploadByPieces } from '@/utils/upload'; //引入uploadByPieces方法
 import { productGetTempKeysApi, uploadType } from '@/api/product';
 import Setting from '@/setting';
 import { getCookies } from '@/libs/util';
+import { isVideoUpload } from '@/utils';
 // import "../../../public/UEditor/dialogs/internal";
 export default {
   name: 'vide11o',
@@ -73,22 +75,23 @@ export default {
   },
   methods: {
     videoSaveToUrl(file) {
-      uploadByPieces({
-        file: file, // 视频实体
-        pieceSize: 3, // 分片大小
-        success: (data) => {
-          this.formValidate.video_link = data.file_path;
-          this.progress = 100;
-        },
-        error: (e) => {
-          this.$message.error(e.msg);
-        },
-        uploading: (chunk, allChunk) => {
-          this.videoIng = true;
-          let st = Math.floor((chunk / allChunk) * 100);
-          this.progress = st;
-        },
-      });
+      if (isVideoUpload(file))
+        uploadByPieces({
+          file: file, // 视频实体
+          pieceSize: 3, // 分片大小
+          success: (data) => {
+            this.formValidate.video_link = data.file_path;
+            this.progress = 100;
+          },
+          error: (e) => {
+            this.$message.error(e.msg);
+          },
+          uploading: (chunk, allChunk) => {
+            this.videoIng = true;
+            let st = Math.floor((chunk / allChunk) * 100);
+            this.progress = st;
+          },
+        });
       return false;
     },
     // 删除视频;

+ 6 - 1
template/admin/src/components/wangEditor/index.vue

@@ -189,7 +189,12 @@ export default {
   margin-bottom: 10px;
   cursor: pointer;
 }
-.monaco-box ::v-deep .el-textarea__inner{
+
+.monaco-box ::v-deep .el-textarea__inner {
   height: 600px;
 }
+
+::v-deep .w-e-toolbar {
+  z-index: 2 !important;
+}
 </style>

+ 3 - 2
template/admin/src/directive/directives.js

@@ -1,11 +1,12 @@
 import draggable from './module/draggable';
 import clipboard from './module/clipboard';
 import auth from './module/auth';
-
+import permission from './module/permission';
 const directives = {
   draggable,
   clipboard,
-  auth
+  auth,
+  permission
 };
 
 export default directives;

+ 3 - 1
template/admin/src/directive/index.js

@@ -21,8 +21,10 @@ const importDirective = (Vue) => {
   Vue.directive('clipboard', directive.clipboard);
   /**
    * v-auth="['string-string']"
-  * */
+   * */
   Vue.directive('auth', directive.auth);
+
+  Vue.directive('permission', directive.permission);
 };
 
 export default importDirective;

+ 38 - 0
template/admin/src/directive/module/permission.js

@@ -0,0 +1,38 @@
+import { Local } from '@/utils/storage.js';
+
+/**
+ * 判断传入的 key 是否在数组 arr 中存在
+ * @param {string} key - 待判断的字符串
+ * @returns {boolean} - 返回布尔值,表示是否有权限
+ */
+function checkArray(key) {
+  // seckill 秒杀 bargain 砍价 combination 拼团
+  let arr = Local.get('PERMISSIONS') || ['seckill', 'bargain', 'combination']; // 定义一个数组,包含三种类型
+  let index = arr.indexOf(key); // 获取 key 在数组中的索引
+  if (index > -1) {
+    // 如果索引大于 -1,说明 key 存在于数组中
+    return true; // 有权限
+  } else {
+    return false; // 无权限
+  }
+}
+
+/**
+ * @description 一个Vue指令,用于控制组件的显示和隐藏
+ * @param {Object} el - 指令绑定的DOM元素
+ * @param {Object} binding - 指令绑定的对象
+ */
+const permission = {
+  inserted: function (el, binding) {
+    let permission = binding.value; // 获取到 v-permission的值
+    if (permission) {
+      let hasPermission = checkArray(permission); // 调用checkArray函数判断是否有权限
+      if (!hasPermission) {
+        // 没有权限 移除Dom元素
+        el.parentNode && el.parentNode.removeChild(el);
+      }
+    }
+  },
+};
+
+export default permission;

+ 1 - 1
template/admin/src/i18n/lang/zh-cn.js

@@ -75,7 +75,7 @@ export default {
     dropdown4: '401',
     dropdown5: '退出登录',
     dropdown6: '个人中心',
-    searchPlaceholder: '菜单搜索:支持中文、路由路径',
+    searchPlaceholder: '菜单搜索:支持中文、路由路径、配置名称',
     newTitle: '通知',
     newBtn: '全部已读',
     newGo: '前往通知中心',

+ 2 - 2
template/admin/src/layout/component/aside.vue

@@ -57,9 +57,9 @@ export default {
       } else {
         // 其它布局给 64px
         if (isCollapse) {
-          return ['layout-aside-width64', asideBrColor];
+          return ['layout-aside-width1', asideBrColor];
         } else {
-          return ['layout-aside-width-default', asideBrColor];
+          return ['layout-aside-width-default', asideBrColor, layout === 'classic' ? 'pt8' : ''];
         }
       }
     },

+ 1 - 0
template/admin/src/layout/component/header.vue

@@ -16,6 +16,7 @@ export default {
     // 设置顶部 header 的具体高度
     setHeaderHeight() {
       let { isTagsview, layout } = this.$store.state.themeConfig.themeConfig;
+      if (layout == 'classic') return '66px';
       if (isTagsview && layout !== 'classic') return '84px';
       else return '50px';
     },

+ 10 - 11
template/admin/src/layout/component/transverseAside.vue

@@ -12,8 +12,8 @@
           :title="$t(v.title)"
         >
           <div :class="setColumnsAsidelayout" v-if="!v.isLink || (v.isLink && v.isIframe)">
-            <i :class="'el-icon-' + v.icon"></i>
-            <div class="font12">
+            <!-- <i :class="'el-icon-' + v.icon"></i> -->
+            <div class="font14">
               {{
                 $t(v.title) && $t(v.title).length >= 4
                   ? $t(v.title).substr(0, setColumnsAsidelayout === 'columns-vertical' ? 4 : 3)
@@ -23,8 +23,8 @@
           </div>
           <div :class="setColumnsAsidelayout" v-else>
             <a :href="v.isLink" target="_blank">
-              <i :class="'el-icon-' + v.icon"></i>
-              <div class="font12">
+              <!-- <i :class="'el-icon-' + v.icon"></i> -->
+              <div class="font14">
                 {{
                   $t(v.title) && $t(v.title).length >= 4
                     ? $t(v.title).substr(0, setColumnsAsidelayout === 'columns-vertical' ? 4 : 3)
@@ -253,7 +253,7 @@ export default {
     li {
       color: var(--prev-bg-columnsMenuBarColor);
       width: 80px;
-      height: 50px;
+      height: 66px;
       text-align: center;
       display: flex;
       cursor: pointer;
@@ -303,26 +303,25 @@ export default {
       background: var(--prev-color-primary);
       position: absolute;
       left: 0;
-      height: 40px;
+      height: 4px;
       width: 80px;
-      margin-top: 5px;
+      margin-top: 59px;
       transform: translatey(0%);
       z-index: 0;
       transition: 0.2s ease-in-out;
-      border-radius: 3px;
     }
     .columns-card {
       @extend .columns-round;
       top: 0;
-      height: 50px;
+      height: 4px;
       width: 80px;
       border-radius: 0;
-      margin-top: 0px;
+      margin-top: 59px;
     }
   }
 }
 ::v-deep .el-scrollbar {
-  height: 50px;
+  height: 66px;
 }
 ::v-deep .el-scrollbar__bar.is-horizontal {
   display: none;

+ 3 - 0
template/admin/src/layout/index.vue

@@ -1,9 +1,12 @@
 <template>
+  <!-- 根据头部菜单是否显示来判断显示哪个组件 -->
   <Mains v-if="headMenuNoShow" />
+  <!-- 根据主题配置中的布局类型来判断显示哪个组件 -->
   <Defaults v-else-if="getThemeConfig.layout === 'defaults'" />
   <Classic v-else-if="getThemeConfig.layout === 'classic'" />
   <Transverse v-else-if="getThemeConfig.layout === 'transverse'" />
   <Columns v-else-if="getThemeConfig.layout === 'columns'" />
+
 </template>
 
 <script>

+ 1 - 1
template/admin/src/layout/navBars/breadcrumb/index.vue

@@ -78,7 +78,7 @@ export default {
 
 <style scoped lang="scss">
 .layout-navbars-breadcrumb-index {
-  height: 50px;
+  height: 64px;
   display: flex;
   align-items: center;
   // padding-right: 15px;

+ 13 - 2
template/admin/src/layout/navBars/breadcrumb/search.vue

@@ -19,7 +19,9 @@
 </template>
 
 <script>
+import { menusSearch } from '@/api/setting';
 import { getAllSiderMenu } from '@/libs/system';
+
 export default {
   name: 'layoutBreadcrumbSearch',
   data() {
@@ -47,8 +49,17 @@ export default {
     },
     // 菜单搜索数据过滤
     menuSearch(queryString, cb) {
-      let results = queryString ? this.tagsViewList.filter(this.createFilter(queryString)) : this.tagsViewList;
-      cb(results);
+      if (!queryString) {
+        let results = queryString ? this.tagsViewList.filter(this.createFilter(queryString)) : this.tagsViewList;
+        cb(results);
+      } else {
+        let queryData = {
+          keyword: queryString,
+        };
+        menusSearch(queryData).then((res) => {
+          cb(res.data);
+        });
+      }
     },
     // 菜单搜索过滤
     createFilter(queryString) {

+ 54 - 8
template/admin/src/layout/navBars/breadcrumb/setings.vue

@@ -100,7 +100,10 @@
           </div>
         </div>
 
-        <div class="layout-breadcrumb-seting-bar-flex" v-if="getThemeConfig.layout === 'columns' || getThemeConfig.layout === 'defaults'">
+        <div
+          class="layout-breadcrumb-seting-bar-flex"
+          v-if="getThemeConfig.layout === 'columns' || getThemeConfig.layout === 'defaults'"
+        >
           <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.threeIsCollapse') }}</div>
           <div class="layout-breadcrumb-seting-bar-flex-value">
             <el-switch v-model="getThemeConfig.isCollapse" :width="35" @change="setLocalThemeConfig"> </el-switch>
@@ -287,16 +290,50 @@ export default {
     },
     setLocalTheme(val) {
       let themeSelect = themeList[val];
-
       themeSelect['--prev-border-color-lighter'] = '#ebeef5';
-      console.log(this.getThemeConfig.layout);
-      if (['classic', 'transverse'].includes(this.getThemeConfig.layout)) { //第三和第四种布局
+      /**
+       * 根据主题配置设置样式
+       * @param {string} val - 主题值
+       */
+      if (['classic'].includes(this.getThemeConfig.layout)) {
+        // 第三种布局
+        themeSelect['--prev-bg-topBar'] = '#282c34';
+        themeSelect['--prev-bg-topBarColor'] = '#fff';
+        // themeSelect['--prev-MenuActiveColor'] = '#fff';
+        themeSelect['--prev-bg-menuBarColor'] = '#515a6e';
+        themeSelect['--prev-bg-menu-hover-ba-color'] = '#e5eeff';
+        // themeSelect['--prev-MenuActiveColor'] = '#6954f0';
+        if (val == 'theme-1') {
+          themeSelect['--prev-bg-menuBar'] = '#fff';
+          themeSelect['--prev-border-color-lighter'] = '#282c34';
+        } else if (val == 'theme-3') {
+          // themeSelect['--prev-bg-menu-hover-ba-color'] = '#41b584';
+          themeSelect['--prev-bg-menuBar'] = '#fff';
+          themeSelect['--prev-border-color-lighter'] = '#282c34';
+        } else if (val == 'theme-5') {
+          // themeSelect['--prev-bg-menu-hover-ba-color'] = '#6954f0';
+          themeSelect['--prev-bg-menuBar'] = '#fff';
+          themeSelect['--prev-border-color-lighter'] = '#282c34';
+        } else if (val == 'theme-7') {
+          // themeSelect['--prev-bg-menu-hover-ba-color'] = '#f34d37';
+          themeSelect['--prev-bg-menuBar'] = '#fff';
+          themeSelect['--prev-border-color-lighter'] = '#282c34';
+        } else {
+          themeSelect['--prev-border-color-lighter'] = '#ebeef5';
+          themeSelect['--prev-bg-topBar'] = '#fff';
+          themeSelect['--prev-bg-topBarColor'] = '#515a6e';
+          themeSelect['--prev-bg-columnsMenuActiveColor'] = '#515a6e';
+
+          // themeSelect['--prev-bg-menuBarColor'] = '#515a6e';
+        }
+      } else if (['transverse'].includes(this.getThemeConfig.layout)) {
+        // 第四种布局
         themeSelect['--prev-bg-topBar'] = '#282c34';
         themeSelect['--prev-bg-topBarColor'] = '#fff';
         themeSelect['--prev-bg-menuBarColor'] = '#fff';
         themeSelect['--prev-MenuActiveColor'] = '#fff';
         if (val == 'theme-1') {
-          themeSelect['--prev-bg-menu-hover-ba-color'] = '#e8f4ff';
+          themeSelect['--prev-bg-menu-hover-ba-color'] = '#0256FF';
           themeSelect['--prev-bg-menuBar'] = '#282c34';
           themeSelect['--prev-border-color-lighter'] = '#282c34';
         } else if (val == 'theme-3') {
@@ -319,14 +356,15 @@ export default {
           themeSelect['--prev-bg-menuBarColor'] = '#515a6e';
           themeSelect['--prev-MenuActiveColor'] = '#515a6e';
         }
-      } else if (this.getThemeConfig.layout === 'columns') { //第二种布局
+      } else if (this.getThemeConfig.layout === 'columns') {
+        //第二种布局
         themeSelect['--prev-bg-topBar'] = '#fff';
         themeSelect['--prev-bg-topBarColor'] = '#515a6e';
         themeSelect['--prev-bg-menuBar'] = '#fff';
         themeSelect['--prev-bg-menuBarColor'] = '#303133';
         themeSelect['--prev-border-color-lighter'] = '#ebeef5';
         if (val == 'theme-1') {
-          themeSelect['--prev-bg-menu-hover-ba-color'] = '#e8f4ff';
+          themeSelect['--prev-bg-menu-hover-ba-color'] = '#e5eeff';
           themeSelect['--prev-color-primary'] = '#0256FF';
           themeSelect['--prev-MenuActiveColor'] = '#0256FF';
         } else if (val == 'theme-3') {
@@ -342,7 +380,8 @@ export default {
           themeSelect['--prev-color-primary'] = '#f34d37';
           themeSelect['--prev-MenuActiveColor'] = '#f34d37';
         }
-      } else { //默认布局
+      } else {
+        //默认布局
         if (val == 'theme-1') {
           themeSelect['--prev-bg-menuBar'] = '#282c34';
           themeSelect['--prev-color-primary'] = '#0256FF';
@@ -377,6 +416,7 @@ export default {
           themeSelect['--prev-bg-menu-hover-ba-color'] = '#f34d37';
         }
       }
+
       if (['theme-1', 'theme-2'].includes(val)) {
         this.$store.state.themeConfig.themeConfig.primary = '#0256FF'; //蓝黑蓝白
       } else if (['theme-3', 'theme-4'].includes(val)) {
@@ -388,10 +428,16 @@ export default {
       } else {
         this.$store.state.themeConfig.themeConfig.primary = '#0256FF'; //默认蓝
       }
+      /**
+       * 遍历主题选择对象,将其属性值设置为文档根元素的样式属性
+       */
       for (let key in themeSelect) {
+        // 将主题选择对象的属性作为样式属性名,属性值作为样式属性值,设置到文档根元素上
         document.documentElement.style.setProperty(key, themeSelect[key]);
       }
+      // 在下一次 DOM 更新循环结束后执行回调函数
       this.$nextTick((e) => {
+        // 调用 onColorPickerChange 方法
         this.onColorPickerChange();
       });
     },

+ 6 - 6
template/admin/src/layout/navBars/breadcrumb/theme.js

@@ -11,7 +11,7 @@ export const themeList = {
     '--prev-bg-columnsMenuBarColor': '#fff',
     '--prev-MenuActiveColor': '#0256FF',
     '--prev-tag-active-color': '#0256FF',
-    '--prev-color-primary-light-9': '#e8f4ff',
+    '--prev-color-primary-light-9': '#e5eeff',
     '--prev-bg-columnsMenuActiveColor': '#fff',
   },
   'theme-2': {
@@ -19,7 +19,7 @@ export const themeList = {
     '--prev-bg-menuBarColor': '#515a6e',
     '--prev-color-primary': '#0256FF',
     '--prev-color-text-white': '#fff',
-    '--prev-bg-menu-hover-ba-color': '#e8f4ff',
+    '--prev-bg-menu-hover-ba-color': '#e5eeff',
     '--prev-bg-topBar': '#ffffff',
     '--prev-bg-topBarColor': '#515a6e',
     '--prev-bg-columnsMenuBar': '#fff',
@@ -28,7 +28,7 @@ export const themeList = {
     '--prev-MenuActiveColor': '#0256FF',
     '--prev-bg-columnsMenuActiveBgColor': '#0256FF',
     '--prev-tag-active-color': '#0256FF',
-    '--prev-color-primary-light-9': '#e8f4ff',
+    '--prev-color-primary-light-9': '#e5eeff',
   },
   'theme-3': {
     '--prev-bg-menuBar': '#282c34',
@@ -82,7 +82,7 @@ export const themeList = {
     '--prev-bg-menuBarColor': '#515a6e',
     '--prev-color-primary': '#6954f0',
     '--prev-color-text-white': '#fff',
-    '--prev-bg-menu-hover-ba-color': '#e8f4ff',
+    '--prev-bg-menu-hover-ba-color': '#e5eeff',
     '--prev-bg-topBar': '#ffffff',
     '--prev-bg-topBarColor': '#515a6e',
     '--prev-bg-columnsMenuBar': '#fff',
@@ -126,7 +126,7 @@ export const themeList = {
     '--prev-bg-menuBarColor': '#515a6e',
     '--prev-color-primary': '#0256FF',
     '--prev-color-text-white': '#fff',
-    '--prev-bg-menu-hover-ba-color': '#e8f4ff',
+    '--prev-bg-menu-hover-ba-color': '#e5eeff',
     '--prev-bg-topBar': '#ffffff',
     '--prev-bg-topBarColor': '#515a6e',
     '--prev-bg-columnsMenuBar': 'linear-gradient(90deg,#006cff,#399efd)',
@@ -134,6 +134,6 @@ export const themeList = {
     '--prev-bg-columnsMenuActiveColor': '#fff',
     '--prev-tag-active-color': '#0256FF',
     '--prev-MenuActiveColor': '#0256FF',
-    '--prev-color-primary-light-9': '#e8f4ff',
+    '--prev-color-primary-light-9': '#e5eeff',
   },
 };

+ 10 - 0
template/admin/src/layout/navBars/breadcrumb/user.vue

@@ -89,13 +89,23 @@ export default {
     }
   },
   methods: {
+    /**
+     * 初始化 isDot 属性
+     * @param {boolean} status - 状态值
+     */
     initIsDot(status) {
       this.isDot = status;
     },
+    /**
+     * 打开新弹窗
+     */
     openNews() {
+      // 切换 isShowUserNewsPopover 属性值
       this.isShowUserNewsPopover = !this.isShowUserNewsPopover;
+      // 将 isDot 属性设置为 false
       this.isDot = false;
     },
+
     // 搜索点击
     onSearchClick() {
       this.$refs.searchRef.openSearch();

+ 13 - 1
template/admin/src/layout/routerView/parent.vue

@@ -28,16 +28,28 @@ export default {
     },
   },
   created() {
-    this.keepAliveNameList = this.getKeepAliveNames();
+    /**
+  * 获取需要保持活动状态的组件名称列表
+  */
+ this.keepAliveNameList = this.getKeepAliveNames();
+    // 监听标签页视图刷新路由视图事件
     this.bus.$on('onTagsViewRefreshRouterView', (path) => {
+      // 如果当前路由路径不等于传入的路径,则直接返回false
       if (this.$route.path !== path) return false;
+      // 过滤掉当前路由对应的组件名称,并重新设置keepAliveNameList
       this.keepAliveNameList = this.getKeepAliveNames().filter((name) => this.$route.name !== name);
+      // 刷新路由视图key
       this.refreshRouterViewKey = this.$route.path;
+      // 在下一个tick中重新设置keepAliveNameList
       this.$nextTick(() => {
         this.refreshRouterViewKey = null;
+        /**
+         * 获取需要保持活动状态的组件名称列表
+         */
         this.keepAliveNameList = this.getKeepAliveNames();
       });
     });
+
   },
 
   methods: {

+ 18 - 0
template/admin/src/libs/permission.js

@@ -0,0 +1,18 @@
+import { Local } from '@/utils/storage.js';
+
+/**
+ * 判断传入的 key 是否在数组 arr 中存在
+ * @param {string} key - 待判断的字符串
+ * @returns {boolean} - 返回布尔值,表示是否有权限
+ */
+export default function checkArray(key) {
+  // seckill 秒杀 bargain 砍价 combination 拼团
+  let arr = Local.get('PERMISSIONS') || ['seckill', 'bargain', 'combination']; // 定义一个数组,包含三种类型
+  let index = arr.indexOf(key); // 获取 key 在数组中的索引
+  if (index > -1) {
+    // 如果索引大于 -1,说明 key 存在于数组中
+    return true; // 有权限
+  } else {
+    return false; // 无权限
+  }
+}

+ 20 - 14
template/admin/src/pages/account/login/index.vue

@@ -63,7 +63,7 @@
     <div class="footer">
       <div class="pull-right" v-if="copyright">{{ copyright }}</div>
       <div class="pull-right" v-else>
-        Copyright © 2014-2023 <a href="https://www.crmeb.com" target="_blank">{{ version }}</a>
+        Copyright © 2014-2024 <a href="https://www.crmeb.com" target="_blank">{{ version }}</a>
       </div>
     </div>
   </div>
@@ -76,6 +76,7 @@ import '@/assets/js/canvas-nest.min';
 import Verify from '@/components/verifition/Verify';
 import { PrevLoading } from '@/utils/loading.js';
 import { formatFlatteningRoutes, findFirstNonNullChildren } from '@/libs/system';
+import { Local } from '@/utils/storage.js';
 
 export default {
   components: {
@@ -203,7 +204,7 @@ export default {
           setCookies('uuid', data.user_info.id, expires);
           setCookies('token', data.token, expires);
           setCookies('expires_time', data.expires_time, expires);
-
+          Local.set('PERMISSIONS', data.site_func);
           this.$store.commit('userInfo/uniqueAuth', data.unique_auth);
           this.$store.commit('userInfo/userInfo', data.user_info);
           // 保存菜单信息
@@ -414,7 +415,7 @@ export default {
 }
 
 .page-account-top {
-  padding: 20px 0 24px 0!important;
+  padding: 20px 0 24px 0 !important;
   box-sizing: border-box !important;
   display: flex;
   justify-content: center;
@@ -464,36 +465,41 @@ a:link, a:visited, a:hover, a:active {
 .from-wh {
   width: 400px;
 }
+
 .pull-right {
-    float: right!important;
+  float: right !important;
 }
-::v-deep .el-button--primary{
-  border:none;
+
+::v-deep .el-button--primary {
+  border: none;
 }
-::v-deep .el-button{
+
+::v-deep .el-button {
   padding: 13px 20px !important;
 }
+
 .pull-right {
-    float: right!important;
-    color: #666;
+  float: right !important;
+  color: #666;
 }
+
 .pull-right a {
-    margin-left: 0;
-    color: #666;
+  margin-left: 0;
+  color: #666;
 }
-.footer{
+
+.footer {
   position: fixed;
   bottom: 0;
   width: 100%;
   left: 0;
   margin: 0;
-  background: rgba(255,255,255,.8);
+  background: rgba(255, 255, 255, 0.8);
   border-top: 1px solid #e7eaec;
   overflow: hidden;
   padding: 10px 20px;
   height: 36px;
   line-height: 18px;
   z-index: 999;
-
 }
 </style>

+ 12 - 0
template/admin/src/pages/agent/handle/promotersList.vue

@@ -128,6 +128,16 @@
               <span>{{ scope.row.brokerage_price || 0 }}</span>
             </template>
           </el-table-column>
+          <el-table-column label="事业部返佣金额" min-width="130" v-if="rowsList.division_type == 1">
+            <template slot-scope="scope">
+              <span>{{ scope.row.division_brokerage || 0 }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="代理商返佣金额" min-width="130" v-if="rowsList.division_type == 2">
+            <template slot-scope="scope">
+              <span>{{ scope.row.agent_brokerage || 0 }}</span>
+            </template>
+          </el-table-column>
         </template>
       </el-table>
       <div class="acea-row row-right page">
@@ -187,6 +197,8 @@ export default {
           { text: '全部', val: '' },
           { text: '一级推广人订单', val: 1 },
           { text: '二级推广人订单', val: 2 },
+          { text: '事业部推广订单', val: 3 },
+          { text: '代理商推广订单', val: 4 },
         ],
       },
       formValidate: {

+ 146 - 0
template/admin/src/pages/app/routine/link/index.vue

@@ -0,0 +1,146 @@
+<template>
+  <div>
+    <el-card :bordered="false" shadow="never" class="ivu-mt">
+      <el-row class="mb20">
+        <el-col :span="24">
+          <el-button type="primary" @click="add" class="mr10">创建链接</el-button>
+        </el-col>
+      </el-row>
+      <el-table
+        :data="tableList"
+        v-loading="loading"
+        highlight-current-row
+        no-userFrom-text="暂无数据"
+        no-filtered-userFrom-text="暂无筛选结果"
+      >
+        <el-table-column label="编号" width="80">
+          <template slot-scope="scope">
+            <span>{{ scope.row.id }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="名称" width="180">
+          <template slot-scope="scope">
+            <span>{{ scope.row.title }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="跳转地址" width="180">
+          <template slot-scope="scope">
+            <span>{{ scope.row.path }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="生成链接" min-width="200">
+          <template slot-scope="scope">
+            <span>{{ scope.row.http_url }}</span>
+            <a class="ml10" @click="onCopy(scope.row.http_url)">复制</a>
+          </template>
+        </el-table-column>
+        <el-table-column label="添加时间" min-width="130">
+          <template slot-scope="scope">
+            <span>{{ scope.row.add_time }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="到期时间" min-width="130">
+          <template slot-scope="scope">
+            <span>{{ scope.row.expire_time }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" fixed="right" width="120">
+          <template slot-scope="scope">
+            <a @click="edit(scope.row)">编辑</a>
+            <el-divider direction="vertical"></el-divider>
+            <a @click="del(scope.row, '删除链接', scope.$index)">删除</a>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex';
+import { routineSchemeList, routineSchemeForm, routineSchemeDel } from '@/api/app';
+export default {
+  name: 'index',
+  computed: {
+    ...mapState('media', ['isMobile']),
+    labelWidth() {
+      return this.isMobile ? undefined : '80px';
+    },
+    labelPosition() {
+      return this.isMobile ? 'top' : 'right';
+    },
+  },
+  data() {
+    return {
+      verModal: false,
+      total: 20,
+      tableFrom: {
+        page: 1,
+        limit: 15,
+      },
+      loading: false,
+      tableList: [],
+    };
+  },
+  created() {
+    this.routineSchemeList();
+  },
+  methods: {
+    // 添加
+    add() {
+      this.$modalForm(routineSchemeForm(0)).then((res) => {
+        this.routineSchemeList();
+      });
+    },
+    onCopy(copyData) {
+      this.$copyText(copyData)
+        .then((message) => {
+          this.$message.success('复制成功');
+        })
+        .catch((err) => {
+          this.$message.error('复制失败');
+        });
+    },
+    // 列表
+    routineSchemeList() {
+      this.loading = true;
+      routineSchemeList(this.tableFrom)
+        .then((res) => {
+          this.tableList = res.data.list;
+          this.total = res.data.count;
+          this.loading = false;
+        })
+        .catch((err) => {
+          this.$message.error(err.msg);
+          this.loading = false;
+        });
+    },
+    // 添加
+    edit(row) {
+      this.$modalForm(routineSchemeForm(row.id)).then((res) => {
+        this.routineSchemeList();
+      });
+    },
+    // 删除
+    del(row, tit, num) {
+      let delfromData = {
+        title: tit,
+        num: num,
+        url: `app/routine/scheme_del/${row.id}`,
+        method: 'DELETE',
+        ids: '',
+      };
+      this.$modalSure(delfromData)
+        .then((res) => {
+          this.$message.success(res.msg);
+          this.tableList.splice(num, 1);
+        })
+        .catch((res) => {
+          this.$message.error(res.msg);
+        });
+    },
+  },
+};
+</script>
+
+<style scoped lang="stylus"></style>

+ 4 - 2
template/admin/src/pages/app/upload/index.vue

@@ -51,6 +51,8 @@
 import Setting from '@/setting';
 import { scanUpload } from '@/api/setting';
 import compressImg from '@/utils/compressImg.js';
+import { isPicUpload } from '@/utils';
+
 export default {
   name: 'app_upload_file',
   data() {
@@ -62,7 +64,7 @@ export default {
       uploading: true,
       limit: 20,
       loading: false,
-      pid: 0
+      pid: 0,
     };
   },
   created() {
@@ -143,7 +145,7 @@ export default {
       console.log(err, file, fileList);
     },
     beforeUpload(file) {
-      console.log(file);
+      return isPicUpload(file);
     },
     async fileChange(file, fileList) {
       if (file.size >= 2097152) {

+ 190 - 167
template/admin/src/pages/app/wechat/reply/follow.vue

@@ -1,9 +1,10 @@
 <template>
   <div>
     <pages-header
-        ref="pageHeader"
-        :title="$route.meta.title"
-        :backUrl="$routeProStr + '/app/wechat/reply/keyword'"></pages-header>
+      ref="pageHeader"
+      :title="$route.meta.title"
+      :backUrl="$routeProStr + '/app/wechat/reply/keyword'"
+    ></pages-header>
     <el-card :bordered="false" shadow="never" class="ivu-mt-16">
       <!-- 公众号设置 -->
       <el-row :gutter="24">
@@ -121,11 +122,12 @@
                           :show-file-list="false"
                           :action="fileUrl"
                           :on-success="handleSuccess"
-                          :format="formValidate.type === 'image' ? formatImg : formatVoice"
+                          :accept="formValidate.type === 'image' ? formatImg : formatVoice"
                           :max-size="2048"
                           :headers="header"
                           :on-format-error="handleFormatError"
                           :on-exceeded-size="handleMaxSize"
+                          :before-upload="beforeUpload"
                           class="mr20"
                           style="margin-top: 1px"
                         >
@@ -169,6 +171,8 @@ import { replyApi, keywordsinfoApi } from '@/api/app';
 // import { mapActions } from 'vuex'
 import newsCategory from '@/components/newsCategory/index';
 import { getCookies } from '@/libs/util';
+import { isPicUpload } from '@/utils';
+
 export default {
   name: 'follow',
   components: { newsCategory },
@@ -254,6 +258,7 @@ export default {
     }
   },
   methods: {
+    beforeUpload(file) {},
     getCentList(val) {
       this.formValidate.data.list = val.new;
       this.modals = false;
@@ -391,23 +396,25 @@ export default {
       if (this.$route.params.id && this.$route.params.id === '0') {
         this.$msgbox({
           title: '提示',
-          message:'是否继续添加',
+          message: '是否继续添加',
           showCancelButton: true,
           cancelButtonText: '否',
           confirmButtonText: '是',
           iconClass: 'el-icon-warning',
-          confirmButtonClass: 'btn-custom-cancel'
-        }).then(() => {
-          setTimeout(() => {
-            this.labelarr = [];
-            this.val = '';
-            this.$refs['formValidate'].resetFields();
-          }, 1000);
-        }).catch(() => {
-          setTimeout(() => {
-            this.$router.push({ path: this.$routeProStr + '/app/wechat/reply/keyword' });
-          }, 500);
+          confirmButtonClass: 'btn-custom-cancel',
         })
+          .then(() => {
+            setTimeout(() => {
+              this.labelarr = [];
+              this.val = '';
+              this.$refs['formValidate'].resetFields();
+            }, 1000);
+          })
+          .catch(() => {
+            setTimeout(() => {
+              this.$router.push({ path: this.$routeProStr + '/app/wechat/reply/keyword' });
+            }, 500);
+          });
       } else if (this.$route.params.id && this.$route.params.id !== '0') {
         this.$router.push({ path: this.$routeProStr + '/app/wechat/reply/keyword' });
       }
@@ -418,207 +425,223 @@ export default {
 
 <style scoped lang="stylus">
 * {
-    -moz-user-select: none; /*火狐*/
-    -webkit-user-select: none; /*webkit浏览器*/
-    -ms-user-select: none; /*IE10*/
-    -khtml-user-select: none; /*早期浏览器*/
-    user-select: none;
+  -moz-user-select: none; /* 火狐 */
+  -webkit-user-select: none; /* webkit浏览器 */
+  -ms-user-select: none; /* IE10 */
+  -khtml-user-select: none; /* 早期浏览器 */
+  user-select: none;
 }
 
 .arrbox {
-    background-color: white;
-    font-size: 12px;
-    border: 1px solid #dcdee2;
-    border-radius: 6px;
-    margin-bottom: 0px;
-    padding:0 5px;
-    text-align: left;
-    box-sizing border-box;
-    width: 90%;
-    .el-tag{
-      margin-right: 3px;
-    }
+  background-color: white;
+  font-size: 12px;
+  border: 1px solid #dcdee2;
+  border-radius: 6px;
+  margin-bottom: 0px;
+  padding: 0 5px;
+  text-align: left;
+  box-sizing: border-box;
+  width: 90%;
+
+  .el-tag {
+    margin-right: 3px;
+  }
 }
 
 .arrbox_ip {
-    font-size: 12px;
-    border: none;
-    box-shadow: none;
-    outline: none;
-    background-color: transparent;
-    padding: 0;
-    margin: 0;
-    width: auto !important;
-    max-width: inherit;
-    min-width: 80px;
-    vertical-align: top;
-    height: 30px;
-    color: #34495e;
-    margin: 2px;
-    line-height: 30px;
+  font-size: 12px;
+  border: none;
+  box-shadow: none;
+  outline: none;
+  background-color: transparent;
+  padding: 0;
+  margin: 0;
+  width: auto !important;
+  max-width: inherit;
+  min-width: 80px;
+  vertical-align: top;
+  height: 30px;
+  color: #34495e;
+  margin: 2px;
+  line-height: 30px;
 }
 
 .left {
-    min-width: 390px;
-    min-height: 550px;
-    position: relative;
-    padding-left: 40px;
+  min-width: 390px;
+  min-height: 550px;
+  position: relative;
+  padding-left: 40px;
 }
 
 .top {
-    position: absolute;
-    top: 0px;
+  position: absolute;
+  top: 0px;
 }
 
 .bottom {
-    position: absolute;
-    bottom: 0px;
+  position: absolute;
+  bottom: 0px;
 }
 
 .centent {
-    background: #f4f5f9;
-    min-height: 438px;
-    position: absolute;
-    top: 63px;
-    width: 320px;
-    height: 60%;
-    overflow-y: auto;
-    padding: 15px;
-    -webkit-box-sizing: border-box;
-    box-sizing: border-box;
+  background: #f4f5f9;
+  min-height: 438px;
+  position: absolute;
+  top: 63px;
+  width: 320px;
+  height: 60%;
+  overflow-y: auto;
+  padding: 15px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
 }
 
 .right {
-    background: #fff;
-    min-height: 300px;
+  background: #fff;
+  min-height: 300px;
 }
 
 .box-content {
-    position: relative;
-    max-width: 60%;
-    min-height: 40px;
-    margin-left: 15px;
-    padding: 10px;
-    box-sizing: border-box;
-    border: 1px solid #ccc;
-    word-break: break-all;
-    word-wrap: break-word;
-    line-height: 1.5;
-    border-radius: 5px;
+  position: relative;
+  max-width: 60%;
+  min-height: 40px;
+  margin-left: 15px;
+  padding: 10px;
+  box-sizing: border-box;
+  border: 1px solid #ccc;
+  word-break: break-all;
+  word-wrap: break-word;
+  line-height: 1.5;
+  border-radius: 5px;
 }
 
 .box-content_pic {
-    width: 100%;
+  width: 100%;
 }
 
 .box-content_pic img {
-    width: 100%;
-    height: auto;
+  width: 100%;
+  height: auto;
 }
 
 .box-content:before {
-    content: '';
-    position: absolute;
-    left: -13px;
-    top: 11px;
-    display: block;
-    width: 0;
-    height: 0;
-    border-left: 8px solid transparent;
-    border-right: 8px solid transparent;
-    border-top: 10px solid #ccc;
-    -webkit-transform: rotate(90deg);
-    transform: rotate(90deg);
+  content: '';
+  position: absolute;
+  left: -13px;
+  top: 11px;
+  display: block;
+  width: 0;
+  height: 0;
+  border-left: 8px solid transparent;
+  border-right: 8px solid transparent;
+  border-top: 10px solid #ccc;
+  -webkit-transform: rotate(90deg);
+  transform: rotate(90deg);
 }
 
 .box-content:after {
-    content: '';
-    content: '';
-    position: absolute;
-    left: -12px;
-    top: 11px;
-    display: block;
-    width: 0;
-    height: 0;
-    border-left: 8px solid transparent;
-    border-right: 8px solid transparent;
-    border-top: 10px solid #f5f5f5;
-    -webkit-transform: rotate(90deg);
-    transform: rotate(90deg);
+  content: '';
+  content: '';
+  position: absolute;
+  left: -12px;
+  top: 11px;
+  display: block;
+  width: 0;
+  height: 0;
+  border-left: 8px solid transparent;
+  border-right: 8px solid transparent;
+  border-top: 10px solid #f5f5f5;
+  -webkit-transform: rotate(90deg);
+  transform: rotate(90deg);
 }
 
 .time-wrapper {
-    margin-bottom: 10px;
-    text-align: center;
+  margin-bottom: 10px;
+  text-align: center;
 }
 
 .time {
-    display: inline-block;
-    color: #f5f5f5;
-    background: rgba(0, 0, 0, .3);
-    padding: 3px 8px;
-    border-radius: 3px;
-    font-size: 12px;
+  display: inline-block;
+  color: #f5f5f5;
+  background: rgba(0, 0, 0, 0.3);
+  padding: 3px 8px;
+  border-radius: 3px;
+  font-size: 12px;
 }
 
 .text-box {
-    display: flex;
+  display: flex;
 }
 
 .avatar {
-    width: 40px;
-    height: 40px;
+  width: 40px;
+  height: 40px;
 }
 
 .avatar img {
-    width: 100%;
-    height: 100%;
+  width: 100%;
+  height: 100%;
+}
+
+.modelBox {
+  ::v-deep .ivu-modal-body {
+    padding: 0 16px 16px 16px !important;
+  }
+}
+
+.news_pic {
+  width: 100%;
+  height: 150px;
+  overflow: hidden;
+  position: relative;
+  background-size: 100%;
+  background-position: center center;
+  border-radius: 5px 5px 0 0;
+  padding: 10px;
+  box-sizing: border-box;
+  display: flex;
+  flex-direction: column;
+  align-items: flex-end;
+}
+
+.news_sp {
+  font-size: 12px;
+  color: #000000;
+  background: #fff;
+  width: 100%;
+  height: 38px;
+  line-height: 38px;
+  padding: 0 12px;
+  box-sizing: border-box;
+  display: block;
+}
+
+.news_cent {
+  width: 100%;
+  height: auto;
+  background: #fff;
+  border-top: 1px dashed #eee;
+  display: flex;
+  padding: 10px;
+  box-sizing: border-box;
+  justify-content: space-between;
+
+  .news_sp1 {
+    font-size: 12px;
+    color: #000000;
+    width: 71%;
+  }
+
+  .news_cent_img {
+    width: 81px;
+    height: 46px;
+    border-radius: 6px;
+    overflow: hidden;
+
+    img {
+      width: 100%;
+      height: 100%;
+    }
+  }
 }
-.modelBox
-   ::v-deep .ivu-modal-body
-     padding 0 16px 16px 16px !important
-.news_pic
-    width: 100%
-    height: 150px
-    overflow: hidden
-    position: relative
-    background-size: 100%
-    background-position: center center
-    border-radius: 5px 5px 0 0
-    padding 10px
-    box-sizing border-box
-    display flex
-    flex-direction column
-    align-items: flex-end
-.news_sp
-    font-size 12px
-    color #000000
-    background #fff
-    width 100%
-    height 38px
-    line-height 38px
-    padding 0 12px
-    box-sizing border-box
-    display: block;
-.news_cent
-    width 100%
-    height auto
-    background #fff
-    border-top: 1px dashed #eee;
-    display flex
-    padding 10px
-    box-sizing border-box
-    justify-content: space-between
-    .news_sp1
-        font-size 12px
-        color #000000
-        width: 71%;
-    .news_cent_img
-        width 81px
-        height 46px
-        border-radius 6px
-        overflow hidden
-        img
-            width 100%
-            height 100%
 </style>

+ 16 - 11
template/admin/src/pages/division/agent/index.vue

@@ -67,16 +67,11 @@
                 <span> {{ scope.row.division_percent }}%</span>
               </template>
             </el-table-column>
-            <el-table-column label="代理商数量" min-width="130">
+            <el-table-column label="员工数量" min-width="130">
               <template slot-scope="scope">
                 <span>{{ scope.row.agent_count }}</span>
               </template>
             </el-table-column>
-            <el-table-column label="订单数量" min-width="130">
-              <template slot-scope="scope">
-                <span>{{ scope.row.order_count }}</span>
-              </template>
-            </el-table-column>
             <el-table-column label="截止时间" min-width="130">
               <template slot-scope="scope">
                 <span>{{ scope.row.division_end_time }}</span>
@@ -95,8 +90,10 @@
                 </el-switch>
               </template>
             </el-table-column>
-            <el-table-column label="操作" fixed="right" width="170">
+            <el-table-column label="操作" fixed="right" width="220">
               <template slot-scope="scope">
+                <a @click="staffAdd(scope.row.uid)">添加员工</a>
+                <el-divider direction="vertical"></el-divider>
                 <a @click="jump(scope.row.uid)">查看员工</a>
                 <el-divider direction="vertical"></el-divider>
                 <a @click="groupAdd(scope.row.uid)">编辑</a>
@@ -142,9 +139,9 @@
         <el-table-column label="姓名" min-width="130">
           <template slot-scope="scope">
             <div class="acea-row">
-              <i class="el-icon-male" v-show="scope.row.sex === '男'" style="color:#2db7f5;font-size: 15px;"></i>
-              <i class="el-icon-female" v-show="scope.row.sex === '女'" style="color:#ed4014;font-size: 15px;"></i>
-              <div v-text="scope.row.nickname" class="ml10"></div>
+              <i class="el-icon-male mr10" v-show="scope.row.sex === '男'" style="color:#2db7f5;font-size: 15px;"></i>
+              <i class="el-icon-female mr10" v-show="scope.row.sex === '女'" style="color:#ed4014;font-size: 15px;"></i>
+              <div v-text="scope.row.nickname" class=""></div>
             </div>
           </template>
         </el-table-column>
@@ -169,7 +166,7 @@
 
 <script>
 import { mapState } from 'vuex';
-import { regionList, agentFrom, isShowApi, clerkList } from '@/api/agent';
+import { regionList, agentFrom, isShowApi, clerkList, staffAddFrom } from '@/api/agent';
 import { formatDate } from '@/utils/validate';
 export default {
   name: 'agent_extra',
@@ -268,6 +265,14 @@ export default {
         })
         .catch((err) => {});
     },
+    //添加员工表单
+    staffAdd(id) {
+      this.$modalForm(staffAddFrom(id))
+        .then((res) => {
+          this.getList();
+        })
+        .catch((err) => {});
+    },
     // 修改是否显示
     onchangeIsShow(row) {
       let data = {

+ 1 - 6
template/admin/src/pages/division/list/index.vue

@@ -73,11 +73,6 @@
                 <span>{{ scope.row.agent_count }}</span>
               </template>
             </el-table-column>
-            <el-table-column label="订单数量" min-width="130">
-              <template slot-scope="scope">
-                <span>{{ scope.row.order_count }}</span>
-              </template>
-            </el-table-column>
             <el-table-column label="截止时间" min-width="130">
               <template slot-scope="scope">
                 <span>{{ scope.row.division_end_time }}</span>
@@ -222,7 +217,7 @@ export default {
     formatDate(time) {
       if (time !== 0) {
         let date = new Date(time * 1000);
-        return formatDate(date, 'yyyy-MM-dd hh:mm');
+        return formatDate(date, 'yyyy-MM-dd');
       }
     },
   },

+ 14 - 10
template/admin/src/pages/kefu/appChat/index.vue

@@ -97,7 +97,7 @@
                     :show-file-list="false"
                     :action="uploadAction"
                     :before-upload="beforeUpload"
-                    :format="['jpg', 'jpeg', 'png', 'gif']"
+                    accept="image/*"
                     :on-format-error="handleFormatError"
                     :data="uploadData"
                     :on-success="uploadSuccess"
@@ -152,6 +152,8 @@ import Setting from '@/setting';
 import Cookies from 'js-cookie';
 import { chatListApi, serviceListApi, getAdvApi, serviceList, getOrderApi, productApi } from '@/api/kefu';
 import feedBack from './feedback';
+import { isPicUpload } from '@/utils';
+
 const chunk = function (arr, num) {
   num = num * 1 || 1;
   var ret = [];
@@ -550,16 +552,18 @@ export default {
       });
     },
     beforeUpload(file) {
-      this.uploadData = {
-        filename: file,
-        token: this.kufuToken,
-      };
-      let promise = new Promise((resolve) => {
-        this.$nextTick(function () {
-          resolve(true);
+      if (isPicUpload(file)) {
+        this.uploadData = {
+          filename: file,
+          token: this.kufuToken,
+        };
+        let promise = new Promise((resolve) => {
+          this.$nextTick(function () {
+            resolve(true);
+          });
         });
-      });
-      return promise;
+        return promise;
+      }
     },
     handleFormatError(file) {
       this.$message.error('上传图片只能是 jpg、jpg、jpeg、gif 格式!');

+ 3 - 1
template/admin/src/pages/kefu/appChat/mobile/index.vue

@@ -98,7 +98,7 @@
           :headers="header"
           :multiple="true"
           :on-success="handleSuccess"
-          :format="['jpg', 'jpeg', 'png', 'gif']"
+          accept="image/*"
           :on-format-error="handleFormatError"
           style="margin-top: 1px; display: inline-block"
         >
@@ -129,6 +129,8 @@ import util from '@/libs/util';
 import emojiList from '@/utils/emoji';
 import { serviceList, serviceListApi, getOrderApi, chatListApi, productApi } from '@/api/kefu';
 import { getCookies, removeCookies, setCookies } from '@/libs/util';
+import { isPicUpload } from '@/utils';
+
 const chunk = function (arr, num) {
   num = num * 1 || 1;
   var ret = [];

+ 1 - 1
template/admin/src/pages/kefu/index.vue

@@ -45,7 +45,7 @@
     </div>
     <div class="foot-box" v-if="copyright">{{ copyright }}</div>
     <div class="foot-box" v-else>
-      Copyright © 2014-2023 <a href="https://www.crmeb.com" target="_blank">{{ version }}</a>
+      Copyright © 2014-2024 <a href="https://www.crmeb.com" target="_blank">{{ version }}</a>
     </div>
   </div>
 </template>

+ 1 - 1
template/admin/src/pages/kefu/mobile/chat_list.vue

@@ -39,7 +39,7 @@
         </div>
       </div>
       <div class="search-box">
-        <el-input v-model="searchTxt" placeholder="搜索用户名称" @on-enter="bindSearch" />
+        <el-input v-model="searchTxt" placeholder="搜索用户名称" @change="bindSearch" />
       </div>
     </div>
     <div class="list-box" v-if="list.length > 0">

+ 6 - 2
template/admin/src/pages/kefu/mobile/index.vue

@@ -69,7 +69,7 @@
           :headers="header"
           :multiple="true"
           :on-success="handleSuccess"
-          :format="['jpg', 'jpeg', 'png', 'gif']"
+          accept="image/*"
           :on-format-error="handleFormatError"
           style="margin-top: 1px; display: inline-block"
         >
@@ -130,6 +130,8 @@ import util from '@/libs/util';
 import emojiList from '@/utils/emoji';
 import { serviceList, speeChcraft, transferList, serviceCate, serviceTransfer } from '@/api/kefu';
 import { getCookies, removeCookies, setCookies } from '@/libs/util';
+import { isPicUpload } from '@/utils';
+
 const chunk = function (arr, num) {
   num = num * 1 || 1;
   var ret = [];
@@ -310,7 +312,9 @@ export default {
       }
     },
     // 上传之前
-    beforeUpload() {},
+    beforeUpload(file) {
+      return isPicUpload(file)
+    },
     // 上传成功
     handleSuccess(res, file, fileList) {
       if (res.status === 200) {

+ 14 - 4
template/admin/src/pages/kefu/pc/components/delivery.vue

@@ -99,7 +99,13 @@
         <el-form-item label="寄件人姓名:" prop="sendName" class="form-item" label-position="right" label-width="100px">
           <el-input v-model="formValidate.sendName" placeholder="请输入寄件人姓名" style="width: 100%"></el-input>
         </el-form-item>
-        <el-form-item label="寄件人电话:" prop="sendPhone" class="form-item" label-position="right" label-width="100px">
+        <el-form-item
+          label="寄件人电话:"
+          prop="sendPhone"
+          class="form-item"
+          label-position="right"
+          label-width="100px"
+        >
           <el-input v-model="formValidate.sendPhone" placeholder="请输入寄件人电话" style="width: 100%"></el-input>
         </el-form-item>
         <el-form-item
@@ -331,7 +337,10 @@ export default {
     },
     // 物流选中
     bindChange(val) {
-      this.formValidate.logisticsName = val.label;
+      let deliveryItem = this.logisticsList.find((item) => {
+        return item.code == val;
+      });
+      this.formValidate.logisticsName = deliveryItem.value;
       if (this.formValidate.shipStatus == 2) {
         orderTemp({
           com: val.value,
@@ -356,6 +365,7 @@ export default {
 </script>
 
 <style lang="stylus" scoped>
-.form-item
-    width 100%
+.form-item {
+  width: 100%;
+}
 </style>

+ 17 - 5
template/admin/src/pages/kefu/pc/components/rightMenu.vue

@@ -139,7 +139,10 @@
                 </div>
                 <div class="order-info">
                   <div class="info-item"><span>订单编号:</span>{{ item.order_id }}</div>
-                  <div class="info-item"><span>付款时间:</span>{{ item._pay_time }}</div>
+                  <div class="info-item">
+                    <span>{{ item.refund_status == 1 ? '发起时间' : '付款时间' }}:</span
+                    >{{ item.refund_status == 1 ? item.add_time : item._pay_time }}
+                  </div>
                   <div class="info-item"><span>邮费:</span>¥ {{ item.pay_postage }}</div>
                   <div class="info-item"><span>实收款:</span>¥ {{ item.pay_price }}</div>
                 </div>
@@ -161,7 +164,9 @@
                   <el-button class="btn" ghost @click.stop="orderEdit(item.id)" v-if="item._status._type == 0"
                     >改价</el-button
                   >
-                  <el-button class="btn" ghost @click.stop="bindRemark(item)">备注</el-button>
+                  <el-button v-if="item.refund_status == 0" class="btn" ghost @click.stop="bindRemark(item)"
+                    >备注</el-button
+                  >
                 </div>
               </div>
             </div>
@@ -516,7 +521,12 @@ export default {
     },
     // 订单改价
     orderEdit(id) {
-      this.$modalForm(orderEdit(id)).then(() => this.getOrderList());
+      this.$modalForm(orderEdit(id)).then(() => {
+        this.orderConfig.page = 1;
+        this.isOrderScroll = true;
+        this.orderList = [];
+        this.getOrderList();
+      });
     },
     // 订单退款
     orderRecord(id) {
@@ -626,10 +636,12 @@ export default {
 ::v-deep .ivu-select .ivu-select-dropdown, ::v-deep .ivu-date-picker .ivu-select-dropdown {
   top: unset !important;
 }
-.right-scroll{
+
+.right-scroll {
   max-height: 650px;
   overflow-y: scroll;
 }
+
 .right-wrapper {
   width: 280px;
 
@@ -889,8 +901,8 @@ color #6440C2, &.routine {
 
     .btn {
       width: 59px;
-      // margin-right: 5px;
 
+      // margin-right: 5px;
       &:last-child {
         margin-right: 0;
       }

+ 7 - 1
template/admin/src/pages/kefu/pc/index.vue

@@ -96,9 +96,10 @@
                     :headers="header"
                     :data="uploadData"
                     :on-success="handleSuccess"
-                    :format="['jpg', 'jpeg', 'png', 'gif']"
+                    accept="image/*"
                     :on-format-error="handleFormatError"
                     :action="upload"
+                    :before-upload="beforeUpload"
                   >
                     <span class="iconfont icontupian1"></span>
                   </el-upload>
@@ -188,6 +189,8 @@ import orderDetail from './components/order_detail';
 import { mapState } from 'vuex';
 import { getCookies, removeCookies, setCookies } from '@/libs/util';
 import { serviceInfo } from '@/api/kefu_mobile';
+import { isPicUpload } from '@/utils';
+
 const chunk = function (arr, num) {
   num = num * 1 || 1;
   var ret = [];
@@ -374,6 +377,9 @@ export default {
     // Socket.init(this,'kefu');
   },
   methods: {
+    beforeUpload(file) {
+     return isPicUpload(file);
+    },
     handleFormatError(file) {
       this.$message.error('上传图片只能是 jpg、jpg、jpeg、gif 格式!');
     },

+ 14 - 12
template/admin/src/pages/marketing/channelCode/channelCodeIndex.vue

@@ -39,18 +39,16 @@
       <el-col :span="20" ref="rightBox">
         <el-card :bordered="false" shadow="never">
           <el-row class="mb14">
-            <el-col :span="20">
+            <el-col :span="18">
               <el-button v-auth="['marketing-channel_code-create']" type="primary" @click="add">新建二维码</el-button>
               <!-- <el-button v-auth="['marketing-channel_code-create']" type="success" @click="addSort">添加分组</el-button> -->
             </el-col>
-            <el-col :span="4">
-              <el-input
-                v-model="tableFrom.name"
-                search
-                @on-search="userSearchs"
-                enter-button="搜索"
-                placeholder="请输入二维码名称"
-              />
+            <el-col :span="6">
+              <div class="flex">
+
+              <el-input class="mr10" v-model="tableFrom.name" search placeholder="请输入二维码名称"> </el-input>
+              <el-button type="primary" @click="userSearchs">搜索</el-button>
+              </div>
             </el-col>
           </el-row>
           <el-table
@@ -84,7 +82,9 @@
             </el-table-column>
             <el-table-column label="用户标签" min-width="80">
               <template slot-scope="scope">
-                <el-tag class="label-name" v-for="(item, index) in scope.row.label_name" :key="index">{{ item }}</el-tag>
+                <el-tag class="label-name" v-for="(item, index) in scope.row.label_name" :key="index">{{
+                  item
+                }}</el-tag>
               </template>
             </el-table-column>
             <el-table-column label="时间" min-width="80">
@@ -531,13 +531,15 @@ export default {
 }
 
 .modelBox {
-  ::v-deep , .ivu-table-header {
+  ::v-deep, .ivu-table-header {
     width: 100% !important;
   }
 }
-.label-name{
+
+.label-name {
   margin: 2px 2px;
 }
+
 .trees-coadd {
   width: 100%;
   height: 385px;

+ 20 - 10
template/admin/src/pages/marketing/channelCode/createCode.vue

@@ -114,6 +114,8 @@
               :on-exceeded-size="handleMaxSize"
               class="mr20"
               style="margin-top: 1px"
+              accept="image/*"
+              :before-upload="beforeUpload"
             >
               <el-button type="primary">上传</el-button>
             </el-upload>
@@ -126,7 +128,7 @@
         >立即提交</el-button
       >
     </el-card>
-    <el-dialog :visible.sync="customerShow" title="请选择商城用户" :show-close="true" width="720px">
+    <el-dialog :visible.sync="customerShow" title="请选择商城用户" :show-close="true" width="1000px">
       <customerInfo v-if="customerShow" @imageObject="imageObject"></customerInfo>
     </el-dialog>
     <!--图文消息 -->
@@ -166,6 +168,7 @@ import { wechatQrcodeSaveApi, wechatQrcodeTree, wechatQrcodeDetail } from '@/api
 import Setting from '@/setting';
 import { getCookies } from '@/libs/util';
 import customerInfo from '@/components/customerInfo';
+import { isPicUpload } from '@/utils';
 
 export default {
   name: 'storeCouponCreate',
@@ -241,6 +244,9 @@ export default {
     }
   },
   methods: {
+    beforeUpload(file) {
+      return isPicUpload(file);
+    },
     activeData(dataLabel) {
       this.labelShow = false;
       this.dataLabel = dataLabel;
@@ -393,9 +399,10 @@ export default {
 </script>
 
 <style scoped lang="stylus">
-.content_width{
-  width:460px;
+.content_width {
+  width: 460px;
 }
+
 .info {
   color: #888;
   font-size: 12px;
@@ -458,9 +465,11 @@ export default {
   cursor: pointer;
   vertical-align: middle;
 }
-::v-deep .el-tag{
+
+::v-deep .el-tag {
   margin-right: 5px;
 }
+
 .upload-list img {
   display: block;
   width: 100%;
@@ -554,17 +563,18 @@ textarea {
   padding: 10px;
   border-radius: 10px;
   margin-top: 20px;
-  position relative
+  position: relative;
 
   .news_pic {
     width: 100%;
     height: 150px;
   }
-  .del_icon{
-    position absolute
-    right -8px
-    top -8px
-    cursor pointer
+
+  .del_icon {
+    position: absolute;
+    right: -8px;
+    top: -8px;
+    cursor: pointer;
   }
 }
 

+ 0 - 2
template/admin/src/pages/marketing/lottery/create.vue

@@ -872,7 +872,6 @@ export default {
     },
     // 获取单张图片信息
     getPic(pc) {
-      console.log(pc, this.tableIndex, this.picTit, this.specsData);
       switch (this.picTit) {
         case 'danFrom':
           this.formValidate.image = pc.att_dir;
@@ -983,7 +982,6 @@ export default {
       }
       this.specsData = [];
       this.$nextTick((e) => {
-        console.log(arr);
         this.specsData = arr;
       });
     },

+ 1 - 11
template/admin/src/pages/marketing/recharge/index.vue

@@ -95,7 +95,6 @@
         </div>
       </div>
     </div>
-    <linkaddress ref="linkaddres" @linkUrl="linkUrl"></linkaddress>
   </div>
 </template>
 
@@ -119,15 +118,13 @@ import {
 } from '@/api/system';
 import draggable from 'vuedraggable';
 import uploadPictures from '@/components/uploadPictures';
-import linkaddress from '@/components/linkaddress';
 import { getCookies } from '@/libs/util';
 
 export default {
   name: 'list',
   components: {
     draggable,
-    uploadPictures,
-    linkaddress,
+    uploadPictures
   },
   computed: {
     bgcolors() {
@@ -336,9 +333,6 @@ export default {
       });
       return promise;
     },
-    linkUrl(e) {
-      this.tabList.list[this.activeIndexs].link = e;
-    },
     color() {
       getColorChange('color_change').then((res) => {
         switch (res.data.status) {
@@ -517,10 +511,6 @@ export default {
           });
       }
     },
-    link(index) {
-      this.activeIndexs = index;
-      this.$refs.linkaddres.modals = true;
-    },
     getListHeader() {
       this.loading = true;
       groupDataHeaderApi({ config_name: this.name }, 'setting/sign_data/header')

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

@@ -134,7 +134,7 @@
                   <div class="acea-row">
                     <el-input-number
                       :controls="false"
-                      :min="0.01"
+                      :min="0"
                       :max="9999999999"
                       v-model="formValidate.postage"
                       placeholder="请输入金额"
@@ -294,7 +294,7 @@
                         <template v-else-if="item.slot === 'pic'">
                           <div
                             class="acea-row row-middle row-center-wrapper"
-                            @click="modalPicTap('dan', 'danTable', index)"
+                            @click="modalPicTap('dan', 'danTable', scope.$index)"
                           >
                             <div class="pictrue pictrueTab" v-if="scope.row.pic">
                               <img v-lazy="scope.row.pic" />
@@ -359,6 +359,7 @@
             </div>
             <el-form-item>
               <el-button
+                v-if="current !== 0"
                 class="submission"
                 @click="step"
                 :disabled="($route.params.id && $route.params.id !== '0' && current === 1) || current === 0"

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

@@ -110,7 +110,7 @@
             <el-tag size="medium" type="info" v-show="scope.row.start_name === '已结束'">已结束</el-tag>
           </template>
         </el-table-column>
-        <el-table-column label="结束时间" min-width="120">
+        <el-table-column label="结束时间" min-width="140">
           <template slot-scope="scope">
             <span> {{ scope.row.stop_time | formatDate }}</span>
           </template>
@@ -165,7 +165,7 @@ export default {
     formatDate(time) {
       if (time !== 0) {
         let date = new Date(time * 1000);
-        return formatDate(date, 'yyyy-MM-dd hh:mm');
+        return formatDate(date, 'yyyy-MM-dd hh:mm:ss');
       }
     },
   },

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

@@ -182,7 +182,7 @@ export default {
         },
         {
           title: '帮砍人数',
-          slot: 'num',
+          key: 'num',
         },
         {
           title: '结束时间',

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

@@ -139,7 +139,7 @@
                   <div class="acea-row">
                     <el-input-number
                       :controls="false"
-                      :min="0.01"
+                      :min="0"
                       :max="9999999999"
                       v-model="formValidate.postage"
                       placeholder="请输入金额"
@@ -359,7 +359,7 @@
                         <template v-else-if="item.slot === 'pic'">
                           <div
                             class="acea-row row-middle row-center-wrapper"
-                            @click="modalPicTap('dan', 'danTable', index)"
+                            @click="modalPicTap('dan', 'danTable', scope.$index)"
                           >
                             <div class="pictrue pictrueTab" v-if="scope.row.pic">
                               <img v-lazy="scope.row.pic" />

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

@@ -176,7 +176,7 @@
                         <template v-else-if="item.slot === 'pic'">
                           <div
                             class="acea-row row-middle row-center-wrapper"
-                            @click="modalPicTap('dan', 'danTable', index)"
+                            @click="modalPicTap('dan', 'danTable', scope.$index)"
                           >
                             <div class="pictrue pictrueTab" v-if="scope.row.pic">
                               <img v-lazy="scope.row.pic" />

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

@@ -127,7 +127,7 @@
                   <div class="acea-row">
                     <el-input-number
                       :controls="false"
-                      :min="0.01"
+                      :min="0"
                       :max="9999999999"
                       v-model="formValidate.postage"
                       placeholder="请输入金额"
@@ -292,7 +292,7 @@
                         <template v-else-if="item.slot === 'pic'">
                           <div
                             class="acea-row row-middle row-center-wrapper"
-                            @click="modalPicTap('dan', 'danTable', index)"
+                            @click="modalPicTap('dan', 'danTable', scope.$index)"
                           >
                             <div class="pictrue pictrueTab" v-if="scope.row.pic">
                               <img v-lazy="scope.row.pic" />

+ 1 - 0
template/admin/src/pages/notify/smsConfig/index.vue

@@ -59,6 +59,7 @@ export default {
           data: {
             sms_account: data.data.accessKey,
             sms_token: data.data.secretKey,
+            sms_save_type: 'yihaotong'
           },
         }).then((res) => {});
       }

+ 53 - 18
template/admin/src/pages/order/orderList/components/tableFrom.vue

@@ -9,7 +9,7 @@
         inline
         @submit.native.prevent
       >
-        <el-form-item label="订单状态:">
+        <el-form-item label="订单类型:">
           <el-select
             v-model="orderData.status"
             clearable
@@ -17,16 +17,12 @@
             placeholder="全部"
             class="form_content_width"
           >
-            <el-option value="" label="全部"></el-option>
-            <el-option value="0" label="未支付"></el-option>
-            <el-option value="1" label="未发货"></el-option>
-            <el-option value="2" label="待收货"></el-option>
-            <el-option value="3" label="待评价"></el-option>
-            <el-option value="4" label="已完成"></el-option>
-            <el-option value="5" label="待核销"></el-option>
-            <el-option value="6" label="已完成"></el-option>
-            <el-option value="-2" label="已退款"></el-option>
-            <el-option value="-4" label="已删除"></el-option>
+            <el-option label="全部订单" value="" />
+            <el-option label="普通订单" value="1" />
+            <el-option v-permission="'combination'" label="拼团订单" value="2" />
+            <el-option v-permission="'seckill'" label="秒杀订单" value="3" />
+            <el-option v-permission="'bargain'" label="砍价订单" value="4" />
+            <el-option label="预售订单" value="5" />
           </el-select>
         </el-form-item>
         <el-form-item label="支付方式:">
@@ -152,14 +148,20 @@ export default {
     },
   },
   created() {
-    // this.timeVal = this.today;
-    // this.orderData.data = this.timeVal ? this.timeVal.join('-') : '';
+    this.setOrderKeyword('');
     if (this.$route.fullPath === this.$routeProStr + '/order/list?status=1') {
       this.getPath();
     }
   },
   methods: {
-    ...mapMutations('order', ['getOrderStatus', 'getOrderType', 'getOrderTime', 'setOrderKeyword', 'getfieldKey']),
+    ...mapMutations('order', [
+      'getOrderStatus',
+      'getOrderType',
+      'getOrderTime',
+      'onChangeTabs',
+      'setOrderKeyword',
+      'getfieldKey',
+    ]),
     getPath() {
       this.orderData.status = this.$route.query.status.toString();
       this.getOrderStatus(this.orderData.status);
@@ -200,13 +202,25 @@ export default {
     onchangeTime(e) {
       this.timeVal = e || [];
       this.orderData.data = this.timeVal[0] ? (this.timeVal ? this.timeVal.join('-') : '') : '';
-      this.$store.dispatch('order/getOrderTabs', { data: this.orderData.data });
+      this.$store.dispatch('order/getOrderTabs', { 
+        type: this.orderData.status,
+        data: this.orderData.data,
+        pay_type: this.orderData.pay_type,
+        field_key: this.orderData.field_key,
+        real_name: this.orderData.real_name,
+      });
       this.getOrderTime(this.orderData.data);
       this.$emit('getList', 1);
     },
     // 选择时间
     selectChange(tab) {
-      this.$store.dispatch('order/getOrderTabs', { data: tab });
+      this.$store.dispatch('order/getOrderTabs', { 
+        type: this.orderData.status,
+        data: this.orderData.data,
+        pay_type: this.orderData.pay_type,
+        field_key: this.orderData.field_key,
+        real_name: this.orderData.real_name,
+      });
       this.orderData.data = tab;
       this.getOrderTime(this.orderData.data);
       this.timeVal = [];
@@ -214,11 +228,25 @@ export default {
     },
     // 订单选择状态
     selectChange2(tab) {
-      this.getOrderStatus(tab);
-      this.$emit('getList', 1);
+      this.onChangeTabs(Number(tab));
+      this.$store.dispatch('order/getOrderTabs', { 
+        type: this.orderData.status,
+        data: this.orderData.data,
+        pay_type: this.orderData.pay_type,
+        field_key: this.orderData.field_key,
+        real_name: this.orderData.real_name,
+      });
+      // this.$emit('getList', 1);
     },
     userSearchs(type) {
       this.getOrderType(type);
+      this.$store.dispatch('order/getOrderTabs', { 
+        type: this.orderData.status,
+        data: this.orderData.data,
+        pay_type: this.orderData.pay_type,
+        field_key: this.orderData.field_key,
+        real_name: this.orderData.real_name,
+      });
       this.$emit('getList', 1);
     },
     // 时间状态
@@ -231,6 +259,13 @@ export default {
       this.setOrderKeyword(this.orderData.real_name);
       this.getfieldKey(this.orderData.field_key);
       this.$emit('getList', 1);
+      this.$store.dispatch('order/getOrderTabs', { 
+        type: this.orderData.status,
+        data: this.orderData.data,
+        pay_type: this.orderData.pay_type,
+        field_key: this.orderData.field_key,
+        real_name: this.orderData.real_name,
+      });
     },
     // 点击订单类型
     onClickTab() {

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

@@ -1,12 +1,15 @@
 <template>
   <div>
     <el-tabs v-model="currentTab" @tab-click="onClickTab" v-if="tablists">
-      <el-tab-pane :label="'全部订单(' + (tablists.all || 0) + ')'" name="" />
-      <el-tab-pane :label="'普通订单(' + (tablists.general || 0) + ')'" name="1" />
-      <el-tab-pane :label="'拼团订单(' + (tablists.pink || 0) + ')'" name="2" />
-      <el-tab-pane :label="'秒杀订单(' + (tablists.seckill || 0) + ')'" name="3" />
-      <el-tab-pane :label="'砍价订单(' + (tablists.bargain || 0) + ')'" name="4" />
-      <el-tab-pane :label="'预售订单(' + (tablists.advance || 0) + ')'" name="5" />
+      <el-tab-pane name="null" label="全部"></el-tab-pane>
+      <el-tab-pane name="0" :label="`待支付(${orderChartType.un_paid})`"></el-tab-pane>
+      <el-tab-pane name="1" :label="`待发货(${orderChartType.un_send})`"></el-tab-pane>
+      <el-tab-pane name="5" label="待核销"></el-tab-pane>
+      <el-tab-pane name="2" label="待收货"></el-tab-pane>
+      <el-tab-pane name="3" label="待评价"></el-tab-pane>
+      <el-tab-pane name="4" label="已完成"></el-tab-pane>
+      <el-tab-pane name="-2" label="已退款"></el-tab-pane>
+      <el-tab-pane name="-4" label="已删除"></el-tab-pane>
     </el-tabs>
     <div class="acea-row">
       <el-button v-auth="['order-write']" type="primary" @click="writeOff">订单核销</el-button>
@@ -36,7 +39,7 @@
       <el-table-column label="订单号 | 类型" width="200">
         <template slot-scope="scope">
           <div>{{ scope.row.order_id }}</div>
-          <div class="pink_name">{{ scope.row.pink_name }}</div>
+          <div class="pink_name" :style="{ color: scope.row.color }">{{ scope.row.pink_name }}</div>
           <span v-show="scope.row.is_del === 1" style="color: #ed4014; display: block">用户已删除</span>
         </template>
       </el-table-column>
@@ -129,7 +132,8 @@
               (scope.row.status === 4 || scope.row._status === 2 || scope.row._status === 8) &&
               scope.row.shipping_type === 1 &&
               (scope.row.pinkStatus === null || scope.row.pinkStatus === 2) &&
-              scope.row.is_del !== 1
+              scope.row.is_del !== 1 && 
+              !scope.row.refund.length
             "
             >发送货</a
           >
@@ -148,7 +152,7 @@
             direction="vertical"
             v-if="
               (scope.row._status === 2 && scope.row.shipping_type === 1 && scope.row.pinkStatus === 2) ||
-              (scope.row.split.length && scope.row.is_del !== 1)
+              (scope.row.split.length && scope.row.is_del !== 1 && !scope.row.refund.length)
             "
           />
           <el-divider
@@ -164,7 +168,7 @@
                   scope.row.status == 0 &&
                   scope.row.paid == 1 &&
                   scope.row.refund_status === 0)) &&
-              scope.row.is_del !== 1
+              scope.row.is_del !== 1 && !scope.row.refund.length
             "
           />
           <template>
@@ -196,7 +200,7 @@
                   "
                   >订单备注</el-dropdown-item
                 >
-                <!-- <el-dropdown-item command="5" v-show="!scope.row.refund.length">立即退款</el-dropdown-item> -->
+                <el-dropdown-item command="5" v-show="scope.row.paid == 1 && scope.row.refund_status == 0">立即退款</el-dropdown-item>
                 <!--                            <el-dropdown-item command="6"  v-show='scope.row._status !==1 && (scope.row.use_integral > 0 && scope.row.use_integral >= scope.row.back_integral) '>退积分</el-dropdown-item>-->
                 <!--                            <el-dropdown-item command="7"  v-show='scope.row._status === 3'>不退款</el-dropdown-item>-->
                 <el-dropdown-item command="8" v-show="scope.row._status === 4">已收货</el-dropdown-item>
@@ -235,6 +239,20 @@
         }
       "
     ></order-send>
+    <order-refund
+      ref="refund"
+      :orderId="orderId"
+      :status="status"
+      :pay_type="pay_type"
+      :virtual_type="virtual_type"
+      @submitFail="submitFail"
+      @clearId="
+        () => {
+          orderId = 0;
+          virtual_type = null;
+        }
+      "
+    ></order-refund>
     <!--    -->
     <el-dialog
       :visible.sync="modals2"
@@ -287,7 +305,15 @@
         <el-button @click="exportDeliveryList">导出发货单</el-button>
         <div class="pl20 tips"></div>
       </div>
-      <el-upload class="upload-demo" drag :action="expressUrl" :headers="header" :on-success="upExpress">
+      <el-upload
+        class="upload-demo"
+        accept=".doc,.docx,.xls,.xlsx"
+        drag
+        :action="expressUrl"
+        :headers="header"
+        :on-success="upExpress"
+        :before-upload="beforeUpload"
+      >
         <i class="el-icon-upload"></i>
         <div class="el-upload__text">批量发货单,拖入上传或<em>点击上传</em></div>
       </el-upload>
@@ -316,12 +342,14 @@ import editFrom from '../../../../components/from/from';
 import detailsFrom from '../handle/orderDetails';
 import orderRemark from '../handle/orderRemark';
 import orderSend from '../handle/orderSend';
+import orderRefund from '../handle/orderRefund';
 import orderShipment from '../handle/orderShipment';
 import { exportOrderList, exportOrderDeliveryList } from '@api/export';
 import Setting from '@/setting';
 import { getCookies } from '@/libs/util';
 import { serveOpnOtherApi } from '@api/setting';
 import createWorkBook from '@/vendor/newToExcel.js';
+import { isFileUpload } from '@/utils';
 
 export default {
   name: 'table_list',
@@ -332,6 +360,7 @@ export default {
     orderRemark,
     orderSend,
     orderShipment,
+    orderRefund,
   },
   data() {
     const codeNum = (rule, value, callback) => {
@@ -375,7 +404,7 @@ export default {
       orderDatalist: null,
       // modalTitleSs: '',
       selectedIds: [], //选中合并项的id
-      currentTab: '',
+      currentTab: 'null',
       spinShow: false,
       tablists: {
         all: '0',
@@ -405,6 +434,7 @@ export default {
       'orderType',
       'delIdList',
       'isDels',
+      'orderChartType'
     ]),
   },
   mounted() {},
@@ -421,8 +451,11 @@ export default {
     },
   },
   methods: {
-    ...mapMutations('order', ['onChangeTabs', 'getIsDel', 'getisDelIdListl']),
+    ...mapMutations('order', ['getOrderStatus', 'onChangeTabs', 'getIsDel', 'getisDelIdListl']),
     batchShipment() {},
+    beforeUpload(file) {
+      return isPicUpload(file);
+    },
     // 操作
     changeMenu(row, name) {
       this.orderId = row.id;
@@ -453,7 +486,15 @@ export default {
           this.$refs.remarks.formValidate.remark = row.remark;
           break;
         case '5':
-          this.getRefundData(row.id);
+          // this.getRefundData(row.id);
+          this.$refs.refund.total_num = row.total_num;
+          this.$refs.refund.order_id = row.order_id;
+          this.$refs.refund.formItem.refund_price = row.pay_price;
+          this.virtual_type = row.virtual_type;
+          this.$refs.refund.modals = true;
+          this.orderId = row.id;
+          this.status = row._status;
+          this.pay_type = row.pay_type;
           break;
         // case '6':
         //   this.getRefundIntegral(row.id);
@@ -770,8 +811,8 @@ export default {
         });
     },
     onClickTab() {
-      this.onChangeTabs(Number(this.currentTab));
-      this.$store.dispatch('order/getOrderTabs', { type: this.currentTab });
+      this.getOrderStatus(this.currentTab == 'null' ? '' : this.currentTab);
+      this.getList();
     },
     // 批量删除
     delAll() {
@@ -791,7 +832,7 @@ export default {
           this.$modalSure(delfromData)
             .then((res) => {
               this.$message.success(res.msg);
-              this.$emit('getList');
+              this.getList();
             })
             .catch((res) => {
               this.$message.error(res.msg);
@@ -889,7 +930,7 @@ export default {
               this.$message.success(res.msg);
               this.modals2 = false;
               this.$refs[name].resetFields();
-              this.$emit('getList', 1);
+              this.getList();
             } else {
               this.$message.error(res.msg);
             }
@@ -912,9 +953,10 @@ export default {
 </script>
 
 <style scoped lang="stylus">
-::v-deep .el-upload ,::v-deep .el-upload-dragger{
+::v-deep .el-upload, ::v-deep .el-upload-dragger {
   width: 100%;
 }
+
 ::v-deep .el-upload-list {
   display: none;
 }
@@ -995,8 +1037,9 @@ img {
 .w-120 {
   width: 120px;
 }
-.tips{
-    color: #c0c4cc;
+
+.tips {
+  color: #c0c4cc;
   font-size: 12px;
 }
 </style>

+ 300 - 0
template/admin/src/pages/order/orderList/handle/orderRefund.vue

@@ -0,0 +1,300 @@
+<template>
+  <el-dialog
+    :visible.sync="modals"
+    title="订单发送货"
+    class="order_box"
+    :show-close="true"
+    width="1000px"
+    @closed="changeModal"
+  >
+    <el-form
+      v-if="modals"
+      ref="formItem"
+      :rules="ruleValidate"
+      :model="formItem"
+      label-width="100px"
+      @submit.native.prevent
+    >
+      <el-form-item label="订单号:">
+        <el-input v-model="order_id" disabled placeholder="请输入订单号" style="width: 60%"></el-input>
+      </el-form-item>
+      <el-form-item label="退款金额:">
+        <el-input-number
+          v-model="formItem.refund_price"
+          placeholder="请输入退款金额"
+          style="width: 60%"
+        ></el-input-number>
+      </el-form-item>
+      <div v-if="total_num > 1">
+        <el-form-item label="分单退款:">
+          <el-switch
+            :active-value="1"
+            :inactive-value="0"
+            size="large"
+            v-model="splitSwitch"
+            :disabled="orderStatus === 8 || orderStatus === 11"
+            @change="changeSplitStatus"
+          >
+            <span slot="open">开启</span>
+            <span slot="close">关闭</span>
+          </el-switch>
+          <div class="trips">
+            <p>可选择表格中的商品单独退款,请谨慎操作!</p>
+          </div>
+          <el-table
+            v-if="splitSwitch && manyFormValidate.length"
+            ref="table"
+            :data="manyFormValidate"
+            @selection-change="selectOne"
+          >
+            <el-table-column type="selection" width="55"> </el-table-column>
+            <el-table-column label="商品信息" width="200">
+              <template slot-scope="scope">
+                <div class="product-data">
+                  <img class="image" :src="scope.row.cart_info.productInfo.image" />
+                  <div class="line2">
+                    {{ scope.row.cart_info.productInfo.store_name }}
+                  </div>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="规格" min-width="120">
+              <template slot-scope="scope">
+                <div>{{ scope.row.cart_info.productInfo.attrInfo.suk }}</div>
+              </template>
+            </el-table-column>
+            <el-table-column label="价格" min-width="120">
+              <template slot-scope="scope">
+                <div class="product-data">
+                  <div>{{ scope.row.cart_info.truePrice }}</div>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="总数" min-width="120">
+              <template slot-scope="scope">
+                <div>{{ scope.row.cart_num }}</div>
+              </template>
+            </el-table-column>
+            <el-table-column label="退款数量" width="180">
+              <template slot-scope="scope">
+                <el-input-number
+                  v-model="scope.row.num"
+                  :controls="false"
+                  :min="1"
+                  :max="scope.row.cart_num"
+                  @change="
+                    (e) => {
+                      handleChange(e, scope.row, scope.$index);
+                    }
+                  "
+                ></el-input-number>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form-item>
+      </div>
+    </el-form>
+    <div slot="footer">
+      <el-button @click="cancel">取消</el-button>
+      <el-button type="primary" @click="putSend">提交</el-button>
+    </div>
+    <!-- <viewer @inited="inited">
+            <img :src="temp.pic" style="display:none" />
+        </viewer> -->
+    <div ref="viewer" v-viewer>
+      <img :src="temp.pic" style="display: none" />
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import {
+  getExpressData,
+  putDelivery,
+  splitDelivery,
+  orderExpressTemp,
+  orderDeliveryList,
+  orderSheetInfo,
+  splitCartInfo,
+  orderPrice,
+  refundPrice,
+} from '@/api/order';
+import printJS from 'print-js';
+export default {
+  name: 'orderSend',
+  props: {
+    orderId: Number,
+    status: Number,
+    // total_num: Number,
+    pay_type: String,
+    virtual_type: {
+      type: Number,
+      default: 0,
+    },
+  },
+  data() {
+    return {
+      orderStatus: 0,
+      total_num: 0,
+      splitSwitch: true,
+      order_id: '',
+      formItem: {
+        refund_price: '',
+        cart_ids: [],
+      },
+      modals: false,
+      express: [],
+      kuaidiExpress: [],
+      expressTemp: [],
+      deliveryList: [],
+      temp: {},
+      export_open: false,
+      manyFormValidate: [],
+      selectData: [],
+      sendPrice: 0,
+      ruleValidate: { sh_delivery: [{ required: true, message: '请输入送货人', trigger: 'change' }] },
+      deliveryErrorMsg: '',
+      isLoading: true,
+      userSendmsg: {},
+    };
+  },
+  mounted() {},
+  methods: {
+    handleChange(e, params, index) {
+      params.num = e || 1;
+      this.manyFormValidate[index] = params;
+
+      let total = 0;
+      this.selectData.forEach((v, i) => {
+        total += this.manyFormValidate[i].num * this.manyFormValidate[i].cart_info.truePrice;
+      });
+      this.formItem.refund_price = total;
+    },
+    selectOne(data) {
+      this.selectData = data;
+      if (this.selectData.length) {
+        let total = 0;
+        this.selectData.forEach((v, i) => {
+          total += this.manyFormValidate[i].num * this.manyFormValidate[i].cart_info.truePrice;
+        });
+        this.formItem.refund_price = total;
+      }
+    },
+    changeModal() {
+      this.cancel();
+      this.isLoading = true;
+    },
+    changeSplitStatus(status) {
+      // this.splitSwitch = status;
+      if (status) {
+        splitCartInfo(this.orderId).then((res) => {
+          this.manyFormValidate = [];
+          Object.keys(res.data).forEach((key) => {
+            this.manyFormValidate.push(res.data[key]);
+          });
+        });
+      } else {
+        this.formItem.cart_ids = [];
+        this.selectData = [];
+      }
+    },
+    reset() {
+      this.formItem = {
+        refund_price: '',
+        cart_ids: [],
+      };
+    },
+    // 提交
+    putSend(name) {
+      this.formItem.cart_ids = [];
+      if (this.splitSwitch) {
+        this.selectData.forEach((v) => {
+          this.formItem.cart_ids.push({
+            cart_id: v.cart_id,
+            cart_num: v.num || v.surplus_num,
+          });
+        });
+      }
+      refundPrice(this.orderId, this.formItem)
+        .then((res) => {
+          this.modals = false;
+          this.$message.success(res.msg);
+          this.$emit('submitFail');
+          this.reset();
+          this.splitSwitch = false;
+          if (res.data.label) this.printImg(res.data.label);
+        })
+        .catch((res) => {
+          this.$message.error(res.msg);
+        });
+    },
+    cancel(name) {
+      this.modals = false;
+      this.orderStatus = 0;
+      this.sendPrice = 0;
+      this.deliveryErrorMsg = '';
+      this.splitSwitch = false;
+      this.selectData = [];
+      this.formItem.type = '1';
+      this.$emit('clearId');
+      this.reset();
+      // this.$refs[name].resetFields();
+      // this.formItem.type = '1';
+    },
+  },
+};
+</script>
+
+<style scoped>
+.express_temp_id {
+  position: relative;
+}
+
+.express_temp_id button {
+  position: absolute;
+  top: 50%;
+  left: 61%;
+  padding: 0;
+  border: none;
+  background: none;
+  transform: translateY(-50%);
+  color: #57a3f3;
+}
+
+.ivu-btn-text:focus {
+  box-shadow: none;
+}
+.trips {
+  color: #ccc;
+  font-size: 12px;
+}
+.product-data {
+  display: flex;
+  align-items: center;
+  /* width: 200px; */
+}
+.product-data .image {
+  width: 50px !important;
+  height: 50px !important;
+  margin-right: 10px;
+}
+.line2 {
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+}
+.from-box {
+  position: relative;
+}
+.trip {
+  position: absolute;
+  bottom: -26px;
+  left: 0;
+  color: red;
+  font-size: 12px;
+}
+.coumped {
+  font-size: 12px;
+}
+</style>

+ 0 - 1
template/admin/src/pages/order/orderList/handle/orderSend.vue

@@ -599,7 +599,6 @@ export default {
         if (expressItem.list.length) {
           this.formItem.express_temp_id = expressItem.list[0].temp_id;
           this.temp = expressItem.list[0];
-          console.log(expressItem.list[0], 'expressItem.list[0]');
         }
       }
     },

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

@@ -4,7 +4,7 @@
     <div class="putSupplier perpage" v-for="(item, index) in newArrayData" :key="index">
       <div class="header acea-row row-between-wrapper">
         <div class="left acea-row row-middle">
-          <div class="picture" :id="'qrCodeUrl' + index"></div>
+          <!-- <div class="picture" :id="'qrCodeUrl' + index"></div> -->
           <div class="info">
             <div><span class="name">收货人:</span>{{ orderData.user_name }}</div>
             <div><span class="name">收货地址:</span>{{ orderData.user_address }}</div>

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

@@ -10,7 +10,7 @@
             @submit.native.prevent
             inline
         >
-          <el-form-item label="订单状态:">
+          <el-form-item label="退款状态:">
             <el-select
                 v-model="pagination.refund_type"
                 clearable

+ 50 - 20
template/admin/src/pages/product/productAdd/index.vue

@@ -146,6 +146,7 @@
                 :headers="header"
                 :multiple="false"
                 style="display: inline-block"
+                accept=".mp4"
               >
                 <div v-if="seletVideo === 0 && !formValidate.video_link" class="videbox">+</div>
               </el-upload>
@@ -1378,8 +1379,9 @@
                 </div>
               </div>
               <div class="add-more" v-if="disk_type == 2">
-                <el-button type="primary" @click="handleAdd">新增</el-button>
-                <el-upload class="ml10" :action="cardUrl" :data="uploadData" :headers="header" :on-success="upFile">
+                <el-button class="h-33" type="primary" @click="handleAdd">新增</el-button>
+                <el-upload class="ml10" :action="cardUrl" :data="uploadData" :headers="header" :on-success="upFile" :before-upload="beforeUpload"
+ >
                   <el-button>导入卡密</el-button>
                 </el-upload>
               </div>
@@ -1459,6 +1461,8 @@ import {
 import Setting from '@/setting';
 import { getCookies } from '@/libs/util';
 import { uploadByPieces } from '@/utils/upload'; //引入uploadByPieces方法
+import { isFileUpload, isVideoUpload } from '@/utils';
+import checkArray from '@/libs/permission';
 
 export default {
   name: 'product_productAdd',
@@ -1914,7 +1918,7 @@ export default {
         },
       ],
       columnsInstalM: [],
-      moveIndex: '',
+      moveIndex: ''
     };
   },
   computed: {
@@ -2004,6 +2008,7 @@ export default {
                 },
               ];
             }
+            this.watchActivity()
             this.spinShow = false;
           }
         })
@@ -2022,26 +2027,32 @@ export default {
     this.productGetTemplate();
     // this.userLabel();
     this.uploadType();
+    this.watchActivity()
   },
   methods: {
+    beforeUpload(file) {
+      return isFileUpload(file)
+    },
     // 分片上传
     videoSaveToUrl(file) {
-      uploadByPieces({
-        file: file, // 视频实体
-        pieceSize: 3, // 分片大小
-        success: (data) => {
-          this.formValidate.video_link = data.file_path;
-          this.progress = 100;
-        },
-        error: (e) => {
-          this.$message.error(e.msg);
-        },
-        uploading: (chunk, allChunk) => {
-          this.videoIng = true;
-          let st = Math.floor((chunk / allChunk) * 100);
-          this.progress = st;
-        },
-      });
+      if(isVideoUpload(file)){
+        uploadByPieces({
+          file: file, // 视频实体
+          pieceSize: 3, // 分片大小
+          success: (data) => {
+            this.formValidate.video_link = data.file_path;
+            this.progress = 100;
+          },
+          error: (e) => {
+            this.$message.error(e.msg);
+          },
+          uploading: (chunk, allChunk) => {
+            this.videoIng = true;
+            let st = Math.floor((chunk / allChunk) * 100);
+            this.progress = st;
+          },
+        });
+      }
       return false;
     },
     // 类型选择/填入内容判断
@@ -2231,6 +2242,7 @@ export default {
           },
         ];
       }
+      this.watchActivity()
     },
     //关闭淘宝弹窗并生成数据;
     onClose(data) {
@@ -2979,7 +2991,6 @@ export default {
     openLabel(row) {
       this.labelShow = true;
       this.$nextTick((e) => {
-        console.log(this.$refs.userLabel);
         // this.$refs.userLabel.userLabel(JSON.parse(JSON.stringify(this.dataLabel)));
       });
     },
@@ -2997,6 +3008,24 @@ export default {
     handleRemoveRecommend(i) {
       this.formValidate.recommend_list.splice(i, 1);
     },
+    watchActivity() {
+      let marketing = []
+       this.formValidate.activity.map((el) => {
+        if (el == '默认') {
+          marketing.push(el);
+        }
+        if (el == '秒杀' && checkArray('seckill')) {
+          marketing.push(el);
+        } 
+         if (el == '砍价' && checkArray('bargain')) {
+          marketing.push(el);
+        } 
+         if (el == '拼团' && checkArray('combination')) {
+          marketing.push(el);
+        } 
+      });
+      this.formValidate.activity = marketing
+    },
   },
 };
 </script>
@@ -3146,6 +3175,7 @@ export default {
   align-items: center;
   .item{
     display:flex;
+    flex-wrap: wrap;
   }
 }
 

+ 1 - 1
template/admin/src/pages/product/productList/taoBao.vue

@@ -170,7 +170,7 @@
                           <template v-else-if="item.slot === 'pic'">
                             <div
                               class="acea-row row-middle row-center-wrapper"
-                              @click="modalPicTap('dan', 'duopi', index)"
+                              @click="modalPicTap('dan', 'duopi', scope.$index)"
                             >
                               <div class="pictrue pictrueTab" v-if="oneFormBatch[0].pic">
                                 <img v-lazy="oneFormBatch[0].pic" />

+ 14 - 3
template/admin/src/pages/setting/devise/diyIndex.vue

@@ -243,6 +243,7 @@ import { mapState } from 'vuex';
 import html2canvas from 'html2canvas';
 import QRCode from 'qrcodejs2';
 import { writeUpdate } from '@api/order';
+import checkArray from '@/libs/permission';
 
 let idGlobal = 0;
 export default {
@@ -384,8 +385,10 @@ export default {
     },
     preview(row) {
       this.modal = true;
-      this.creatQrCode(row.id);
-      this.routineCode(this.$route.query.id);
+      this.$nextTick((e) => {
+        this.creatQrCode(row.id);
+        this.routineCode(this.$route.query.id);
+      });
     },
     //生成二维码
     creatQrCode(id) {
@@ -780,7 +783,15 @@ export default {
           basis.list.push(el);
         }
         if (el.type == 1) {
-          marketing.list.push(el);
+          if (el.name == 'home_seckill' && checkArray('seckill')) {
+            marketing.list.push(el);
+          } else if (el.name == 'home_bargain' && checkArray('bargain')) {
+            marketing.list.push(el);
+          } else if (el.name == 'home_pink' && checkArray('combination')) {
+            marketing.list.push(el);
+          } else if (el.name != 'home_seckill' && el.name != 'home_bargain' && el.name != 'home_pink') {
+            marketing.list.push(el);
+          }
         }
         if (el.type == 2) {
           tool.list.push(el);

+ 56 - 0
template/admin/src/pages/setting/notification/components/keysList.vue

@@ -0,0 +1,56 @@
+<template>
+  <div>
+    <div class="virtual-data mb10" v-for="(item, index) in keyList" :key="index">
+      <el-input
+        class="mr10"
+        type="text"
+        v-model.trim="item.key"
+        style="width: 150px"
+        placeholder="请输入字段名称"
+        disabled
+      ></el-input>
+
+      <span class="mr10 virtual-title">-></span>
+
+      <el-select v-model="item.value" placeholder="请选择">
+        <el-option v-for="item in variableList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
+      </el-select>
+
+      <!-- <el-button v-if="keyList.length" class="deteal-btn mr10" @click="remove(index)"> 删除 </el-button> -->
+    </div>
+
+    <div class="add-more">
+      <!-- <el-button class="h-33" type="primary" @click="add"> 新增 </el-button> -->
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    keyList: {
+      type: Array,
+      required: true,
+    },
+    variableList: {
+      type: Array,
+      required: true,
+    },
+  },
+  methods: {
+    add() {
+      this.$emit('add');
+    },
+    remove(index) {
+      this.$emit('remove', index);
+    },
+  },
+};
+</script>
+
+<style scoped>
+.virtual-title {
+  font-size: 12px;
+  color: #303133;
+}
+</style>

+ 37 - 4
template/admin/src/pages/setting/notification/index.vue

@@ -21,6 +21,11 @@
           >
         </el-col>
       </el-row>
+      <el-row class="mb14" v-if="currentTab == 3">
+        <el-col>
+          <el-button type="primary" @click="notificationForm(0)">添加通知</el-button>
+        </el-col>
+      </el-row>
       <el-alert v-if="currentTab == 1" type="warning" :closable="false">
         <template slot="title">
           <p class="alert_title">小程序订阅消息</p>
@@ -136,9 +141,15 @@
             <div v-else>-</div>
           </template>
         </el-table-column>
-        <el-table-column label="操作" fixed="right" width="70">
+        <el-table-column label="操作" fixed="right" :width="currentTab == 3 ? 130 :70">
           <template slot-scope="scope">
             <a class="setting btn" @click="setting(item, scope.row)">设置</a>
+            <template v-if="currentTab == 3">
+              <el-divider direction="vertical"></el-divider>
+              <a class="setting btn" @click="notificationForm(scope.row.id)">编辑</a>
+              <el-divider direction="vertical"></el-divider>
+              <a class="setting btn" @click="del(scope.row, '删除', scope.$index)">删除</a>
+            </template>
           </template>
         </el-table-column>
       </el-table>
@@ -147,7 +158,7 @@
 </template>
 
 <script>
-import { getNotificationList, getNotificationInfo, noticeStatus } from '@/api/notification.js';
+import { getNotificationList, getNotificationInfo, noticeStatus, notificationForm } from '@/api/notification.js';
 import { routineSyncTemplate, wechatSyncTemplate } from '@/api/app';
 export default {
   data() {
@@ -155,8 +166,9 @@ export default {
       modalTitle: '',
       notificationModal: false,
       headerList: [
-        { label: '通知会员', value: '1' },
-        { label: '通知平台', value: '2' },
+        { label: '会员通知', value: '1' },
+        { label: '平台通知', value: '2' },
+        { label: '自定义通知', value: '3' },
       ],
       levelLists: [],
       currentTab: '1',
@@ -177,6 +189,9 @@ export default {
           this.$message.error(err.msg);
         });
     },
+    notificationForm(id) {
+      this.$modalForm(notificationForm(id)).then(() => this.changeTab());
+    },
     changeTab() {
       getNotificationList(this.currentTab).then((res) => {
         this.levelLists = res.data;
@@ -224,6 +239,24 @@ export default {
         this.notificationModal = true;
       });
     },
+    // 删除
+    del(row, tit, num) {
+      let delfromData = {
+        title: tit,
+        num: num,
+        url: `setting/notification/del_not/${row.id}`,
+        method: 'DELETE',
+        ids: '',
+      };
+      this.$modalSure(delfromData)
+        .then((res) => {
+          this.$message.success(res.msg);
+          this.levelLists.splice(num, 1);
+        })
+        .catch((res) => {
+          this.$message.error(res.msg);
+        });
+    },
   },
 };
 </script>

+ 211 - 33
template/admin/src/pages/setting/notification/notificationEdit.vue

@@ -22,19 +22,35 @@
                   <el-form-item label="通知内容:">
                     <div class="content">
                       <el-input
+                        ref="system_text"
+                        id="system_text"
                         v-model="formData.system_text"
                         type="textarea"
                         :autosize="{ minRows: 5, maxRows: 8 }"
                         placeholder="请输入通知内容"
                         style="width: 500px"
-                      ></el-input>
-                      <div class="trip">
-                        <div>请输入模板消息详细内容对应的变量。关键字个数需与已添加的模板一致。 可以使用如下变量:</div>
-                        <div v-for="(i, index) in formData.variable.split(',')" :key="index">
-                          {{ i }}
-                        </div>
+                      >
+                      </el-input>
+                      <div class="value-list" v-if="formData.type_n == 3">
+                        <el-popover placement="right" width="200" trigger="click">
+                          <div class="variable">
+                            <div
+                              class="item"
+                              @click="changeValue(i.value)"
+                              v-for="(i, index) in formData.custom_variable"
+                              :key="index"
+                            >
+                              {{ i.label }}
+                            </div>
+                          </div>
+
+                          <i class="el-icon-link" slot="reference"></i>
+                        </el-popover>
                       </div>
                     </div>
+                    <div class="tips-info">
+                      可点击右下角图标,插入自定义变量
+                    </div>
                   </el-form-item>
                   <el-form-item label="状态:" prop="is_system">
                     <el-radio-group v-model="formData.is_system">
@@ -50,13 +66,32 @@
                   <el-form-item label="通知内容:">
                     <div class="content">
                       <el-input
-                        v-model="formData.content"
+                        v-model="formData.sms_text"
                         type="textarea"
-                        disabled
+                        :disabled="formData.type_n != 3"
                         :autosize="{ minRows: 5, maxRows: 8 }"
                         placeholder="请输入通知内容"
                         style="width: 500px"
                       ></el-input>
+                      <div class="value-list" v-if="formData.type_n == 3">
+                        <el-popover placement="right" width="200" trigger="click">
+                          <div class="variable">
+                            <div
+                              class="item"
+                              @click="changeValue(i.value)"
+                              v-for="(i, index) in formData.custom_variable"
+                              :key="index"
+                            >
+                              {{ i.label }}
+                            </div>
+                          </div>
+
+                          <i class="el-icon-link" slot="reference"></i>
+                        </el-popover>
+                      </div>
+                    </div>
+                    <div class="tips-info">
+                      可点击右下角图标,插入自定义变量
                     </div>
                   </el-form-item>
                   <el-form-item label="状态:" prop="is_sms">
@@ -70,23 +105,52 @@
                   <el-form-item label="模板编号:">
                     <el-input
                       v-model="formData.tempkey"
-                      disabled
+                      :disabled="formData.type_n !== 3"
                       placeholder="请输入通模板编号"
                       style="width: 500px"
                     ></el-input>
                   </el-form-item>
+                  <el-form-item label="模板ID:">
+                    <el-input v-model="formData.tempid" placeholder="请输入模板ID" style="width: 500px"></el-input>
+                  </el-form-item>
                   <el-form-item label="模板:">
+                    <div class="content">
+                      <el-input
+                        :disabled="formData.type_n !== 3"
+                        v-model="formData.content"
+                        type="textarea"
+                        :autosize="{ minRows: 5, maxRows: 8 }"
+                        placeholder="请输入模板"
+                        style="width: 500px"
+                        @input="handleContentChange"
+                      ></el-input>
+                    </div>
+                  </el-form-item>
+                  <el-form-item label="字段:" v-if="formData.type_n == 3 && keyList.length">
+                    <div class="content">
+                      <keys-list
+                        :key-list="keyList"
+                        :variableList="formData.custom_variable"
+                        @add="handleAdd"
+                        @remove="handleRemove"
+                      />
+                    </div>
+                  </el-form-item>
+                  <el-form-item label="跳转链接:">
                     <el-input
-                      disabled
-                      v-model="formData.content"
-                      type="textarea"
-                      :autosize="{ minRows: 5, maxRows: 8 }"
-                      placeholder="请输入模板"
+                      v-model="formData.wechat_link"
+                      placeholder="请输入模版跳转链接,可携带参数"
                       style="width: 500px"
                     ></el-input>
                   </el-form-item>
-                  <el-form-item label="模板ID:">
-                    <el-input v-model="formData.tempid" placeholder="请输入模板ID" style="width: 500px"></el-input>
+                  <el-form-item label="跳转小程序:" prop="wechat_to_routine">
+                    <el-radio-group v-model="formData.wechat_to_routine">
+                      <el-radio :label="1">开启</el-radio>
+                      <el-radio :label="0">关闭</el-radio>
+                    </el-radio-group>
+                    <div class="tips-info">
+                      开启之后,点击模版消息,跳转小程序对应的页面,需要小程序已经审核上线才可使用
+                    </div>
                   </el-form-item>
                   <el-form-item label="状态:" prop="is_wechat">
                     <el-radio-group v-model="formData.is_wechat">
@@ -99,24 +163,44 @@
                   <el-form-item label="模板编号:">
                     <el-input
                       v-model="formData.tempkey"
-                      disabled
+                      :disabled="formData.type_n !== 3"
                       placeholder="请输入通模板编号"
                       style="width: 500px"
                     ></el-input>
                   </el-form-item>
+                  <el-form-item label="模板ID:">
+                    <el-input v-model="formData.tempid" placeholder="请输入模板ID" style="width: 500px"></el-input>
+                  </el-form-item>
                   <el-form-item label="模板:">
+                    <div class="content">
+                      <el-input
+                        :disabled="formData.type_n !== 3"
+                        v-model="formData.content"
+                        type="textarea"
+                        :autosize="{ minRows: 5, maxRows: 8 }"
+                        placeholder="请输入模板"
+                        style="width: 500px"
+                        @input="handleContentChange"
+                      ></el-input>
+                    </div>
+                  </el-form-item>
+                  <el-form-item label="字段:" v-if="formData.type_n == 3 && keyList.length">
+                    <div class="content">
+                      <keys-list
+                        :key-list="keyList"
+                        :variableList="formData.custom_variable"
+                        @add="handleAdd"
+                        @remove="handleRemove"
+                      />
+                    </div>
+                  </el-form-item>
+                  <el-form-item label="跳转链接:">
                     <el-input
-                      disabled
-                      v-model="formData.content"
-                      type="textarea"
-                      :autosize="{ minRows: 5, maxRows: 8 }"
-                      placeholder="请输入模板"
+                      v-model="formData.routine_link"
+                      placeholder="请输入模版跳转链接,可携带参数"
                       style="width: 500px"
                     ></el-input>
                   </el-form-item>
-                  <el-form-item label="模板ID:">
-                    <el-input v-model="formData.tempid" placeholder="请输入模板ID" style="width: 500px"></el-input>
-                  </el-form-item>
                   <el-form-item label="状态:" prop="is_routine">
                     <el-radio-group v-model="formData.is_routine">
                       <el-radio :label="1">开启</el-radio>
@@ -135,18 +219,30 @@
                         placeholder="请输入通知内容"
                         style="width: 500px"
                       ></el-input>
-                      <div class="trip">
-                        <div>请输入模板消息详细内容对应的变量。关键字个数需与已添加的模板一致。 可以使用如下变量:</div>
-                        <div v-for="(i, index) in formData.variable.split(',')" :key="index">
-                          {{ i }}
-                        </div>
+                      <div class="value-list" v-if="formData.type_n == 3">
+                        <el-popover placement="right" width="200" trigger="click">
+                          <div class="variable">
+                            <div
+                              class="item"
+                              @click="changeValue(i.value)"
+                              v-for="(i, index) in formData.custom_variable"
+                              :key="index"
+                            >
+                              {{ i.label }}
+                            </div>
+                          </div>
+
+                          <i class="el-icon-link" slot="reference"></i>
+                        </el-popover>
                       </div>
                     </div>
+                    <div class="tips-info">
+                      可点击右下角图标,插入自定义变量
+                    </div>
                   </el-form-item>
                   <el-form-item label="机器人链接:">
                     <div class="content">
                       <el-input v-model="formData.url" placeholder="请输入机器人链接" style="width: 500px"></el-input>
-                      <div class="trip">企业微信群机器人链接</div>
                     </div>
                   </el-form-item>
                   <el-form-item label="状态:" prop="is_ent_wechat">
@@ -170,7 +266,9 @@
 
 <script>
 import { getNotificationInfo, getNotificationSave } from '@/api/notification.js';
+import keysList from './components/keysList.vue';
 export default {
+  components: { keysList },
   data() {
     return {
       tabs: [
@@ -223,6 +321,7 @@ export default {
           },
         ],
       },
+      keyList: [],
     };
   },
   created() {
@@ -230,6 +329,29 @@ export default {
     this.getData(this.id, this.tagName, 1);
   },
   methods: {
+    handleContentChange(e) {
+      if (this.formData.type_n == 3) {
+        const regex = /{{(.*?)\./g;
+        let match;
+        this.keyList = [];
+        while ((match = regex.exec(e))) {
+          this.keyList.push({
+            key: match[1],
+            value: '',
+          });
+        }
+      }
+    },
+    handleRemove(index) {
+      this.keyList.splice(index, 1);
+    },
+    // 新增卡密
+    handleAdd() {
+      this.keyList.push({
+        key: '',
+        value: '',
+      });
+    },
     changeTabs() {
       this.getData(this.id, this.tagName);
     },
@@ -247,8 +369,10 @@ export default {
           }
           if (init) this.tagName = this.tabsList[0].slot;
           this.formData = res.data;
-          this.formData.type = name;
+          this.formData.type_n = res.data.type; // - -!
+          this.formData.type = name; // 类型名称
           this.formData.id = id;
+          this.keyList = res.data.key_list || [];
           this.loading = false;
         })
         .catch((err) => {
@@ -256,6 +380,7 @@ export default {
         });
     },
     handleSubmit(name) {
+      this.formData.key_list = this.keyList;
       getNotificationSave(this.formData)
         .then((res) => {
           this.$message.success('设置成功');
@@ -267,11 +392,25 @@ export default {
     handleReset(name) {
       this.$emit('close');
     },
+    changeValue(e) {
+      // 获取dom元素
+      let textInput = document.getElementById('system_text');
+      // 获取光标初始索引
+      let index = textInput.selectionStart;
+      // 拼接字符串的形式来得到需要的内容
+      this.formData.system_text =
+        this.formData.system_text.substring(0, index) + e + this.formData.system_text.substring(index);
+      this.$nextTick(() => {
+        textInput.selectionStart = index + e.length;
+        textInput.selectionEnd = index + e.length;
+        textInput.focus();
+      });
+    },
   },
 };
 </script>
 
-<style scoped>
+<style scoped lang="scss">
 .edit {
 }
 .header_top {
@@ -310,9 +449,48 @@ export default {
 
 .content {
   display: flex;
+  position: relative;
 }
 
 .form-sty {
   margin-top: 20px;
 }
+.value-list {
+  position: absolute;
+  right: 7px;
+  bottom: 7px;
+  width: 22px;
+  height: 22px;
+  line-height: 22px;
+  text-align: center;
+  background: var(--prev-color-primary);
+  color: #ededed;
+  cursor: pointer;
+  border-radius: 4px;
+}
+.variable {
+  .item {
+    cursor: pointer;
+    padding: 5px 10px;
+    transition: all 0.3s ease;
+  }
+  .item:hover {
+    background: var(--prev-color-primary-light-9);
+    color: var(--prev-color-primary);
+    border-radius: 4px;
+  }
+}
+// 滚动条样式
+.variable::-webkit-scrollbar {
+    width: 4px;
+    height: 4px;
+}
+.variable::-webkit-scrollbar-thumb {
+    background: var(--prev-color-primary-light-9);
+    border-radius: 4px;
+}
+.variable::-webkit-scrollbar-track {
+    background: #f2f2f2;
+}
+
 </style>

+ 11 - 2
template/admin/src/pages/setting/setSystem/index.vue

@@ -115,7 +115,10 @@ export default {
     getHeader(index) {
       this.spinShow = true;
       return new Promise((resolve, reject) => {
-        let tab_id = this.$route.params.tab_id;
+        if (this.$route.query.tab_id) {
+          this.currentTab = this.$route.query.tab_id;
+        }
+        let tab_id = this.$route.params.tab_id ? this.$route.params.tab_id : this.$route.query.tab_id;
         let data = {
           type: this.$route.params.type ? this.$route.params.type : 0,
           pid: tab_id ? tab_id : 0,
@@ -124,7 +127,13 @@ export default {
           .then(async (res) => {
             let config = res.data.config_tab;
             this.headerList = config;
-            this.currentTab = config[index ? index : 0].value.toString();
+            if (!this.currentTab) {
+            }
+            if (this.$route.query.tab_id) {
+              this.currentTab = this.$route.query.tab_id;
+            } else {
+              this.currentTab = config[index ? index : 0].value.toString();
+            }
             this.childrenList(index ? 1 : 0);
             resolve(this.currentTab);
             this.spinShow = false;

+ 3 - 3
template/admin/src/pages/setting/storage/index.vue

@@ -174,7 +174,7 @@
                 </div>
               </div>
             </div>
-            <divider />
+            <el-divider />
             <div class="content mt20">
               <el-form-item label="是否开启水印:" label-width="120px">
                 <el-switch
@@ -344,7 +344,7 @@
       </el-card>
     </div>
     <!-- 缩略图配置 -->
-    <div class="pt10" v-else-if="currentTab == 10">我去恶趣味我去</div>
+    <div class="pt10" v-else-if="currentTab == 10"></div>
     <div class="pt10" v-else>
       <el-card :bordered="false" shadow="never" class="ivu-mt">
         <el-row class="mb20">
@@ -422,7 +422,7 @@
             :total="total"
             :page.sync="list.page"
             :limit.sync="list.limit"
-            @pagination="getList"
+            @pagination="getlist"
           />
         </div>
       </el-card>

+ 38 - 24
template/admin/src/pages/setting/storeService/index.vue

@@ -378,10 +378,14 @@ export default {
     edit(row) {
       if (this.eidtLoading) return;
       this.eidtLoading = true;
-      this.$modalForm(kefuEditApi(row.id)).then(() => {
-        this.getList();
-        this.eidtLoading = false;
-      });
+      this.$modalForm(kefuEditApi(row.id))
+        .then(() => {
+          this.getList();
+          this.eidtLoading = false;
+        })
+        .catch(() => {
+          this.eidtLoading = false;
+        });
     },
     // 添加
     add() {
@@ -506,28 +510,38 @@ export default {
 </script>
 
 <style scoped lang="stylus">
-.tabBox_img
-    width 36px
-    height 36px
-    border-radius:4px;
-    cursor pointer
-    img
-        width 100%
-        height 100%
-.modelBox
-    ::v-deep
-    .ivu-table-header
-        width 100% !important
-.trees-coadd
+.tabBox_img {
+  width: 36px;
+  height: 36px;
+  border-radius: 4px;
+  cursor: pointer;
+
+  img {
     width: 100%;
-    height: 385px;
-    .scollhide
-        width: 100%;
-        height: 100%;
-        overflow-x: hidden;
-        overflow-y: scroll;
+    height: 100%;
+  }
+}
+
+.modelBox {
+  ::v-deep, .ivu-table-header {
+    width: 100% !important;
+  }
+}
+
+.trees-coadd {
+  width: 100%;
+  height: 385px;
+
+  .scollhide {
+    width: 100%;
+    height: 100%;
+    overflow-x: hidden;
+    overflow-y: scroll;
+  }
+}
+
 // margin-left: 18px;
 .scollhide::-webkit-scrollbar {
-    display: none;
+  display: none;
 }
 </style>

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

@@ -374,7 +374,6 @@ export default {
         let parentNode = currentObj.pid ? this.$refs.tree.getNode(currentObj.pid).data : undefined;
         if (parentNode && parentNode.children.length) {
           for (let i = 0; i < parentNode.children.length; i++) {
-            console.log(treeStatus.checkedKeys, parentNode.children[i].id);
             if (treeStatus.checkedKeys.includes(parentNode.children[i].id)) {
               selParent = true;
             }

+ 0 - 1
template/admin/src/pages/system/codeGeneration/components/TableForm.vue

@@ -358,7 +358,6 @@ export default {
       }
       this.tableField = [];
       this.$nextTick((e) => {
-        console.log(arr);
         this.tableField = arr;
       });
     },

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

@@ -259,7 +259,6 @@ export default {
     saveTimer(data) {
       saveTimer(data)
         .then((res) => {
-          console.log(res);
           this.$message.success({
             message: res.msg,
             onClose: () => {

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

@@ -45,7 +45,7 @@
         <template slot-scope="scope">
           <a @click="edit(scope.row.id)">编辑</a>
           <el-divider direction="vertical"></el-divider>
-          <a @click="handleDelete(scope.row, '删除秒杀商品', scope.$index)">删除</a>
+          <a v-permission="'seckill'" @click="handleDelete(scope.row, '删除秒杀商品', scope.$index)">删除</a>
         </template>
       </el-table-column>
     </el-table>

+ 0 - 1
template/admin/src/pages/system/systemMenus/components/menusFrom.vue

@@ -318,7 +318,6 @@ export default {
     // 搜索
     upIcon(n) {
       this.searchData = this.list.filter((item) => item.indexOf(this.iconVal) > -1);
-      console.log(this.searchData);
     },
     // 搜索规则
     searchRules() {

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

@@ -85,7 +85,11 @@ export default {
   methods: {
     // 添加
     add() {
-      this.$modalForm(groupAddApi(0)).then(() => this.getList());
+      this.$modalForm(groupAddApi(0))
+        .then(() => this.getList())
+        .catch(() => {
+          console.log('error');
+        });
     },
     // 分组列表
     getList() {

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

@@ -266,7 +266,7 @@ export default {
                     minWidth: 120,
                   },
                   {
-                    title: '兑换时间',
+                    title: '领取时间',
                     key: '_add_time',
                     minWidth: 120,
                   },

+ 40 - 23
template/admin/src/pages/user/list/index.vue

@@ -716,13 +716,35 @@ export default {
       }
     },
     activeSelectData(data) {
-      // let labels = [];
-      // if (!data.length) return;
-      // data.map((i) => {
-      //   labels.push(i.id);
-      // });
       this.selectLabelShow = false;
       this.selectDataLabel = data || [];
+      if (this.selectDataLabel.length) {
+        let activeIds = [];
+        this.selectDataLabel.map((item) => {
+          activeIds.push(item.id);
+        });
+        this.userFrom.label_id = activeIds.join(',');
+      } else {
+        this.userFrom.label_id = '';
+      }
+    },
+    handleClose(tag) {
+      let i = this.selectDataLabel.findIndex((item) => item.id === tag.id);
+      if (i !== -1) {
+        this.selectDataLabel.splice(i, 1);
+      }
+      this.$nextTick(() => {
+        if (this.selectDataLabel.length) {
+          let activeIds = [];
+          this.selectDataLabel.map((item) => {
+            activeIds.push(item.id);
+          });
+          this.userFrom.label_id = activeIds.join(',');
+        } else {
+          this.userFrom.label_id = '';
+        }
+      });
+      // this.userSearchs();
     },
     // 批量设置标签
     activeData(data) {
@@ -830,6 +852,11 @@ export default {
     cancel(name) {
       this.promoterShow = false;
       this.$refs[name].resetFields();
+      this.formInline = {
+        uid: 0,
+        spread_uid: 0,
+        image: '',
+      };
     },
     // 赠送会员等级
     giveLevel(id) {
@@ -889,13 +916,13 @@ export default {
     },
     // 会员列表
     getList() {
-      if (this.selectDataLabel.length) {
-        let activeIds = [];
-        this.selectDataLabel.forEach((item) => {
-          activeIds.push(item.id);
-        });
-        this.userFrom.label_id = activeIds.join(',');
-      }
+      // if (this.selectDataLabel.length) {
+      //   let activeIds = [];
+      //   this.selectDataLabel.forEach((item) => {
+      //     activeIds.push(item.id);
+      //   });
+      //   this.userFrom.label_id = activeIds.join(',');
+      // }
       this.userFrom.user_type = this.userFrom.user_type || '';
       this.userFrom.status = this.userFrom.status || '';
       this.userFrom.sex = this.userFrom.sex || '';
@@ -925,13 +952,6 @@ export default {
     },
     // 用户导出
     async exportList() {
-      if (this.selectDataLabel.length) {
-        let activeIds = [];
-        this.selectDataLabel.forEach((item) => {
-          activeIds.push(item.id);
-        });
-        this.userFrom.label_id = activeIds.join(',');
-      }
       if (this.ids.length) {
         this.userFrom.ids = this.ids;
       }
@@ -976,10 +996,7 @@ export default {
       this.selectionList = [];
       this.getList();
     },
-    handleClose(tag) {
-      this.selectDataLabel.splice(this.selectDataLabel.indexOf(tag), 1);
-      this.userSearchs()
-    },
+
     // 搜索
     userSearchs() {
       this.userFrom.page = 1;

+ 0 - 7
template/admin/src/router/index.js

@@ -1,10 +1,3 @@
-/*
- * @Author: From-wh from-wh@hotmail.com
- * @Date: 2023-03-04 11:49:55
- * @FilePath: /admin/src/router/index.js
- * @Description:
- *
- */
 // +----------------------------------------------------------------------
 // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
 // +----------------------------------------------------------------------

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

@@ -126,6 +126,15 @@ export default {
       },
       component: () => import('@/pages/app/routine/download/index'),
     },
+    {
+      path: 'routine/link',
+      name: `${pre}routineLink`,
+      meta: {
+        auth: ['routine-link'],
+        title: '小程序链接',
+      },
+      component: () => import('@/pages/app/routine/link/index'),
+    },
     {
       path: 'app/version',
       name: `${pre}version`,

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

@@ -193,6 +193,15 @@ export default {
       },
       component: () => import('@/pages/setting/setSystem/index'),
     },
+    {
+      path: `model/system_config/:type?/:tab_id?`,
+      name: `${pre}model`,
+      meta: {
+        auth: ['system-model-system_config'],
+        title: '模块配置',
+      },
+      component: () => import('@/pages/setting/setSystem/index'),
+    },
     {
       path: 'store_integral/index',
       name: `${pre}storeIntegral`,

+ 1 - 1
template/admin/src/router/modules/setting.js

@@ -498,7 +498,7 @@ export default {
     },
     {
       path: 'pc_group_data',
-      name: `${pre}systemGroupData`,
+      name: `${pre}systemPcGroupData`,
       meta: {
         auth: ['setting-system-pc_data'],
         title: 'PC商城',

+ 33 - 32
template/admin/src/store/module/moren.js

@@ -26,7 +26,7 @@ export default {
           },
           imgUrl: {
             title: '最多可添加1张图片,图片建议宽度128 * 45px',
-            url: 'http://kaifa.crmeb.net/uploads/attach/2019/10/20191023/db7b7bef9dffdedd27e9a3aa34218cea.png',
+            url: '',
           },
           titleInfo: {
             title: '',
@@ -57,7 +57,7 @@ export default {
           },
           imgUrl: {
             title: '最多可添加1张图片,图片建议宽度128 * 45px',
-            url: 'http://kaifa.crmeb.net/uploads/attach/2019/10/20191023/db7b7bef9dffdedd27e9a3aa34218cea.png',
+            url: '',
           },
           titleInfo: {
             title: '',
@@ -93,7 +93,7 @@ export default {
             max: 10,
             list: [
               {
-                img: 'http://kaifa.crmeb.net/uploads/attach/2020/03/20200319/a32307fd1043c350932a462839288d38.jpg',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -110,7 +110,7 @@ export default {
                 ],
               },
               {
-                img: 'http://kaifa.crmeb.net/uploads/attach/2020/03/20200319/906d46eb6f734eaf1fd820601893af0d.jpg',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -138,7 +138,7 @@ export default {
             max: 10,
             list: [
               {
-                img: 'http://kaifa.crmeb.net/uploads/attach/2020/03/20200319/a32307fd1043c350932a462839288d38.jpg',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -155,7 +155,7 @@ export default {
                 ],
               },
               {
-                img: 'http://kaifa.crmeb.net/uploads/attach/2020/03/20200319/906d46eb6f734eaf1fd820601893af0d.jpg',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -185,7 +185,7 @@ export default {
             max: 20,
             list: [
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/723bb4d18893a5aa6871c94d19f3bc4d.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -202,7 +202,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/e908c8f088db07a0f4f6fddc2a7b96f9.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -219,7 +219,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/1a9a1189bf4a1e9970517d31bcb00bbc.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -236,7 +236,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/dded4f4779e705d54cf640826d1b5558.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -253,7 +253,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/f95dd1f3f71fef869e80533df9ccb1a0.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -270,7 +270,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/8bf36e0cd9f9490c1f06abcd7efe8c2d.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -287,7 +287,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/5cbdc6eda8c4a2c92c88abffee50d1ff.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -304,7 +304,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/fdb67663ea188163b0ad863a05f77fbf.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -332,7 +332,7 @@ export default {
             max: 20,
             list: [
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/723bb4d18893a5aa6871c94d19f3bc4d.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -349,7 +349,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/e908c8f088db07a0f4f6fddc2a7b96f9.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -366,7 +366,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/1a9a1189bf4a1e9970517d31bcb00bbc.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -383,7 +383,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/dded4f4779e705d54cf640826d1b5558.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -400,7 +400,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/f95dd1f3f71fef869e80533df9ccb1a0.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -417,7 +417,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/8bf36e0cd9f9490c1f06abcd7efe8c2d.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -434,7 +434,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/5cbdc6eda8c4a2c92c88abffee50d1ff.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -451,7 +451,7 @@ export default {
                 ],
               },
               {
-                img: 'http://admin.crmeb.net/uploads/attach/2020/05/20200515/fdb67663ea188163b0ad863a05f77fbf.png',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -491,7 +491,7 @@ export default {
           },
           imgUrl: {
             title: '最多可添加10个模板,图片建议宽度124 * 28px',
-            url: 'http://kaifa.crmeb.net/uploads/attach/2019/10/20191023/db7b7bef9dffdedd27e9a3aa34218cea.png',
+            url: '',
           },
           newList: {
             max: 10,
@@ -521,7 +521,7 @@ export default {
           },
           imgUrl: {
             title: '最多可添加10个模板,图片建议宽度124 * 28px',
-            url: 'http://kaifa.crmeb.net/uploads/attach/2019/10/20191023/db7b7bef9dffdedd27e9a3aa34218cea.png',
+            url: '',
           },
           newList: {
             max: 10,
@@ -557,7 +557,7 @@ export default {
             max: 3,
             list: [
               {
-                img: 'http://datong.crmeb.net/public/uploads/attach/2019/03/28/5c9ccf7e9f4d0.jpg',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -580,7 +580,7 @@ export default {
                 ],
               },
               {
-                img: 'http://datong.crmeb.net/public/uploads/attach/2019/03/28/5c9ccf7e97660.jpg',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -603,7 +603,7 @@ export default {
                 ],
               },
               {
-                img: 'http://datong.crmeb.net/public/uploads/attach/2019/03/28/5c9ccfc86a6c1.jpg',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -639,7 +639,7 @@ export default {
             max: 3,
             list: [
               {
-                img: 'http://datong.crmeb.net/public/uploads/attach/2019/03/28/5c9ccf7e9f4d0.jpg',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -662,7 +662,7 @@ export default {
                 ],
               },
               {
-                img: 'http://datong.crmeb.net/public/uploads/attach/2019/03/28/5c9ccf7e97660.jpg',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -685,7 +685,7 @@ export default {
                 ],
               },
               {
-                img: 'http://datong.crmeb.net/public/uploads/attach/2019/03/28/5c9ccfc86a6c1.jpg',
+                img: '',
                 info: [
                   {
                     title: '标题',
@@ -920,7 +920,7 @@ export default {
             max: 10,
             list: [
               {
-                img: 'http://kaifa.crmeb.net/uploads/attach/2020/03/20200319/906d46eb6f734eaf1fd820601893af0d.jpg',
+                img: '',
                 info: [
                   {
                     title: '链接',
@@ -942,7 +942,7 @@ export default {
             max: 10,
             list: [
               {
-                img: 'http://kaifa.crmeb.net/uploads/attach/2020/03/20200319/906d46eb6f734eaf1fd820601893af0d.jpg',
+                img: '',
                 info: [
                   {
                     title: '链接',
@@ -1817,6 +1817,7 @@ export default {
         },
       },
     },
+
     component: {
       headerSerch: {
         list: [

+ 133 - 6
template/admin/src/styles/style.scss

@@ -1,27 +1,34 @@
 @charset "UTF-8";
+
 .vxe-tree-cell,
 .vxe-cell {
   font-size: 12px;
 }
+
 .plusColor {
   color: #e83323;
 }
+
 .reduceColor {
   color: #16ac57;
 }
+
 .c_label {
   font-size: 14px;
   color: #999999;
 }
+
 .c_label span {
   margin-left: 10px;
   color: #333;
 }
+
 .c_row-item {
   display: flex;
   justify-content: space-between;
   align-items: center;
 }
+
 .acea-row {
   display: -webkit-box;
   display: -moz-box;
@@ -209,9 +216,11 @@ body {
   font-size: 13px;
   padding: 10px 5px !important;
 }
+
 .ivu-form .ivu-form-item-label {
   font-size: 12px !important;
 }
+
 .ivu-radio-group-button .ivu-radio-wrapper,
 .ivu-table {
   font-size: 13px !important;
@@ -224,6 +233,7 @@ body {
 .ivu-table th {
   background: rgba(33, 100, 250, 0.05) !important;
 }
+
 .form_content_width {
   width: 250px;
 }
@@ -247,9 +257,11 @@ body {
 .product_tabs .ivu-page-header-content {
   margin-bottom: 0 !important;
 }
+
 .ivu-radio {
   padding: 8px 0;
 }
+
 .ivu-radio-wrapper {
   font-size: 12px !important;
 }
@@ -257,13 +269,16 @@ body {
 .ivu-input {
   font-size: 12px !important;
 }
+
 .ivu-notice-desc {
   word-break: normal;
   text-align: left !important;
 }
+
 .el-input-number .el-input__inner {
   text-align: unset;
 }
+
 .modal-form {
   width: 540px;
   position: absolute;
@@ -274,34 +289,43 @@ body {
   border-radius: 6px;
   padding-bottom: 20px;
 }
+
 .modal-form .el-message-box__header {
   padding: 15px;
   border-bottom: 1px solid #eee;
 }
+
 .modal-form .el-message-box__title {
   font-size: 14px;
   font-weight: 500;
   color: #333333;
 }
+
 .modal-form .el-message-box__content {
   padding: 30px 15px 10px;
 }
+
 .modal-form .el-message-box__headerbtn {
   // top: 10px;
   color: #c0c4cc;
 }
+
 .common-form-create .el-input-number .el-input__inner {
   text-align: unset;
 }
+
 .form-create .el-select {
   width: 100%;
 }
+
 .form-create .el-input-number {
   width: 100%;
 }
+
 .el-dialog ::v-deep .form-create .el-button {
   float: right;
 }
+
 .modalBody .ivu-modal-body {
   padding: 27px !important;
 }
@@ -324,6 +348,10 @@ body {
   width: 100% !important;
 }
 
+.h-33 {
+  height: 33px;
+}
+
 /*距离样式*/
 .mr {
   margin-right: 15px;
@@ -348,6 +376,7 @@ body {
 .ml40 {
   margin-left: 40px !important;
 }
+
 .ml95 {
   margin-left: 95px !important;
 }
@@ -368,6 +397,7 @@ body {
 .mr15 {
   margin-right: 15px !important;
 }
+
 .mr5 {
   margin-right: 5px !important;
 }
@@ -375,12 +405,15 @@ body {
 .mb20 {
   margin-bottom: 20px !important;
 }
+
 .mb5 {
   margin-bottom: 5px !important;
 }
+
 .mb14 {
   margin-bottom: 14px !important;
 }
+
 .mb15 {
   margin-bottom: 15px !important;
 }
@@ -412,9 +445,11 @@ body {
 .mt20 {
   margin-top: 20px;
 }
+
 .mt14 {
   margin-top: 14px;
 }
+
 .mt50 {
   margin-top: 50px;
 }
@@ -422,33 +457,41 @@ body {
 .mt10 {
   margin-top: 10px;
 }
+
 .mb10 {
   margin-bottom: 10px !important;
 }
+
 .spBlock {
   display: block;
 }
+
 .mb5 {
   margin-bottom: 5px !important;
 }
+
 .pl25 {
   padding-left: 25px;
   box-sizing: border-box;
 }
+
 .padding-add {
   padding: 20px 20px 0;
 }
+
 .index_bg {
   width: 100%;
   /*height: 100vh;*/
   background: rgba(0, 0, 0, 0.6) !important;
   z-index: 0 !important;
 }
+
 .fl_header {
   display: flex;
   align-items: center;
   padding-left: 0px !important;
 }
+
 .header_top {
   padding-bottom: 16px !important;
   padding-left: 10px !important;
@@ -463,9 +506,11 @@ body {
 .i-layout-menu-side-title-icon-single .ivu-icon {
   font-size: 20px;
 }
+
 .ivu-layout-content {
   position: relative;
 }
+
 .ivu-form-item-content {
   font-size: 12px !important;
 }
@@ -481,6 +526,7 @@ body {
   line-height: 28px !important;
   padding: 0 10px !important;
 }
+
 #shopp-manager .ivu-tag .ivu-icon-ios-close {
   top: 0;
 }
@@ -490,6 +536,7 @@ body {
   color: #2d8cf0;
   cursor: pointer;
 }
+
 /*tab标签栏*/
 .i-layout-tabs-fix {
   z-index: 5 !important;
@@ -498,28 +545,35 @@ body {
 .vxe-header--row th:nth-of-type(1) {
   padding-left: 10px !important;
 }
+
 .vxe-table--body td:nth-of-type(1) {
   padding-left: 10px !important;
 }
+
 .ivu-modal-header {
   background: #fafafa;
 }
+
 .ivu-mb,
 .ivu-mb-16 {
   margin-bottom: 16px !important;
 }
+
 .ivu-mt-16 {
   margin-top: 16px !important;
 }
+
 .ivu-table-wrapper {
   border: 0;
 }
+
 .i-layout-page-header {
   margin: 0;
   /* display: none; */
   background-color: #fff;
   padding: 7px 32px 0 32px;
 }
+
 .header-title {
   padding: 10px 20px;
   // border-bottom: 1px solid #f2f2f2;
@@ -537,6 +591,7 @@ body {
   font-size: 14px;
   color: #303133;
 }
+
 .statics-header-title {
   font-size: 16px;
   color: #303133;
@@ -550,6 +605,7 @@ body {
   -ms-flex-pack: justify;
   justify-content: space-between;
 }
+
 .ivu-page-header-title {
   display: inline-block;
   color: #17233d;
@@ -557,74 +613,94 @@ body {
   font-size: 20px;
   line-height: 32px;
 }
+
 .main .content-wrapper {
   padding: 16px;
   height: calc(100% - 80px);
   overflow: auto;
   background-color: #f5f7f9;
 }
+
 .left-wrapper {
   height: calc(100vh - 120px);
   background: #fff;
   border-right: 1px solid #f2f2f2;
 }
+
 .ivu-tabs-bar {
   margin-bottom: 0;
 }
+
 .perW100 {
   width: 100%;
 }
+
 .perW90 {
   width: 90%;
 }
+
 .perW50 {
   width: 50%;
 }
+
 .perW20 {
   width: 20%;
 }
+
 .perW35 {
   width: 35%;
 }
+
 .perW30 {
   width: 30%;
 }
+
 .font12 {
   font-size: 12px !important;
 }
+
 .font14 {
   font-size: 14px !important;
 }
+
 .ivu-table:after {
   width: 0;
 }
+
 /*复制pro*/
 .ivu-text-left {
   text-align: left;
 }
+
 .ivu-text-right {
   text-align: right;
 }
+
 .ivu-block {
   display: block;
 }
+
 .ivu-pl-8 {
   padding-left: 8px !important;
 }
+
 .tabBox_img {
   width: 36px;
   height: 36px;
   border-radius: 4px;
   cursor: pointer;
 }
+
 .tabBox_img img {
   width: 100%;
   height: 100%;
 }
+
 .content img {
   display: block;
   max-width: 100%;
 }
+
 /*客服*/
 .mask-footer {
   display: flex;
@@ -632,30 +708,37 @@ body {
   padding-top: 20px;
   border-top: 1px solid #e8eaec;
 }
+
 .mask-footer button {
   margin-left: 10px;
 }
+
 .goods-mask .ivu-modal-body {
   padding: 0;
 }
+
 .content img {
   display: block;
   max-width: 100%;
   object-fit: contain;
 }
+
 .none-radius .ivu-modal-content {
   border-radius: 0;
 }
+
 .transfer-mask .ivu-modal-wrap {
   width: 1200px;
   margin: 0 auto;
 }
+
 .transfer-mask .ivu-modal {
   position: absolute;
   right: 279px;
   top: auto;
   bottom: 271px;
 }
+
 .maskModel {
   position: fixed;
   top: 0;
@@ -665,6 +748,7 @@ body {
   z-index: 55;
   background-color: rgba(0, 0, 0, 0.5);
 }
+
 .input-input {
   display: block;
   height: 100%;
@@ -681,20 +765,24 @@ body {
   text-shadow: inherit;
   border: none;
 }
+
 .kf_mobile .textarea-box textarea {
   resize: none !important;
   height: 148px;
   border-color: transparent;
   font-size: 14px !important;
 }
+
 .kf_mobile .textarea-box textarea:focus {
   box-shadow: none;
 }
+
 .line1 {
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
 }
+
 .line2 {
   overflow: hidden;
   text-overflow: ellipsis;
@@ -702,14 +790,17 @@ body {
   -webkit-line-clamp: 2;
   -webkit-box-orient: vertical;
 }
+
 .df-n-warp {
   display: flex;
   flex-wrap: nowrap;
 }
+
 .none-radius .ivu-modal-mask,
 .label-box .ivu-modal-mask {
   background-color: transparent;
 }
+
 .empty-box {
   width: 100%;
   height: 100%;
@@ -719,13 +810,16 @@ body {
   background: #f3f5f7;
   border-radius: 6px;
 }
+
 .empty-box.on {
   border-radius: 0px;
 }
+
 .empty-box .iconfont-diy {
   color: #bbbfc8;
   font-size: 30px;
 }
+
 .paddingBox {
   padding: 0 10px 10px;
 }
@@ -737,13 +831,16 @@ body {
   color: #c0c4cc;
   font-size: 12px;
 }
+
 .pt10 {
   padding-top: 10px;
 }
+
 .common-form-create-footer {
   display: flex;
   justify-content: right;
 }
+
 .common-form-button {
   margin-right: 10px;
 }
@@ -751,40 +848,51 @@ body {
 .pl10 {
   padding-left: 10px;
 }
+
 .el-switch__label * {
   font-size: 12px;
   line-height: 20px !important;
   font-weight: 400;
 }
+
 .defineSwitch .el-switch__label {
   position: absolute;
   display: none;
   color: #fff !important;
 }
+
 /*打开时文字位置设置*/
 .defineSwitch .el-switch__label--right {
   z-index: 1;
-  right: -8px; /*不同场景下可能不同,自行调整*/
+  right: -8px;
+  /*不同场景下可能不同,自行调整*/
 }
+
 /*关闭时文字位置设置*/
 .defineSwitch .el-switch__label--left {
   z-index: 1;
-  left: 22px; /*不同场景下可能不同,自行调整*/
+  left: 22px;
+  /*不同场景下可能不同,自行调整*/
 }
+
 /*显示文字*/
 .defineSwitch .el-switch__label.is-active {
   display: block;
 }
+
 .defineSwitch.el-switch .el-switch__core,
 .defineSwitch.el-switch .el-switch__label {
-  width: 55px !important; /*开关按钮的宽度大小*/
+  width: 55px !important;
+  /*开关按钮的宽度大小*/
 }
+
 .df-jcsb {
   display: flex;
   justify-content: space-between;
 }
 
 .el-table {
+
   .el-table__header-wrapper,
   .el-table__fixed-header-wrapper {
     th {
@@ -803,6 +911,7 @@ a {
   cursor: pointer;
   text-decoration: none;
 }
+
 .label_text {
   color: #606266;
   font-size: 12px;
@@ -811,9 +920,11 @@ a {
   text-align: right;
   padding-right: 12px;
 }
+
 .el-table-column--selection .cell {
   padding-left: 10px;
 }
+
 .tree_tit {
   font-size: 15px;
   color: #606266;
@@ -822,38 +933,47 @@ a {
   display: flex;
   align-items: center;
   cursor: pointer;
+
   .el-icon-circle-plus {
     color: #c0c4cc;
     font-size: 20px;
     margin-right: 6px;
   }
 }
+
 .tree {
   min-height: 374px;
+
   .is-current .file-name {
     color: var(--prev-color-primary);
   }
+
   .file-name {
     display: flex;
     align-items: center;
     color: #303133;
     font-size: 14px;
+
     .icon {
       width: 15px;
       height: 13px;
       margin-right: 6px;
     }
   }
+
   .el-tree-node {
     // margin-right: 16px;
   }
+
   .el-tree-node__children .el-tree-node {
     margin-right: 0;
   }
+
   .el-tree-node__content {
     width: 100%;
     height: 48px;
   }
+
   .custom-tree-node {
     flex: 1;
     display: flex;
@@ -865,18 +985,22 @@ a {
     color: rgba(0, 0, 0, 0.6);
     line-height: 13px;
   }
+
   .is-current {
     background: #f1f9ff !important;
     color: var(--prev-color-primary) !important;
   }
+
   .is-current .custom-tree-node {
     color: var(--prev-color-primary) !important;
   }
-  .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
+
+  .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
     background-color: var(--prev-color-primary-light-9) !important;
     border-right: 2px solid var(--prev-color-primary);
   }
 }
+
 .upload-box {
   font-size: 24px;
   font-weight: 500;
@@ -888,6 +1012,7 @@ a {
   font-size: 24px;
   font-weight: 500;
 }
+
 .fixed-card {
   position: fixed;
   right: 16px;
@@ -901,6 +1026,7 @@ a {
   align-items: center;
   background-color: rgba(255, 255, 255, 0.6) !important;
   backdrop-filter: blur(4px);
+
   ::v-deep .ivu-card-body {
     padding: 15px 16px 14px;
   }
@@ -914,13 +1040,14 @@ a {
     text-align: center;
   }
 }
+
 .drag {
   display: flex;
   align-items: center;
   justify-content: center;
+
   .handle {
     width: 9px;
     height: 15px;
   }
-}
-
+}

+ 31 - 0
template/admin/src/utils/index.js

@@ -7,6 +7,7 @@
 // +----------------------------------------------------------------------
 // | Author: CRMEB Team <admin@crmeb.com>
 // +----------------------------------------------------------------------
+import { Message } from 'element-ui';
 export function importAll(r) {
   let __modules = {};
   r.keys().forEach((key) => {
@@ -16,3 +17,33 @@ export function importAll(r) {
   });
   return __modules;
 }
+
+export function isPicUpload(file) {
+  const typeArry = ['.jpg', '.png', '.JPG', '.PNG', '.gif', '.GIF'];
+  const type = file.name.substring(file.name.lastIndexOf('.'));
+  const isImage = typeArry.indexOf(type) > -1;
+  if (!isImage) {
+    Message.error('上传图片格式不对');
+  }
+  return isImage;
+}
+
+export function isVideoUpload(file) {
+  const typeArry = ['.mp4', '.MP4'];
+  const type = file.name.substring(file.name.lastIndexOf('.'));
+  const isImage = typeArry.indexOf(type) > -1;
+  if (!isImage) {
+    Message.error('上传文件必须为mp4格式视频');
+  }
+  return isImage;
+}
+
+export function isFileUpload(file) {
+  const typeArry = ['.doc', '.DOC', '.docx', '.xls', '.xlsx'];
+  const type = file.name.substring(file.name.lastIndexOf('.'));
+  const isFile = typeArry.indexOf(type) > -1;
+  if (!isFile) {
+    Message.error('上传文件格式不对');
+  }
+  return isFile;
+}

+ 2 - 2
template/admin/src/utils/modalForm.js

@@ -84,7 +84,7 @@ export default function modalForm(formRequestPromise, config = {}) {
                     })
                     .catch((err) => {
                       this.$message.error(err.msg || '提交失败');
-                      reject(err);
+                      // reject(err);
                     })
                     .finally(() => {
                       fn();
@@ -100,7 +100,7 @@ export default function modalForm(formRequestPromise, config = {}) {
         });
       })
       .catch((e) => {
-        this.$message.error(e.message || '--');
+        this.$message.error(e.msg || '--');
       });
   });
 }

+ 0 - 6
template/admin/src/utils/upload.js

@@ -14,7 +14,6 @@ export const uploadByPieces = ({ file, pieceSize = 2, success, error, uploading
     fileRederInstance.addEventListener('load', (e) => {
       let fileBolb = e.target.result;
       fileMD5 = md5(fileBolb);
-      console.log('文件未被上传,将分片上传');
       readChunkMD5();
     });
   };
@@ -29,8 +28,6 @@ export const uploadByPieces = ({ file, pieceSize = 2, success, error, uploading
     // 针对单个文件进行chunk上传
     for (var i = 0; i < chunkCount; i++) {
       const { chunk } = getChunkInfo(file, i, chunkSize);
-      console.log('总片数' + chunkCount);
-      console.log('分片后的数据---测试:' + i);
       await uploadChunk({ chunk, currentChunk: i, chunkCount });
     }
   };
@@ -53,7 +50,6 @@ export const uploadByPieces = ({ file, pieceSize = 2, success, error, uploading
       fetchForm.append('md5', fileMD5);
       upload(fetchForm, config)
         .then((res) => {
-          console.log('分片上传返回信息:', res);
           if (res.data.code == 1) {
             // // 结合不同项目 将成功的信息返回出去
             // 下面如果在项目中没有用到可以不用打开注释
@@ -61,11 +57,9 @@ export const uploadByPieces = ({ file, pieceSize = 2, success, error, uploading
             resolver(true);
           } else if (res.data.code == 2) {
             if (chunkInfo.currentChunk < chunkInfo.chunkCount - 1) {
-              console.log('分片上传成功');
             } else {
               // 当总数大于等于分片个数的时候
               if (chunkInfo.currentChunk + 1 == chunkInfo.chunkCount) {
-                console.log('文件开始------合并成功');
                 success(res.data);
               }
             }

+ 2 - 2
template/admin/vue.config.js

@@ -1,7 +1,5 @@
 const path = require('path');
 const Setting = require('./src/setting.env');
-// 引入打包分析文件
-const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
 // 引入js打包工具
 const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
 
@@ -20,6 +18,7 @@ const resolve = (dir) => {
 // iview-admin线上演示打包路径: https://file.iviewui.com/admin-dist/
 const BASE_URL = process.env.NODE_ENV === 'production' ? '/' : '/';
 const env = process.env.NODE_ENV;
+
 module.exports = {
   // Project deployment base
   // By default we assume your app will be deployed at the root of a domain,
@@ -81,6 +80,7 @@ module.exports = {
     }
   },
   chainWebpack: (config) => {
+    config.plugins.delete('prefetch');
     config.resolve.alias
       .set('@', resolve('src')) // key,value自行定义,比如.set('@@', resolve('src/components'))
       .set('_c', resolve('src/components'));

+ 353 - 383
template/uni-app/App.vue

@@ -1,384 +1,354 @@
-<script>
-	import {
-		checkLogin
-	} from './libs/login';
-	import {
-		HTTP_REQUEST_URL,
-		SYSTEM_VERSION
-	} from './config/app';
-	import {
-		getShopConfig,
-		silenceAuth,
-		getSystemVersion,
-		basicConfig
-	} from '@/api/public';
-	import Auth from '@/libs/wechat.js';
-	import Routine from './libs/routine.js';
-	import {
-		silenceBindingSpread
-	} from "@/utils";
-	import {
-		colorChange,
-		getCrmebCopyRight,
-	} from '@/api/api.js';
-	import {
-		getLangJson,
-		getLangVersion
-	} from '@/api/user.js'
-	import {
-		mapGetters
-	} from "vuex"
-	import colors from '@/mixins/color.js';
-	import Cache from '@/utils/cache';
-	let green =
-		'--view-theme: rgba(66,202,77,1);--view-theme-16: #42CA4D;--view-priceColor:#FF7600;--view-minorColor:rgba(108, 198, 94, 0.5);--view-minorColorT:rgba(66, 202, 77, 0.1);--view-bntColor:#FE960F;--view-op-ten: rgba(66,202,77, 0.1);--view-main-start:#70E038; --view-main-over:#42CA4D;--view-op-point-four: rgba(66,202,77, 0.04);--view-op-point-eight: rgba(66,202,77, 0.8);--view-linear:linear-gradient(180deg, rgba(66,202,77,0.2) 0%, rgba(255,255,255,0) 100%);'
-	let red =
-		'--view-theme: rgba(233,51,35,1);--view-theme-16: #e93323;--view-priceColor:#e93323;--view-minorColor:rgba(233, 51, 35, 0.5);--view-minorColorT:rgba(233, 51, 35, 0.1);--view-bntColor:#FE960F;--view-op-ten: rgba(233,51,35, 0.1);--view-main-start:#FF6151; --view-main-over:#e93323;--view-op-point-four: rgba(233,51,35, 0.04);--view-op-point-eight: rgba(233,51,35, 0.8);--view-linear:linear-gradient(180deg, rgba(232,58,35,0.2) 0%, rgba(255,255,255,0) 100%)'
-	let blue =
-		'--view-theme: rgba(29,176,252,1);--view-theme-16:#1db0fc;--view-priceColor:#FD502F;--view-minorColor:rgba(58, 139, 236, 0.5);--view-minorColorT:rgba(9, 139, 243, 0.1);--view-bntColor:#22CAFD;--view-op-ten: rgba(29,176,252, 0.1);--view-main-start:#40D1F4; --view-main-over:#1DB0FC;--view-op-point-four: rgba(29,176,252, 0.04);--view-op-point-eight: rgba(29,176,252, 0.8);--view-linear:linear-gradient(180deg, rgba(29,176,252,0.2) 0%, rgba(255,255,255,0) 100%);'
-	let pink =
-		'--view-theme: rgba(255,68,143,1);--view-theme-16:#ff448f;--view-priceColor:#FF448F;--view-minorColor:rgba(255, 68, 143, 0.5);--view-minorColorT:rgba(255, 68, 143, 0.1);--view-bntColor:#282828;--view-op-ten: rgba(255,68,143, 0.1);--view-main-start:#FF67AD; --view-main-over:#FF448F;--view-op-point-four: rgba(255,68,143, 0.04);--view-op-point-eight: rgba(255,68,143, 0.8);--view-linear:linear-gradient(180deg, rgba(255,68,143,0.2) 0%, rgba(255,255,255,0) 100%);'
-	let orange =
-		'--view-theme: rgba(254,92,45,1); --view-theme-16:#FE5C2D;--view-priceColor:#FE5C2D;--view-minorColor:rgba(254, 92, 45, 0.5);--view-minorColorT:rgba(254, 92, 45, 0.1);--view-bntColor:#FDB000;--view-op-ten: rgba(254,92,45, 0.1);--view-main-start:#FF9445; --view-main-over:#FE5C2D;--view-op-point-four: rgba(254,92,45, 0.04);--view-op-point-eight: rgba(254,92,45, 0.8);--view-linear:linear-gradient(180deg, rgba(254,92,45,0.2) 0%, rgba(255,255,255,0) 100%);'
-
-	export default {
-		globalData: {
-			spid: 0,
-			code: 0,
-			isLogin: false,
-			userInfo: {},
-			MyMenus: [],
-			globalData: false,
-			isIframe: false,
-			tabbarShow: true,
-			windowHeight: 0,
-			locale: ''
-		},
-		mixins: [colors],
-		computed: mapGetters(['isLogin', 'cartNum']),
-		watch: {
-			isLogin: {
-				deep: true, //深度监听设置为 true
-				handler: function(newV, oldV) {
-					if (newV) {
-						// this.getCartNum()
-					} else {
-						this.$store.commit('indexData/setCartNum', '')
-					}
-				}
-			},
-			cartNum(newCart, b) {
-				this.$store.commit('indexData/setCartNum', newCart + '')
-				if (newCart > 0) {
-					uni.setTabBarBadge({
-						index: Number(uni.getStorageSync('FOOTER_ADDCART')) || 2,
-						text: newCart + ''
-					})
-				} else {
-					uni.hideTabBarRedDot({
-						index: Number(uni.getStorageSync('FOOTER_ADDCART')) || 2
-					})
-				}
-			}
-		},
-		onShow() {
-			const queryData = uni.getEnterOptionsSync() // uni-app版本 3.5.1+ 支持
-			if (queryData.query.spread) {
-				this.$Cache.set('spread', queryData.query.spread);
-				this.globalData.spid = queryData.query.spread;
-				this.globalData.pid = queryData.query.spread;
-				silenceBindingSpread(this.globalData)
-			}
-			if (queryData.query.spid) {
-				this.$Cache.set('spread', queryData.query.spid);
-				this.globalData.spid = queryData.query.spid;
-				this.globalData.pid = queryData.query.spid;
-				silenceBindingSpread(this.globalData)
-			}
-			// #ifdef MP
-			if (queryData.query.scene) {
-				let param = this.$util.getUrlParams(decodeURIComponent(queryData.query.scene))
-				if (param.pid) {
-					this.$Cache.set('spread', param.pid);
-					this.globalData.spid = param.pid;
-					this.globalData.pid = param.pid;
-				} else {
-					switch (queryData.scene) {
-						//扫描小程序码
-						case 1047:
-							this.globalData.code = queryData.query.scene;
-							break;
-							//长按图片识别小程序码
-						case 1048:
-							this.globalData.code = queryData.query.scene;
-							break;
-							//手机相册选取小程序码
-						case 1049:
-							this.globalData.code = queryData.query.scene;
-							break;
-							//直接进入小程序
-						case 1001:
-							this.globalData.spid = queryData.query.scene;
-							break;
-					}
-				}
-				silenceBindingSpread(this.globalData)
-			}
-			// #endif
-		},
-		async onLaunch(option) {
-			uni.hideTabBar()
-			let that = this;
-			// #ifdef H5
-			if (option.query.hasOwnProperty('mdType') && option.query.mdType == "iframeWindow") {
-				this.globalData.isIframe = true;
-			} else {
-				this.globalData.isIframe = false;
-			}
-			// #endif
-			basicConfig().then(res => {
-				uni.setStorageSync('BASIC_CONFIG', res.data);
-			})
-			colorChange('color_change').then(res => {
-				uni.setStorageSync('is_diy', res.data.is_diy)
-				uni.$emit('is_diy', res.data.is_diy)
-				uni.setStorageSync('color_status', res.data.status)
-				switch (res.data.status) {
-					case 1:
-						uni.setStorageSync('viewColor', blue)
-						uni.$emit('ok', blue, res.data.status)
-						break;
-					case 2:
-						uni.setStorageSync('viewColor', green)
-						uni.$emit('ok', green, res.data.status)
-						break;
-					case 3:
-						uni.setStorageSync('viewColor', red)
-						uni.$emit('ok', red, res.data.status)
-						break;
-					case 4:
-						uni.setStorageSync('viewColor', pink)
-						uni.$emit('ok', pink, res.data.status)
-						break;
-					case 5:
-						uni.setStorageSync('viewColor', orange)
-						uni.$emit('ok', orange, res.data.status)
-						break;
-					default:
-						uni.setStorageSync('viewColor', red)
-						uni.$emit('ok', red, res.data.status)
-						break
-				}
-			});
-			getLangVersion().then(res => {
-				let version = res.data.version
-				if (version != uni.getStorageSync('LANG_VERSION')) {
-					getLangJson().then(res => {
-						let value = Object.keys(res.data)[0]
-						Cache.set('locale', Object.keys(res.data)[0])
-						this.$i18n.setLocaleMessage(value, res.data[value]);
-						uni.setStorageSync('localeJson', res.data);
-					})
-				}
-				uni.setStorageSync('LANG_VERSION', version)
-			})
-
-			// #ifdef APP-PLUS || H5
-			uni.getSystemInfo({
-				success: function(res) {
-					// 首页没有title获取的整个页面的高度,里面的页面有原生标题要减掉就是视口的高度
-					// 状态栏是动态的可以拿到 标题栏是固定写死的是44px
-					let height = res.windowHeight - res.statusBarHeight - 44
-					// #ifdef H5 || APP-PLUS
-					that.globalData.windowHeight = res.windowHeight + 'px'
-					// #endif
-					// // #ifdef APP-PLUS
-					// that.globalData.windowHeight = height + 'px'
-					// // #endif
-
-				}
-			});
-			// #endif	
-			// #ifdef MP
-			if (HTTP_REQUEST_URL == '') {
-				console.error(
-					"请配置根目录下的config.js文件中的 'HTTP_REQUEST_URL'\n\n请修改开发者工具中【详情】->【AppID】改为自己的Appid\n\n请前往后台【小程序】->【小程序配置】填写自己的 appId and AppSecret"
-				);
-				return false;
-			}
-
-			const updateManager = wx.getUpdateManager();
-			const startParamObj = wx.getEnterOptionsSync();
-			if (wx.canIUse('getUpdateManager') && startParamObj.scene != 1154) {
-				const updateManager = wx.getUpdateManager()
-				updateManager.onCheckForUpdate(function(res) {
-					// 请求完新版本信息的回调
-					// console.log(res.hasUpdate)
-					if (res.hasUpdate) {
-						updateManager.onUpdateFailed(function() {
-							return that.Tips({
-								title: '新版本下载失败'
-							});
-						});
-						updateManager.onUpdateReady(function() {
-							wx.showModal({
-								title: '更新提示',
-								content: '新版本已经下载好,是否重启当前应用?',
-								success(res) {
-									if (res.confirm) {
-										updateManager.applyUpdate()
-									}
-								}
-							})
-						})
-						updateManager.onUpdateFailed(function() {
-							wx.showModal({
-								title: '发现新版本',
-								content: '请删除当前小程序,重启搜索打开...',
-							})
-						})
-					}
-				})
-			}
-			// #endif
-
-			// getShopConfig().then(res => {
-			// 	this.$store.commit('SETPHONESTATUS', res.data.status);
-			// });
-			// 获取导航高度;
-			uni.getSystemInfo({
-				success: function(res) {
-					that.globalData.navHeight = res.statusBarHeight * (750 / res.windowWidth) + 91;
-				}
-			});
-			// #ifdef MP
-			let menuButtonInfo = uni.getMenuButtonBoundingClientRect();
-			that.globalData.navH = menuButtonInfo.top * 2 + menuButtonInfo.height / 2;
-			const version = uni.getSystemInfoSync().SDKVersion
-			if (Routine.compareVersion(version, '2.21.3') >= 0) {
-				that.$Cache.set('MP_VERSION_ISNEW', true)
-			} else {
-				that.$Cache.set('MP_VERSION_ISNEW', false)
-			}
-			// #endif
-
-
-			// #ifdef MP
-			// 小程序静默授权
-			// if (!this.$store.getters.isLogin) {
-			// 	Routine.getCode()
-			// 		.then(code => {
-			// 			this.silenceAuth(code);
-			// 		})
-			// 		.catch(res => {
-			// 			uni.hideLoading();
-			// 		});
-			// }
-			// #endif
-			// #ifdef H5
-			// 添加crmeb chat 统计
-			var __s = document.createElement('script');
-			__s.src = `${HTTP_REQUEST_URL}/api/get_script`;
-			document.head.appendChild(__s);
-			// #endif
-			getCrmebCopyRight().then(res => {
-				uni.setStorageSync('copyRight', res.data)
-			})
-			// #ifdef MP
-			getSystemVersion().then(res => {
-				if (res.data.version_code < SYSTEM_VERSION) {
-					uni.showModal({
-						title: '提示',
-						content: '请重新打包并上传小程序',
-						success: function(res) {
-							if (res.confirm) {}
-						}
-					});
-				}
-			})
-			// #endif
-		},
-		// #ifdef H5
-		onHide() {
-			this.$Cache.clear('snsapiKey')
-		},
-		// #endif
-		methods: {
-			// 小程序静默授权
-			// silenceAuth(code) {
-			// 	let that = this;
-			// 	let spread = that.globalData.spid ? that.globalData.spid : '';
-			// 	silenceAuth({
-			// 			code: code,
-			// 			spread_spid: spread,
-			// 			spread_code: that.globalData.code
-			// 		})
-			// 		.then(res => {
-			// 			if (res.data.token !== undefined && res.data.token) {
-			// 				uni.hideLoading();
-			// 				let time = res.data.expires_time - this.$Cache.time();
-			// 				that.$store.commit('LOGIN', {
-			// 					token: res.data.token,
-			// 					time: time
-			// 				});
-			// 				that.$store.commit('SETUID', res.data.userInfo.uid);
-			// 				that.$store.commit('UPDATE_USERINFO', res.data.userInfo);
-			// 			}
-			// 		})
-			// 		.catch(res => {});
-			// },
-		},
-
-	};
-</script>
-
-<style>
-	@import url('@/plugin/emoji-awesome/css/tuoluojiang.css');
-	@import url('@/plugin/animate/animate.min.css');
-	@import 'static/css/base.css';
-	@import 'static/iconfont/iconfont.css';
-	@import 'static/css/guildford.css';
-	@import 'static/css/style.scss';
-
-	view {
-		box-sizing: border-box;
-	}
-
-	page {
-		font-family: PingFang SC;
-	}
-
-	.bg-color-red {
-		background-color: var(--view-theme) !important;
-	}
-
-	.syspadding {
-		padding-top: var(--status-bar-height);
-	}
-
-	.flex {
-		display: flex;
-	}
-
-	.uni-scroll-view::-webkit-scrollbar {
-		/* 隐藏滚动条,但依旧具备可以滚动的功能 */
-		display: none;
-	}
-
-	::-webkit-scrollbar {
-		width: 0;
-		height: 0;
-		color: transparent;
-	}
-
-	.uni-system-open-location .map-content.fix-position {
-		height: 100vh;
-		top: 0;
-		bottom: 0;
-	}
-
-	.open-location {
-		width: 100%;
-		height: 100vh;
-	}
+<script>
+import { checkLogin } from './libs/login';
+import { HTTP_REQUEST_URL, SYSTEM_VERSION } from './config/app';
+import { getShopConfig, silenceAuth, getSystemVersion, basicConfig } from '@/api/public';
+import Auth from '@/libs/wechat.js';
+import Routine from './libs/routine.js';
+import { silenceBindingSpread } from '@/utils';
+import { colorChange, getCrmebCopyRight } from '@/api/api.js';
+import { getLangJson, getLangVersion } from '@/api/user.js';
+import { mapGetters } from 'vuex';
+import colors from '@/mixins/color.js';
+import Cache from '@/utils/cache';
+import themeList from '@/utils/theme';
+
+export default {
+	globalData: {
+		spid: 0,
+		code: 0,
+		isLogin: false,
+		userInfo: {},
+		MyMenus: [],
+		globalData: false,
+		isIframe: false,
+		tabbarShow: true,
+		windowHeight: 0,
+		locale: ''
+	},
+	mixins: [colors],
+	computed: mapGetters(['isLogin', 'cartNum']),
+	watch: {
+		isLogin: {
+			deep: true, //深度监听设置为 true
+			handler: function (newV, oldV) {
+				if (newV) {
+					// this.getCartNum()
+				} else {
+					this.$store.commit('indexData/setCartNum', '');
+				}
+			}
+		},
+		cartNum(newCart, b) {
+			this.$store.commit('indexData/setCartNum', newCart + '');
+			if (newCart > 0) {
+				uni.setTabBarBadge({
+					index: Number(uni.getStorageSync('FOOTER_ADDCART')) || 2,
+					text: newCart + ''
+				});
+			} else {
+				uni.hideTabBarRedDot({
+					index: Number(uni.getStorageSync('FOOTER_ADDCART')) || 2
+				});
+			}
+		}
+	},
+	onShow() {
+		const queryData = uni.getEnterOptionsSync(); // uni-app版本 3.5.1+ 支持
+		if (queryData.query.spread) {
+			this.$Cache.set('spread', queryData.query.spread);
+			this.globalData.spid = queryData.query.spread;
+			this.globalData.pid = queryData.query.spread;
+			silenceBindingSpread(this.globalData);
+		}
+		if (queryData.query.spid) {
+			this.$Cache.set('spread', queryData.query.spid);
+			this.globalData.spid = queryData.query.spid;
+			this.globalData.pid = queryData.query.spid;
+			silenceBindingSpread(this.globalData);
+		}
+		// #ifdef MP
+		if (queryData.query.scene) {
+			let param = this.$util.getUrlParams(decodeURIComponent(queryData.query.scene));
+			console.log(param, 'param');
+			if (param.pid) {
+				this.$Cache.set('spread', param.pid);
+				this.globalData.spid = param.pid;
+				this.globalData.pid = param.pid;
+			} else {
+				switch (queryData.scene) {
+					//扫描小程序码
+					case 1047:
+						this.globalData.code = queryData.query.scene;
+						break;
+					//长按图片识别小程序码
+					case 1048:
+						this.globalData.code = queryData.query.scene;
+						break;
+					//手机相册选取小程序码
+					case 1049:
+						this.globalData.code = queryData.query.scene;
+						break;
+					//直接进入小程序
+					case 1001:
+						this.globalData.spid = queryData.query.scene;
+						break;
+				}
+			}
+			silenceBindingSpread(this.globalData);
+		}
+		// #endif
+	},
+	async onLaunch(option) {
+		uni.hideTabBar();
+		let that = this;
+		// #ifdef H5
+		if (option.query.hasOwnProperty('mdType') && option.query.mdType == 'iframeWindow') {
+			this.globalData.isIframe = true;
+		} else {
+			this.globalData.isIframe = false;
+		}
+		// #endif
+		basicConfig().then((res) => {
+			uni.setStorageSync('BASIC_CONFIG', res.data);
+		});
+		colorChange('color_change').then((res) => {
+			uni.setStorageSync('is_diy', res.data.is_diy);
+			uni.$emit('is_diy', res.data.is_diy);
+			uni.setStorageSync('color_status', res.data.status);
+			switch (res.data.status) {
+				case 1:
+					uni.setStorageSync('viewColor', themeList.blue);
+					uni.$emit('ok', themeList.blue, res.data.status);
+					break;
+				case 2:
+					uni.setStorageSync('viewColor', themeList.green);
+					uni.$emit('ok', themeList.green, res.data.status);
+					break;
+				case 3:
+					uni.setStorageSync('viewColor', themeList.red);
+					uni.$emit('ok', themeList.red, res.data.status);
+					break;
+				case 4:
+					uni.setStorageSync('viewColor', themeList.pink);
+					uni.$emit('ok', themeList.pink, res.data.status);
+					break;
+				case 5:
+					uni.setStorageSync('viewColor', themeList.orange);
+					uni.$emit('ok', themeList.orange, res.data.status);
+					break;
+				default:
+					uni.setStorageSync('viewColor', themeList.red);
+					uni.$emit('ok', themeList.red, res.data.status);
+					break;
+			}
+		});
+		getLangVersion().then((res) => {
+			let version = res.data.version;
+			if (version != uni.getStorageSync('LANG_VERSION')) {
+				getLangJson().then((res) => {
+					let value = Object.keys(res.data)[0];
+					Cache.set('locale', Object.keys(res.data)[0]);
+					this.$i18n.setLocaleMessage(value, res.data[value]);
+					uni.setStorageSync('localeJson', res.data);
+				});
+			}
+			uni.setStorageSync('LANG_VERSION', version);
+		});
+
+		// #ifdef APP-PLUS || H5
+		uni.getSystemInfo({
+			success: function (res) {
+				// 首页没有title获取的整个页面的高度,里面的页面有原生标题要减掉就是视口的高度
+				// 状态栏是动态的可以拿到 标题栏是固定写死的是44px
+				let height = res.windowHeight - res.statusBarHeight - 44;
+				// #ifdef H5 || APP-PLUS
+				that.globalData.windowHeight = res.windowHeight + 'px';
+				// #endif
+				// // #ifdef APP-PLUS
+				// that.globalData.windowHeight = height + 'px'
+				// // #endif
+			}
+		});
+		// #endif
+		// #ifdef MP
+		if (HTTP_REQUEST_URL == '') {
+			console.error(
+				"请配置根目录下的config.js文件中的 'HTTP_REQUEST_URL'\n\n请修改开发者工具中【详情】->【AppID】改为自己的Appid\n\n请前往后台【小程序】->【小程序配置】填写自己的 appId and AppSecret"
+			);
+			return false;
+		}
+
+		const updateManager = wx.getUpdateManager();
+		const startParamObj = wx.getEnterOptionsSync();
+		if (wx.canIUse('getUpdateManager') && startParamObj.scene != 1154) {
+			const updateManager = wx.getUpdateManager();
+			updateManager.onCheckForUpdate(function (res) {
+				// 请求完新版本信息的回调
+				// console.log(res.hasUpdate)
+				if (res.hasUpdate) {
+					updateManager.onUpdateFailed(function () {
+						return that.Tips({
+							title: '新版本下载失败'
+						});
+					});
+					updateManager.onUpdateReady(function () {
+						wx.showModal({
+							title: '更新提示',
+							content: '新版本已经下载好,是否重启当前应用?',
+							success(res) {
+								if (res.confirm) {
+									updateManager.applyUpdate();
+								}
+							}
+						});
+					});
+					updateManager.onUpdateFailed(function () {
+						wx.showModal({
+							title: '发现新版本',
+							content: '请删除当前小程序,重启搜索打开...'
+						});
+					});
+				}
+			});
+		}
+		// #endif
+
+		// getShopConfig().then(res => {
+		// 	this.$store.commit('SETPHONESTATUS', res.data.status);
+		// });
+		// 获取导航高度;
+		uni.getSystemInfo({
+			success: function (res) {
+				that.globalData.navHeight = res.statusBarHeight * (750 / res.windowWidth) + 91;
+			}
+		});
+		// #ifdef MP
+		let menuButtonInfo = uni.getMenuButtonBoundingClientRect();
+		that.globalData.navH = menuButtonInfo.top * 2 + menuButtonInfo.height / 2;
+		const version = uni.getSystemInfoSync().SDKVersion;
+		if (Routine.compareVersion(version, '2.21.3') >= 0) {
+			that.$Cache.set('MP_VERSION_ISNEW', true);
+		} else {
+			that.$Cache.set('MP_VERSION_ISNEW', false);
+		}
+		// #endif
+
+		// #ifdef MP
+		// 小程序静默授权
+		// if (!this.$store.getters.isLogin) {
+		// 	Routine.getCode()
+		// 		.then(code => {
+		// 			this.silenceAuth(code);
+		// 		})
+		// 		.catch(res => {
+		// 			uni.hideLoading();
+		// 		});
+		// }
+		// #endif
+		// #ifdef H5
+		// 添加crmeb chat 统计
+		var __s = document.createElement('script');
+		__s.src = `${HTTP_REQUEST_URL}/api/get_script`;
+		document.head.appendChild(__s);
+		// #endif
+		getCrmebCopyRight().then((res) => {
+			uni.setStorageSync('copyRight', res.data);
+		});
+		// #ifdef MP
+		getSystemVersion().then((res) => {
+			if (res.data.version_code < SYSTEM_VERSION) {
+				uni.showModal({
+					title: '提示',
+					content: '请重新打包并上传小程序',
+					success: function (res) {
+						if (res.confirm) {
+						}
+					}
+				});
+			}
+		});
+		// #endif
+	},
+	// #ifdef H5
+	onHide() {
+		this.$Cache.clear('snsapiKey');
+	},
+	// #endif
+	methods: {
+		// 小程序静默授权
+		// silenceAuth(code) {
+		// 	let that = this;
+		// 	let spread = that.globalData.spid ? that.globalData.spid : '';
+		// 	silenceAuth({
+		// 			code: code,
+		// 			spread_spid: spread,
+		// 			spread_code: that.globalData.code
+		// 		})
+		// 		.then(res => {
+		// 			if (res.data.token !== undefined && res.data.token) {
+		// 				uni.hideLoading();
+		// 				let time = res.data.expires_time - this.$Cache.time();
+		// 				that.$store.commit('LOGIN', {
+		// 					token: res.data.token,
+		// 					time: time
+		// 				});
+		// 				that.$store.commit('SETUID', res.data.userInfo.uid);
+		// 				that.$store.commit('UPDATE_USERINFO', res.data.userInfo);
+		// 			}
+		// 		})
+		// 		.catch(res => {});
+		// },
+	}
+};
+</script>
+
+<style>
+@import url('@/plugin/emoji-awesome/css/tuoluojiang.css');
+@import url('@/plugin/animate/animate.min.css');
+@import 'static/css/base.css';
+@import 'static/iconfont/iconfont.css';
+@import 'static/css/guildford.css';
+@import 'static/css/style.scss';
+
+view {
+	box-sizing: border-box;
+}
+
+page {
+	font-family: PingFang SC;
+}
+
+.bg-color-red {
+	background-color: var(--view-theme) !important;
+}
+
+.syspadding {
+	padding-top: var(--status-bar-height);
+}
+
+.flex {
+	display: flex;
+}
+
+.uni-scroll-view::-webkit-scrollbar {
+	/* 隐藏滚动条,但依旧具备可以滚动的功能 */
+	display: none;
+}
+
+::-webkit-scrollbar {
+	width: 0;
+	height: 0;
+	color: transparent;
+}
+
+.uni-system-open-location .map-content.fix-position {
+	height: 100vh;
+	top: 0;
+	bottom: 0;
+}
+
+.open-location {
+	width: 100%;
+	height: 100vh;
+}
 </style>

+ 0 - 0
template/uni-app/api/user.js


이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.