Browse Source

上测试

喻文俊 3 years ago
parent
commit
51d259fc3c

+ 1 - 1
src/api/system.js

@@ -29,7 +29,7 @@ export function updateUser(id, data) {
 /** 创建用户 */
 /** 创建用户 */
 export function createUser(data) {
 export function createUser(data) {
   return request({
   return request({
-    url: '/sys/user/create',
+    url: '/sys/user/admin/create',
     method: 'post',
     method: 'post',
     data: data
     data: data
   })
   })

+ 18 - 0
src/api/user.js

@@ -53,3 +53,21 @@ export function bindLoginAccount(data) {
     data
     data
   })
   })
 }
 }
+
+/** 获取菜单列表 */
+export function fetchUserInfo(params) {
+  return request({
+    url: '/sys/user/info',
+    method: 'get',
+    params
+  })
+}
+
+/** 获取会员信息 */
+export function fetchUserVipInfo(params) {
+  return request({
+    url: '/vip/info',
+    method: 'get',
+    params
+  })
+}

BIN
src/assets/img/vip-icon-active.png


BIN
src/assets/img/vip-icon.png


+ 69 - 17
src/layout/components/Navbar.vue

@@ -16,32 +16,40 @@
         <!-- <error-log class="errLog-container right-menu-item hover-effect" /> -->
         <!-- <error-log class="errLog-container right-menu-item hover-effect" /> -->
         <screenfull id="screenfull" class="right-menu-item hover-effect" />
         <screenfull id="screenfull" class="right-menu-item hover-effect" />
       </template>
       </template>
-      <!-- <div class="user-info">
-        <div>
-          <span>{{ loginAccount || mobile || name }}</span>
-          <span>2022-02-11 会员到期续费购买记录</span>
-        </div>
-        <i v-if="userIdentity === 2" class="vip-icon close" />
-        <span>开通会员</span>
-      </div> -->
       <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
       <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
         <div class="avatar-wrapper">
         <div class="avatar-wrapper">
           <img src="https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif" class="user-avatar">
           <img src="https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif" class="user-avatar">
           <span>{{ loginAccount || mobile || name }}</span>
           <span>{{ loginAccount || mobile || name }}</span>
-          <i v-if="userIdentity === 2" class="vip-icon close" />
+          <template v-if="userIdentity === 2">
+            <i v-if="vipInfo.vipStatus !== 3" class="vip-icon " :class="{ close: vipInfo.vipStatus === 0 }" />
+            <el-button
+              v-if="vipInfo.vipStatus === 3"
+              type="primary"
+              size="mini"
+              class="vip-button"
+              @click.stop="toOpenVipPage('open')"
+            >开通会员</el-button>
+            <el-button
+              v-else
+              type="primary"
+              size="mini"
+              class="vip-button xufei"
+              @click.stop="toOpenVipPage('xufei')"
+            >续费</el-button>
+          </template>
           <i class="el-icon-caret-bottom" />
           <i class="el-icon-caret-bottom" />
         </div>
         </div>
-        <el-dropdown-menu slot="dropdown" :class="{user: userIdentity === 2}">
+        <el-dropdown-menu slot="dropdown" :class="{ user: userIdentity === 2 }">
           <template v-if="userIdentity === 2">
           <template v-if="userIdentity === 2">
             <el-dropdown-item class="user-info">
             <el-dropdown-item class="user-info">
               <img src="https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif" class="user-avatar">
               <img src="https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif" class="user-avatar">
               <div class="right-content">
               <div class="right-content">
                 <div class="name">
                 <div class="name">
                   <span>{{ loginAccount || mobile || name }}</span>
                   <span>{{ loginAccount || mobile || name }}</span>
-                  <i class="vip-icon close" />
+                  <i class="vip-icon " :class="{ close: vipInfo.vipStatus === 0 || vipInfo.vipStatus === 3 }" />
                 </div>
                 </div>
                 <div class="info">
                 <div class="info">
-                  <span class="time">到期时间:2020-12-21</span>
+                  <span v-if="vipInfo.endTime" class="time">到期时间:{{ vipInfo.endTime | formatTime }}</span>
                   <span class="record">购买记录</span>
                   <span class="record">购买记录</span>
                 </div>
                 </div>
               </div>
               </div>
@@ -73,33 +81,58 @@
         </el-dropdown-menu>
         </el-dropdown-menu>
       </el-dropdown>
       </el-dropdown>
     </div>
     </div>
+    <vip-tip-dialog />
   </div>
   </div>
 </template>
 </template>
 
 
 <script>
 <script>
 import { mapGetters } from 'vuex'
 import { mapGetters } from 'vuex'
+import { formatDate } from '@/utils'
 import Breadcrumb from '@/components/Breadcrumb'
 import Breadcrumb from '@/components/Breadcrumb'
 import Hamburger from '@/components/Hamburger'
 import Hamburger from '@/components/Hamburger'
 // import ErrorLog from '@/components/ErrorLog'
 // import ErrorLog from '@/components/ErrorLog'
 import Screenfull from '@/components/Screenfull'
 import Screenfull from '@/components/Screenfull'
 // import Search from '@/components/HeaderSearch'
 // import Search from '@/components/HeaderSearch'
 // import NoticeTodo from './NoticeTodo'
 // import NoticeTodo from './NoticeTodo'
