guhongwei 4 年之前
父节点
当前提交
f231b2b76d

+ 9 - 2
src/components/common/Header.vue

@@ -5,7 +5,7 @@
       <i v-if="!collapse" class="el-icon-s-fold"></i>
       <i v-else class="el-icon-s-unfold"></i>
     </div>
-    <div class="logo">网站中台</div>
+    <div class="logo">用户权限管理系统</div>
     <div class="header-right">
       <div class="header-user-con">
         <!-- 全屏显示 -->
@@ -21,7 +21,7 @@
         <!-- 用户名下拉菜单 -->
         <el-dropdown class="user-name" trigger="click" @command="handleCommand">
           <span class="el-dropdown-link">
-            {{ user.name }}
+            {{ userInfo.name || '游客' }}
             <i class="el-icon-caret-bottom"></i>
           </span>
           <el-dropdown-menu slot="dropdown">
@@ -40,8 +40,14 @@ export default {
     return {
       collapse: false,
       fullscreen: false,
+      userInfo: {},
     };
   },
+  created() {
+    if (this.user) {
+      this.$set(this, `userInfo`, this.user);
+    }
+  },
   computed: {
     ...mapState(['user']),
   },
@@ -50,6 +56,7 @@ export default {
     handleCommand(command) {
       if (command == 'loginout') {
         localStorage.removeItem('user');
+        localStorage.removeItem('token');
         this.$router.push('/login');
       }
     },

+ 13 - 21
src/components/common/Sidebar.vue

@@ -41,32 +41,16 @@
 import _ from 'lodash';
 import { mapState, createNamespacedHelpers } from 'vuex';
 import bus from '../common/bus';
+const { mapActions: role } = createNamespacedHelpers('role');
 export default {
   data() {
     return {
       collapse: false,
       items: [
         {
-          icon: 'el-icon-s-home',
           index: 'homeIndex',
           title: '系统首页',
         },
-        {
-          icon: 'el-icon-s-home',
-          index: 'test',
-          title: '测试菜单',
-        },
-        // {
-        //   icon: 'el-icon-s-home',
-        //   index: '1',
-        //   title: '测试菜单',
-        //   subs: [
-        //     {
-        //       index: 'test',
-        //       title: '测试菜单',
-        //     },
-        //   ],
-        // },
       ],
     };
   },
@@ -84,15 +68,23 @@ export default {
     });
   },
   methods: {
+    ...role({ roleQuery: 'query' }),
     // 分配用户彩带权限
-    getMenu() {
+    async getMenu() {
       // 客户信息
       let user = this.user;
       // 复制列表
       let list = _.cloneDeep(this.items);
-      let data = [];
-      list.push(...data);
-      this.$set(this, `items`, _.uniqBy(list, 'index'));
+      if (user.role == '0') {
+        let res = await this.roleQuery();
+        if (this.$checkRes(res)) {
+          let newres = res.data.map(item => ({ title: item.role_name, index: item.url })).reverse();
+          list.push(...newres);
+          this.$set(this, `items`, _.uniqBy(list, 'index'));
+        }
+      } else {
+        console.log('机构用户');
+      }
     },
   },
   watch: {

+ 28 - 3
src/router/index.js

@@ -21,9 +21,34 @@ export default new Router({
           meta: { title: '系统首页' },
         },
         {
-          path: '/test',
-          component: () => import('../views/test/index.vue'),
-          meta: { title: '测试菜单' },
+          path: '/role',
+          component: () => import('../views/role/index.vue'),
+          meta: { title: '菜单管理' },
+        },
+        {
+          path: '/permission',
+          component: () => import('../views/permission/index.vue'),
+          meta: { title: '权限管理' },
+        },
+        {
+          path: '/adminUser',
+          component: () => import('../views/adminUser/index.vue'),
+          meta: { title: '机构管理员' },
+        },
+        {
+          path: '/business',
+          component: () => import('../views/business/index.vue'),
+          meta: { title: '业务管理员' },
+        },
+        {
+          path: '/vip',
+          component: () => import('../views/vip/index.vue'),
+          meta: { title: 'VIP用户' },
+        },
+        {
+          path: '/user',
+          component: () => import('../views/user/index.vue'),
+          meta: { title: '用户管理' },
         },
       ],
     },

+ 11 - 5
src/store/index.js

@@ -2,9 +2,10 @@ import Vue from 'vue';
 import Vuex from 'vuex';
 import * as ustate from './user/state';
 import * as umutations from './user/mutations';
-import login from './login';
-import repair from './repair';
-import car from './car';
+import login from './user/login';
+import role from './user/role';
+import marketuser from './user/marketuser';
+import authUser from './user/auth-user';
 
 Vue.use(Vuex);
 
@@ -13,8 +14,13 @@ export default new Vuex.Store({
   mutations: { ...umutations },
   actions: {},
   modules: {
+    // 登录
     login,
-    repair,
-    car,
+    // 菜单
+    role,
+    // 用户
+    marketuser,
+    // 权限用户
+    authUser,
   },
 });

+ 0 - 47
src/store/login.js

@@ -1,47 +0,0 @@
-import Vue from 'vue';
-import Vuex from 'vuex';
-import _ from 'lodash';
-Vue.use(Vuex);
-const api = {
-  loginInfo: `/api/jh/v1/login`,
-};
-const state = () => ({});
-const mutations = {};
-
-const actions = {
-  async query({ commit }, { skip = 0, limit, ...info } = {}) {
-    const res = await this.$axios.$get(`${api.loginInfo}`, {
-      skip,
-      limit,
-      ...info,
-    });
-    return res;
-  },
-  async login({ commit }, { user }) {
-    const res = await this.$axios.$post(`${api.loginInfo}`, user);
-    if (res.errcode === 0) {
-      localStorage.setItem('user', JSON.stringify(res.data));
-      commit('setUser', res.data, { root: true });
-    }
-    return res;
-  },
-  async fetch({ commit }, payload) {
-    const res = await this.$axios.$get(`${api.loginInfo}/${payload}`);
-    return res;
-  },
-  async update({ commit }, { id, ...data }) {
-    const res = await this.$axios.$post(`${api.loginInfo}/${id}`, data);
-    return res;
-  },
-
-  async delete({ commit }, payload) {
-    const res = await this.$axios.$delete(`${api.loginInfo}/${payload}`);
-    return res;
-  },
-};
-export default {
-  namespaced: true,
-  state,
-  mutations,
-  actions,
-};

+ 0 - 54
src/store/repair.js

@@ -1,54 +0,0 @@
-//第一步
-import Vue from 'vue';
-import Vuex from 'vuex';
-import _ from 'lodash';
-Vue.use(Vuex);
-const api = {
-  //接口地址
-  repair: `/api/servicetest/repair`,
-};
-const state = () => ({});
-const mutations = {};
-
-const actions = {
-  //查询列表 skip:第一页,limit:第一页显示的数据,info:其余查询参数
-  async query({ commit }, { skip = 0, limit, ...info } = {}) {
-    //连接接口。。。。
-    const res = await this.$axios.$get(`${api.repair}`, {
-      skip,
-      limit,
-      ...info,
-    });
-    //把数据集合res返回
-    return res;
-  },
-  //创建数据  payload是添加form表单中的数据集合  创建数据的时候需要拿到form表单里面的数据
-  async create({ commit }, payload) {
-    //通过$axios提交post请求????
-    const res = await this.$axios.$post(`${api.repair}`, payload);
-    return res;
-  },
-  //查询详情,payload:参数位,一般传当前数据id
-  async fetch({ commit }, payload) {
-    //有/一般都是路径
-    const res = await this.$axios.$get(`${api.repair}/${payload}`);
-    return res;
-  },
-  //修改:id: 当前数据id, data: 当前修改数据的新form表单
-  async update({ commit }, { id, ...data }) {
-    const res = await this.$axios.$post(`${api.repair}/update/${id}`, data);
-    return res;
-  },
-  //删除:payload:参数位,一般传当前数据id
-  async delete({ commit }, payload) {
-    const res = await this.$axios.$delete(`${api.repair}/${payload}`);
-    return res;
-  },
-};
-
-export default {
-  namespaced: true,
-  state,
-  mutations,
-  actions,
-};

+ 49 - 0
src/store/user/auth-user.js

@@ -0,0 +1,49 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+//用户的菜单选项增删改查
+Vue.use(Vuex);
+const api = {
+  interface: `/api/userjurisform/user`,
+  getMenu: `/api/userjurisform/user/menus`,
+  getBusinessUser: `/api/userjurisform/businessuser`, //pid,skip,limit
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit = undefined, ...info } = {}) {
+    const res = await this.$axios.$get(api.interface, { skip, limit, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.interface}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    //特殊变化,查用户菜单
+    const res = await this.$axios.$get(`${api.getMenu}`, payload);
+    return res;
+  },
+  async update({ commit }, { id, ...info } = {}) {
+    const res = await this.$axios.$post(`${api.interface}/update/${id}`, {
+      ...info,
+    });
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.interface}/${payload}`);
+    return res;
+  },
+  async getBusinessUser({ commit }, { skip = 0, limit = 10, ...info } = {}) {
+    const res = await this.$axios.$get(api.getBusinessUser, { skip, limit, ...info });
+    return res;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 119 - 0
src/store/user/login.js

@@ -0,0 +1,119 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import axios from 'axios';
+import _ from 'lodash';
+import { Notification } from 'element-ui';
+const jwt = require('jsonwebtoken');
+Vue.use(Vuex);
+const api = {
+  interface: `/api/userjurisform/login`,
+  getUser: `/api/userjurisform/token`,
+  logout: '/api/userjurisform/logout',
+  getMenu: `/api/userjurisform/user/menus`,
+  updatePassword: '/api/userjurisform/pwd_edit',
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  /**
+    user:Object required 登陆信息 
+    router:router 如果跳转就传
+    path:String 跳转到的路由位置
+    needReturn: Boolean 是否返回结果
+    typeCheck: Boolean 是否检查身份对应匹配的前端项目
+    isWx: Boolean 是否是微信登陆
+    needNotice:Boolean 是否需要提示
+   */
+  async login({ commit, dispatch }, { user, router, path = '/', needReturn = false, typeCheck = false, isWx = false, needNotice = true }) {
+    let res = await this.$axios.$post(`${api.interface}`, user);
+    const setUser = async (token, commit) => {
+      localStorage.setItem('token', token);
+      let userInfo = await dispatch('toGetUser');
+      return userInfo;
+    };
+    let userInfo = {};
+    if (res.errcode == '0') {
+      userInfo = await setUser(res.data.key, commit);
+      Notification({
+        title: '登录成功',
+        // message: `欢迎,${user.user_name}`,
+        type: 'success',
+        duration: 2000,
+        offset: 50,
+      });
+      return userInfo;
+    } else {
+      if (needReturn) return res;
+      else {
+        Notification({
+          title: '登录失败',
+          message: `失败原因:${res.errmsg || '登陆失败'}`,
+          type: 'error',
+        });
+      }
+    }
+  },
+  async toGetUser({ commit }, payload) {
+    let key = localStorage.getItem('token');
+    if (!key) {
+      if (_.isFunction(payload)) {
+        payload();
+        return;
+      }
+    }
+    let res = await axios.post(api.getUser, { key: key });
+    let user = {};
+    if (res.data.errcode == '0') {
+      let token = _.get(res, `data.data.token`);
+      if (token) {
+        user = jwt.decode(token);
+        localStorage.setItem('user', JSON.stringify(user));
+        commit('setUser', user, { root: true });
+      }
+    }
+    return user;
+  },
+  async toGetMenu({ commit }, payload) {
+    const res = await this.$axios.$get(api.getMenu, payload);
+    return res;
+  },
+  async logout({ commit }, payload) {
+    window.localStorage.removeItem('user');
+    let key = localStorage.removeItem('token');
+    const res = await this.$axios.$post(api.logout, { key: key });
+
+    commit('deleteUser');
+  },
+  async update({ commit }, payload) {
+    let res = await this.$axios.$post(`${api.updatePassword}`, {
+      data: payload,
+    });
+    return res;
+  },
+  async bind({ commit }, payload) {
+    let res = await this.$axios.$post(`${api.bind}`, payload);
+    return res;
+  },
+  async userBind({ commit }, payload) {
+    let res = await this.$axios.$post(`${api.userBind}`, payload);
+    return res;
+  },
+  async getQrcode({ commit }, payload) {
+    let res = await this.$axios.$get(`${api.connection}`);
+    if (res.errcode === 0) return res.data;
+    else {
+      console.warn('请求qrcode失败');
+    }
+  },
+  async wxCheck({ commit }, payload) {
+    let res = await this.$axios.$post(`${api.wxCheck}`, payload);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 49 - 0
src/store/user/marketuser.js

@@ -0,0 +1,49 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  interface: `/api/userjurisform/marketuser`,
+  userinterface: `/api/userjurisform/marketuser/hwsxg`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit = undefined, isdel = '0', ...info } = {}) {
+    const res = await this.$axios.$get(api.interface, { skip, limit, isdel, ...info });
+    return res;
+  },
+  async userquery({ commit }, { skip = 0, limit = undefined, isdel = '0', ...info } = {}) {
+    const res = await this.$axios.$get(api.userinterface, {
+      skip,
+      limit,
+      isdel,
+      ...info,
+    });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.interface}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.interface}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...info } = {}) {
+    const res = await this.$axios.$post(`${api.interface}/${id}`, { ...info });
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.interface}/${payload}`);
+    return res;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 3 - 25
src/store/user/mutations.js

