Просмотр исходного кода

Merge branch 'v4.7.0dev' of https://gitee.com/ZhongBangKeJi/CRMEB into v4.7.0dev

liaofei 2 лет назад
Родитель
Сommit
59ace8147a
44 измененных файлов с 405 добавлено и 245 удалено
  1. 6 1
      crmeb/app/api/controller/v1/wechat/AuthController.php
  2. 17 0
      crmeb/app/api/controller/v2/wechat/AuthController.php
  3. 2 0
      crmeb/app/api/route/v2.php
  4. 2 1
      crmeb/app/model/order/StoreOrder.php
  5. 3 2
      crmeb/app/model/product/product/StoreProduct.php
  6. 1 1
      crmeb/app/services/order/DeliveryServiceServices.php
  7. 1 0
      crmeb/app/services/system/admin/SystemAdminServices.php
  8. 28 0
      crmeb/app/services/wechat/RoutineServices.php
  9. 10 2
      crmeb/app/services/wechat/WechatUserServices.php
  10. 1 1
      template/admin/src/components/main/components/header-notice/index.vue
  11. 8 7
      template/admin/src/components/main/components/header-search/index.vue
  12. 24 35
      template/admin/src/components/main/components/side-menu/side-menu.vue
  13. 0 17
      template/admin/src/components/main/main.vue
  14. 23 14
      template/admin/src/main.js
  15. 1 3
      template/admin/src/pages/app/wechat/menus/index.vue
  16. 3 0
      template/admin/src/pages/app/wechat/reply/follow.vue
  17. 1 1
      template/admin/src/pages/finance/billingRecords/index.vue
  18. 0 16
      template/admin/src/pages/marketing/lottery/create.vue
  19. 3 1
      template/admin/src/pages/marketing/sign/index.vue
  20. 7 1
      template/admin/src/pages/marketing/storeBargain/statistics.vue
  21. 15 8
      template/admin/src/pages/marketing/storeCombination/combinaList.vue
  22. 0 5
      template/admin/src/pages/marketing/storeCombination/index.vue
  23. 7 2
      template/admin/src/pages/marketing/storeCombination/statistics.vue
  24. 10 1
      template/admin/src/pages/marketing/storeSeckill/statistics.vue
  25. 2 4
      template/admin/src/pages/notify/smsConfig/index.vue
  26. 2 2
      template/admin/src/pages/product/productAdd/index.vue
  27. 2 0
      template/admin/src/pages/setting/setSystem/index.vue
  28. 5 5
      template/admin/src/pages/setting/storage/index.vue
  29. 2 2
      template/admin/src/pages/setting/systemOutInterface/index.vue
  30. 2 0
      template/admin/src/pages/setting/user/index.vue
  31. 67 67
      template/admin/src/pages/system/group/list.vue
  32. 1 3
      template/admin/src/pages/system/maintain/systemCleardata/index.vue
  33. 4 4
      template/admin/src/pages/system/maintain/systemDatabackup/index.vue
  34. 3 1
      template/admin/src/pages/system/maintain/systemFile/index.vue
  35. 27 20
      template/admin/src/pages/system/maintain/systemFile/login.vue
  36. 3 1
      template/admin/src/pages/user/grade/right/index.vue
  37. 3 0
      template/admin/src/store/module/userInfo.js
  38. 5 0
      template/admin/src/styles/style.css
  39. 9 0
      template/uni-app/api/user.js
  40. 2 2
      template/uni-app/manifest.json
  41. 14 8
      template/uni-app/pages/order_addcart/order_addcart.vue
  42. 35 1
      template/uni-app/pages/user/index.vue
  43. 0 1
      template/uni-app/pages/users/components/login_mobile/routine_phone.vue
  44. 44 5
      template/uni-app/pages/users/user_info/index.vue

+ 6 - 1
crmeb/app/api/controller/v1/wechat/AuthController.php

@@ -37,7 +37,12 @@ class AuthController
     /**
      * 小程序授权登录
      * @param Request $request
-     * @return mixed
+     * @return \think\Response
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/02/24
      */
     public function mp_auth(Request $request)
     {

+ 17 - 0
crmeb/app/api/controller/v2/wechat/AuthController.php

@@ -79,6 +79,23 @@ class AuthController
             return app('json')->fail(410019);
     }
 
+    /**
+     * 小程序绑定手机号
+     * @param string $code
+     * @param string $iv
+     * @param string $encryptedData
+     * @return \think\Response
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/02/24
+     */
+    public function bindingPhone($code = '', $iv = '', $encryptedData = '')
+    {
+        if (!$code || !$iv || !$encryptedData) return app('json')->fail(100100);
+        $this->services->bindingPhone($code, $iv, $encryptedData);
+        return app('json')->success(410016);
+    }
+
     /** 以下方法该版本暂未使用 */
     /**
      * 小程序授权登录

+ 2 - 0
crmeb/app/api/route/v2.php

@@ -36,6 +36,8 @@ Route::group('v2', function () {
         Route::get('bind_status', 'v2.PublicController/bindPhoneStatus');
         //小程序授权绑定手机号
         Route::post('auth_bindind_phone', 'v2.wechat.AuthController/authBindingPhone');
+        //小程序授权后绑定手机号
+        Route::post('routine/binding_phone', 'v2.wechat.AuthController/BindingPhone');
         //小程序手机号登录直接绑定
         Route::post('phone_silence_auth', 'v2.wechat.AuthController/silenceAuthBindingPhone');
         //微信手机号登录直接绑定

+ 2 - 1
crmeb/app/model/order/StoreOrder.php

@@ -596,6 +596,7 @@ class StoreOrder extends BaseModel
      */
     public function searchIdsAttr($query, $value)
     {
-        if ($value !== '') $query->whereIn('id', $value);
+        if (is_string($value)) $value = explode(',', $value);
+        if (count($value)) $query->whereIn('id', $value);
     }
 }