+import VipTipDialog from './VipTipDialog'
 
 
 export default {
 export default {
+  filters: {
+    formatTime(time) {
+      if (!time) {
+        return ''
+      }
+      return formatDate(time, 'yyyy-MM-DD HH:mm:ss')
+    }
+  },
   components: {
   components: {
     Breadcrumb,
     Breadcrumb,
     Hamburger,
     Hamburger,
     // ErrorLog,
     // ErrorLog,
-    Screenfull
+    Screenfull,
+    VipTipDialog
     // NoticeTodo
     // NoticeTodo
     // Search
     // Search
   },
   },
   computed: {
   computed: {
-    ...mapGetters(['sidebar', 'device', 'name', 'userIdentity', 'openSoket', 'proxyState', 'mobile', 'loginAccount']),
+    ...mapGetters([
+      'sidebar',
+      'device',
+      'name',
+      'userIdentity',
+      'openSoket',
+      'proxyState',
+      'mobile',
+      'loginAccount',
+      'vipInfo'
+    ]),
     userName() {
     userName() {
       return this.name
       return this.name
     }
     }
   },
   },
+  created() {
+    console.log(this.vipInfo)
+  },
   methods: {
   methods: {
     toggleSideBar() {
     toggleSideBar() {
       this.$store.dispatch('app/toggleSideBar')
       this.$store.dispatch('app/toggleSideBar')
@@ -122,6 +155,14 @@ export default {
         this.$store.commit('proxy/CLOSE_PROXY')
         this.$store.commit('proxy/CLOSE_PROXY')
         this.$router.replace('/proxy')
         this.$router.replace('/proxy')
       }, 500)
       }, 500)
+    },
+    // 去开通/续费会员
+    toOpenVipPage(type) {
+      if (type === 'open') {
+        this.$router.push('/vip/vip-open')
+      } else {
+        this.$router.push('/vip/vip-open')
+      }
     }
     }
   }
   }
 }
 }
@@ -141,6 +182,18 @@ export default {
     border-radius: 8px;
     border-radius: 8px;
   }
   }
 }
 }