@@ -1,30 +1,8 @@
+const jwt = require('jsonwebtoken');
 export const setUser = (state, payload) => {
   state.user = payload;
-  // let res = true;
-  // //登陆时
-  // if (payload) {
-  //   state.token = payload;
-  // } else {
-  //   //已经登陆,切换路由时取出客户信息放在总store中
-  //   let token = localStorage.getItem('token');
-  //   if (token && token !== 'guest') {
-  //     state.user = jwt.decode(token);
-  //   } else if (token && token == 'guest') {
-  //     let user = localStorage.getItem('user');
-  //     state.user = JSON.parse(user);
-  //   } else {
-  //     let timestamp = new Date().getTime();
-  //     let user = {
-  //       // id: `guest${timestamp}`,
-  //       name: `游客${timestamp}`,
-  //     };
-  //     state.user = user;
-  //     localStorage.setItem('token', 'guest');
-  //     localStorage.setItem('user', JSON.stringify(user));
-  //     console.warn('游客身份');
-  //   }
-  // }
-  // return res;
+  let res = true;
+  return res;
 };
 
 export const deleteUser = (state, payload) => {

+ 40 - 0
src/store/user/role.js

@@ -0,0 +1,40 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+//用户的菜单选项增删改查
+Vue.use(Vuex);
+const api = {
+  interface: `/api/userjurisform/role`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit = undefined, ...info } = {}) {
+    const res = await this.$axios.$get(api.interface, { skip, limit, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.interface}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.interface}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...info } = {}) {
+    const res = await this.$axios.$post(`${api.interface}/update/${id}`, { ...info });
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.interface}/${payload}`);
+    return res;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 126 - 0
src/views/Login copy.vue

@@ -0,0 +1,126 @@
+<template>
+  <div id="login">
+    <el-row>
+      <el-col :span="24">
+        <el-row>
+          <el-col :span="24" class="main">
+            <div class="w_1200">
+              <el-col :span="24" class="login">
+                <div class="ms-title">后台管理系统</div>
+                <el-form :model="form" :rules="rules" ref="login" label-width="0px" class="ms-content">
+                  <el-form-item prop="username">
+                    <el-input v-model="form.tel" placeholder="请输入手机号">
+                      <el-button slot="prepend" icon="el-icon-user"></el-button>
+                    </el-input>
+                  </el-form-item>
+                  <el-form-item prop="password">
+                    <el-input type="password" placeholder="请输入密码" v-model="form.pwd">
+                      <el-button slot="prepend" icon="el-icon-lock"></el-button>
+                    </el-input>
+                  </el-form-item>
+                  <div class="login-btn">
+                    <el-button type="primary" @click="submitForm()">登录</el-button>
+                  </div>
+                </el-form>
+              </el-col>
+            </div>
+          </el-col>
+        </el-row>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: login } = createNamespacedHelpers('login');
+export default {
+  metaInfo: { title: '登录' },
+  name: 'login',
+  props: {},
+  components: {},
+  data: function() {
+    return {
+      form: {},
+      rules: {
+        tel: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
+        pwd: [{ required: true, message: '请输入密码', trigger: 'blur' }],
+      },
+    };
+  },
+  created() {},
+  methods: {
+    ...login(['login']),
+    submitForm() {
+      this.$refs.login.validate(async valid => {
+        if (valid) {
+          // let res = await this.login({ user: this.form });
+          // if (this.$checkRes(res)) {
+          localStorage.setItem('user', JSON.stringify(this.form));
+          this.$message.success('登录成功');
+          this.$router.push('/homeIndex');
+          // }
+        } else {
+          this.$message.error('请输入账号和密码');
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+  },
+  computed: {},
+};
+</script>
+
+<style lang="less" scoped>
+.w_1200 {
+  width: 1200px;
+  margin: 0 auto;
+}
+.main {
+  background-image: url(../assets/img/login-bg.jpg);
+  height: 100vh;
+  background-repeat: no-repeat;
+  background-size: cover;
+  .login {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    width: 350px;
+    margin: -190px 0 0 -175px;
+    border-radius: 5px;
+    background: hsla(0, 0%, 100%, 0.3);
+    overflow: hidden;
+    .ms-title {
+      width: 100%;
+      line-height: 50px;
+      text-align: center;
+      font-size: 20px;
+      color: #fff;
+      border-bottom: 1px solid #ddd;
+    }
+    .ms-content {
+      padding: 30px 30px;
+    }
+    .login-btn {
+      text-align: center;
+    }
+    .login-btn button {
+      width: 100%;
+      height: 36px;
+      margin-bottom: 10px;
+    }
+    .login-tips {
+      font-size: 12px;
+      line-height: 30px;
+      color: #fff;
+    }
+    /deep/.js .el-form-item__content {
+      padding: 0 25px;
+      .el-radio {
+        color: #fff;
+      }
+    }
+  }
+}
+</style>

+ 140 - 82
src/views/Login.vue

@@ -1,31 +1,62 @@
 <template>
-  <div id="login">
+  <div id="Login">
     <el-row>
-      <el-col :span="24">
-        <el-row>
-          <el-col :span="24" class="main">
-            <div class="w_1200">
-              <el-col :span="24" class="login">
-                <div class="ms-title">后台管理系统</div>
-                <el-form :model="form" :rules="rules" ref="login" label-width="0px" class="ms-content">
-                  <el-form-item prop="username">
-                    <el-input v-model="form.tel" placeholder="请输入手机号">
-                      <el-button slot="prepend" icon="el-icon-user"></el-button>
-                    </el-input>
-                  </el-form-item>
-                  <el-form-item prop="password">
-                    <el-input type="password" placeholder="请输入密码" v-model="form.pwd">
-                      <el-button slot="prepend" icon="el-icon-lock"></el-button>
-                    </el-input>
-                  </el-form-item>
-                  <div class="login-btn">
-                    <el-button type="primary" @click="submitForm()">登录</el-button>
-                  </div>
-                </el-form>
+      <el-col :span="24" class="main">
+        <div class="w_1200">
+          <el-col :span="24" class="info">
+            <el-col :span="24" class="login">
+              <el-col :span="24" class="top">
+                用户权限管理系统
               </el-col>
-            </div>
+              <el-tabs v-model="activeName" class="tabs">
+                <el-tab-pane label="平台用户" name="first">
+                  <el-col :span="24" class="one">
+                    <el-form ref="form" :model="form" :rules="rule" label-width="100px">
+                      <el-form-item label="用户名" prop="phone">
+                        <el-input type="phone" v-model="form.phone" autocomplete="off" placeholder="请输入手机号/统一社会信用代码"></el-input>
+                      </el-form-item>
+                      <el-form-item label="登录密码" prop="passwd">
+                        <el-input v-model="form.passwd" placeholder="请输入登录密码" show-password></el-input>
+                      </el-form-item>
+                      <el-form-item label="用户类别" prop="role">
+                        <el-radio-group v-model="form.role">
+                          <el-radio label="4">个人用户</el-radio>
+                          <el-radio label="5">机构用户</el-radio>
+                          <el-radio label="6">专家用户</el-radio>
+                          <el-radio label="2">VIP用户</el-radio>
+                        </el-radio-group>
+                      </el-form-item>
+                      <el-col :span="24" class="userSubmit">
+                        <el-button type="primary" @click="userSubmit">登录</el-button>
+                      </el-col>
+                    </el-form>
+                  </el-col>
+                </el-tab-pane>
+                <el-tab-pane label="管理登录" name="second">
+                  <el-col :span="24" class="two">
+                    <el-form ref="adminform" :model="adminform" :rules="adminRules" label-width="130px">
+                      <el-form-item label="手机号&机构代码" prop="phone">
+                        <el-input v-model="adminform.phone" placeholder="请输入手机号&机构代码"></el-input>
+                      </el-form-item>
+                      <el-form-item label="登录密码" prop="passwd">
+                        <el-input v-model="adminform.passwd" placeholder="请输入登录密码" show-password></el-input>
+                      </el-form-item>
+                      <el-form-item label="用户类别" prop="role">
+                        <el-radio v-model="adminform.role" label="1">合作机构&业务管理员</el-radio>
+                      </el-form-item>
+                      <el-col :span="24" class="adminSubmit">
+                        <el-button type="primary" @click="adminSubmit">登录</el-button>
+                      </el-col>
+                    </el-form>
+                  </el-col>
+                </el-tab-pane>
+              </el-tabs>
+              <el-col :span="24" class="btn">
+                <el-button type="primary" size="mini">去注册</el-button>
+              </el-col>
+            </el-col>
           </el-col>
-        </el-row>
+        </div>
       </el-col>
     </el-row>
   </div>
@@ -35,40 +66,55 @@
 import { mapState, createNamespacedHelpers } from 'vuex';
 const { mapActions: login } = createNamespacedHelpers('login');
 export default {
-  metaInfo: { title: '登录' },
-  name: 'login',
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  name: 'Login',
   props: {},
   components: {},
   data: function() {
     return {
+      activeName: 'first',
+      // 平台用户登录
       form: {},
-      rules: {
-        tel: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
-        pwd: [{ required: true, message: '请输入密码', trigger: 'blur' }],
+      rule: {
+        phone: [{ required: true, message: '请输入手机号/统一社会信用代码', trigger: 'blur' }],
+        passwd: [{ required: true, message: '请输入登录密码', trigger: 'blur' }],
+        role: [{ type: 'array', required: true, message: '请至少选择一个用户类别', trigger: 'change' }],
+      },
+      // 管理用户登录
+      adminform: {},
+      adminRules: {
+        phone: [{ required: true, message: '请输入手机号/统一社会信用代码', trigger: 'blur' }],
+        passwd: [{ required: true, message: '请输入登录密码', trigger: 'blur' }],
+        role: [{ type: 'array', required: true, message: '请至少选择一个用户类别', trigger: 'change' }],
       },
     };
   },
   created() {},
   methods: {
     ...login(['login']),
-    submitForm() {
-      this.$refs.login.validate(async valid => {
-        if (valid) {
-          // let res = await this.login({ user: this.form });
-          // if (this.$checkRes(res)) {
-          localStorage.setItem('user', JSON.stringify(this.form));
-          this.$message.success('登录成功');
-          this.$router.push('/homeIndex');
-          // }
-        } else {
-          this.$message.error('请输入账号和密码');
-          console.log('error submit!!');
-          return false;
-        }
-      });
+    userSubmit() {
+      let data = this.form;
+      localStorage.setItem('user', JSON.stringify(data));
+      this.$message.success('登录成功');
+      this.$router.push('/homeIndex');
+    },
+    async adminSubmit() {
+      let data = this.adminform;
+      if (data.role == null) {
+        data.role = '0';
+      }
+      let res = await this.login({ user: data });
+      if (res.uid) {
+        this.$router.push('/homeIndex');
+      }
     },
   },
-  computed: {},
+  computed: {
+    ...mapState(['user']),
+  },
+  watch: {},
 };
 </script>
 
@@ -82,43 +128,55 @@ export default {
   height: 100vh;
   background-repeat: no-repeat;
   background-size: cover;
-  .login {
-    position: absolute;
-    left: 50%;
-    top: 50%;
-    width: 350px;
-    margin: -190px 0 0 -175px;
-    border-radius: 5px;
-    background: hsla(0, 0%, 100%, 0.3);
-    overflow: hidden;
-    .ms-title {
-      width: 100%;
-      line-height: 50px;
-      text-align: center;
-      font-size: 20px;
-      color: #fff;
-      border-bottom: 1px solid #ddd;
-    }
-    .ms-content {
-      padding: 30px 30px;
-    }
-    .login-btn {
-      text-align: center;
-    }
-    .login-btn button {
-      width: 100%;
-      height: 36px;
-      margin-bottom: 10px;
-    }
-    .login-tips {
-      font-size: 12px;
-      line-height: 30px;
-      color: #fff;
-    }
-    /deep/.js .el-form-item__content {
-      padding: 0 25px;
-      .el-radio {
-        color: #fff;
+  .info {
+    padding: 15% 25% 0 25%;
+    .login {
+      height: 500px;
+      background-color: #ffffff9f;
+      border-radius: 10px;
+      .top {
+        height: 50px;
+        line-height: 50px;
+        text-align: center;
+        font-size: 20px;
+        font-weight: bold;
+      }
+      .tabs {
+        height: 400px;
+        overflow: hidden;
+        border-bottom: 1px dashed #000;
+        padding: 0 5%;
+        /deep/.el-tabs__nav {
+          width: 100%;
+          text-align: center;
+        }
+        /deep/.el-tabs__active-bar {
+          left: 33%;
+        }
+        /deep/.el-tabs__item {
+          height: 50px;
+          line-height: 50px;
+          font-size: 18px;
+          font-weight: bold;
+        }
+        .one {
+          padding: 10% 0;
+          .userSubmit {
+            text-align: center;
+          }
+        }
+        .two {
+          padding: 10% 0;
+          .adminSubmit {
+            text-align: center;
+          }
+        }
+      }
+      .btn {
+        text-align: right;
+        height: 50px;
+        line-height: 50px;
+        padding: 0 10px;
       }
     }
   }

+ 143 - 0
src/views/adminUser/index.vue

@@ -0,0 +1,143 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="main">
+        <breadcrumb :breadcrumbTitle="this.$route.meta.title"></breadcrumb>
+        <el-col :span="24" class="container info">
+          <el-col :span="24" class="top">
+            <el-button type="primary" size="mini" @click="dialog = true">添加</el-button>
+          </el-col>
+          <el-col :span="24" class="list">
+            <data-table :fields="fields" :opera="opera" :data="list" :total="total" @edit="toEdit" @delete="toDelete" @query="search"></data-table>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+    <el-dialog :visible.sync="dialog" title="增加机构管理员" @close="toClose" :destroy-on-close="true" width="50%">
+      <data-form :data="form" :fields="formFields" :rules="rules" @save="turnSave"> </data-form>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import breadcrumb from '@c/common/breadcrumb.vue';
+import dataTable from '@/components/frame/filter-page-table.vue';
+import dataForm from '@/components/frame/form.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: marketuser } = createNamespacedHelpers('marketuser');
+const { mapActions: authUser } = createNamespacedHelpers('authUser');
+export default {
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  name: 'index',
+  props: {},
+  components: {
+    breadcrumb,
+    dataTable,
+    dataForm,
+  },
+  data: function() {
+    return {
+      opera: [
+        {
+          label: '修改',
+          icon: 'el-icon-edit',
+          method: 'edit',
+        },
+        {
+          label: '删除',
+          icon: 'el-icon-delete',
+          method: 'delete',
+        },
+      ],
+      fields: [
+        { label: '机构代码或邀请码', prop: 'code' },
+        { label: '用户名', prop: 'name' },
+        { label: '机构名称', prop: 'deptname' },
+        { label: '电话', prop: 'phone' },
+      ],
+      list: [],
+      total: 0,
+      // 增加菜单
+      dialog: false,
+      formFields: [
+        { label: '机构代码或邀请码', model: 'code' },
+        { label: '姓名', model: 'name' },
+        { label: '机构名称', model: 'deptname' },
+        { label: '手机号', model: 'phone', options: { maxLength: 11, minLength: 11, type: 'number' } },
+        { label: '密码', model: 'password', type: 'password' },
+      ],
+      form: {},
+      rules: {
+        code: [{ required: true, message: '请输入推荐码' }],
+      },
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    ...marketuser(['query', 'fetch', 'create', 'update', 'delete']),
+    ...authUser({ authUserDelete: 'delete', getAdminUser: 'query' }),
+    // 查询列表
+    async search({ skip = 0, limit = 10, ...info } = {}) {
+      const res = await this.getAdminUser({ skip, limit, pid: this.user.uid, isdel: '0', ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+        this.$set(this, `total`, res.total);
+      }
+    },
+    // 修改
+    toEdit({ data }) {
+      this.$set(this, 'form', data);
+      this.dialog = true;
+    },
+    // 删除
+    async toDelete({ data }) {
+      const arr = await this.authUserDelete(data.id);
+      const res = await this.delete(data.uid);
+      if (this.$checkRes(arr, '删除成功', res.errmsg || '删除失败')) this.search();
+    },
+    // 增加菜单
+    // 保存
+    async turnSave({ data }) {
+      let res;
+      let msg;
+      if (data.id) {
+        res = await this.update(data);
+        msg = '修改成功';
+      } else {
+        data.pid = this.user.uid;
+        data.status = '1';
+        data.role = '1';
+        res = await this.create(data);
+        msg = '创建成功';
+      }
+      if (this.$checkRes(res, msg, res.errmsg)) {
+        this.toClose();
+        this.search();
+      }
+    },
+    // 取消增加
+    toClose() {
+      this.form = {};
+      this.dialog = false;
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  .info {
+    .top {
+      text-align: right;
+      margin: 15px 0;
+    }
+  }
+}
+</style>

+ 32 - 0
src/views/business/index.vue

@@ -0,0 +1,32 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24">
+        <p>index</p>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  name: 'index',
+  props: {},
+  components: {},
+  data: function() {
+    return {};
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+  },
+  watch: {},
+};
+</script>
+
+<style lang="less" scoped></style>

+ 32 - 0
src/views/permission/index.vue

@@ -0,0 +1,32 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24">
+        <p>index</p>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  name: 'index',
+  props: {},
+  components: {},
+  data: function() {
+    return {};
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+  },
+  watch: {},
+};
+</script>
+
+<style lang="less" scoped></style>

+ 36 - 27
src/views/test/index.vue

@@ -14,25 +14,17 @@
       </el-col>
     </el-row>
     <el-dialog :visible.sync="dialog" title="增加菜单" @close="toClose" :destroy-on-close="true" width="50%">
-      <data-form :data="form" :fields="formFields" :rules="rules" @save="turnSave">
-        <template #custom="{item}">
-          <template v-if="item.model == 'icon'">
-            <el-radio-group v-model="form.icon">
-              <el-radio v-for="(item, index) in iconlist" :key="index" :label="item.iconkey"><i :class="item.iconkey"></i></el-radio>
-            </el-radio-group>
-          </template>
-        </template>
-      </data-form>
+      <data-form :data="form" :fields="formFields" :rules="rules" @save="turnSave"> </data-form>
     </el-dialog>
   </div>
 </template>
 
 <script>
-import { iconmenu } from '@/util/iconmenu';
 import breadcrumb from '@c/common/breadcrumb.vue';
 import dataTable from '@/components/frame/filter-page-table.vue';
 import dataForm from '@/components/frame/form.vue';
 import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: role } = createNamespacedHelpers('role');
 export default {
   metaInfo() {
     return { title: this.$route.meta.title };
@@ -59,47 +51,64 @@ export default {
         },
       ],
       fields: [
-        { label: '菜单名称', prop: 'title' },
-        { label: '菜单地址', prop: 'index' },
-        { label: '菜单图标', prop: 'icon' },
+        { label: '菜单名称', prop: 'role_name' },
+        { label: '路由', prop: 'url' },
       ],
       list: [],
       total: 0,
       // 增加菜单
       dialog: false,
       formFields: [
-        { label: '菜单名称', required: true, model: 'title' },
-        { label: '菜单地址', required: true, model: 'index' },
-        { label: '菜单图标', required: true, model: 'icon', custom: true },
+        { label: '菜单名称', required: true, model: 'role_name' },
+        { label: '菜单地址', required: true, model: 'url' },
       ],
       form: {},
       rules: {
-        title: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
-        index: [{ required: true, message: '请输入菜单地址', trigger: 'blur' }],
-        icon: [{ required: true, message: '请输入菜单图标', trigger: 'blur' }],
+        role_name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
+        url: [{ required: true, message: '请输入菜单地址', trigger: 'blur' }],
       },
-      // 图标
-      iconlist: iconmenu,
     };
   },
   created() {
     this.search();
   },
   methods: {
+    ...role(['query', 'create', 'update', 'delete']),
     // 查询列表
-    async search({ skip = 0, limit = 10, ...info } = {}) {},
+    async search({ skip = 0, limit = 10, ...info } = {}) {
+      const res = await this.query({ ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data.reverse());
+        this.$set(this, `total`, res.total);
+      }
+    },
     // 修改
     toEdit({ data }) {
-      console.log(data);
+      this.$set(this, 'form', data);
+      this.dialog = true;
     },
     // 删除
-    toDelete({ data }) {
-      console.log(data);
+    async toDelete({ data }) {
+      const res = await this.delete(data.id);
+      if (this.$checkRes(res, '删除成功', res.errmsg || '删除失败')) this.search();
     },
     // 增加菜单
     // 保存
-    turnSave({ data }) {
-      console.log(data);
+    async turnSave({ data }) {
+      let res;
+      let msg;
+      data.type = 1;
+      if (data.id) {
+        res = await this.update(data);
+        msg = '修改成功';
+      } else {
+        res = await this.create(data);
+        msg = '创建成功';
+      }
+      if (this.$checkRes(res, msg, res.errmsg)) {
+        this.toClose();
+        this.search();
+      }
     },
     // 取消增加
     toClose() {

+ 3 - 3
src/views/test/detail.vue

@@ -1,8 +1,8 @@
 <template>
-  <div id="detail">
+  <div id="index">
     <el-row>
       <el-col :span="24">
-        <p>detail</p>
+        <p>index</p>
       </el-col>
     </el-row>
   </div>
@@ -14,7 +14,7 @@ export default {
   metaInfo() {
     return { title: this.$route.meta.title };
   },
-  name: 'detail',
+  name: 'index',
   props: {},
   components: {},
   data: function() {

+ 32 - 0
src/views/vip/index.vue

@@ -0,0 +1,32 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24">
+        <p>index</p>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  name: 'index',
+  props: {},
+  components: {},
+  data: function() {
+    return {};
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+  },
+  watch: {},
+};
+</script>
+
+<style lang="less" scoped></style>