+ 3 - 2
crmeb/app/model/product/product/StoreProduct.php

@@ -339,13 +339,14 @@ class StoreProduct extends BaseModel
     }
 
     /**
-     * 在当前id中查询
+     * 在当前id中查询
      * @param $query
      * @param $value
      */
     public function searchIdsAttr($query, $value)
     {
-        if ($value != '') $query->whereIn('id', $value);
+        if (is_string($value)) $value = explode(',', $value);
+        if (count($value)) $query->whereIn('id', $value);
     }
 
     /**

+ 1 - 1
crmeb/app/services/order/DeliveryServiceServices.php

@@ -158,7 +158,7 @@ class DeliveryServiceServices extends BaseServices
      */
     public function saveDeliveryService(array $data)
     {
-        if ($data['image'] == '') throw new AdminException(400466);
+        if ($data['image'] == '') throw new AdminException(400250);
         $data['uid'] = $data['image']['uid'];
         /** @var UserServices $userService */
         $userService = app()->make(UserServices::class);

+ 1 - 0
crmeb/app/services/system/admin/SystemAdminServices.php

@@ -138,6 +138,7 @@ class SystemAdminServices extends BaseServices
                 'account' => $adminInfo->getData('account'),
                 'head_pic' => $adminInfo->getData('head_pic'),
                 'level' => $adminInfo->getData('level'),
+                'real_name' => $adminInfo->getData('real_name'),
             ],
             'logo' => sys_config('site_logo'),
             'logo_square' => sys_config('site_logo_square'),

+ 28 - 0
crmeb/app/services/wechat/RoutineServices.php

@@ -461,6 +461,34 @@ class RoutineServices extends BaseServices
             throw new ApiException(410019);
     }
 
