Переглянути джерело

Merge branch 'deploy' of http://git.chelingzhu.com/chelingzhu-web/qhsxKx-admin-html into deploy

zhangdan 4 роки тому
батько
коміт
757ec8fc85

+ 17 - 1
src/api/car-wash.js

@@ -68,7 +68,23 @@ export const storeDel = params => {
 }
 // 获取当前设备图片
 export const deviceImage = params => {
-  const url = `device/image/${params.id}`
+  const url = `device/image/${params.deviceNo}`
+  return axios.request({
+    url: url,
+    method: 'get'
+  })
+}
+// 获取网点小程序码
+export const storeQrCode = params => {
+  const url = `store/qrCode/${params.deviceNo}/${params.id}`
+  return axios.request({
+    url: url,
+    method: 'get'
+  })
+}
+// 更改网点营业状态
+export const storeUpdateStatus = params => {
+  const url = `store/updateStatus/${params.id}/${params.businessStatus}`
   return axios.request({
     url: url,
     method: 'get'

+ 0 - 1
src/api/login.js

@@ -58,7 +58,6 @@ export function get2step (parameter) {
 export function changePwd (parameter) {
   return axios({
     url: 'user/changePWD',
-    // url: 'employee/changePWD',
     method: 'post',
     data: parameter
   })

+ 242 - 228
src/config/router.config.js

@@ -1,229 +1,243 @@
-// eslint-disable-next-line
-import { UserLayout, BasicLayout, RouteView, BlankLayout, PageView } from '@/layouts'

-export const asyncRouterMap = [
-  {
-    path: '/',
-    name: 'index',
-    component: BasicLayout,
-    meta: {
-      title: '首页'
-    },
-    redirect: '/home',
-    children: [{
-      path: '/home',
-      name: 'home',
-      redirect: '/home',
-      component: PageView,
-      meta: {
-        title: '首页',
-        icon: 'home'
-      },
-      hideChildrenInMenu: true,
-      children: [{
-        path: '/home',
-        name: 'home',
-        component: () => import(/* webpackChunkName: "home" */ '@/views/Home'),
-        meta: {
-          title: '首页',
-          icon: 'home',
-          hidden: true
-        }
-      },
-      {
-        path: '/changePwd',
-        name: 'changePwd',
-        component: () => import(/* webpackChunkName: "home" */ '@/views/user/ChangePwd'),
-        meta: {
-          title: '修改密码',
-          icon: 'home',
-          hidden: true
-        }
-      }
-      ]
-    },
-    // Car washing machine management center
-    {
-      path: '/CarWashManagement',
-      redirect: '/CarWashManagement/CarWashManagement',
-      component: PageView,
-      meta: {
-        title: '洗车机管理中心',
-        icon: 'setting'
-        // permission: 'M_setting_0'
-      },
-      children: [{
-        path: '/CarWashManagement/CarWashManagement',
-        name: 'CarWashManagement',
-        component: () => import('@/views/CarWashManagement/CarWashManagement.vue'),
-        meta: {
-          title: '洗车机管理',
-          icon: 'database'
-          // permission: 'M_sys_dataDictionary'
-        }
-      }]
-    },
-    {
-      path: '/Order',
-      redirect: '/Order/OrderCenter',
-      name: 'Order',
-      component: PageView,
-      meta: {
-        title: '订单中心',
-        icon: 'snippets'
-        // permission: 'M_setting_0'
-      },
-      children: [
-        {
-          path: '/Order/OrderCenter',
-          name: 'OrderCenter',
-          component: () => import('@/views/Order/OrderCenter.vue'),
-          meta: {
-            title: '订单中心',
-            icon: 'snippets'
-          // permission: 'M_sys_dataDictionary'
-          }
-        }
-      ]
-    },
-    // {
-    //   path: '/RefundRecord',
-    //   redirect: '/RefundRecord/RefundRecord',
-    //   component: PageView,
-    //   meta: {
-    //     title: '退单记录',
-    //     icon: 'setting'
-    //     // permission: 'M_setting_0'
-    //   },
-    //   children: [{
-    //     path: '/RefundRecord/RefundRecord',
-    //     name: 'RefundRecord',
-    //     component: () => import('@/views/RefundRecord/RefundRecord.vue'),
-    //     meta: {
-    //       title: '退单记录',
-    //       icon: 'setting'
-    //       // permission: 'M_sys_dataDictionary'
-    //     }
-    //   }
-    //   ]
-    // },
-    {
-      path: '/auth',
-      redirect: '/auth/userList',
-      component: PageView,
-      meta: { title: '权限管理', icon: 'lock'
-        // permission: 'M_auth_0' ,
-      },
-      children: [
-        {
-          path: '/auth/userList',
-          name: 'powerUserList',
-          component: () => import(/* webpackChunkName: "auth" */ '@/views/power/user/userList.vue'),
-          meta: { title: '用户管理', icon: 'user'
-            // permission: 'M_auth_userList' ,
-          }
-        },
-        {
-          path: '/auth/roleList',
-          name: 'powerRoleList',
-          component: () => import(/* webpackChunkName: "auth" */ '@/views/power/role/roleList.vue'),
-          meta: { title: '角色管理', icon: 'solution'
-            // permission: 'M_auth_roleList',
-          }
-        },
-        {
-          path: '/menusAuth/menu',
-          name: 'powerMenu',
-          component: () => import(/* webpackChunkName: "auth" */ '@/views/power/menu/menu.vue'),
-          meta: {
-            title: '菜单管理',
-            icon: 'profile'
-            // permission: 'M_menusAuth_menu'
-          }
-        }
-      ]
-    },
-    {
-      path: '/setting',
-      redirect: '/setting/userList',
-      component: PageView,
-      meta: {
-        title: '系统设置',
-        icon: 'setting'
-        // permission: 'M_setting_0'
-      },
-      children: [{
-        path: '/setting/dataDictionary',
-        name: 'powerDD',
-        component: () => import(/* webpackChunkName: "setting" */ '@/views/power/dataDictionary/dataDictionary.vue'),
-        meta: {
-          title: '数据字典管理',
-          icon: 'database'
-          // permission: 'M_sys_dataDictionary'
-        }
-      },
-      {
-        path: '/setting/register',
-        name: 'powerRegister',
-        component: () => import(/* webpackChunkName: "setting" */ '@/views/power/register/register.vue'),
-        meta: {
-          title: '参数管理',
-          icon: 'key'
-          // permission: 'M_sys_register'
-        }
-      },
-      {
-        path: '/setting/jobs',
-        name: 'powerJobs',
-        component: () => import(/* webpackChunkName: "setting" */ '@/views/power/job/jobs.vue'),
-        meta: {
-          title: '定时器',
-          icon: 'alert'
-          // permission: 'M_sys_job'
-        }
-      }
-      ]
-    }
-    ]
-  },
-  {
-    path: '*',
-    redirect: '/404',
-    hidden: true
-  }
-]

-/**
- * 基础路由
- * @type { *[] }
- */
-export const constantRouterMap = [{
-  path: '/user',
-  component: UserLayout,
-  redirect: '/user/login',
-  hidden: true,
-  children: [{
-    path: 'login',
-    name: 'login',
-    component: () => import(/* webpackChunkName: "user" */ '@/views/user/Login')
-  },
-  {
-    path: 'register',
-    name: 'register',
-    component: () => import(/* webpackChunkName: "user" */ '@/views/user/Register')
-  },
-  {
-    path: 'register-result',
-    name: 'registerResult',
-    component: () => import(/* webpackChunkName: "user" */ '@/views/user/RegisterResult')
-  },
-  {
-    path: 'recover',
-    name: 'recover',
-    component: undefined
-  }
-  ]
-},
-{
-  path: '/404',
-  component: () => import(/* webpackChunkName: "fail" */ '@/views/exception/404')
-}

+// eslint-disable-next-line
+import {
+  UserLayout,
+  BasicLayout,
+  RouteView,
+  BlankLayout,
+  PageView
+} from '@/layouts'
+
+export const asyncRouterMap = [{
+  path: '/',
+  name: 'index',
+  component: BasicLayout,
+  meta: {
+    title: '首页'
+  },
+  redirect: '/home',
+  children: [{
+    path: '/home',
+    name: 'home',
+    redirect: '/home',
+    component: PageView,
+    meta: {
+      title: '首页',
+      icon: 'home'
+    },
+    hideChildrenInMenu: true,
+    children: [{
+      path: '/home',
+      name: 'home',
+      component: () => import(/* webpackChunkName: "home" */ '@/views/Home'),
+      meta: {
+        title: '首页',
+        icon: 'home',
+        hidden: true
+      }
+    },
+    {
+      path: '/changePwd',
+      name: 'changePwd',
+      component: () => import(/* webpackChunkName: "home" */ '@/views/user/ChangePwd'),
+      meta: {
+        title: '修改密码',
+        icon: 'home',
+        hidden: true
+      }
+    }
+    ]
+  },
+  // Car washing machine management center
+  {
+    path: '/CarWashManagement',
+    redirect: '/CarWashManagement/CarWashManagement',
+    component: PageView,
+    meta: {
+      title: '洗车机管理中心',
+      icon: 'setting'
+      // permission: 'M_setting_0'
+    },
+    children: [{
+      path: '/CarWashManagement/CarWashManagement',
+      name: 'CarWashManagement',
+      component: () => import('@/views/CarWashManagement/CarWashManagement.vue'),
+      meta: {
+        title: '洗车机管理',
+        icon: 'database'
+        // permission: 'M_sys_dataDictionary'
+      }
+    }]
+  },
+  {
+    path: '/Order',
+    redirect: '/Order/OrderCenter',
+    name: 'Order',
+    component: PageView,
+    meta: {
+      title: '订单中心',
+      icon: 'snippets'
+      // permission: 'M_setting_0'
+    },
+    children: [{
+      path: '/Order/OrderCenter',
+      name: 'OrderCenter',
+      component: () => import('@/views/Order/OrderCenter.vue'),
+      meta: {
+        title: '订单中心',
+        icon: 'snippets'
+        // permission: 'M_sys_dataDictionary'
+      }
+    }]
+  },
+  // {
+  //   path: '/RefundRecord',
+  //   redirect: '/RefundRecord/RefundRecord',
+  //   component: PageView,
+  //   meta: {
+  //     title: '退单记录',
+  //     icon: 'setting'
+  //     // permission: 'M_setting_0'
+  //   },
+  //   children: [{
+  //     path: '/RefundRecord/RefundRecord',
+  //     name: 'RefundRecord',
+  //     component: () => import('@/views/RefundRecord/RefundRecord.vue'),
+  //     meta: {
+  //       title: '退单记录',
+  //       icon: 'setting'
+  //       // permission: 'M_sys_dataDictionary'
+  //     }
+  //   }
+  //   ]
+  // },
+  {
+    path: '/auth',
+    redirect: '/auth/userList',
+    component: PageView,
+    meta: {
+      title: '权限管理',
+      icon: 'lock'
+      // permission: 'M_auth_0' ,
+    },
+    children: [{
+      path: '/auth/userList',
+      name: 'powerUserList',
+      component: () => import(/* webpackChunkName: "auth" */ '@/views/power/user/userList.vue'),
+      meta: {
+        title: '用户管理',
+        icon: 'user'
+        // permission: 'M_auth_userList' ,
+      }
+    },
+    {
+      path: '/auth/roleList',
+      name: 'powerRoleList',
+      component: () => import(/* webpackChunkName: "auth" */ '@/views/power/role/roleList.vue'),
+      meta: {
+        title: '角色管理',
+        icon: 'solution'
+        // permission: 'M_auth_roleList',
+      }
+    },
+    {
+      path: '/menusAuth/adminMenus',
+      name: 'adminMenus',
+      component: () => import(/* webpackChunkName: "bnSetting" */ '@/views/bnSetting/menu/adminMenus.vue'),
+      meta: {
+        title: '菜单管理',
+        icon: 'appstore'
+        // permission: 'M_menusAuth_adminMenus'
+      }
+    }
+    ]
+  },
+  {
+    path: '/setting',
+    redirect: '/setting/userList',
+    component: PageView,
+    meta: {
+      title: '系统设置',
+      icon: 'setting'
+      // permission: 'M_setting_0'
+    },
+    children: [{
+      path: '/setting/dataDictionary',
+      name: 'powerDD',
+      component: () => import(/* webpackChunkName: "setting" */
+        '@/views/power/dataDictionary/dataDictionary.vue'),
+      meta: {
+        title: '数据字典管理',
+        icon: 'database'
+        // permission: 'M_sys_dataDictionary'
+      }
+    }
+      // 暂时屏蔽,后期可能需要
+      // {
+      //   path: '/setting/register',
+      //   name: 'powerRegister',
+      //   component: () => import( /* webpackChunkName: "setting" */ '@/views/power/register/register.vue'),
+      //   meta: {
+      //     title: '参数管理',
+      //     icon: 'key'
+      //     // permission: 'M_sys_register'
+      //   }
+      // },
+      // 暂时屏蔽,后期可能需要
+      // {
+      //   path: '/setting/jobs',
+      //   name: 'powerJobs',
+      //   component: () => import( /* webpackChunkName: "setting" */ '@/views/power/job/jobs.vue'),
+      //   meta: {
+      //     title: '定时器',
+      //     icon: 'alert'
+      //     // permission: 'M_sys_job'
+      //   }
+      // }
+    ]
+  }
+  ]
+},
+{
+  path: '*',
+  redirect: '/404',
+  hidden: true
+}
+]
+
+/**
+ * 基础路由
+ * @type { *[] }
+ */
+export const constantRouterMap = [{
+  path: '/user',
+  component: UserLayout,
+  redirect: '/user/login',
+  hidden: true,
+  children: [{
+    path: 'login',
+    name: 'login',
+    component: () => import(/* webpackChunkName: "user" */ '@/views/user/Login')
+  },
+  {
+    path: 'register',
+    name: 'register',
+    component: () => import(/* webpackChunkName: "user" */ '@/views/user/Register')
+  },
+  {
+    path: 'register-result',
+    name: 'registerResult',
+    component: () => import(/* webpackChunkName: "user" */ '@/views/user/RegisterResult')
+  },
+  {
+    path: 'recover',
+    name: 'recover',
+    component: undefined
+  }
+  ]
+},
+{
+  path: '/404',
+  component: () => import(/* webpackChunkName: "fail" */ '@/views/exception/404')
+}
+
 ]

+ 83 - 56
src/views/CarWashManagement/AddCarWashModal.vue

@@ -3,38 +3,50 @@
     <!-- 表单 -->
     <a-form-model ref="ruleForm" :model="form" :rules="rules" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
       <a-row :gutter="20">
-        <a-col :span="12">
-          <a-form-model-item label="网点名称" prop="name">
-            <a-input v-model="form.name" :maxLength="20" placeholder="请输入网店名称,20个字以内" />
-          </a-form-model-item>
-        </a-col>
-        <a-col :span="12">
-          <a-form-model-item label="地址" class="default-form-item form-item-required">
-            <a-row :gutter="20">
-              <a-col :span="8">
-                <a-form-model-item prop="addrProvince">
-                  <a-select v-model="form.addrProvince" placeholder="请选择省" @change="getCityList">
-                    <a-select-option v-for="item in addrProvinceList" :key="item.id" :value="item.id">{{item.name}}</a-select-option>
-                  </a-select>
-                </a-form-model-item>
-              </a-col>
-              <a-col :span="8">
-                <a-form-model-item prop="addrCity">
-                  <a-select v-model="form.addrCity" placeholder="请选择市" @change="getAreaList">
-                    <a-select-option v-for="item in addrCityList" :key="item.id" :value="item.id">{{item.name}}</a-select-option>
-                  </a-select>
-                </a-form-model-item>
-              </a-col>
-              <a-col :span="8">
-                <a-form-model-item prop="addrDistrict">
-                  <a-select v-model="form.addrDistrict" placeholder="请选择区" @change="areaCharged">
-                    <a-select-option v-for="item in addrDistrictList" :key="item.id" :value="item.id">{{item.name}}</a-select-option>
-                  </a-select>
-                </a-form-model-item>
-              </a-col>
-            </a-row>
-          </a-form-model-item>
-        </a-col>
+        <a-row>
+          <a-col :span="12">
+            <a-form-model-item label="网点名称" prop="name">
+              <a-input v-model="form.name" :maxLength="20" placeholder="请输入网店名称,20个字以内" />
+            </a-form-model-item>
+            <a-form-model-item label="地址" class="default-form-item form-item-required">
+              <a-row :gutter="20">
+                <a-col :span="8">
+                  <a-form-model-item prop="addrProvince">
+                    <a-select v-model="form.addrProvince" placeholder="请选择省" @change="getCityList">
+                      <a-select-option v-for="item in addrProvinceList" :key="item.id" :value="item.id">{{item.name}}</a-select-option>
+                    </a-select>
+                  </a-form-model-item>
+                </a-col>
+                <a-col :span="8">
+                  <a-form-model-item prop="addrCity">
+                    <a-select v-model="form.addrCity" placeholder="请选择市" @change="getAreaList">
+                      <a-select-option v-for="item in addrCityList" :key="item.id" :value="item.id">{{item.name}}</a-select-option>
+                    </a-select>
+                  </a-form-model-item>
+                </a-col>
+                <a-col :span="8">
+                  <a-form-model-item prop="addrDistrict">
+                    <a-select v-model="form.addrDistrict" placeholder="请选择区" @change="areaCharged">
+                      <a-select-option v-for="item in addrDistrictList" :key="item.id" :value="item.id">{{item.name}}</a-select-option>
+                    </a-select>
+                  </a-form-model-item>
+                </a-col>
+              </a-row>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="网点照片" prop="icon" class="default-form-item">
+              <a-row>
+                <a-col :span="8">
+                  <Upload ref="showPicture" :fileSize="5" :maxNums="1" @change="pictureChange" listType="picture-card" upText="上传图片"></Upload>
+                </a-col>
+                <a-col :span="16">
+                  <p class="pic-remarks">(尺寸为100*100px)</p>
+                </a-col>
+              </a-row>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
         <a-col :span="24">
           <a-form-model-item label="详细地址" prop="addrDetail" :label-col="{ span: 3 }" :wrapper-col="{ span: 21 }">
             <a-input v-model="form.addrDetail" :maxLength="32" placeholder="请输入详细地址,32个字以内" />
@@ -47,7 +59,7 @@
                 <a-tag v-if="form.deviceDTOList.length > 0" color="blue">{{deviceNo}}</a-tag>
               </a-col>
               <a-col :span="5">
-                <a-button type="primary" size="small" class="small-btn" @click="openEquipmentModal=true">选择</a-button>
+                <a-button type="primary" size="small" class="small-btn" v-if="pageType != 'edit'" @click="openEquipmentModal=true">选择</a-button>
               </a-col>
             </a-row>
           </a-form-model-item>
@@ -129,7 +141,7 @@
                 <a-row :gutter="20">
                   <a-col :span="8" v-for="(priceItem, subInd) in item.currentPrices" :key="subInd">
                     <a-form-model-item :prop="'storeItemPriceDTOList.'+ ind +'.currentPrices.'+ subInd + '.price'" :rules="{required: true, message: `请输入【${priceItem.name}】单价`, trigger: 'blur'}">
-                      <a-input-number v-model="priceItem.price" :min="0" :max="999999" :placeholder="'【'+ priceItem.name +'】单价'" class="input-number-s" />
+                      <a-input-number v-model="priceItem.price" :min="0" :max="999999" :precision="2" :placeholder="'【'+ priceItem.name +'】单价'" class="input-number-s" />
                       <span class="unit">元</span>
                     </a-form-model-item>
                   </a-col>
@@ -172,7 +184,7 @@
 </template>
 
 <script>
-  import { VSelect } from '@/components'
+  import { VSelect, Upload } from '@/components'
   import ChooseEquipment from './ChooseEquipment.vue'
   import Editor from '@/components/WEeditor'
   import moment from 'moment'
@@ -180,7 +192,7 @@
   import { itemQuery, storeSave, storeFind, findItem } from '@/api/car-wash'
   export default{
     name: 'AddCarWashModal',
-    components: { VSelect, Editor, ChooseEquipment },
+    components: { VSelect, Upload, Editor, ChooseEquipment },
     props: {
       openModal: {  //  弹框是否展示
         type: Boolean,
@@ -199,6 +211,7 @@
       return{
         isShow: this.openModal,  //  弹框是否展示
         form: {
+          icon: '',  //  网点照片
           name: '',  //  网点名称
           addrProvince: undefined,  //  省  编码
           addrProvinceName: '',  //  省
@@ -219,6 +232,9 @@
           reminder: ''  //  温馨提示
         },
         rules: {
+          icon: [
+            { required: true, message: '请选择网店照片', trigger: 'change' }
+          ],
           name: [
             { required: true, message: '请输入网店名称', trigger: 'blur' }
           ],
@@ -293,10 +309,11 @@
       setVal(item){
         const _this = this
         console.log(item)
-        let arr = [ 'id', 'name', 'addrProvince', 'addrProvinceName', 'addrCityName', 'addrDistrictName', 'featuredServiceLabel', 'lng', 'lat', 'serviceType', 'guidance', 'reminder' ]
+        let arr = [ 'id', 'icon', 'name', 'addrProvince', 'addrProvinceName', 'addrCityName', 'addrDistrictName', 'featuredServiceLabel', 'lng', 'lat', 'serviceType', 'guidance', 'reminder' ]
         arr.map(k => {
           this.form[k] = item[k]
         })
+        this.$refs.showPicture.setFileList(this.form.icon)
         this.getCityList(item.addrProvince)  //  获取市区下拉数据
         this.form.addrCity = item.addrCity  //  市区赋值
         this.getAreaList(item.addrCity)  //  获取区县下拉数据
@@ -309,25 +326,22 @@
         this.form.endTime = moment(item.endTime, 'HH:mm')  //  营业时间  结束时间
         this.setPeriodPrice(item.storeItemPriceDTOList)  // 时段价格
         this.isShow ? this.$refs.editor.setHtml(item.guidance) : null  //  文本编辑器赋值
+        console.log(this.form,'----赋值后的表单')
       },
       // 时段价格  赋值处理
       setPeriodPrice(storeItemPriceDTOList){
-        let arrInd = 0
         this.form.storeItemPriceDTOList = []
-        for (var key in storeItemPriceDTOList) {
-          if (storeItemPriceDTOList.hasOwnProperty(key)) {
-            this.form.storeItemPriceDTOList.push({
-              beginTime: moment(key.split(',')[0], 'HH:mm'),
-              endTime: moment(key.split(',')[1], 'HH:mm'),
-              currentPrices: []
-            })
-            let idArr = []
-            storeItemPriceDTOList[key].map((k, ind) => {
-              this.form.storeItemPriceDTOList[arrInd].currentPrices.push({ name: k.itemName, price: k.currentPrice, itemId: k.itemId })
-              idArr.push(k.itemId)
-            })
-            this.form.serviceType = idArr  //  服务类型
-            arrInd++
+        for(let i = 0; i < storeItemPriceDTOList.length; i++){
+          this.form.storeItemPriceDTOList.push({
+            beginTime: moment(storeItemPriceDTOList[i][0].beginTime, 'HH:mm'),
+            endTime: moment(storeItemPriceDTOList[i][0].endTime, 'HH:mm'),
+            currentPrices: []
+          })
+          this.form.serviceType = []
+          for(let j = 0; j < storeItemPriceDTOList[i].length; j++){
+            let k = storeItemPriceDTOList[i][j]
+            this.form.storeItemPriceDTOList[i].currentPrices.push({ name: k.itemName, price: k.currentPrice, itemId: k.itemId })
+            this.form.serviceType.push(k.itemId)
           }
         }
       },
@@ -398,8 +412,10 @@
         this.subendTime = []  //  时段价格  时段区间结束时间  change前的值
         this.featuredServiceLabel = []  //  网点标签
         this.deviceNo = ''  //  已选设备序列号
-        // this.$refs.ruleForm.resetFields()    无效
+        // this.$refs.ruleForm.resetFields()    //  无效
         this.form.id = null
+        this.form.icon = ''  //  网点照片
+        this.$refs.showPicture ? this.$refs.showPicture.setFileList('') : null
         this.form.name = ''  //  网点名称
         this.form.addrProvince = undefined  //  省  编码
         this.form.addrProvinceName = ''  //  省
@@ -421,7 +437,6 @@
       },
       // 是否重置时段价格 (更改服务类型、营业开始结束时间)
       isResetstoreItemPriceDTOList(type, val){
-        console.log(type, val)
         // type: serviceType  服务类型  beginTime  营业时间  开始时间  endTime  营业时间  结束时间
         const _this = this
         setTimeout(()=>{
@@ -470,6 +485,10 @@
         }
         this.openEquipmentModal = false
       },
+      // 网点照片  change
+      pictureChange(data){
+        this.form.icon = data
+      },
       //  设置时段价格
       setTimeInterval(){
         if(this.form.serviceType.length == 0){
@@ -632,9 +651,8 @@
         }
       },
       carWashId (newValue, oldValue){
-        console.log(newValue,'-----新增编辑')
         if(newValue && this.isShow){
-          console.log('进来    编辑')
+          this.getProvinceList()  //  获取省下拉
           this.getCarWashInfo(newValue)
         }
       }
@@ -664,6 +682,11 @@
         }
       }
     }
+    .pic-remarks{
+      font-size: 12px;
+      color: #f5222d;
+      margin: 55px 0 0;
+    }
     .small-btn{
       background-color: #19be6b;
       font-size: 13px;
@@ -697,5 +720,9 @@
       padding-left: 5px;
       box-sizing: border-box;
     }
+    .upload-file .ant-upload.ant-upload-select-picture-card, .upload-file .ant-upload-list-picture-card .ant-upload-list-item{
+      width: 100px;
+      height: 100px;
+    }
   }
 </style>

+ 66 - 15
src/views/CarWashManagement/CarWashManagement.vue

@@ -49,25 +49,35 @@
       <!-- 营业时间 -->
       <template slot="businessHours" slot-scope="text, record">{{ record.beginTime.substr(0,5) + '-' + record.endTime.substr(0,5) }}</template>
       <!-- 设备状态 -->
-      <template slot="deviceStatus" slot-scope="text, record">{{ record.deviceVOList ? $refs.deviceStatus.getNameByCode(record.deviceVOList[0].deviceStatus) : '-' }}</template>
+      <template slot="deviceStatus" slot-scope="text, record">{{ record.deviceStatus ? $refs.deviceStatus.getNameByCode(record.deviceStatus) : '-' }}</template>
       <!-- 营业状态 -->
       <template slot="businessStatus" slot-scope="text, record">{{ record.businessStatus ? $refs.businessStatus.getNameByCode(record.businessStatus) : '-' }}</template>
       <!-- 操作 -->
       <template slot="action" slot-scope="text, record">
-        <a-tooltip placement="left" trigger="click" overlayClassName="btn-cont">
+        <a-tooltip placement="left" overlayClassName="btn-cont">
           <template slot="title">
             <div class="btn-set-cont">
-              <p class="set-sub-btn normal"><a-icon type="check-circle" class="icon" />正常营业</p>
-              <p class="set-sub-btn suspension"><a-icon type="pause-circle" class="icon" />暂停营业</p>
-              <p class="set-sub-btn soon"><a-icon type="play-circle" class="icon" />即将开业</p>
+              <p class="set-sub-btn normal" @click="setStoreUpdateStatus(record, 'OPEN')" v-if="record.deviceStatus != 'PAUSE' && record.businessStatus != 'OPEN'">
+                <a-icon type="check-circle" class="icon" />
+                正常营业
+              </p>
+              <p class="set-sub-btn suspension" @click="setStoreUpdateStatus(record, 'CLOSED')" v-if="record.businessStatus != 'CLOSED'">
+                <a-icon type="pause-circle" class="icon" />
+                暂停营业
+              </p>
+              <p class="set-sub-btn soon" @click="setStoreUpdateStatus(record, 'TO_BE_OPENED')" v-if="record.deviceStatus != 'PAUSE' && record.businessStatus != 'TO_BE_OPENED'">
+                <a-icon type="play-circle" class="icon" />
+                即将开业
+              </p>
             </div>
           </template>
-          <a-icon type="setting" title="设置" :style="{ fontSize: '20px', color: '#19be6b', padding: '0 10px' }" />
+          <a-icon type="setting" title="设置" v-if="record.deviceStatus != 'PAUSE'" :style="{ fontSize: '20px', color: '#19be6b', padding: '0 10px' }" />
         </a-tooltip>
+        <a-icon type="setting" title="设置" v-if="record.deviceStatus == 'PAUSE'" @click="tooltipSet" :style="{ fontSize: '20px', color: '#19be6b', padding: '0 10px' }" />
         <a-icon type="edit" title="编辑" @click="modalHandle('edit', record)" :style="{ fontSize: '20px', color: '#1890FF', padding: '0 10px' }" />
         <a-icon type="eye" title="查看详情" @click="modalHandle('details', record)" :style="{ fontSize: '20px', color: '#e29e14', padding: '0 10px' }" />
         <a-icon type="delete" title="删除" @click="del(record)" :style="{ fontSize: '20px', color: 'red', padding: '0 10px' }" />
-        <a-icon type="qrcode" title="查看小程序码" @click="isQrCodeModal=true" :style="{ fontSize: '20px', color: '#e29e14', padding: '0 10px' }" />
+        <a-icon type="qrcode" title="查看小程序码" @click="getQrCode(record)" :style="{ fontSize: '20px', color: '#e29e14', padding: '0 10px' }" />
       </template>
     </s-table>
     
@@ -87,7 +97,8 @@
     />
     <!-- 查看小程序码 -->
     <a-modal class="qrCodeModal" title="查看小程序码" :width="500" :footer="null" :destroyOnClose="true" @cancel="isQrCodeModal=false" v-model="isQrCodeModal">
-      <img :src="qrCode" class="qrCode" />
+      <img :src="qrCode" width="400" height="400" class="qrCode" />
+      <a-button type="primary" class="downQrCode" @click="downloadCode">下载小程序码</a-button>
     </a-modal>
   </a-card>
 </template>
@@ -97,7 +108,7 @@
   import AddCarWashModal from './AddCarWashModal.vue'
   import DetailsCarWashModal from './DetailsCarWashModal.vue'
   import { getProvince, getCityByPro } from '@/api/lookup'
-  import { storeQuery, storeFind, findItem, storeDel } from '@/api/car-wash'
+  import { storeQuery, storeFind, findItem, storeDel, storeQrCode, storeUpdateStatus } from '@/api/car-wash'
   export default{
     name: 'CarWashManagement',
     components: { STable, VSelect, AddCarWashModal, DetailsCarWashModal },
@@ -112,7 +123,7 @@
         },
         columns: [
           { title: '创建时间', dataIndex: 'createDate', width: '100', align: 'center' },
-          { title: '设备ID', dataIndex: 'deviceVOList[0].deviceNo', width: '100', align: 'center' },
+          { title: '设备ID', dataIndex: 'deviceNos', width: '100', align: 'center' },
           { title: '网点名称', dataIndex: 'name', width: '100', align: 'center' },
           { title: '省', dataIndex: 'addrProvinceName', width: '100', align: 'center' },
           { title: '市', dataIndex: 'addrCityName', width: '100', align: 'center' },
@@ -147,8 +158,6 @@
       //  新建/编辑/查看
       modalHandle(type, item){
         this.pageType = type
-        // this.carWashId = (type == 'edit' || type == 'details') ? String(item.id) : type == 'add' ? '' : ''
-        // type == 'add' || type == 'edit' ? this.openModal = true : this.openDetailsModal = true
         if(type == 'add'){
           this.carWashId = ''
           this.openModal = true
@@ -176,10 +185,9 @@
           content: '确定要删除吗?',
           onOk () {
             storeDel({ id: item.id }).then(res => {
-              console.log(res)
               if(res.status == 200){
                 _this.$message.success(res.message)
-                _this.$refs.table.refresh(true)
+                _this.$refs.table.refresh()
               }else{
                 _this.$message.error(res.message)
               }
@@ -198,6 +206,40 @@
         }
         this.$refs.table.refresh(true)
       },
+      // 查看小程序码
+      getQrCode(item){
+        storeQrCode({ id: item.id,deviceNo: item.deviceNos }).then(res => {
+          if(res.status == 200){
+            this.qrCode = 'data:image/png;base64,' + res.data
+            this.isQrCodeModal = true
+          }else{
+            this.qrCode = ''
+            this.$message.success(res.message)
+          }
+        })
+      },
+      //  下载小程序码
+      downloadCode (){
+        let link = document.createElement('a')
+        link.href = this.qrCode
+        link.download = 'qrCode.png'
+        link.click()
+      },
+      // 更改网点营业状态
+      setStoreUpdateStatus(item, businessStatus){
+        storeUpdateStatus({ id: item.id, businessStatus: businessStatus }).then(res => {
+          if(res.status == 200){
+            this.$message.success(res.message)
+            this.$refs.table.refresh(true)
+          }else{
+            this.$message.success(res.message)
+          }
+        })
+      },
+      //  设置提示
+      tooltipSet(){
+        this.$message.warning('洗车机设备离线(或暂停),暂不能设置营业状态!')
+      },
       // 获取省列表
       getProvinceList() {
         const _this = this
@@ -272,10 +314,17 @@
         margin-right: 10px;
       }
     }
+  }
+  // 查看小程序码  弹框
+  .qrCodeModal{
     .qrCode{
       display: block;
-      width: 100%;
       max-width: 100%;
+      margin: 0 auto;
+    }
+    .downQrCode{
+      display: block;
+      margin: 40px auto 30px;
     }
   }
   .btn-cont{
@@ -297,6 +346,7 @@
       .normal{
         color: rgb(0, 204, 0);
         border-color: rgb(0, 204, 0);
+        margin: 7px 0;
         .icon{
           margin-right: 5px;
         }
@@ -312,6 +362,7 @@
       .soon{
         color: #2d8cf0;
         border-color: #2d8cf0;
+        margin: 7px 0;
         .icon{
           margin-right: 5px;
         }

+ 58 - 32
src/views/CarWashManagement/DetailsCarWashModal.vue

@@ -3,6 +3,12 @@
     <a-modal class="DetailsCarWashModal" title="查看详情" :width="1000" :footer="null" :destroyOnClose="true" @cancel="isShow=false" v-model="isShow">
       <v-select v-show="false" ref="featuredServiceLabel" placeholder="请选择网点标签" code="STORE_LABEL"></v-select>
       <a-row :gutter="20">
+        <a-col :span="12" class="item-cont">
+          <p class="item-label">网点照片:</p>
+          <p class="item-main">
+            <img :src="carWashInfo.icon" width="100" height="100" class="wd-icon" />
+          </p>
+        </a-col>
         <a-col :span="12" class="item-cont">
           <p class="item-label">网点名称:</p>
           <p class="item-main">{{ carWashInfo.name }}</p>
@@ -11,19 +17,21 @@
           <p class="item-label">地址:</p>
           <p class="item-main">{{ carWashInfo.addrProvinceName }} - {{ carWashInfo.addrCityName }} - {{ carWashInfo.addrDistrictName }}</p>
         </a-col>
-        <a-col :span="24" class="item-cont">
+        <a-col :span="12" class="item-cont">
           <p class="item-label">详细地址:</p>
           <p class="item-main">{{ carWashInfo.addrDetail }}</p>
         </a-col>
         <a-col :span="12" class="item-cont">
           <p class="item-label">设备ID:</p>
-          <p class="item-main">{{ carWashInfo.deviceVOList ? carWashInfo.deviceVOList[0].deviceNo : '' }}</p>
+          <p class="item-main">
+            <a-tag color="blue" v-if="carWashInfo.deviceVOList">{{ carWashInfo.deviceVOList[0].deviceNo }}</a-tag>
+          </p>
         </a-col>
         <a-col :span="12" class="item-cont">
           <p class="item-label">网点标签:</p>
-          <p class="item-main">
+          <div class="item-main">
             <a-tag color="blue" v-for="(item, index) in labelList" :ket="index">{{ item }}</a-tag>
-          </p>
+          </div>
         </a-col>
         <a-col :span="12" class="item-cont">
           <p class="item-label">经度:</p>
@@ -54,7 +62,7 @@
         </a-col>
         <a-col :span="24" class="item-cont">
           <p class="item-label">路段指引:</p>
-          <p class="item-main" v-html="carWashInfo.guidance"></p>
+          <p class="item-main guidance-con" v-html="carWashInfo.guidance"></p>
         </a-col>
         <a-col :span="24" class="item-cont">
           <p class="item-label">温馨提示:</p>
@@ -63,7 +71,7 @@
         <a-col :span="24" class="item-cont">
           <p class="item-label">现场照片:</p>
           <p class="item-main">
-            <img src="../../assets/avatar2.jpg" class="small-pic" @click="isPicModal=true" />
+            <img :src="pic" class="small-pic" @click="isPicModal=true" />
           </p>
         </a-col>
         <a-col :span="24" class="btn-cont">
@@ -82,7 +90,7 @@
 <script>
   import { VSelect } from '@/components'
   import moment from 'moment'
-  import { storeFind, findItem } from '@/api/car-wash'
+  import { storeFind, findItem, deviceImage, itemQuery } from '@/api/car-wash'
   export default{
     name: 'DetailsCarWashModal',
     components: { VSelect },
@@ -101,22 +109,32 @@
         isShow: this.openModal,  //  弹框是否展示
         labelList: [],  //  网点标签
         isPicModal: false,  //  现场照片  弹框是否展示
-        pic: require('../../assets/avatar2.jpg'),  //  现场照片  路径
+        pic: '',  //  现场照片  路径
         carWashInfo: {}  ,//  网点信息
         serviceType: [],  //  服务类型
         storeItemPriceDTOList: [],  //  时段价格
+        itemQueryList: []  //  服务类型  列表数据
       }
     },
     methods: {
       // 网点详情
       getCarWashInfo(id){
+        this.getItemQuery()
         storeFind({ id: id }).then(res => {
           if(res.status == 200){
             // 查询门店的服务时段价格
             findItem({ id: id }).then(result => {
               if(result.status == 200){
                 this.carWashInfo = Object.assign(res.data, {storeItemPriceDTOList: result.data})
-                console.log(this.carWashInfo)
+                // 获取当前设备图片
+                console.log(res.data)
+                deviceImage({ deviceNo: res.data.deviceVOList[0].deviceNo }).then(results => {
+                  if(results.status == 200){
+                    this.pic = results.data
+                  }else{
+                    this.pic = ''
+                  }
+                })
                 this.setVal()
               }
             })
@@ -140,32 +158,35 @@
       },
       // 时段价格  赋值处理
       setPeriodPrice(storeItemPriceDTOList){
-        let arrInd = 0
         this.storeItemPriceDTOList = []
-        for (let key in storeItemPriceDTOList) {
-          if (storeItemPriceDTOList.hasOwnProperty(key)) {
-            console.log(key,'====key ---------for in')
-            this.storeItemPriceDTOList.push({
-              beginTime: key.split(',')[0],
-              endTime: key.split(',')[1],
-              currentPrices: []
-            })
-            let idArr = []
-            storeItemPriceDTOList[key].map((k, ind) => {
-              this.storeItemPriceDTOList[arrInd].currentPrices.push({ name: k.itemName, price: k.currentPrice, itemId: k.itemId })
-              idArr.push(k.itemName)
-            })
-            this.serviceType = idArr  //  服务类型
-            arrInd++
+        for(let i = 0; i < storeItemPriceDTOList.length; i++){
+          this.storeItemPriceDTOList.push({
+            beginTime: storeItemPriceDTOList[i][0].beginTime,
+            endTime: storeItemPriceDTOList[i][0].endTime,
+            currentPrices: []
+          })
+          this.serviceType = []
+          for(let j = 0; j < storeItemPriceDTOList[i].length; j++){
+            let k = storeItemPriceDTOList[i][j]
+            this.storeItemPriceDTOList[i].currentPrices.push({ name: k.itemName, price: k.currentPrice, itemId: k.itemId })
+            let ind = this.itemQueryList.findIndex(item => item.id == k.itemId)
+            this.serviceType.push(this.itemQueryList[ind].itemName)
           }
         }
-        Object.getOwnPropertyNames(storeItemPriceDTOList).forEach(function(key){
-          console.log(key+ '---'+storeItemPriceDTOList[key],'----------foreach')
-        })
-        console.log(Object.keys(storeItemPriceDTOList),'----------Object.keys')
-        // console.log(this.storeItemPriceDTOList)
-        // console.log(this.serviceType)
       },
+      // 获取服务类型列表
+      getItemQuery(){
+        itemQuery({
+          pageNo: 1,
+          pageSize: 1000
+        }).then(res => {
+          if(res.status == 200){
+            this.itemQueryList = res.data.list || []
+          }else{
+            this.itemQueryList = []
+          }
+        })
+      }
     },
     watch: {
       //  父页面传过来的弹框状态
@@ -200,11 +221,16 @@
         width: 115px;
         font-size: 14px;
         color: rgba(0, 0, 0, 0.85);
-        text-align: right;
         flex-shrink: 0;
       }
       .item-main{
         flex-grow: 1;
+        .wd-icon{
+          display: block;
+        }
+      }
+      .guidance-con{
+        border: 1px solid #e8e8e8;
       }
       .period-price-con{
         border-bottom: 1px solid #e8e8e8;

+ 9 - 9
src/views/power/menu/menu.vue → src/views/bnSetting/menu/adminMenus.vue

@@ -178,14 +178,14 @@
 
       </a-col>
     </a-row>
-    <childModal :visible="showChildModal" @refresh="getMenuList" :data="parentData" @close="showChildModal = false"></childModal>
+    <childModal parentType="admin" :visible="showChildModal" @refresh="getYyMenuList" :data="parentData" @close="showChildModal = false"></childModal>
   </a-card>
 </template>
 
 <script>
 import { STable, VSelect } from '@/components'
 import childModal from './childModal.vue'
-import { getMenuList, saveMenu, deleteMenu } from '@/api/menu.js'
+import { getYyMenuList, saveYyMenu, deleteYyMenu } from '@/api/menu.js'
 
 export default {
   name: 'Menu',
@@ -310,8 +310,8 @@ export default {
       })
     },
     // 获取菜单树列表
-    getMenuList () {
-      getMenuList().then(res => {
+    getYyMenuList () {
+      getYyMenuList().then(res => {
         console.log(res, 'res1111111')
         if (res.status == 200) {
           this.treeData = res.data
@@ -372,12 +372,12 @@ export default {
         okText: '确定',
         cancelText: '取消',
         onOk () {
-          deleteMenu({
+          deleteYyMenu({
             id: _this.formData.id
           }).then(res => {
             if (res.status == 200) {
               _this.$message.success('删除成功')
-              _this.getMenuList()
+              _this.getYyMenuList()
             }
           }).catch(() => {
             _this.$message.success('删除失败, 请稍后重试')
@@ -392,11 +392,11 @@ export default {
       this.form.validateFields((err, values) => {
         if (!err) {
           console.log(values.formData, ' formData.type222222222')
-          saveMenu(Object.assign({ id: this.formData.id }, values.formData)).then(res => {
+          saveYyMenu(Object.assign({ id: this.formData.id }, values.formData)).then(res => {
             console.log(res, 'res--save')
             if (res.status + '' === '200') {
               this.$message.success(res.message ? res.message : '保存成功')
-              _this.getMenuList()
+              _this.getYyMenuList()
               _this.clear()
             } else {
               // this.$message.warning(res.message)
@@ -417,7 +417,7 @@ export default {
   },
   beforeRouteEnter (to, from, next) {
     next(vm => {
-      vm.getMenuList()
+      vm.getYyMenuList()
     })
   },
   watch: {

+ 41 - 2
src/views/power/menu/childModal.vue → src/views/bnSetting/menu/childModal.vue

@@ -126,6 +126,36 @@
               rules: [] }]"
           />
         </a-form-item>
+        <!-- 连锁可用 -->
+        <a-form-item v-if="parentType=='store'" label="连锁可用" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+          <a-radio-group
+            name="radioGroup"
+            v-decorator="[
+              'formData.chainOrgUse',
+              {
+                initialValue: formData.chainOrgUse,
+                rules: [{ required: true, message: '请选择!' }] },
+            ]"
+          >
+            <a-radio :value="1">是</a-radio>
+            <a-radio :value="0">否</a-radio>
+          </a-radio-group>
+        </a-form-item>
+        <!-- 单店可用 -->
+        <a-form-item v-if="parentType=='store'" label="单店可用" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+          <a-radio-group
+            name="radioGroup"
+            v-decorator="[
+              'formData.singleOrgUse',
+              {
+                initialValue: formData.singleOrgUse,
+                rules: [{ required: true, message: '请选择!' }] },
+            ]"
+          >
+            <a-radio :value="1">是</a-radio>
+            <a-radio :value="0">否</a-radio>
+          </a-radio-group>
+        </a-form-item>
         <!-- 状态 -->
         <a-form-item label="启用" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
           <a-radio-group
@@ -158,7 +188,7 @@
 
 <script>
 import { STable, VSelect } from '@/components'
-import { saveMenu } from '@/api/menu.js'
+import { saveYyMenu, saveMdMenu } from '@/api/menu.js'
 export default {
   name: 'ChildModal',
   components: {
@@ -169,6 +199,10 @@ export default {
       type: Boolean,
       default: false
     },
+    parentType: {
+      type: String,
+      default: ''
+    },
     data: {
       type: Object,
       default: function () {
@@ -196,6 +230,8 @@ export default {
         urlPath: '',
         sort: '',
         type: undefined,
+        chainOrgUse: 1,
+        singleOrgUse: 1,
         status: 1 // 活动状态
       }
     }
@@ -216,7 +252,8 @@ export default {
       this.form.validateFields((err, values) => {
         if (!err) {
           console.log(values.formData, ' formData.type222222222')
-          saveMenu(Object.assign(this.formData, values.formData)).then(res => {
+          const saveRequest = this.parentType == 'store' ? saveMdMenu : saveYyMenu
+          saveRequest(Object.assign(this.formData, values.formData)).then(res => {
             console.log(res, 'res--save')
             if (res.status + '' === '200') {
               this.$message.success(res.message ? res.message : '保存成功')
@@ -258,6 +295,8 @@ export default {
       this.formData.sort = ''
       this.formData.type = ''
       this.formData.status = 1
+      this.formData.chainOrgUse = 1
+      this.formData.singleOrgUse = 1
       this.formData.code = ''
       this.formData.permission = ''
     }

+ 494 - 0
src/views/bnSetting/menu/storeMenus.vue

@@ -0,0 +1,494 @@
+<template>
+  <a-card :bordered="false">
+    <a-row :gutter="24">
+      <a-button style="margin-right: 10px;" type="primary" icon="plus" @click="addChild">添加子菜单</a-button>
+      <a-button style="margin-right: 10px;background-color: #19be6b;color: #fff;" type="" icon="plus" @click="addTitle">添加顶部菜单</a-button>
+      <a-button style="margin-right: 10px;background-color: red;color: #fff;" type="" icon="delete" @click="delect()">删除</a-button>
+
+    </a-row>
+    <a-row :gutter="24">
+      <!-- 左侧菜单树列表 -->
+      <a-col :span="8">
+        <a-row :gutter="24" class="textCount">
+          <a-icon type="info-circle" style="color: #1890FF;margin-right: 10px;" />
+          <span>当前选择:<span style="color: #40a9ff;font-weight: 600;">{{ selectedMenu }}</span><span v-if="selectedKeys.length" class="imgSize" @click="cancelSel">取消选择</span></span>
+        </a-row>
+
+        <a-row :gutter="24" >
+          <a-input-search placeholder="输入搜索菜单名搜索" style="width: 100%" @change="onChange" />
+          <a-tree
+            @expand="onExpand"
+            :treeData="getMenus"
+            :expandedKeys="expandedKeys"
+            :autoExpandParent="autoExpandParent"
+            @select="onSelect"
+            :selectedKeys="selectedKeys"
+            showIcon
+          >
+            <template slot="title" slot-scope="{title}">
+              <span v-if="title.indexOf(searchValue) > -1">
+                {{ title.substr(0, title.indexOf(searchValue)) }}
+                <span style="color: #f50">{{ searchValue }}</span>
+                {{ title.substr(title.indexOf(searchValue) + searchValue.length) }}
+              </span>
+              <span v-else>{{ title }}</span>
+            </template>
+            <a-icon slot="file" type="file" />
+            <a-icon slot="pushpin" type="pushpin" />
+          </a-tree>
+        </a-row>
+      </a-col>
+      <!-- 右侧 -->
+      <a-col :span="16" >
+        <a-form :form="form" @submit="handleSubmit">
+          <!-- 类型 -->
+          <a-form-item label="类型" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <div v-if="!formData.type||formData.type=='0'">
+              <a-icon type="file" style="margin-right: 10px;" /><span >页面菜单</span>
+            </div>
+            <div v-if="formData.type=='1'">
+              <a-icon type="pushpin" style="margin-right: 10px;" /><span >操作按钮</span>
+            </div>
+          </a-form-item>
+
+          <!-- 名称 -->
+          <a-form-item label="名称" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <a-input
+              placeholder="请输入名称"
+              v-decorator="['formData.name', {
+                initialValue: formData.name,
+                rules: [{ required: true, message: '请输入名称!' },{pattern:'^[^<|>]{1,20}$',message:'请输入不含<或>的字符,最多20个字符'}] }]"
+            />
+          </a-form-item>
+          <!-- 路由英文名 -->
+          <!-- <a-form-item v-if="!formData.type||formData.type=='0'" label="路由英文名" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <a-input
+              placeholder="请输入路由英文名"
+              v-decorator="['formData.routeName', {
+                initialValue: formData.routeName,
+                rules: [{ required: true, message: '请输入路由英文名!' }] }]"
+            />
+          </a-form-item> -->
+          <!-- 路径 -->
+          <!-- <a-form-item v-if="!formData.type||formData.type=='0'" label="路径" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <a-input
+              placeholder="请输入路径"
+              v-decorator="['formData.routePath', {
+                initialValue: formData.routePath,
+                rules: [{ required: true, message: '请输入路径!' }] }]"
+            />
+          </a-form-item> -->
+          <!-- 请求路径 -->
+          <!-- <a-form-item v-if="formData.type==1" label="请求路径" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <a-input
+              placeholder="请输入请求路径"
+              v-decorator="['formData.urlPath', {
+                initialValue: formData.urlPath,
+                rules: [{ required: true, message: '请输入请求路径!' }] }]"
+            />
+          </a-form-item> -->
+          <!-- 前端权限编码 -->
+          <a-form-item label="前端权限编码" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <a-input
+              placeholder="请输入前端权限编码"
+              v-decorator="[
+                'formData.code',
+                {
+                  initialValue: formData.code,
+                  rules: [{ required: true, message: '请输入前端权限编码!' }] },
+              ]"
+            />
+          </a-form-item>
+          <!-- 后台权限编码 -->
+          <a-form-item label="后台权限编码" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <a-input
+              placeholder="请输入后台权限编码"
+              v-decorator="[
+                'formData.permission',
+                {
+                  initialValue: formData.permission,
+                  rules: [{ required: formData.isLeaf, message: '请输入后台权限编码!' }] },
+              ]"
+            />
+          </a-form-item>
+          <!-- 图标 -->
+          <!-- <a-form-item v-if="!formData.type ||formData.type=='0' " label="图标" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <a-input
+              placeholder="请输入图标名称"
+              v-decorator="['formData.icon', {
+                initialValue: formData.icon,
+                rules: [] }]"
+            />
+          </a-form-item> -->
+          <!-- 前端组件 -->
+          <!-- <a-form-item v-if="!formData.type ||formData.type=='0'" label="前端组件" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <a-input
+              placeholder="请输入前端组件路径"
+              v-decorator="['formData.componentPath', {
+                initialValue: formData.componentPath,
+                rules: [{ required: true, message: '请输入前端组件路径!' }] }]"
+            />
+          </a-form-item> -->
+
+          <!-- 第三方链接 -->
+          <!-- <a-form-item v-if="!formData.type ||formData.type=='0'" label="第三方链接" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <a-input
+              placeholder="请输入第三方链接地址"
+              v-decorator="['formData.urlPath', {
+                initialValue: formData.urlPath,
+                rules: [] }]"
+            />
+          </a-form-item> -->
+
+          <!-- 排序值 -->
+          <a-form-item label="排序值" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <a-input
+              type="number"
+              placeholder="请输入排序值"
+              v-decorator="['formData.sort', {
+                initialValue: formData.sort,
+                rules: [] }]"
+            />
+          </a-form-item>
+          <!-- 连锁可用 -->
+          <a-form-item label="连锁可用" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <a-radio-group
+              name="radioGroup"
+              v-decorator="[
+                'formData.chainOrgUse',
+                {
+                  initialValue: formData.chainOrgUse,
+                  rules: [{ required: true, message: '请选择!' }] },
+              ]"
+            >
+              <a-radio :value="1">是</a-radio>
+              <a-radio :value="0">否</a-radio>
+            </a-radio-group>
+          </a-form-item>
+          <!-- 单店可用 -->
+          <a-form-item label="单店可用" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <a-radio-group
+              name="radioGroup"
+              v-decorator="[
+                'formData.singleOrgUse',
+                {
+                  initialValue: formData.singleOrgUse,
+                  rules: [{ required: true, message: '请选择!' }] },
+              ]"
+            >
+              <a-radio :value="1">是</a-radio>
+              <a-radio :value="0">否</a-radio>
+            </a-radio-group>
+          </a-form-item>
+          <!-- 状态 -->
+          <a-form-item label="启用" :label-col="{ span: 5 }" :wrapper-col="{ span: 14 }">
+            <a-radio-group
+              name="radioGroup"
+              v-decorator="[
+                'formData.status',
+                {
+                  initialValue: formData.status,
+                  rules: [{ required: true, message: '请选择状态!' }] },
+              ]"
+            >
+              <a-radio :value="1">是</a-radio>
+              <a-radio :value="0">否</a-radio>
+            </a-radio-group>
+          </a-form-item>
+
+          <a-form-item :wrapper-col="{ span: 12, offset: 5 }">
+            <a-button type="primary" @click="handleSubmit()">
+              保存
+            </a-button>
+            <a-button :style="{ marginLeft: '8px' }" @click="clear">
+              重置
+            </a-button>
+          </a-form-item>
+        </a-form>
+
+      </a-col>
+    </a-row>
+    <childModal parentType="store" :visible="showChildModal" @refresh="getMdMenuList" :data="parentData" @close="showChildModal = false"></childModal>
+  </a-card>
+</template>
+
+<script>
+import { STable, VSelect } from '@/components'
+import childModal from './childModal.vue'
+import { getMdMenuList, saveMdMenu, deleteMdMenu } from '@/api/menu.js'
+
+export default {
+  name: 'Menu',
+  components: {
+    STable, VSelect, childModal
+  },
+  props: {},
+  data () {
+    return {
+      treeData: [],
+      dataList: [],
+      searchValue: '',
+      expandedKeys: [],
+      autoExpandParent: true,
+      selectedKeys: [],
+      selectedMenu: '', // 选择的树节点名
+      formLayout: 'horizontal',
+      form: this.$form.createForm(this, { name: 'menu' }),
+      showChildModal: false,
+      parentData: {}, // 父级菜单
+      formData: {
+        id: '',
+        name: '',
+        routePath: '',
+        icon: '',
+        routeName: '',
+        componentPath: '',
+        urlPath: '',
+        code: '',
+        permission: '',
+        sort: '',
+        type: '0',
+        isLeaf: true,
+        chainOrgUse: '',
+        singleOrgUse: '',
+        status: '' // 活动状态
+      }
+    }
+  },
+  computed: {
+    getMenus () {
+      this.generateList(this.treeData)
+      return this.treeData
+    }
+  },
+  methods: {
+    onExpand (expandedKeys) {
+      // console.log('onExpand', expandedKeys)
+      this.expandedKeys = expandedKeys
+      this.autoExpandParent = false
+    },
+
+    onSelect (selectedKeys, info) {
+      console.log('onSelect', info)
+      this.selectedKeys = selectedKeys
+      if (info.selected) {
+        const data = info.selectedNodes[0].data.props
+        const isLeaf = data.dataRef.children
+        // this.formData = Object.assign({}, this.formData, info.selectedNodes[0].data.props)
+        this.formData = {
+          id: data.id,
+          name: data.name,
+          routePath: data.routePath,
+          icon: data.icon,
+          routeName: data.routeName,
+          componentPath: data.componentPath,
+          urlPath: data.urlPath,
+          code: data.code,
+          permission: data.permission,
+          sort: data.sort,
+          type: data.type,
+          chainOrgUse: data.chainOrgUse,
+          singleOrgUse: data.singleOrgUse,
+          status: data.status,
+          isLeaf: !(isLeaf && isLeaf.length)
+        }
+
+        this.selectedMenu = this.formData.name
+        this.formData.status = Number(this.formData.status)
+        this.formData.chainOrgUse = Number(this.formData.chainOrgUse)
+        this.formData.singleOrgUse = Number(this.formData.singleOrgUse)
+      } else {
+        this.selectedMenu = ''
+        this.clear()
+      }
+    },
+    generateList (data) {
+      for (let i = 0; i < data.length; i++) {
+        const node = data[i]
+        const key = node.title
+        this.dataList.push({ key, title: key })
+        node.scopedSlots = { title: 'title' }
+        node.slots = { icon: node.type == '0' ? 'file' : 'pushpin' }
+
+        if (node.children) {
+          this.generateList(node.children)
+        }
+      }
+    },
+    getParentKey (key, tree) {
+      let parentKey
+      for (let i = 0; i < tree.length; i++) {
+        const node = tree[i]
+        if (node.children) {
+          if (node.children.some(item => item.title == key)) {
+            parentKey = node.key
+          } else if (this.getParentKey(key, node.children)) {
+            parentKey = this.getParentKey(key, node.children)
+          }
+        }
+      }
+      return parentKey
+    },
+    onChange (e) {
+      const value = e.target.value
+      const expandedKeys = this.dataList
+        .map(item => {
+          if (item.title.indexOf(value) > -1) {
+            return this.getParentKey(item.title, this.treeData)
+          }
+          return null
+        })
+        .filter((item, i, self) => item && self.indexOf(item) === i)
+      Object.assign(this, {
+        expandedKeys,
+        searchValue: value,
+        autoExpandParent: true
+      })
+    },
+    // 获取菜单树列表
+    getMdMenuList () {
+      getMdMenuList().then(res => {
+        console.log(res, 'res1111111')
+        if (res.status == 200) {
+          this.treeData = res.data
+          console.log(this.treeData, 'this.treeData')
+        }
+      })
+    },
+    // 添加子节点
+    addChild () {
+      if (!this.selectedMenu) {
+        return this.$message.warning('请先选择一个父级菜单')
+      } else if (this.formData.type == '1') {
+        return this.$message.warning('请选择一个页面级菜单')
+      }
+      this.showChildModal = true
+      this.parentData = this.formData
+    },
+    // 添加顶部菜单
+    addTitle () {
+      this.showChildModal = true
+      this.parentData = {}
+    },
+    //  取消选择
+    cancelSel () {
+      this.selectedKeys = []
+      this.selectedMenu = ''
+      this.clear()
+    },
+    // 清空列表
+    clear () {
+      this.form.resetFields()
+      this.formData.id = ''
+      this.formData.name = ''
+      this.formData.routePath = ''
+      this.formData.icon = ''
+      this.formData.routeName = ''
+      this.formData.componentPath = ''
+      this.formData.urlPath = ''
+      this.formData.sort = ''
+      this.formData.type = ''
+	    this.formData.chainOrgUse = ''
+	    this.formData.singleOrgUse = ''
+      this.formData.status = ''
+      this.formData.code = ''
+      this.formData.permission = ''
+      this.formData.isLeaf = true
+    },
+
+    // 删除数据
+    delect () {
+      if (!this.selectedKeys.length) {
+        return this.$message.warning('您还未选择要删除的数据')
+      }
+      const _this = this
+      console.log(_this.formData.id, '_this.formData.id')
+      this.$confirm({
+        title: '警告',
+        content: `确定要删除您选择的 ${_this.formData.name} 的数据吗?`,
+        okText: '确定',
+        cancelText: '取消',
+        onOk () {
+          deleteMdMenu({
+            id: _this.formData.id
+          }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success('删除成功')
+              _this.getMdMenuList()
+            }
+          }).catch(() => {
+            _this.$message.success('删除失败, 请稍后重试')
+          })
+        }
+      })
+    },
+
+    // 保存提交
+    handleSubmit () {
+      const _this = this
+      this.form.validateFields((err, values) => {
+        if (!err) {
+          console.log(values.formData, ' formData.type222222222')
+          saveMdMenu(Object.assign({ id: this.formData.id }, values.formData)).then(res => {
+            console.log(res, 'res--save')
+            if (res.status + '' === '200') {
+              this.$message.success(res.message ? res.message : '保存成功')
+              _this.getMdMenuList()
+              _this.clear()
+            } else {
+              // this.$message.warning(res.message)
+            }
+          })
+        }
+      })
+    },
+    handleCancel () {
+      this.clear()
+    }
+
+  },
+  mounted () {
+  },
+  beforeCreate () {
+    this.form = this.$form.createForm(this, { name: 'menu' })
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {
+      vm.getMdMenuList()
+    })
+  },
+  watch: {
+
+  }
+}
+</script>
+
+<style>
+  .menu-box::-webkit-scrollbar{
+    width: 6px;
+    height: 6px ;
+  }
+
+  .menu-box::-webkit-scrollbar-thumb{
+    width: 6px;
+    height: 6px ;
+    border-radius: 4px;
+    -webkit-box-shadow: inset 0 0 2px #d1d1d1;
+    background: #e4e4e4;
+  }
+
+  .textCount{
+    border: 1px solid #91d5ff;
+    background-color: #e6f7ff;
+    border-radius: 5px;
+    padding: 5px 10px 5px 20px;
+    margin: 10px 0;
+    color: rgba(0, 0, 0, 0.85);
+  }
+  .imgSize{
+    color: #2d8cf0;
+    margin-left: 10px;
+    font-size: 14px;
+  }
+
+</style>

+ 162 - 0
src/views/bnSetting/menusAuth.vue

@@ -0,0 +1,162 @@
+<template>
+  <div>
+    <a-form class="form-box" style="height: 500px;overflow: auto;margin-bottom: 15px;" :form="form" @submit="handleSubmit">
+      <a-tree
+        checkable
+        @check="onCheck"
+        @expand="onExpand"
+        :autoExpandParent="autoExpandParent"
+        v-model="checkedKeys"
+        :treeData="treeData"
+      />
+    </a-form>
+    <a-form-item :wrapper-col="{ offset: 3 }">
+      <a-button type="primary" @click="handleSubmit()">
+        保存
+      </a-button>
+    </a-form-item>
+  </div>
+</template>
+
+<script>
+import { findLsMenu, saveLsMouldMenu, findDdMenu, saveDdMouldMenu } from '@/api/menuSet'
+export default {
+  name: 'MenusAuth',
+  props: {
+    types: {
+      type: String,
+      default: 'dd'
+    }
+  },
+  data () {
+    return {
+      menuIds: '',
+      treeData: [],
+      expandedKeys: [],
+      autoExpandParent: false,
+      checkedKeys: [],
+      checkedData: [],
+      formLayout: 'horizontal',
+      form: this.$form.createForm(this, { name: 'menuModal' })
+    }
+  },
+  methods: {
+    tabChange (v) {
+      console.log(v)
+    },
+    // 初始化树
+    treeInit (dr) {
+      this.treeData = dr.menuList
+      this.menuIds = dr.mould.menuIds
+      if (this.menuIds) {
+        const arr = this.menuIds.split(',')
+        const temp = []
+        arr.map(item => {
+          temp.push(Number(item))
+        })
+        this.checkedData = temp
+        this.expandedKeys = temp
+        // 找出叶子节点
+        this.findLeaf(this.treeData, temp)
+      }
+    },
+    // 获取连锁树数据
+    getfindLsMenu () {
+      findLsMenu().then(res => {
+        console.log(res, '+++++++++连锁+++++++++')
+        if (res.status == 200) {
+          this.treeInit(res.data)
+        }
+      })
+    },
+    // 获取单店树数据
+    getfindDdMenu () {
+      findDdMenu().then(res => {
+        console.log(res, '+++++++++单店+++++++++')
+        if (res.status == 200) {
+          this.treeInit(res.data)
+        }
+      })
+    },
+    onExpand (expandedKeys) {
+      console.log('onExpand', expandedKeys)
+      this.expandedKeys = expandedKeys
+      this.autoExpandParent = false
+    },
+    onCheck (checkedKeys, info) {
+      this.checkedData = [...checkedKeys, ...info.halfCheckedKeys]
+      this.checkedKeys = checkedKeys
+    },
+    // 勾选已选的菜单
+    findLeaf (data, arr) {
+      for (let i = 0; i < data.length; i++) {
+        const node = data[i]
+        if (node.children) {
+          this.findLeaf(node.children, arr)
+        } else {
+          const hasNode = arr.find(item => {
+            return item == node.id
+          })
+          if (hasNode) {
+            this.checkedKeys.push(node.id)
+          }
+        }
+      }
+    },
+    // 保存提交
+    handleSubmit () {
+      const _this = this
+      this.form.validateFields((err, values) => {
+        if (!err) {
+          // console.log(this.checkedData)
+          if (this.checkedData.length == 0) {
+            return this.$message.warning('请先选择菜单')
+          }
+          const arr = this.checkedData.join(',')
+          if (this.types == 'dd') {
+            this.ddSave({ menuIds: arr })
+          } else {
+            this.lsSave({ menuIds: arr })
+          }
+        }
+      })
+    },
+    // 保存单店
+    ddSave (pars) {
+      saveDdMouldMenu(pars).then(res => {
+        console.log(res, 'res--save')
+        if (res.status + '' === '200') {
+          this.$message.success(res.message ? res.message : '保存成功')
+        } else {
+          // this.$message.warning(res.message)
+        }
+      })
+    },
+    // 保存连锁
+    lsSave (pars) {
+      saveLsMouldMenu(pars).then(res => {
+        console.log(res, 'res--save')
+        if (res.status + '' === '200') {
+          this.$message.success(res.message ? res.message : '保存成功')
+        } else {
+          // this.$message.warning(res.message)
+        }
+      })
+    }
+  },
+  mounted () {
+    // 单店
+    if (this.types == 'dd') {
+      this.getfindDdMenu()
+    } else {
+      this.getfindLsMenu()
+    }
+  },
+  beforeCreate () {
+    this.form = this.$form.createForm(this, { name: 'menu' })
+  }
+}
+</script>
+
+<style>
+</style>

+ 41 - 0
src/views/bnSetting/menusAuthTab.vue

@@ -0,0 +1,41 @@
+<template>
+  <div class="menusAuth-cons">
+    <a-tabs @change="tabChange" type="card">
+      <a-tab-pane tab="单店菜单设置" key="1">
+        <menusAuth types="dd"></menusAuth>
+      </a-tab-pane>
+      <a-tab-pane tab="连锁店菜单设置" key="2">
+        <menusAuth types="ls"></menusAuth>
+      </a-tab-pane>
+    </a-tabs>
+  </div>
+</template>
+
+<script>
+  import menusAuth from './menusAuth.vue'
+  export default {
+    name: 'menusAuthTab',
+    components: {
+      menusAuth
+    },
+    data() {
+      return {}
+    },
+    methods: {
+      tabChange(v) {
+        console.log(v)
+      },
+    },
+    beforeRouteEnter (to, from, next) {
+      next(vm => {
+      })
+    },
+  }
+</script>
+
+<style>
+  .menusAuth-cons{
+    background: #fff;
+    padding: 10px;
+  }
+</style>