+.vip-button {
+  height: 24px;
+  line-height: 24px;
+  padding: 0 10px;
+  margin-left: 4px;
+
+  &.xufei {
+    background: #ff6d6d;
+    border-color: #ff6d6d;
+  }
+}
+
 .user-info {
 .user-info {
   display: flex;
   display: flex;
   justify-content: space-between;
   justify-content: space-between;
@@ -181,13 +234,12 @@ export default {
   width: 40px;
   width: 40px;
   height: 32px;
   height: 32px;
   margin: 0 4px;
   margin: 0 4px;
-  background: url(~@/assets/img/vip-icon.png) no-repeat;
+  background: url(~@/assets/img/vip-icon-active.png) no-repeat;
   background-size: 40px;
   background-size: 40px;
   vertical-align: -5px;
   vertical-align: -5px;
 
 
   &.close {
   &.close {
-    filter: grayscale(1);
-    opacity: 0.6;
+    background: url(~@/assets/img/vip-icon.png) no-repeat;
   }
   }
 }
 }
 
 

+ 41 - 0
src/layout/components/VipTipDialog/index.vue

@@ -0,0 +1,41 @@
+<template>
+  <el-dialog
+    title="提示"
+    :visible="vipTipVisiable && (vipInfo.freeUseFlag && vipInfo.freeUseFlag !== 0)"
+    width="24%"
+    :close-on-click-modal="false"
+    center
+  >
+    <div>{{ contentText }}</div>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="vipTipVisiable = false">取消</el-button>
+      <el-button type="primary" @click="toOpenVipPage">开通会员</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+export default {
+  name: 'VipTipDialog',
+  data() {
+    return {
+      vipTipVisiable: true
+    }
+  },
+  computed: {
+    ...mapGetters(['vipInfo']),
+    contentText() {
+      const insertText = ['', '账号试用即将到期', '账号试用已到期', '会员账号即将到期', '会员账号已到期']
+      return `对不起,您的账号${insertText[this.vipInfo.freeUseFlag]},请尽快开通会员,以免影响正常使用`
+    }
+
+  },
+  methods: {
+    toOpenVipPage() {
+      this.$router.push('/vip/vip-open')
+    }
+  }
+}
+</script>
+

+ 6 - 5
src/permission.js

@@ -17,16 +17,16 @@ const whiteList = ['/login']
 router.beforeEach(async(to, from, next) => {
 router.beforeEach(async(to, from, next) => {
   // 获取token
   // 获取token
   const hasToken = getToken()
   const hasToken = getToken()
-
   // 设置页面标题
   // 设置页面标题
   document.title = getPageTitle(to.meta.title)
   document.title = getPageTitle(to.meta.title)
+
   if (hasToken) {
   if (hasToken) {
     // 如果是访问登录页面,强制跳转到首页
     // 如果是访问登录页面,强制跳转到首页
     if (to.path === '/login') {
     if (to.path === '/login') {
       next({ path: initGoPage() })
       next({ path: initGoPage() })
     } else {
     } else {
       // 加载国家列表并保存到store
       // 加载国家列表并保存到store
-      store.dispatch('app/setCountry')
+      // store.dispatch('app/setCountry')
       // 判断当前用户是否拥有角色
       // 判断当前用户是否拥有角色
       const hasRoles = store.getters.roles && store.getters.roles.length > 0
       const hasRoles = store.getters.roles && store.getters.roles.length > 0
       if (hasRoles) {
       if (hasRoles) {
@@ -38,10 +38,11 @@ router.beforeEach(async(to, from, next) => {
           if (store.getters.isChangeProxy) {
           if (store.getters.isChangeProxy) {
             store.commit('tagsView/CLEAR_ALL_VIEW')
             store.commit('tagsView/CLEAR_ALL_VIEW')
           }
           }
-          // 获取当前用户所分配的角色
-          const roles = await store.dispatch('user/getRoles')
+          // store.commit('user/SET_ROLES', roles)
+          await store.dispatch('user/fetchUserInfo')
+          await store.dispatch('user/fetchUserVipInfo')
           // 根据用户角色获取路由配置
           // 根据用户角色获取路由配置
-          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
+          const accessRoutes = await store.dispatch('permission/generateRoutes')
           // 添加路由配置
           // 添加路由配置
           router.addRoutes(accessRoutes)
           router.addRoutes(accessRoutes)
           // 放行
           // 放行

+ 1 - 1
src/router/index.js

@@ -28,7 +28,6 @@ export const asyncRoutes = [
   ...feedbackRoutes,
   ...feedbackRoutes,
   ...settingRoutes,
   ...settingRoutes,
   ...helperRoutes,
   ...helperRoutes,
-  ...vipRoutes,
   ...personalRoutes,
   ...personalRoutes,
   // 404页面 放在最后面
   // 404页面 放在最后面
   { path: '*', redirect: '/404', hidden: true }
   { path: '*', redirect: '/404', hidden: true }
@@ -89,6 +88,7 @@ export const constantRoutes = [
       }
       }
     ]
     ]
   },
   },
+  ...vipRoutes,
   {
   {
     path: '/404',
     path: '/404',
     component: () => import(/* webpackChunkName: "common-page" */ '@/views/common/error-page/404'),
     component: () => import(/* webpackChunkName: "common-page" */ '@/views/common/error-page/404'),

+ 7 - 7
src/router/module/vip.js

@@ -8,28 +8,28 @@ const vipRoutes = [
     redirect: '/vip/vip-open',
     redirect: '/vip/vip-open',
     name: 'Member',
     name: 'Member',
     meta: { title: '权益与支付', roles: ['normal'] },
     meta: { title: '权益与支付', roles: ['normal'] },
-    // alwaysShow: true,
+    alwaysShow: false,
     children: [
     children: [
       {
       {
         path: 'vip-open',
         path: 'vip-open',
         component: () => import('@/views/normal/vip'),
         component: () => import('@/views/normal/vip'),
         name: 'VipOpen',
         name: 'VipOpen',
-        meta: { title: '开通会员', roles: ['normal'] }
-        // hidden: true
+        meta: { title: '开通会员', roles: ['normal'] },
+        hidden: true
       },
       },
       {
       {
         path: 'vip-renewal',
         path: 'vip-renewal',
         component: () => import('@/views/normal/vip'),
         component: () => import('@/views/normal/vip'),
         name: 'VipRenewal',
         name: 'VipRenewal',
-        meta: { title: '续费会员', roles: ['normal'] }
-        // hidden: true
+        meta: { title: '续费会员', roles: ['normal'] },
+        hidden: true
       },
       },
       {
       {
         path: 'vip-pay',
         path: 'vip-pay',
         component: () => import('@/views/normal/vip/buy'),
         component: () => import('@/views/normal/vip/buy'),
         name: 'VipPay',
         name: 'VipPay',
-        meta: { title: '购买会员', roles: ['normal'] }
-        // hidden: true
+        meta: { title: '购买会员', roles: ['normal'] },
+        hidden: true
       }
       }
     ]
     ]
   }
   }

+ 3 - 0
src/store/getters.js

@@ -11,7 +11,10 @@ const getters = {
   loginAccount: state => state.user.loginAccount,
   loginAccount: state => state.user.loginAccount,
   mobile: state => state.user.mobile,
   mobile: state => state.user.mobile,
   vipStatus: state => state.user.vipStatus,
   vipStatus: state => state.user.vipStatus,
+  vipInfo: state => state.user.vipInfo,
   roles: state => state.user.roles,
   roles: state => state.user.roles,
+  menusList: state => state.user.menusList,
+  permissions: state => state.user.permissions,
   authUserId: state => state.user.authUserId,
   authUserId: state => state.user.authUserId,
   userIdentity: state => state.user.userIdentity,
   userIdentity: state => state.user.userIdentity,
   permission_routes: state => state.permission.routes,
   permission_routes: state => state.permission.routes,

+ 62 - 69
src/store/modules/permission.js

@@ -1,69 +1,62 @@
-import { asyncRoutes, constantRoutes } from '@/router'
-
-/**
- * 通过meta.role判断是否与当前用户权限匹配
- * @param roles
- * @param route
- */
-function hasPermission(roles, route) {
-  if (route.meta && route.meta.roles) {
-    return roles.some(role => route.meta.roles.includes(role))
-  } else {
-    return true
-  }
-}
-
-/**
- * 递归过滤异步路由表,返回符合用户角色权限的路由表
- * @param routes asyncRoutes
- * @param roles
- */
-export function filterAsyncRoutes(routes, roles) {
-  const res = []
-
-  routes.forEach(route => {
-    const tmp = { ...route }
-    if (hasPermission(roles, tmp)) {
-      if (tmp.children) {
-        tmp.children = filterAsyncRoutes(tmp.children, roles)
-      }
-      res.push(tmp)
-    }
-  })
-
-  return res
-}
-
-const state = {
-  routes: [],
-  addRoutes: []
-}
-
-const mutations = {
-  SET_ROUTES: (state, routes) => {
-    state.addRoutes = routes
-    state.routes = constantRoutes.concat(routes)
-  }
-}
-
-const actions = {
-  generateRoutes({ commit }, roles) {
-    return new Promise(resolve => {
-      const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
-      // if (roles.includes('admin')) {
-      //   accessedRoutes = asyncRoutes
-      // } else {
-      //   accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
-      // }
-      commit('SET_ROUTES', accessedRoutes)
-      resolve(accessedRoutes)
-    })
-  }
-}
-
-export default {
-  namespaced: true,
-  state,
-  mutations,
-  actions
-}
+import { asyncRoutes, constantRoutes } from '@/router'
+
+// 根据路由名称查询路由
+function findRoute(name, routes) {
+  return routes.find(route => route.name === name)
+}
+
+// 设置路由meta属性
+function getMeta(route) {
+  return {
+    icon: route.icon,
+    title: route.title,
+    sort: route.sort,
+    id: route.id
+  }
+}
+
+function filterAsyncRoutes(sourceRoutes, targetRoutes) {
+  console.log(targetRoutes.map(item => item.id))
+  const res = []
+  sourceRoutes.forEach(route => {
+    const userRoute = findRoute(route.name, targetRoutes)
+    if (userRoute) {
+      route.hidden = Boolean(userRoute.hidden)
+      route.meta = { ...route.meta, ...getMeta(userRoute) }
+      if (route.children && route.children.length > 0) {
+        route.children = filterAsyncRoutes(route.children, targetRoutes).sort((a, b) => a.meta.sort - b.meta.sort)
+      }
+      res.push(route)
+    }
+    // res.push(route)
+  })
+  return res
+}
+
+const state = {
+  routes: [],
+  addRoutes: []
+}
+const mutations = {
+  SET_ROUTES: (state, routes) => {
+    state.addRoutes = routes
+    state.routes = constantRoutes.concat(routes)
+  }
+}
+
+const actions = {
+  generateRoutes({ commit, rootGetters }) {
+    return new Promise(resolve => {
+      const accessedRoutes = filterAsyncRoutes(asyncRoutes, rootGetters.menusList)
+      commit('SET_ROUTES', accessedRoutes)
+      resolve(accessedRoutes)
+    })
+  }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}

+ 64 - 0
src/store/modules/permission1.js

@@ -0,0 +1,64 @@
+import { asyncRoutes, constantRoutes } from '@/router'
+
+/**
+ * 通过meta.role判断是否与当前用户权限匹配
+ * @param roles
+ * @param route
+ */
+function hasPermission(roles, route) {
+  if (route.meta && route.meta.roles) {
+    return roles.some(role => route.meta.roles.includes(role))
+  } else {
+    return true
+  }
+}
+
+/**
+ * 递归过滤异步路由表,返回符合用户角色权限的路由表
+ * @param routes asyncRoutes
+ * @param roles
+ */
+export function filterAsyncRoutes(routes, roles) {
+  const res = []
+
+  routes.forEach(route => {
+    const tmp = { ...route }
+    if (hasPermission(roles, tmp)) {
+      if (tmp.children) {
+        tmp.children = filterAsyncRoutes(tmp.children, roles)
+      }
+      res.push(tmp)
+    }
+  })
+
+  return res
+}
+
+const state = {
+  routes: [],
+  addRoutes: []
+}
+
+const mutations = {
+  SET_ROUTES: (state, routes) => {
+    state.addRoutes = routes
+    state.routes = constantRoutes.concat(routes)
+  }
+}
+
+const actions = {
+  generateRoutes({ commit }, roles) {
+    return new Promise(resolve => {
+      const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
+      commit('SET_ROUTES', accessedRoutes)
+      resolve(accessedRoutes)
+    })
+  }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}

+ 44 - 25
src/store/modules/user.js

@@ -1,23 +1,12 @@
-import { login } from '@/api/user'
+import { login, fetchUserInfo, fetchUserVipInfo } from '@/api/user'
 import { resetRouter } from '@/router'
 import { resetRouter } from '@/router'
 import { getToken, getUserInfo, removeToken, removeUserInfo, setToken, setUserInfo } from '@/utils/auth'
 import { getToken, getUserInfo, removeToken, removeUserInfo, setToken, setUserInfo } from '@/utils/auth'
 
 
-// 处理角色权限
-const formatRoles = userIdentity => {
-  if (userIdentity === 1) {
-    return ['admin']
-  }
-  if (userIdentity === 2) {
-    return ['normal']
-  }
-  return []
-}
-
 // 用户信息
 // 用户信息
 const state = {
 const state = {
   token: getToken(),
   token: getToken(),
+  userInfo: null,
   name: '',
   name: '',
-  roles: [],
   shopStatus: '',
   shopStatus: '',
   authUserId: '',
   authUserId: '',
   userIdentity: '',
   userIdentity: '',
@@ -26,7 +15,10 @@ const state = {
   loginAccount: '',
   loginAccount: '',
   mobile: '',
   mobile: '',
   vipStatus: '',
   vipStatus: '',
-  userInfo: null
+  roles: [],
+  menusList: [],
+  permissions: [],
+  vipInfo: {}
 }
 }
 
 
 const mutations = {
 const mutations = {
@@ -44,24 +36,31 @@ const mutations = {
     state.vipStatus = userInfo.vipStatus || ''
     state.vipStatus = userInfo.vipStatus || ''
   },
   },
   // 设置token
   // 设置token
-  SET_TOKEN: (state, playload) => {
-    state.token = playload
+  SET_TOKEN: (state, token) => {
+    state.token = token
   },
   },
   // 设置用户角色
   // 设置用户角色
-  SET_ROLES: (state, playload) => {
-    state.roles = playload
+  SET_ROLES: (state, roles) => {
+    state.roles = roles
+  },
+  // 保存菜单列表
+  SET_MENUS: (state, menus) => {
+    state.menusList = menus
+  },
+  // 保存权限列表
+  SET_PERMISSIONS: (state, permissions) => {
+    state.permissions = permissions
+  },
+  // 保存会员信息
+  SET_VIPINFO: (state, info) => {
+    state.vipInfo = info
+    console.log(state.vipInfo)
   }
   }
 }
 }
 
 
 const actions = {
 const actions = {
-  // 获取用户角色
-  getRoles({ commit, state }) {
-    const roles = formatRoles(state.userIdentity)
-    commit('SET_ROLES', roles)
-    return roles
-  },
   // 登录操作
   // 登录操作
-  login({ commit }, userInfo) {
+  login({ commit, dispatch }, userInfo) {
     const { username, password } = userInfo
     const { username, password } = userInfo
     return login({ mobileOrName: username.trim(), password: password })
     return login({ mobileOrName: username.trim(), password: password })
       .then(res => {
       .then(res => {
@@ -77,6 +76,25 @@ const actions = {
         commit('SET_ROLES', [])
         commit('SET_ROLES', [])
       })
       })
   },
   },
+
+  // 获取用户菜单列表
+  fetchUserInfo({ commit, state }) {
+    return fetchUserInfo({ authUserId: state.authUserId }).then(res => {
+      console.log(res)
+      commit('SET_ROLES', res.data.roles)
+      commit('SET_MENUS', res.data.menus)
+      commit('SET_PERMISSIONS', res.data.permissions)
+    })
+  },
+
+  // 获取用户会员信息
+  fetchUserVipInfo({ commit, state }) {
+    if (state.userIdentity === 1) return
+    fetchUserVipInfo({ authUserId: state.authUserId }).then(res => {
+      commit('SET_VIPINFO', res.data)
+    })
+  },
+
   // 退出登录
   // 退出登录
   logout({ commit }) {
   logout({ commit }) {
     removeToken()
     removeToken()
@@ -92,6 +110,7 @@ const actions = {
     commit('SET_ROLES', [])
     commit('SET_ROLES', [])
     commit('SAVE_USER_INOF', rootGetters.proxyInfo)
     commit('SAVE_USER_INOF', rootGetters.proxyInfo)
   },
   },
+
   // 代理登出
   // 代理登出
   proxyLogout({ commit }) {
   proxyLogout({ commit }) {
     commit('SET_ROLES', [])
     commit('SET_ROLES', [])

+ 1 - 1
src/views/admin/member/service.vue

@@ -18,7 +18,7 @@
 
 
     <!-- 确认 取消 -->
     <!-- 确认 取消 -->
     <div class="control-box">
     <div class="control-box">
-      <el-button type="warning">返回</el-button>
+      <el-button type="warning" @click="$_back">返回</el-button>
       <el-button type="primary" @click="updateUserMenusConfigure">保存</el-button>
       <el-button type="primary" @click="updateUserMenusConfigure">保存</el-button>
     </div>
     </div>
   </div>
   </div>

+ 1 - 1
src/views/admin/member/settings/service-edit.vue

@@ -62,7 +62,7 @@
 
 
     <!-- 确认 取消 -->
     <!-- 确认 取消 -->
     <div class="control-box">
     <div class="control-box">
-      <el-button type="warning">返回</el-button>
+      <el-button type="warning" @click="$_back">返回</el-button>
       <el-button type="primary" @click="updateVipMenusConfigure">保存</el-button>
       <el-button type="primary" @click="updateVipMenusConfigure">保存</el-button>
     </div>
     </div>
   </div>
   </div>

+ 108 - 46
src/views/admin/settings/accounts/edit.vue

@@ -1,98 +1,160 @@
 <template>
 <template>
   <div class="app-container menus-edit">
   <div class="app-container menus-edit">
-    <el-form label-width="100px">
-      <el-form-item label="用户头像:">
+    <el-form ref="userInfoFormRef" label-width="100px" :model="userInfo" :rules="rules">
+      <!-- <el-form-item label="用户头像:">
         <el-input v-show="false" v-model="user.avatar" />
         <el-input v-show="false" v-model="user.avatar" />
         <upload-image tip="建议尺寸:60 * 60px" />
         <upload-image tip="建议尺寸:60 * 60px" />
+      </el-form-item> -->
+      <el-form-item label="登录名:" prop="username">
+        <el-input v-model="userInfo.username" placeholder="登录名" />
       </el-form-item>
       </el-form-item>
-      <el-form-item label="姓名:">
-        <el-input v-model="user.username" placeholder="姓名" />
+      <el-form-item v-if="!userInfo.id" label="密码:" prop="password">
+        <el-input v-model="userInfo.password" placeholder="密码" />
       </el-form-item>
       </el-form-item>
-      <el-form-item label="登录名:">
-        <el-input v-model="user.fullName" placeholder="登录名" />
+      <el-form-item label="联系人:">
+        <el-input v-model="userInfo.linkMan" placeholder="联系人" />
       </el-form-item>
       </el-form-item>
-      <el-form-item label="密码:">
-        <el-input v-model="user.password" placeholder="密码" />
-      </el-form-item>
-      <el-form-item label="手机号:">
-        <el-input v-model="user.phone" placeholder="手机号" />
+      <el-form-item label="手机号:" prop="mobile">
+        <el-input v-model="userInfo.mobile" placeholder="手机号" />
       </el-form-item>
       </el-form-item>
       <el-form-item label="状态:">
       <el-form-item label="状态:">
-        <el-radio-group v-model="user.loginFlag">
-          <el-radio>启用</el-radio>
-          <el-radio>停用</el-radio>
+        <el-radio-group v-model="userInfo.status">
+          <el-radio :label="1">启用</el-radio>
+          <el-radio :label="0">停用</el-radio>
         </el-radio-group>
         </el-radio-group>
       </el-form-item>
       </el-form-item>
-      <el-form-item label="用户角色:">
-        <el-checkbox-group v-model="checkList">
-          <el-checkbox label="管理员" />
-          <el-checkbox label="供应商" />
-          <el-checkbox label="系统开发者" />
+      <el-form-item label="用户角色:" prop="roleList">
+        <el-checkbox-group v-model="userInfo.roleList">
+          <el-checkbox v-for="item in roleList" :key="item.id" :label="item.id">{{ item.roleName }}</el-checkbox>
         </el-checkbox-group>
         </el-checkbox-group>
       </el-form-item>
       </el-form-item>
       <el-form-item>
       <el-form-item>
         <!-- 确认 取消 -->
         <!-- 确认 取消 -->
         <div class="control-box">
         <div class="control-box">
-          <el-button type="primary">保存</el-button>
-          <el-button type="info">重置</el-button>
-          <el-button type="warning">返回</el-button>
+          <el-button type="warning" @click="$_back">返回</el-button>
+          <el-button type="primary" @click="onSubmit">保存</el-button>
         </div>
         </div>
       </el-form-item>
       </el-form-item>
     </el-form>
     </el-form>
-
   </div>
   </div>
 </template>
 </template>
 
 
 <script>
 <script>
-import UploadImage from '@/components/UploadImage'
-import { fetchRoleList } from '@/api/system'
+import { fetchRoleList, createUser, getUser, updateUser } from '@/api/system'
+import { isMobile } from '@/utils/validate'
+
 export default {
 export default {
-  components: {
-    UploadImage
-  },
   data() {
   data() {
+    // 校验角色
+    const validateRoleList = (rule, value, callback) => {
+      if (value instanceof Array) {
+        if (value.length === 0) {
+          callback(new Error('请至少选择一个角色'))
+        } else {
+          callback()
+        }
+      } else {
+        callback(new Error('角色列表为一个数组'))
+      }
+    }
+    // 校验手机号
+    const validateMobile = (rule, value, callback) => {
+      if (value && isMobile(value)) {
+        callback()
+      } else {
+        callback(new Error('请输入合法的手机号'))
+      }
+    }
     return {
     return {
-      user: {
+      editType: 'add',
+      userInfo: {
         id: 0,
         id: 0,
         username: '',
         username: '',
         password: '',
         password: '',
-        fullName: '',
-        phone: '',
-        avatar: 'https://img.caimei365.com/group1/M00/03/ED/rB-lGGHpCyKAGi-aAAAYvvHB_HE522.gif',
-        roleIds: '',
-        loginFlag: 0
+        linkMan: '',
+        mobile: '',
+        status: 1,
+        roleList: [],
+        roleIds: ''
       },
       },
-      roleIdList: [],
       roleList: [],
       roleList: [],
       rules: {
       rules: {
         username: [
         username: [
           { required: true, message: '请输入登录名', trigger: 'blur' },
           { required: true, message: '请输入登录名', trigger: 'blur' },
           { min: 2, max: 15, message: '长度在 2 到 15 个字符', trigger: 'blur' }
           { min: 2, max: 15, message: '长度在 2 到 15 个字符', trigger: 'blur' }
         ],
         ],
-        password: [
-          { required: true, message: '请输入密码', trigger: 'blur' },
-          { min: 6, max: 30, message: '长度在 6 到 30 个字符', trigger: 'blur' }
-        ],
-        fullName: [
-          { required: true, message: '请输入姓名', trigger: 'blur' },
-          { min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' }
-        ]
+        mobile: [{ validator: validateMobile, trigger: 'blur' }],
+        password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
+        roleList: [{ required: true, validator: validateRoleList, trigger: 'change' }]
       }
       }
     }
     }
   },
   },
+  created() {
+    this.editType = this.$route.query.type
+    this.fetchRoleList()
+    if (this.editType === 'edit') {
+      this.userInfo.id = this.$route.query.id
+      this.fetchUserInfo()
+    }
+  },
   methods: {
   methods: {
     // 获取角色列表
     // 获取角色列表
     fetchRoleList() {
     fetchRoleList() {
-      fetchRoleList(this.listQuery).then(res => {
-        this.list = [...this.list, ...res.data.list]
+      fetchRoleList().then(res => {
+        this.roleList = [...this.roleList, ...res.data.list]
+      })
+    },
+    // 修改保存用户信息
+    updateUserInfo() {
+      this.userInfo.roleIds = this.userInfo.roleList.join(',')
+      updateUser(this.userInfo.id, this.userInfo).then(res => {
+        this.$message.success('修改用户成功')
+        this.$store.dispatch('tagsView/delView', this.$route)
+        this.$router.back()
       })
       })
+    },
+    // 保存用户信息
+    createUserInfo() {
+      this.userInfo.roleIds = this.userInfo.roleList.join(',')
+      createUser(this.userInfo).then(res => {
+        this.$message.success('添加用户成功')
+        this.$store.dispatch('tagsView/delView', this.$route)
+        this.$router.back()
+      })
+    },
+    // 提交表单
+    onSubmit() {
+      this.$refs.userInfoFormRef.validate(valide => {
+        if (!valide) return
+        if (this.editType === 'add') {
+          this.createUserInfo()
+        } else {
+          this.updateUserInfo()
+        }
+      })
+    },
+    // 获取用户信息
+    fetchUserInfo() {
+      getUser(this.userInfo.id).then(res => {
+        this.setUserInfo(res.data)
+      })
+    },
+    // 设置用户信息
+    setUserInfo(data) {
+      console.log(data)
+      for (const key in this.userInfo) {
+        if (Object.hasOwnProperty.call(data, key)) {
+          this.userInfo[key] = data[key]
+        }
+      }
+      this.userInfo.roleList = data.roleIds.split(',').map(item => parseInt(item))
     }
     }
   }
   }
 }
 }
 </script>
 </script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">
-.menus-edit{
+.menus-edit {
   width: 600px;
   width: 600px;
   margin: 0 auto;
   margin: 0 auto;
   margin-top: 100px;
   margin-top: 100px;

+ 41 - 29
src/views/admin/settings/accounts/index.vue

@@ -1,5 +1,6 @@
 <template>
 <template>
   <div class="app-container">
   <div class="app-container">
+    <!-- 搜索区域START -->
     <div class="filter-container">
     <div class="filter-container">
       <div class="filter-control">
       <div class="filter-control">
         <span>启用状态:</span>
         <span>启用状态:</span>
@@ -17,7 +18,7 @@
         </el-select>
         </el-select>
       </div>
       </div>
       <div class="filter-control">
       <div class="filter-control">
-        <el-button type="primary" @click="$_navigationTo('accounts/add')">添加用户</el-button>
+        <el-button type="primary" @click="$_navigationTo('accounts/add?type=add')">添加用户</el-button>
       </div>
       </div>
     </div>
     </div>
     <!-- 搜索区域END -->
     <!-- 搜索区域END -->
@@ -31,28 +32,32 @@
       header-row-class-name="tableHeader"
       header-row-class-name="tableHeader"
     >
     >
       <el-table-column :index="indexMethod" label="序号" type="index" width="80" align="center" />
       <el-table-column :index="indexMethod" label="序号" type="index" width="80" align="center" />
-      <el-table-column prop="title" label="头像" align="center" width="60">
+      <!-- <el-table-column prop="title" label="头像" align="center" width="60">
         <template slot-scope="{ row }">
         <template slot-scope="{ row }">
           <img :src="row.avatar" class="avatar" alt="">
           <img :src="row.avatar" class="avatar" alt="">
         </template>
         </template>
-      </el-table-column>
-      <el-table-column prop="username" label="登录账号" align="center" />
-      <el-table-column prop="fullName" label="姓名" align="center" />
+      </el-table-column> -->
+      <el-table-column prop="username" label="登录" align="center" />
+      <el-table-column prop="linkMan" label="联系人" align="center" />
       <el-table-column label="手机号" align="center">
       <el-table-column label="手机号" align="center">
         <template slot-scope="{row}">
         <template slot-scope="{row}">
-          <span>{{ row.phone || '—' }}</span>
+          <span>{{ row.mobile || '—' }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="角色描述" align="center">
+        <template slot-scope="{ row }">
+          <span>{{ row.roleDesc || '—' }}</span>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-      <el-table-column prop="roleDesc" label="角色描述" align="center" />
       <el-table-column label="启用状态" align="center" width="100">
       <el-table-column label="启用状态" align="center" width="100">
         <template slot-scope="{ row }">
         <template slot-scope="{ row }">
-          <el-switch v-model="row.loginFlag" :active-value="1" :inactive-value="0" />
+          <el-switch v-model="row.status" :active-value="1" :inactive-value="0" />
         </template>
         </template>
       </el-table-column>
       </el-table-column>
       <el-table-column label="操作" align="center" width="200">
       <el-table-column label="操作" align="center" width="200">
-        <template>
-          <el-button type="primary" size="mini" @click="$_navigationTo('accounts/edit')">编辑</el-button>
-          <el-button type="danger" size="mini">删除</el-button>
+        <template slot-scope="{ row }">
+          <el-button type="primary" size="mini" :disabled="!row.id" @click="$_navigationTo(`accounts/edit?type=edit&id=${row.id}`)">编辑</el-button>
+          <el-button type="danger" size="mini" :disabled="!row.id" @click="removeUser(row)">删除</el-button>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
     </el-table>
     </el-table>
@@ -60,6 +65,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { fetchUserList, deleteUser } from '@/api/system'
 export default {
 export default {
   data() {
   data() {
     return {
     return {
@@ -69,30 +75,36 @@ export default {
         pageSize: 10,
         pageSize: 10,
         pageNum: 1
         pageNum: 1
       },
       },
-      list: [{
-        avatar: 'https://img.caimei365.com/group1/M00/03/ED/rB-lGGHpCyKAGi-aAAAYvvHB_HE522.gif',
-        createTime: '2021-12-27 16:48:21',
-        delFlag: 0,
-        fullName: '系统管理员',
-        id: 1,
-        loginFlag: 1,
-        menus: null,
-        password: null,
-        permissions: null,
-        phone: '',
-        roleDesc: '管理员 ',
-        roleIds: '1',
-        roles: ['admin'],
-        updateTime: '2022-02-07 04:00:50',
-        username: 'sysadmin'
-      }]
+      list: []
     }
     }
   },
   },
+  created() {
+    this.getList()
+  },
   methods: {
   methods: {
     indexMethod(index) {
     indexMethod(index) {
       return index + this.listQuery.pageSize * (this.listQuery.pageNum - 1) + 1
       return index + this.listQuery.pageSize * (this.listQuery.pageNum - 1) + 1
     },
     },
-    getList() {}
+    // 获取列表
+    getList() {
+      this.listQuery.pageNum = 1
+      this.list = []
+      this.fetchUserList()
+    },
+    // 获取用户列表
+    fetchUserList() {
+      fetchUserList(this.listQuery).then(res => {
+        console.log(res)
+        this.list = [...this.list, ...res.data.list]
+      })
+    },
+    // 删除用户
+    removeUser(row) {
+      deleteUser(row.id).then(res => {
+        this.$message.success('删除用户成功')
+        this.getList()
+      })
+    }
   }
   }
 }
 }
 </script>
 </script>

+ 14 - 1
src/views/admin/settings/menus/components/table-list.vue

@@ -57,10 +57,11 @@
       </el-table-column>
       </el-table-column>
       <el-table-column label="操作" align="center" width="200">
       <el-table-column label="操作" align="center" width="200">
         <template slot-scope="{ row }">
         <template slot-scope="{ row }">
+
           <el-button
           <el-button
             type="primary"
             type="primary"
             size="mini"
             size="mini"
-            @click="$_navigationTo(`/settings/menus/edit?id=${row.id}&type=edit`)"
+            @click="handleEditMenu(row)"
           >编辑</el-button>
           >编辑</el-button>
           <el-button type="danger" size="mini" @click="deleteMenu(row)">删除</el-button>
           <el-button type="danger" size="mini" @click="deleteMenu(row)">删除</el-button>
         </template>
         </template>
@@ -141,6 +142,18 @@ export default {
       this.listQuery.parentId = row.id
       this.listQuery.parentId = row.id
       this.$router.replace(`/settings/menus/children/${this.menuType}/${row.id}/${row.title}`)
       this.$router.replace(`/settings/menus/children/${this.menuType}/${row.id}/${row.title}`)
     },
     },
+    // 修改菜单
+    handleEditMenu(row) {
+      // $_navigationTo(`/settings/menus/edit?id=${row.id}&type=edit`)
+      this.$router.push({
+        path: '/settings/menus/edit',
+        query: {
+          id: row.id,
+          type: 'edit',
+          menuType: this.menuType
+        }
+      })
+    },
     // 获取列表
     // 获取列表
     getList() {
     getList() {
       this.listQuery.pageNum = 1
       this.listQuery.pageNum = 1

+ 4 - 3
src/views/admin/settings/menus/edit.vue

@@ -23,7 +23,7 @@
           <svg-icon v-else-if="menuData.icon" :icon-class="menuData.icon" />
           <svg-icon v-else-if="menuData.icon" :icon-class="menuData.icon" />
         </template>
         </template>
       </el-form-item>
       </el-form-item>
-      <template v-if="!parentMenuData">
+      <template v-if="!parentMenuData && menuType!== 1">
         <el-form-item label="功能类型:" prop="baseFlag">
         <el-form-item label="功能类型:" prop="baseFlag">
           <el-radio-group v-model="menuData.baseFlag">
           <el-radio-group v-model="menuData.baseFlag">
             <el-radio :label="1">基础功能</el-radio>
             <el-radio :label="1">基础功能</el-radio>
@@ -75,9 +75,8 @@
       <el-form-item>
       <el-form-item>
         <!-- 确认 取消 -->
         <!-- 确认 取消 -->
         <div class="control-box">
         <div class="control-box">
+          <el-button type="warning" @click="$_back">返回</el-button>
           <el-button type="primary" @click="submit">保存</el-button>
           <el-button type="primary" @click="submit">保存</el-button>
-          <el-button type="info">重置</el-button>
-          <el-button type="warning">返回</el-button>
         </div>
         </div>
       </el-form-item>
       </el-form-item>
     </el-form>
     </el-form>
@@ -92,6 +91,7 @@ export default {
     return {
     return {
       // 编辑类型
       // 编辑类型
       editType: 'add',
       editType: 'add',
+      menuType: '',
       // 上级菜单信息
       // 上级菜单信息
       parentMenuData: null,
       parentMenuData: null,
       // 表单参数
       // 表单参数
@@ -135,6 +135,7 @@ export default {
   },
   },
   methods: {
   methods: {
     init() {
     init() {
+      this.menuType = parseInt(this.$route.query.menuType)
       // 编辑修改菜单
       // 编辑修改菜单
       if (this.editType === 'edit') {
       if (this.editType === 'edit') {
         this.menuData.id = parseInt(this.$route.query.id)
         this.menuData.id = parseInt(this.$route.query.id)

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

@@ -23,9 +23,8 @@
       <el-form-item>
       <el-form-item>
         <!-- 确认 取消 -->
         <!-- 确认 取消 -->
         <div class="control-box">
         <div class="control-box">
+          <el-button type="warning" @click="$_back">返回</el-button>
           <el-button type="primary" @click="handleSubmit">保存</el-button>
           <el-button type="primary" @click="handleSubmit">保存</el-button>
-          <el-button type="info">重置</el-button>
-          <el-button type="warning">返回</el-button>
         </div>
         </div>
       </el-form-item>
       </el-form-item>
     </el-form>
     </el-form>
@@ -84,6 +83,7 @@ export default {
           this.role[key] = data[key]
           this.role[key] = data[key]
         }
         }
       }
       }
+      console.log(this.role.menuIds.split(','))
       this.$refs.tree.setCheckedKeys([...this.role.menuIds.split(',')])
       this.$refs.tree.setCheckedKeys([...this.role.menuIds.split(',')])
     },
     },
     // 获取角色信息
     // 获取角色信息