+    /**
+     * @param $code
+     * @param $iv
+     * @param $encryptedData
+     * @return bool
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/02/24
+     */
+    public function bindingPhone($code, $iv, $encryptedData)
+    {
+        [$userInfoCong, $userInfo] = app()->make(OAuth::class, ['mini_program'])->oauth($code, [
+            'iv' => $iv,
+            'encryptedData' => $encryptedData
+        ]);
+        if (!$userInfo || !isset($userInfo['purePhoneNumber'])) {
+            throw new ApiException(410079);
+        }
+        $uid = app()->make(WechatUserServices::class)->openidTouid($userInfoCong['openid']);
+        $userServices = app()->make(UserServices::class);
+        if ($userServices->count(['phone' => $userInfo['purePhoneNumber']])) {
+            throw new ApiException(410028);
+        }
+        $res = app()->make(UserServices::class)->update(['uid' => $uid], ['phone' => $userInfo['purePhoneNumber']]);
+        if ($res) return true;
+        throw new ApiException(410017);
+    }
+
 
     /**
      * 更新用户信息

+ 10 - 2
crmeb/app/services/wechat/WechatUserServices.php

@@ -198,6 +198,10 @@ class WechatUserServices extends BaseServices
      * 授权后获取用户信息
      * @param $openid
      * @param $user_type
+     * @return array|\think\Model|null
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/02/24
      */
     public function getAuthUserInfo($openid, $user_type)
     {
@@ -256,10 +260,14 @@ class WechatUserServices extends BaseServices
 
     /**
      * 微信授权成功后
-     * @param $event
+     * @param array $data
+     * @return array|mixed|\think\Model|null
      * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
      * @throws \think\db\exception\ModelNotFoundException
-     * @throws \think\exception\DbException
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/02/24
      */
     public function wechatOauthAfter(array $data)
     {

+ 1 - 1
template/admin/src/components/main/components/header-notice/index.vue

@@ -6,7 +6,7 @@
           <Icon type="ios-notifications-outline" size="24"></Icon>
         </Badge>
       </div>
-      <DropdownMenu slot="list">
+      <DropdownMenu slot="list" v-show="needList.length">
         <DropdownItem :name="item.url" v-for="(item, index) in needList" :key="index"
           ><Icon :type="item.icon" :style="'background-color:' + item.iconColor" class="iconImg" />{{
             item.title

+ 8 - 7
template/admin/src/components/main/components/header-search/index.vue

@@ -6,6 +6,7 @@
       placeholder="菜单搜索"
       filterable
       remote
+      clearable
       :remote-method="remoteMethod"
       :loading="loading"
     >
@@ -19,22 +20,22 @@
     </Select>
   </div>
 </template>
-<style>
-.search .ivu-select-selection {
+<style scoped>
+.search /deep/ .ivu-select-selection {
   margin-right: 20px;
   border-radius: 30px;
 }
-.search .ivu-select-visible .ivu-select-selection {
+.search /deep/ .ivu-select-visible .ivu-select-selection {
   box-shadow: unset !important;
 }
-.search li.ivu-select-item {
+.search /deep/ li.ivu-select-item {
   text-align: left;
 }
-.search .select .ivu-select-input,
-.search .select .ivu-select-item {
+.search /deep/ .select .ivu-select-input,
+.search /deep/ .select .ivu-select-item {
   font-size: 13px !important;
 }
-.search .ivu-select-input{
+.search /deep/ .ivu-select-input{
   padding-left: 19px;
   border-radius: 30px;
   background-color: rgba(255,255,255,0.3);

+ 24 - 35
template/admin/src/components/main/components/side-menu/side-menu.vue

@@ -65,8 +65,8 @@
       </div>
     </div>
 
-    <div class="menu-collapsed" v-show="collapsed" :list="menuList">
-      <template v-for="item in menuList">
+    <div class="menu-collapsed" v-show="collapsed">
+      <template v-for="item in menusName">
         <collapsed-menu
           v-if="item.children && item.children.length > 0"
           @on-click="collHandleSelect"
@@ -111,12 +111,6 @@ export default {
     siderTrigger,
   },
   props: {
-    menuList: {
-      type: Array,
-      default() {
-        return [];
-      },
-    },
     collapsed: {
       type: Boolean,
     },
@@ -150,7 +144,7 @@ export default {
     };
   },
   computed: {
-    ...mapState('menus', ['openMenus']),
+    ...mapState('menus', ['menusName']),
     ...mapState('menu', ['activePath', 'openNames', 'header', 'headerName', 'sider', 'oneMenuName']),
     ...mapGetters('menu', ['filterSider']),
 
@@ -159,18 +153,14 @@ export default {
     },
   },
   watch: {
-    openedNames() {
-      this.$nextTick(() => {
-        this.$refs.menu.updateOpened();
-        this.$refs.childMenu.updateActiveName();
-      });
-    },
-    oneMenuName() {
-      this.$nextTick(() => {});
-    },
+    // openedNames() {
+    //   this.$nextTick(() => {
+    //     this.$refs.menu.updateOpened();
+    //     this.$refs.childMenu.updateActiveName();
+    //   });
+    // },
     activePath() {
       this.$nextTick(() => {
-        console.log();
         this.$refs.childMenu.updateOpened();
         this.$refs.childMenu.updateActiveName();
       });
@@ -188,13 +178,10 @@ export default {
   mounted() {},
   methods: {
     handleCollpasedChange(state) {
-      console.log(state);
-      // this.collapsed = state;
       this.$emit('on-coll-change', state);
-      // setCookies('collapsed', state);
     },
     handleSelect(name, type) {
-      this.menuList.map((e) => {
+      this.menusName.map((e) => {
         if (e.path === name) {
           this.turnToPage(this.getChilden(e));
         }
@@ -210,14 +197,6 @@ export default {
     handleChildSelect(name) {
       this.turnToPage(name);
     },
-    jump(data) {
-      if (data[0].children) {
-        this.jump(data[0].children);
-      } else {
-        this.turnToPage(data[0].path);
-      }
-    },
-
     collHandleSelect(name) {
       this.turnToPage(name);
     },
@@ -238,14 +217,12 @@ export default {
         query,
       });
     },
-    openNameData(n) {
-      // this.openedNames = n
-      // this.$store.commit('menus/getopenMenus', n)
-    },
+    openNameData(n) {},
     openChildNameData(e) {},
   },
 };
 </script>
+<style lang="less" scoped></style>
 <style lang="less">
 @import './side-menu.less';
 .ivu-menu {
@@ -338,6 +315,14 @@ export default {
       color: #fff !important;
       border-radius: 4px;
     }
+    .ivu-menu-vertical .ivu-menu-item:hover {
+      color: #1890ff !important;
+      background-color: rgba(24, 144, 255, 0.1) !important;
+      border-radius: 4px;
+      .ivu-icon {
+        color: #1890ff !important;
+      }
+    }
     .ivu-menu-vertical .ivu-menu-item {
       padding: 10px 10px;
       margin-bottom: 8px;
@@ -372,6 +357,9 @@ export default {
         .ivu-menu-submenu-title {
           padding-left: 23px !important;
         }
+        .ivu-menu-item {
+          padding-left: 35px !important;
+        }
       }
     }
     .ivu-menu-vertical .ivu-menu-submenu-title {
@@ -438,6 +426,7 @@ export default {
       white-space: nowrap;
     }
   }
+
   .drop-menu-a {
     padding: 0;
   }

+ 0 - 17
template/admin/src/components/main/main.vue

@@ -37,7 +37,6 @@
           :active-name="$route.path"
           :collapsed="collapsed"
           @on-select="turnToPage"
-          :menu-list="menuList"
         >
           <!-- 需要放在菜单上面的内容,如Logo,写在side-menu标签内部,如下 -->
         </side-menu>
@@ -145,20 +144,6 @@ export default {
       ];
       return list;
     },
-    menuList() {
-      let menus = this.$store.state.menus.menusName;
-      let newArray = [];
-      menus.forEach((now, index) => {
-        newArray[index] = now;
-        if (newArray[index].children && now.children) {
-          newArray[index].children = now.children.filter((item) => {
-            return !item.auth;
-          });
-        }
-      });
-      return newArray;
-      // return this.$store.state.menus.menusName
-    },
     local() {
       return this.$store.state.app.local;
     },
@@ -237,8 +222,6 @@ export default {
   watch: {
     $route(newRoute) {
       this.headMenuNoShow = this.$route.meta.fullScreen;
-      let openNames = getMenuopen(newRoute, this.menuList);
-      this.$store.commit('menus/setopenMenus', openNames);
       const { name, query, params, meta } = newRoute;
       this.addTag({
         route: { name, query, params, meta },

+ 23 - 14
template/admin/src/main.js

@@ -198,20 +198,29 @@ new Vue({
       const path = to.path;
       let menus = this.$store.state.menus.menusName;
       const menuSider = menus;
-      this.$store.commit('menu/setActivePath', path);
-      const openNames = getSiderSubmenu(to, menuSider);
-      this.$store.commit('menu/setOpenNames', openNames);
-      // 设置顶栏菜单 后台添加一个接口,设置顶部菜单
-      const headerSider = getHeaderSider(menuSider);
-      this.$store.commit('menu/setHeader', headerSider);
-      // 指定当前侧边栏隶属顶部菜单名称。如果你没有使用顶部菜单,则设置为默认的(一般为 home)名称即可
       const headerName = getHeaderName(to, menuSider);
-      this.$store.commit('menu/setHeaderName', headerName);
-      // 获取侧边栏菜单
-      const filterMenuSider = getMenuSider(menuSider, headerName);
-      // 指定当前显示的侧边菜单
-      this.$store.commit('menu/setOpenMenuName', filterMenuSider[0].title);
-      this.$store.commit('menu/setSider', filterMenuSider[0]?.children || []);
+
+      if (headerName !== null) {
+        this.$store.commit('menu/setActivePath', path);
+        const openNames = getSiderSubmenu(to, menuSider);
+        this.$store.commit('menu/setOpenNames', openNames);
+        // 设置顶栏菜单 后台添加一个接口,设置顶部菜单
+        const headerSider = getHeaderSider(menuSider);
+        this.$store.commit('menu/setHeader', headerSider);
+        // 指定当前侧边栏隶属顶部菜单名称。如果你没有使用顶部菜单,则设置为默认的(一般为 home)名称即可
+        this.$store.commit('menu/setHeaderName', headerName);
+        // 获取侧边栏菜单
+        const filterMenuSider = getMenuSider(menuSider, headerName);
+        // 指定当前显示的侧边菜单
+        this.$store.commit('menu/setOpenMenuName', filterMenuSider[0].title);
+        this.$store.commit('menu/setSider', filterMenuSider[0]?.children || []);
+      } else {
+        //子路由给默认 如果你没有使用顶部菜单,则设置为默认的(一般为 home)名称即可
+        // this.$store.commit('menu/setHeaderName', 'home');
+        // 指定当前显示的侧边菜单
+        // this.$store.commit('menu/setSider', menuSider);
+      }
+
       if (to.meta.kefu) {
         document.getElementsByTagName('body')[0].className = 'kf_mobile';
       } else {
@@ -228,7 +237,7 @@ new Vue({
         return;
       }
       // 在 404 时,是没有 headerName 的
-      
+
       // });
     },
   },

+ 1 - 3
template/admin/src/pages/app/wechat/menus/index.vue

@@ -1,9 +1,7 @@
 <template>
   <div class="article-manager">
-    <div class="i-layout-page-header">
-      <div class="i-layout-page-header">
+    <div class="i-layout-page-header" style="padding: 18px 32px;border-bottom: 1px solid #f2f2f2;">
         <span class="ivu-page-header-title">{{ $route.meta.title }}</span>
-      </div>
     </div>
     <Card :bordered="false" dis-hover class="ivu-mt">
       <!-- 公众号设置 -->

+ 3 - 0
template/admin/src/pages/app/wechat/reply/follow.vue

@@ -1,5 +1,8 @@
 <template>
   <div>
+    <div class="i-layout-page-header" style="padding: 18px 32px;border-bottom: 1px solid #f2f2f2;">
+      <span class="ivu-page-header-title">{{ $route.meta.title }}</span>
+    </div>
     <Card :bordered="false" dis-hover class="ivu-mt">
       <!-- 公众号设置 -->
       <Row :gutter="24" type="flex">

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

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <Card :bordered="false" dis-hover class="ive-mt tablebox">
+    <Card :bordered="false" dis-hover class="ive-mt">
       <div class="ive-mt tabbox">
         <Tabs @on-click="onClickTab" class="mb20">
           <TabPane label="日账单" name="day" />

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

@@ -1,21 +1,5 @@
 <template>
   <div>
-    <div class="i-layout-page-header header_top">
-      <div class="i-layout-page-header fl_header">
-        <!-- <router-link :to="{ path: '/admin/marketing/lottery/index' }"
-          ><Button icon="ios-arrow-back" size="small" type="text"
-            >返回</Button
-          ></router-link
-        > -->
-        <!-- <Divider type="vertical" /> -->
-        <span
-          class="ivu-page-header-title mr20"
-          style="padding: 0"
-          v-text="$route.params.id ? '编辑抽奖信息' : '添加抽奖信息'"
-        ></span>
-      </div>
-    </div>
-
     <Card :bordered="false" dis-hover class="ivu-mt">
       <div>
         <Tabs v-model="formValidate.factor" @on-click="onClickTab">

+ 3 - 1
template/admin/src/pages/marketing/sign/index.vue

@@ -1,5 +1,8 @@
 <template>
   <div :style="bgcolors">
+    <div class="i-layout-page-header">
+      <span class="ivu-page-header-title">{{ $route.meta.title }}</span>
+    </div>
     <div class="box-wrapper">
       <div v-if="name == 'sign_day_num'" class="iframe" :bordered="false">
         <div class="iframe-box">
@@ -1174,7 +1177,6 @@ export default {
   padding: 20px;
   background-color: #fff;
   border-radius: 5px;
-  margin: 20px;
 }
 
 .iview-video-style {

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

@@ -412,7 +412,13 @@ export default {
 }
 
 .i-layout-page-header {
-  padding-left: 13px;
+  padding-left: 5px;
+  padding-bottom: 1px;
+  margin-bottom: 10px;
+}
+/deep/ .ivu-tabs-nav-scroll{
+  background-color: #fff;
+  padding-top: 5px;
 }
 
 .tabBox_img {

+ 15 - 8
template/admin/src/pages/marketing/storeCombination/combinaList.vue

@@ -348,12 +348,19 @@ export default {
 </script>
 
 <style scoped lang="stylus">
-.tabBox_img
-    width 36px
-    height 36px
-    border-radius:4px
-    cursor pointer
-    img
-        width 100%
-        height 100%
+.article-manager{
+  margin-top: 3px;
+}
+.tabBox_img{
+  width: 36px;
+  height: 36px;
+  border-radius:4px;
+  cursor: pointer;
+  img{
+    width: 100%;
+    height: 100%;
+  }
+
+}
+
 </style>

+ 0 - 5
template/admin/src/pages/marketing/storeCombination/index.vue

@@ -1,10 +1,5 @@
 <template>
   <div>
-    <div class="i-layout-page-header">
-      <div class="i-layout-page-header">
-        <span class="ivu-page-header-title">{{ $route.meta.title }}</span>
-      </div>
-    </div>
     <Card :bordered="false" dis-hover class="ivu-mt">
       <Form
         ref="formValidate"

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

@@ -407,9 +407,14 @@ export default {
 }
 
 .i-layout-page-header {
-  padding-left: 13px;
+  padding-left: 5px;
+  padding-bottom 1px
+  margin-bottom 10px
+}
+/deep/ .ivu-tabs-nav-scroll{
+  background-color: #fff;
+  padding-top 5px
 }
-
 .tabBox_img {
   width: 36px;
   height: 36px;

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

@@ -247,7 +247,7 @@ export default {
 };
 </script>
 
-<style scoped>
+<style lang='less' scoped>
 .cl {
   margin-right: 20px;
 }
@@ -262,6 +262,15 @@ export default {
 .ech-box {
   margin-top: 10px;
 }
+.i-layout-page-header {
+  padding-left: 5px;
+  padding-bottom: 1px;
+  margin-bottom: 10px;
+}
+/deep/ .ivu-tabs-nav-scroll{
+  background-color: #fff;
+  padding-top: 5px;
+}
 .change-style {
   border: 1px solid #ccc;
   border-radius: 15px;

+ 2 - 4
template/admin/src/pages/notify/smsConfig/index.vue

@@ -1,7 +1,6 @@
 <template>
   <div>
-    <div class="i-layout-page-header">
-      <div class="i-layout-page-header">
+    <div class="i-layout-page-header pt10">
         <span class="ivu-page-header-title" v-if="!isShowList">短信账户</span>
         <div v-if="isShowList" class="acea-row row-between-wrapper picTxt">
           <div slot="content">
@@ -83,9 +82,8 @@
             </div>
           </div>
         </div>
-      </div>
     </div>
-    <Card :bordered="false" dis-hover class="ivu-mt">
+    <Card :bordered="false" dis-hover class="ivu-mt" style="min-height: 600px">
       <login-from
         @on-change="onChangePasssword"
         v-if="isShowLogn"

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

@@ -1,7 +1,7 @@
 <template>
   <div class="" id="shopp-manager">
-    <div class="i-layout-page-header header_top">
-      <div class="i-layout-page-header fl_header">
+    <div class="i-layout-page-header header-title">
+      <div class=" fl_header">
         <router-link :to="{ path: $routeProStr + '/product/product_list' }"
           ><Button icon="ios-arrow-back" size="small" type="text">返回</Button></router-link
         >

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

@@ -1,4 +1,5 @@
 <template>
+  <div>
   <div class="article-manager">
     <Card :bordered="false" dis-hover class="ivu-mt fromBox">
       <Tabs v-model="currentTab" @on-click="changeTab" v-if="headerList.length">
@@ -22,6 +23,7 @@
       <Spin size="large" fix v-if="spinShow"></Spin>
     </Card>
   </div>
+  </div>
 </template>
 
 <script>

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

@@ -1,6 +1,6 @@
 <template>
-  <div class="message">
-    <div class="table-box" style="padding-bottom: 0">
+  <div >
+    <div class="message">
       <Card :bordered="false" dis-hover class="">
         <div class="mb20">
           <Tabs v-model="currentTab" @on-click="changeTab">
@@ -42,7 +42,7 @@
         </template>
       </Card>
     </div>
-    <div class="table-box" style="padding-top: 10px" v-if="currentTab == 1">
+    <div class="pt10" v-if="currentTab == 1">
       <Card :bordered="false" dis-hover class="ivu-mt">
         <Row type="flex">
           <Col span="24">
@@ -322,8 +322,8 @@
       </Card>
     </div>
     <!-- 缩略图配置 -->
-    <div class="table-box" style="padding-top: 10px" v-else-if="currentTab == 5"></div>
-    <div class="table-box" style="padding-top: 10px" v-else>
+    <div class="pt10" v-else-if="currentTab == 5"></div>
+    <div class="pt10" v-else>
       <Card :bordered="false" dis-hover class="ivu-mt">
         <Row type="flex" class="mb20">
           <Col span="24">

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

@@ -892,7 +892,7 @@ export default {
   .main-btn {}
   .card-tree{
     width: 270px;
-    height: calc(100vh - 190px);
+    height: calc(100vh - 115px);
     overflow-y: scroll;
   }
   >>> .tree {
@@ -981,7 +981,7 @@ export default {
   }
   .right-card {
     flex: 1;
-    max-height: calc(100vh - 190px);
+    max-height: calc(100vh - 115px);
     overflow-y: scroll;
   }
 

+ 2 - 0
template/admin/src/pages/setting/user/index.vue

@@ -59,6 +59,7 @@ export default {
   },
   mounted() {
     this.account = this.$store.state.userInfo.userInfo.account;
+    this.formValidate.real_name = this.$store.state.userInfo.userInfo.real_name;
   },
   methods: {
     handleSubmit(name) {
@@ -66,6 +67,7 @@ export default {
         if (valid) {
           updtaeAdmin(this.formValidate)
             .then((res) => {
+              this.$store.commit('userInfo/userRealName', this.formValidate.real_name);
               this.$Message.success(res.msg);
             })
             .catch((res) => {

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

@@ -2,10 +2,10 @@
   <div>
     <div class="i-layout-page-header header_top">
       <div class="i-layout-page-header fl_header">
-        <router-link :to="{ path: $routeProStr + '/system/config/system_group/index' }"
+        <router-link v-if="$route.params.id != 49" :to="{ path: $routeProStr + '/system/config/system_group/index' }"
           ><Button icon="ios-arrow-back" size="small" type="text">返回</Button></router-link
         >
-        <Divider type="vertical" />
+        <Divider v-if="$route.params.id != 49" type="vertical" />
         <span class="ivu-page-header-title mr20" style="padding: 0" v-text="$route.meta.title"></span>
       </div>
     </div>
@@ -27,70 +27,68 @@
           </Menu>
         </Col>
         <Col :xs="24" :sm="24" :md="$route.params.id ? 24 : 17" :lg="$route.params.id ? 24 : 20" ref="rightBox">
-          <Card :bordered="false" dis-hover>
-            <Form
-              ref="formValidate"
-              :model="formValidate"
-              :label-width="labelWidth"
-              :label-position="labelPosition"
-              @submit.native.prevent
-            >
-              <Row type="flex" :gutter="24">
-                <Col v-bind="grid">
-                  <FormItem label="是否显示:">
-                    <Select v-model="formValidate.status" placeholder="请选择" clearable @on-change="userSearchs">
-                      <Option value="1">显示</Option>
-                      <Option value="0">不显示</Option>
-                    </Select>
-                  </FormItem>
-                </Col>
-              </Row>
-              <Row type="flex">
-                <Col v-bind="grid">
-                  <Button type="primary" icon="md-add" @click="groupAdd('添加数据')" class="mr20">添加数据</Button>
-                </Col>
-              </Row>
-            </Form>
-            <Table
-              :columns="columns1"
-              :data="tabList"
-              ref="table"
-              class="mt25"
-              :loading="loading"
-              highlight-row
-              no-userFrom-text="暂无数据"
-              no-filtered-userFrom-text="暂无筛选结果"
-            >
-              <template slot-scope="{ row, index }" slot="status">
-                <i-switch
-                  v-model="row.status"
-                  :value="row.status"
-                  :true-value="1"
-                  :false-value="0"
-                  @on-change="onchangeIsShow(row)"
-                  size="large"
-                >
-                  <span slot="open">显示</span>
-                  <span slot="close">隐藏</span>
-                </i-switch>
-              </template>
-              <template slot-scope="{ row, index }" slot="action">
-                <a @click="edit(row, '编辑')">编辑</a>
-                <Divider type="vertical" />
-                <a @click="del(row, '删除这条信息', index)">删除</a>
-              </template>
-            </Table>
-            <div class="acea-row row-right page">
-              <Page
-                :total="total"
-                :current="formValidate.page"
-                show-elevator
-                show-total
-                @on-change="pageChange"
-                :page-size="formValidate.limit"
-              />
-            </div>
-          </Card>
+          <Form
+            ref="formValidate"
+            :model="formValidate"
+            :label-width="labelWidth"
+            :label-position="labelPosition"
+            @submit.native.prevent
+          >
+            <Row type="flex" :gutter="24">
+              <Col v-bind="grid">
+                <FormItem label="是否显示:">
+                  <Select v-model="formValidate.status" placeholder="请选择" clearable @on-change="userSearchs">
+                    <Option value="1">显示</Option>
+                    <Option value="0">不显示</Option>
+                  </Select>
+                </FormItem>
+              </Col>
+            </Row>
+            <Row type="flex">
+              <Col v-bind="grid">
+                <Button type="primary" icon="md-add" @click="groupAdd('添加数据')" class="mr20">添加数据</Button>
+              </Col>
+            </Row>
+          </Form>
+          <Table
+            :columns="columns1"
+            :data="tabList"
+            ref="table"
+            class="mt25"
+            :loading="loading"
+            highlight-row
+            no-userFrom-text="暂无数据"
+            no-filtered-userFrom-text="暂无筛选结果"
+          >
+            <template slot-scope="{ row, index }" slot="status">
+              <i-switch
+                v-model="row.status"
+                :value="row.status"
+                :true-value="1"
+                :false-value="0"
+                @on-change="onchangeIsShow(row)"
+                size="large"
+              >
+                <span slot="open">显示</span>
+                <span slot="close">隐藏</span>
+              </i-switch>
+            </template>
+            <template slot-scope="{ row, index }" slot="action">
+              <a @click="edit(row, '编辑')">编辑</a>
+              <Divider type="vertical" />
+              <a @click="del(row, '删除这条信息', index)">删除</a>
+            </template>
+          </Table>
+          <div class="acea-row row-right page">
+            <Page
+              :total="total"
+              :current="formValidate.page"
+              show-elevator
+              show-total
+              @on-change="pageChange"
+              :page-size="formValidate.limit"
+            />
+          </div>
         </Col>
       </Row>
     </Card>
@@ -348,7 +346,9 @@ export default {
 /deep/ .ivu-menu-vertical.ivu-menu-light:after{
     display none
 }
-
+/deep/ .i-layout-page-header{
+  padding-left: 10px!important;
+}
 .left-wrapper
     height 904px
     background #fff

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

@@ -1,13 +1,11 @@
 <template>
   <div>
-    <div class="i-layout-page-header">
-      <div class="i-layout-page-header">
+    <div class="i-layout-page-header header-title">
         <span class="ivu-page-header-title">{{ $route.meta.title }}</span>
         <div class="clear_tit">
           <Icon type="md-information-circle" color="#ED4014" />
           <span>清除数据请谨慎,清除就无法恢复哦!</span>
         </div>
-      </div>
     </div>
     <Card :bordered="false" dis-hover class="ivu-mt">
       <Row type="flex" :gutter="24">

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

@@ -1,9 +1,9 @@
 <template>
   <div>
-    <Card :bordered="false" dis-hover class="ivu-mt tableBox">
-      <div slot="title">
-        <span class="ivu-pl-8">数据库备份记录</span>
-      </div>
+    <div class="i-layout-page-header header-title">
+      <span class="ivu-page-header-title">{{ $route.meta.title }}</span>
+    </div>
+    <Card :bordered="false" dis-hover class="ivu-mt">
       <Table
         ref="selection"
         :columns="columns4"

+ 3 - 1
template/admin/src/pages/system/maintain/systemFile/index.vue

@@ -1,5 +1,8 @@
 <template>
   <div>
+    <div class="i-layout-page-header header-title">
+      <span class="ivu-page-header-title">{{ $route.meta.title }}</span>
+    </div>
     <Card :bordered="false" dis-hover class="ivu-mt">
       <Table
         ref="selection"
@@ -8,7 +11,6 @@
         :loading="loading"
         no-data-text="暂无数据"
         highlight-row
-        class="mt25"
         no-filtered-data-text="暂无筛选结果"
       >
         <template slot-scope="{ row }" slot="nickname">

+ 27 - 20
template/admin/src/pages/system/maintain/systemFile/login.vue

@@ -1,9 +1,7 @@
 <template>
   <div>
     <div class="i-layout-page-header">
-      <div class="i-layout-page-header">
         <span class="ivu-page-header-title">{{ $route.meta.title }}</span>
-      </div>
     </div>
     <Row type="flex">
       <Col span="24">
@@ -105,10 +103,13 @@ export default {
 </script>
 
 <style scoped lang="stylus">
+.i-layout-page-header{
+  padding: 18px 32px;
+}
 .maxInpt{
-    max-width 400px
-    margin-left auto
-    margin-right auto
+    max-width: 400px;
+    margin-left: auto;
+    margin-right: auto;
 }
 .index_from{
   display: flex;
@@ -117,27 +118,33 @@ export default {
   align-items: center;
 }
 .trip{
-    width 400px
+    width: 400px;
     text-align: left;
-    color #aaa
+    color: #aaa;
 }
 .page-account-container{
-    text-align center
-    padding 200px 0
+    text-align: center;
+    padding: 200px 0;
 }
 .page-account-top{
-    margin-bottom 50px
+    margin-bottom: 50px;
+}
+.page-account-top-tit{
+  font-size:30px;
+  color:#1890FF;
+  font-weight:500;
+}
+
+.page-account-other{
+  text-align:center;
+  color:#1890FF;
+  font-size:12px;
+  span{
+    cursor: pointe;
+  }
 }
-.page-account-top-tit
-    font-size 30px
-    color #1890FF
-    font-weight 500
-.page-account-other
-    text-align center
-    color #1890FF
-    font-size 12px
-    span
-        cursor pointer
+
+
 >>> .btn{
   font-size: 15px !important;
 }

+ 3 - 1
template/admin/src/pages/user/grade/right/index.vue

@@ -1,8 +1,10 @@
 <template>
   <div>
+    <div class="i-layout-page-header" style="padding: 18px 32px;border-bottom: 1px solid #f2f2f2;">
+      <span class="ivu-page-header-title">{{ $route.meta.title }}</span>
+    </div>
     <Card :bordered="false" dis-hover class="ivu-mt">
       <Table
-        class="mt25"
         :columns="thead"
         :data="tbody"
         :loading="loading"

+ 3 - 0
template/admin/src/store/module/userInfo.js

@@ -56,6 +56,9 @@ export default {
     userInfo(state, userInfo) {
       state.userInfo = userInfo;
     },
+    userRealName(state, realName) {
+      state.userInfo.real_name = realName;
+    },
     uniqueAuth(state, uniqueAuth) {
       state.uniqueAuth = uniqueAuth;
     },

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

@@ -513,6 +513,11 @@ body {
   background-color: #fff;
   padding: 7px 32px 0 32px;
 }
+.header-title {
+  padding: 10px 16px;
+  border-bottom: 1px solid #f2f2f2;
+  margin-bottom: 10px;
+}
 .ivu-page-header-title {
   display: inline-block;
   color: #17233d;

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

@@ -697,3 +697,12 @@ export function getLangJson() {
 		noAuth: true
 	})
 }
+
+/**
+ * 
+ * 小程序绑定手机号
+ * @param object data
+ */
+export function mpBindingPhone(data) {
+	return request.post('v2/routine/binding_phone', data);
+}

+ 2 - 2
template/uni-app/manifest.json

@@ -2,8 +2,8 @@
     "name" : "CRMEB标准版",
     "appid" : "__UNI__A3F1ED4",
     "description" : "CRMEB标准版",
-    "versionName" : "4.6.0",
-    "versionCode" : 461,
+    "versionName" : "4.7.0",
+    "versionCode" : 470,
     "transformPx" : false,
     /* 5+App特有相关 */
     "app-plus" : {

+ 14 - 8
template/uni-app/pages/order_addcart/order_addcart.vue

@@ -241,7 +241,8 @@
 				sysHeight: sysHeight,
 				newData: {},
 				activeRouter: '',
-				is_diy_set: false
+				is_diy_set: false,
+				adding: false
 			};
 		},
 		computed: mapGetters(['isLogin']),
@@ -700,28 +701,32 @@
 						that.cartList.valid[index] = item;
 						that.getCartNum();
 						that.switchSelect();
-					});
+					}).catch(err => {
+						item.cart_num = Number(item.cart_num) + 1
+					})
 				}
 			},
 			addCart: function(index) {
 				let that = this;
+				if (this.adding) return
 				let item = that.cartList.valid[index];
-				let lastnum = Number(item.cart_num) + 1
+				item.cart_num = Number(item.cart_num) + 1
 				let productInfo = item.productInfo;
-				if (productInfo.hasOwnProperty('attrInfo') && lastnum >= item.productInfo.attrInfo.stock) {
-					lastnum = item.productInfo.attrInfo.stock;
+				if (productInfo.hasOwnProperty('attrInfo') && item.cart_num >= item.productInfo.attrInfo.stock) {
+					item.cart_num = item.productInfo.attrInfo.stock;
 					item.numAdd = true;
 					item.numSub = false;
 				} else {
 					item.numAdd = false;
 					item.numSub = false;
 				}
-				that.setCartNum(item.id, lastnum, (data) => {
+				that.setCartNum(item.id, item.cart_num, (data) => {
 					that.cartList.valid[index] = item;
-					item.cart_num = Number(item.cart_num) + 1;
 					that.getCartNum();
 					that.switchSelect();
-				});
+				}).catch(err => {
+					item.cart_num = Number(item.cart_num) - 1
+				})
 			},
 			setCartNum(cartId, cartNum, successCallback) {
 				let that = this;
@@ -737,6 +742,7 @@
 				let that = this;
 				getCartCounts().then(res => {
 					that.cartCount = res.data.count;
+					this.adding = false
 					this.$store.commit('indexData/setCartNum', res.data.count > 99 ? '..' : res.data.count)
 					if (res.data.count > 0) {
 						wx.setTabBarBadge({

+ 35 - 1
template/uni-app/pages/user/index.vue

@@ -77,9 +77,15 @@
 										<image src="/static/images/edit.png" mode=""></image>
 									</view> -->
 								</view>
+								<!-- #ifdef MP -->
+								<button class="phone" v-if="!userInfo.phone && isLogin" open-type="getPhoneNumber"
+									@getphonenumber="getphonenumber">{{$t(`绑定手机号`)}}</button>
+								<!-- #endif -->
+								<!-- #ifndef MP -->
 								<view class="phone" v-if="!userInfo.phone && isLogin" @tap="bindPhone">
 									{{$t('绑定手机号')}}
 								</view>
+								<!-- #endif -->
 							</view>
 							<view class="message">
 								<navigator url="/pages/users/user_info/index" hover-class="none">
@@ -284,7 +290,8 @@
 		getMenuList,
 		getUserInfo,
 		setVisit,
-		updateUserInfo
+		updateUserInfo,
+		mpBindingPhone
 	} from '@/api/user.js';
 	import {
 		wechatAuthV2,
@@ -521,6 +528,32 @@
 					url: '/pages/users/user_phone/index'
 				})
 			},
+			getphonenumber(e) {
+				Routine.getCode()
+					.then(code => {
+						let data = {
+							code,
+							iv: e.detail.iv,
+							encryptedData: e.detail.encryptedData,
+						}
+						mpBindingPhone(data).then(res => {
+							this.getUserInfo()
+							this.$util.Tips({
+								title: res.msg,
+								icon: 'success'
+							});
+						}).catch(err => {
+							return this.$util.Tips({
+								title: err
+							});
+						})
+					})
+					.catch(error => {
+						uni.hideLoading();
+					});
+
+				console.log(e)
+			},
 			/**
 			 * 获取个人用户信息
 			 */
@@ -1260,6 +1293,7 @@
 			background-color: #CCC;
 			border-radius: 15px;
 			width: max-content;
+			font-size: 28rpx;
 			padding: 0 10px;
 		}
 

+ 0 - 1
template/uni-app/pages/users/components/login_mobile/routine_phone.vue

@@ -60,7 +60,6 @@
 				});
 				Routine.getCode()
 					.then(code => {
-
 						this.getUserPhoneNumber(e.detail.encryptedData, e.detail.iv, code);
 					})
 					.catch(error => {

+ 44 - 5
template/uni-app/pages/users/user_info/index.vue

@@ -43,15 +43,25 @@
 					</view>
 					<view class='item acea-row row-between-wrapper'>
 						<view>{{$t(`昵称`)}}</view>
-						<view class='input'><input type='nickname' name='nickname' :maxlength="16" :value='userInfo.nickname'></input>
+						<view class='input'><input type='nickname' name='nickname' :maxlength="16"
+								:value='userInfo.nickname'></input>
 						</view>
 					</view>
 					<view class='item acea-row row-between-wrapper'>
 						<view>{{$t(`手机号码`)}}</view>
+						<!-- #ifdef MP -->
+						<button class="input" open-type="getPhoneNumber" @getphonenumber="getphonenumber"
+							v-if="!userInfo.phone">{{$t(`点击绑定手机号`)}}
+							<text class="iconfont icon-xiangyou"></text>
+						</button>
+						<!-- #endif -->
+						<!-- #ifndef MP -->
 						<navigator url="/pages/users/user_phone/index" hover-class="none" class="input"
 							v-if="!userInfo.phone">
 							{{$t(`点击绑定手机号`)}}<text class="iconfont icon-xiangyou"></text>
 						</navigator>
+						<!-- #endif -->
+
 						<view class='input acea-row row-between-wrapper' v-else>
 							<input type='text' disabled='true' name='phone' :value='userInfo.phone' class='id'></input>
 							<text class='iconfont icon-suozi'></text>
@@ -160,7 +170,8 @@
 		userEdit,
 		getLogout,
 		getLangList,
-		getLangJson
+		getLangJson,
+		mpBindingPhone
 	} from '@/api/user.js';
 	import {
 		switchH5Login,
@@ -174,6 +185,7 @@
 	import dayjs from "@/plugin/dayjs/dayjs.min.js";
 	// #ifdef MP
 	import authorize from '@/components/Authorize';
+	import Routine from '@/libs/routine';
 	// #endif
 	import Cache from '@/utils/cache';
 	import colors from '@/mixins/color.js';
@@ -244,6 +256,31 @@
 					title: this.$t(`当前为最新版本`)
 				});
 			},
+			getphonenumber(e) {
+				Routine.getCode()
+					.then(code => {
+						let data = {
+							code,
+							iv: e.detail.iv,
+							encryptedData: e.detail.encryptedData,
+						}
+						mpBindingPhone(data).then(res => {
+							this.getUserInfo()
+							this.$util.Tips({
+								title: res.msg,
+								icon: 'success'
+							});
+						}).catch(err => {
+							return this.$util.Tips({
+								title: err
+							});
+						})
+					})
+					.catch(error => {
+						uni.hideLoading();
+					});
+
+			},
 			setLang() {
 				this.array.map((item, i) => {
 					if (this.$i18n.locale == item.value) {
@@ -639,9 +676,11 @@
 	.personal-data .list .item .input {
 		max-width: 400rpx;
 		text-align: right;
-		color: #868686;
-		.icon-suozi{
-			margin-left: 10rpx;
+		color: #868686;
+		font-size: 28rpx;
+
+		.icon-suozi {
+			margin-left: 10rpx;
 		}
 	}