shaogen1995 3 anni fa
parent
commit
4c78362b82

+ 19 - 0
src/router/index.js

@@ -67,6 +67,25 @@ const routes = [
         meta: { myInd: 3 },
         component: () => import('../views/Tab7/index.vue')
       },
+      {
+        path: '/Layout/tab7List/:id/:p',
+        name: 'tab7List',
+        meta: { myInd: 3 },
+        component: () => import('../views/Tab7/List.vue')
+      },
+      // 用户
+      {
+        path: '/Layout/tab8',
+        name: 'tab8',
+        meta: { myInd: 4 },
+        component: () => import('../views/Tab8/index.vue')
+      },
+      {
+        path: '/Layout/Accredit/:id/:p',
+        name: 'tab8Accredit',
+        meta: { myInd: 4 },
+        component: () => import('../views/Tab8/accredit.vue')
+      },
     ]
   },
 ]

+ 87 - 0
src/utils/api.js

@@ -90,6 +90,7 @@ export const delField = (data) => {
   })
 }
 
+
 // 通过表id获取详细信息
 export const getInfoById = (tableId,data) => {
   return axios({
@@ -131,4 +132,90 @@ export const recordDel = (tableId,ids) => {
     method: 'get',
     url: `/db/record/del/${tableId}/${ids}`,
   })
+}
+
+// ---------------白名单相关
+// 列表
+export const ipGetList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/sys/ip/getList',
+    data
+  })
+}
+
+// 新增和编辑
+export const ipSave = (data) => {
+  return axios({
+    method: 'post',
+    url: '/sys/ip/save',
+    data
+  })
+}
+
+// 删除
+export const ipRemoves = (ids) => {
+  return axios({
+    method: 'get',
+    url: `/sys/ip/removes/${ids}`,
+  })
+}
+
+// ----------------用户相关
+// 列表
+export const userList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/sys/user/list',
+    data
+  })
+}
+
+// 新增和编辑用户
+export const userSave = (data) => {
+  return axios({
+    method: 'post',
+    url: '/sys/user/save',
+    data
+  })
+}
+
+// 删除用户
+export const userRemoves = (ids) => {
+  return axios({
+    method: 'get',
+    url: `/sys/user/removes/${ids}`,
+  })
+}
+
+// 重置密码
+export const userResetPass = (id) => {
+  return axios({
+    method: 'get',
+    url: `/sys/user/resetPass/${id}`,
+  })
+}
+
+// 修改密码
+export const userUpdatePwd = (data) => {
+  return axios({
+    method: 'post',
+    url: '/sys/user/updatePwd',
+    data
+  })
+}
+
+// 获取用户详情
+export const userDetail = (id) => {
+  return axios({
+    method: 'get',
+    url: `/sys/user/detail/${id}`,
+  })
+}
+// 授权项目
+export const userAuth = (projectIds,userId) => {
+  return axios({
+    method: 'get',
+    url: `/sys/user/auth/${projectIds}/${userId}`,
+  })
 }

+ 110 - 15
src/views/Layout.vue

@@ -7,8 +7,9 @@
       </div>
       <div class="right">
         <img src="../assets/img/user.jpg" alt="" />
-        <p>{{ userName }}</p>
+        <p>{{ userInfo.realName }}</p>
         <div class="outLogin" @click="outLogin">退出登录</div>
+        <div class="outLogin" @click="isShow = true">修改密码</div>
       </div>
     </div>
     <div class="main">
@@ -23,32 +24,90 @@
         >
           {{ item.name }}
         </div>
-        <div class="title">系统管理</div>
-        <div
-          class="row"
-          @click="skip(item.path)"
-          v-for="item in tabData2"
-          :key="item.id"
-          :class="{ active: $route.meta.myInd === item.id }"
-        >
-          {{ item.name }}
-        </div>
+        <div class="title" v-if="userInfo.isAdmin === 1">系统管理</div>
+        <template v-if="userInfo.isAdmin === 1">
+          <div
+            class="row"
+            @click="skip(item.path)"
+            v-for="item in tabData2"
+            :key="item.id"
+            :class="{ active: $route.meta.myInd === item.id }"
+          >
+            {{ item.name }}
+          </div>
+        </template>
       </div>
       <div class="right">
         <Router-view />
       </div>
     </div>
+    <!-- 点击修改密码出现弹窗 -->
+    <el-dialog title="修改密码" :visible.sync="isShow" @close="btnX()">
+      <el-form :model="form" label-width="100px" :rules="rules" ref="ruleForm">
+        <el-form-item label="旧密码:" prop="oldPassword">
+          <el-input
+            style="width: 400px"
+            v-model="form.oldPassword"
+            placeholder="请输入"
+            show-password
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="新密码:" prop="newPassword">
+          <el-input
+            style="width: 400px"
+            v-model="form.newPassword"
+            placeholder="请输入"
+            show-password
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="确定新密码:" prop="checkPass">
+          <el-input
+            style="width: 400px"
+            v-model="form.checkPass"
+            placeholder="请输入"
+            show-password
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="btnX">取 消</el-button>
+        <el-button type="primary" @click="btnOk">确 定</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
+import { userUpdatePwd } from "@/utils/api";
+import { encodeStr } from "../utils/pass";
+import { Base64 } from "js-base64";
 export default {
   name: "Layout",
   components: {},
   data() {
     //这里存放数据
+    const validatePass2 = (rule, value, callback) => {
+      if (value !== this.form.newPassword) {
+        callback(new Error("两次输入密码不一致!"));
+      } else {
+        callback();
+      }
+    };
     return {
-      userName: "",
+      isShow: false,
+      form: {
+        oldPassword: "",
+        newPassword: "",
+        checkPass: "",
+      },
+      rules: {
+        checkPass: [{ validator: validatePass2, trigger: "blur" }],
+        oldPassword: [{ required: true, message: "不能为空", trigger: "blur" }],
+        newPassword: [{ required: true, message: "不能为空", trigger: "blur" }],
+      },
+      // 修改密码 👆
+
+      userInfo: "",
       tabData: [
         {
           id: 2,
@@ -67,6 +126,11 @@ export default {
           name: "白名单",
           path: "/Layout/tab7",
         },
+        {
+          id: 4,
+          name: "用户",
+          path: "/Layout/tab8",
+        },
       ],
     };
   },
@@ -87,7 +151,7 @@ export default {
       })
         .then(() => {
           localStorage.clear("Yun_token");
-          localStorage.clear("Yun_Name");
+          localStorage.clear("Yun_User");
           this.$router.push("/");
           this.$message.success("退出成功!");
         })
@@ -95,11 +159,41 @@ export default {
           this.$message.info("已取消");
         });
     },
+    // 修改密码点击取消
+    btnX() {
+      this.$refs.ruleForm.resetFields();
+      this.cut = false;
+      this.isShow = false;
+      this.form = {
+        oldPassword: "",
+        newPassword: "",
+        checkPass: "",
+      };
+    },
+    // 修改密码点击确定
+    async btnOk() {
+      await this.$refs.ruleForm.validate();
+      try {
+        let data = {
+          oldPassword: encodeStr(Base64.encode(this.form.oldPassword)),
+          newPassword: encodeStr(Base64.encode(this.form.newPassword)),
+        };
+        let res = await userUpdatePwd(data);
+        if (res.code === 0) {
+          this.$message.success("修改成功");
+          localStorage.clear("Yun_token");
+          localStorage.clear("Yun_User");
+          this.$router.push("/");
+        } else this.$message.error(res.msg);
+      } catch (error) {
+        console.log(error);
+      }
+    },
   },
   //生命周期 - 创建完成(可以访问当前this实例)
   created() {
     // 获取用户信息
-    this.userName = localStorage.getItem("Yun_Name");
+    this.userInfo = JSON.parse(localStorage.getItem("Yun_User"));
   },
   //生命周期 - 挂载完成(可以访问DOM元素)
   mounted() {},
@@ -142,10 +236,11 @@ export default {
         border-radius: 50%;
       }
       & > p {
-        margin: 0 30px 0 5px;
+        margin: 0 20px 0 5px;
       }
       .outLogin {
         cursor: pointer;
+        margin-right: 20px;
       }
     }
   }

+ 2 - 2
src/views/Login.vue

@@ -68,8 +68,8 @@ export default {
       let res = await userLogin(obj);
       if (res.code === 0) {
         localStorage.setItem("Yun_token", res.data.token);
-        localStorage.setItem("Yun_Name", res.data.user.realName);
-        this.$router.push("/Layout");
+        localStorage.setItem("Yun_User", JSON.stringify(res.data.user));
+        this.$router.push("/Layout/tab4");
         this.$message.success("登录成功");
       } else this.$message.warning(res.msg);
     },

+ 108 - 0
src/views/Tab7/Dialog.vue

@@ -0,0 +1,108 @@
+<template>
+  <el-dialog :title="ruleForm.id?'编辑ip':'新增ip'" :visible="dialogVisible" @close="btnX">
+    <el-form
+      :model="ruleForm"
+      :rules="rules"
+      ref="ruleForm"
+      label-width="100px"
+      class="demo-ruleForm"
+    >
+      <el-form-item label="ip地址" prop="ip">
+        <el-input
+          @input="changeInput"
+          v-model="ruleForm.ip"
+          maxlength="15"
+          show-word-limit
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="备注" prop="remark">
+        <el-input
+          v-model="ruleForm.remark"
+          maxlength="30"
+          show-word-limit
+        ></el-input>
+      </el-form-item>
+    </el-form>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="btnX">取 消</el-button>
+      <el-button type="primary" @click="btnOk">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import { ipSave } from "@/utils/api";
+export default {
+  name: "tab7Dialog",
+  props: {
+    dialogVisible: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      ruleForm: {
+        projectId: null,
+        ip: "",
+        remark: "",
+      },
+      rules: {
+        ip: [{ required: true, message: "不能为空", trigger: "blur" }],
+        remark: [{ required: true, message: "不能为空", trigger: "blur" }],
+      },
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {
+    // 让父组件点击编辑的时候调用
+    setRuleForm(item){
+      this.ruleForm={...item}
+    },
+    // 限制ip只能输入数字和.
+    changeInput() {
+      this.ruleForm.ip=this.ruleForm.ip.replace(/[^\d^\.]+/g, '')
+    },
+    // 点击取消
+    btnX() {
+      this.$refs.ruleForm.resetFields();
+      this.$emit("update:dialogVisible", false);
+    },
+    async btnOk() {
+      try {
+        await this.$refs.ruleForm.validate();
+        let res = await ipSave(this.ruleForm);
+        if (res.code === 0) {
+          this.$emit("clickSon");
+          this.btnX();
+          this.$message.success("操作成功");
+        } else this.$message.warning(res.msg);
+      } catch (error) {
+        console.log(error);
+      }
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.ruleForm.projectId = Number(this.$route.params.id);
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+//@import url(); 引入公共css类
+</style>

+ 201 - 0
src/views/Tab7/List.vue

@@ -0,0 +1,201 @@
+    <template>
+  <div class="tab7List">
+    <div class="crumbs">
+      <div>
+        <span @click="$router.push('/Layout/tab7')"
+          >白名单 /</span
+        >
+        <span class="active"> 列表 </span>
+      </div>
+      <div class="title">{{ $route.params.p }}</div>
+    </div>
+
+    <div class="search">
+      <div class="left">
+        <el-input
+          style="width: 380px"
+          v-model="pageData.searchKey"
+          placeholder="请输入ip"
+        ></el-input>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          @click="ipGetList(pageData)"
+          >搜索</el-button
+        >
+      </div>
+      <div class="right">
+        <el-button
+          type="danger"
+          :disabled="selecArr.length === 0"
+          @click="ipRemoves"
+          >删除</el-button
+        >
+        <el-button type="success" @click="dialogVisible = true"
+          >新增</el-button
+        >
+      </div>
+    </div>
+    <div class="table">
+      <el-table
+        :data="tableData"
+        style="width: 100%"
+        @selection-change="selecChange"
+      >
+        <el-table-column type="selection" width="55"> </el-table-column>
+        <el-table-column label="序号" width="80">
+          <template slot-scope="scope">
+            {{ scope.$index + (pageData.pageNum - 1) * pageData.pageSize + 1 }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="ip" label="ip"> </el-table-column>
+        <el-table-column prop="remark" label="备注"> </el-table-column>
+        <el-table-column label="操作">
+          <template #default="{ row }">
+            <el-button
+              type="text"
+              @click="edit(row)"
+              >编辑</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <!-- 分页器 -->
+    <div class="paging">
+      <el-pagination
+        :current-page="pageData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+        layout="prev, pager, next,sizes,jumper"
+        :total="total"
+      >
+      </el-pagination>
+    </div>
+    <!-- 点击新增和编辑出现的弹窗 -->
+    <Dialog
+      ref="projectRef"
+      :dialogVisible.sync="dialogVisible"
+      @clickSon="ipGetList(pageData)"
+    />
+  </div>
+</template>
+
+<script>
+import Dialog from "./Dialog";
+import { ipGetList, ipRemoves } from "@/utils/api";
+export default {
+  name: "tab7List",
+  components: { Dialog },
+  data() {
+    //这里存放数据
+    return {
+      total: 0,
+      dialogVisible: false,
+      tableData: [],
+      pageData: {
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: "",
+        id: null,
+      },
+      selecArr: [],
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {
+    // 点击编辑
+    edit(item){
+      this.$refs.projectRef.setRuleForm(item)
+      this.dialogVisible=true
+    },
+    // 点击删除项目
+    async ipRemoves() {
+      this.$confirm("确定删除吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(async () => {
+          let temp = [];
+          this.selecArr.forEach((v) => {
+            temp.push(v.id);
+          });
+          let res = await ipRemoves(temp.join(','));
+          if (res.code === 0) {
+            this.$message.success("删除成功!");
+            this.ipGetList(this.pageData);
+          } else this.$message.warning(res.msg);
+        })
+        .catch(() => {
+          this.$message.info("已取消删除");
+        });
+    },
+    // 分页器
+    currentChange(val) {
+      this.pageData.pageNum = val;
+      this.ipGetList(this.pageData);
+    },
+    sizeChange(val) {
+      this.pageData.pageNum = 1;
+      this.pageData.pageSize = val;
+      this.ipGetList(this.pageData);
+    },
+    selecChange(val) {
+      this.selecArr = val;
+    },
+    // 封装一个获取表列表的方法
+    async ipGetList(data) {
+      let res = await ipGetList(data);
+      this.total = res.data.total;
+      this.tableData = res.data.records;
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.pageData.id = Number(this.$route.params.id);
+    this.ipGetList(this.pageData);
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.tab7List {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .search {
+    display: flex;
+    justify-content: space-between;
+    .left {
+      justify-content: space-between;
+      display: flex;
+      width: 500px;
+    }
+  }
+  .table {
+    /deep/.el-table__body-wrapper {
+      width: 1570px;
+      max-height: 585px;
+      overflow-y: auto;
+    }
+  }
+  .paging {
+    position: absolute;
+    right: 20px;
+    bottom: 40px;
+  }
+}
+</style>

+ 2 - 2
src/views/Tab7/index.vue

@@ -28,8 +28,8 @@
           <template #default="{ row }">
             <el-button
               type="text"
-              @click="$router.push(`/Layout/tab5/${row.id}/${row.name}`)"
-              >表数据</el-button
+              @click="$router.push(`/Layout/tab7List/${row.id}/${row.name}`)"
+              >管理白名单</el-button
             >
           </template>
         </el-table-column>

+ 141 - 0
src/views/Tab8/Dialog.vue

@@ -0,0 +1,141 @@
+<template>
+  <el-dialog
+    :title="ruleForm.id ? '编辑用户' : '新增用户'"
+    :visible="dialogVisible"
+    @close="btnX"
+  >
+    <el-form
+      :model="ruleForm"
+      :rules="rules"
+      ref="ruleForm"
+      label-width="100px"
+      class="demo-ruleForm"
+    >
+      <el-form-item label="账号" prop="userName">
+        <el-input
+          v-model="ruleForm.userName"
+          maxlength="15"
+          show-word-limit
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="真实姓名" prop="realName">
+        <el-input
+          v-model="ruleForm.realName"
+          maxlength="8"
+          show-word-limit
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="电话" prop="phone">
+        <el-input
+          v-model="ruleForm.phone"
+          maxlength="11"
+          show-word-limit
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="是否启用:">
+        <el-radio v-model="ruleForm.isEnabled" :label="1">是</el-radio>
+        <el-radio v-model="ruleForm.isEnabled" :label="0">否</el-radio>
+      </el-form-item>
+      <div class="hint">* 默认密码:123456</div>
+    </el-form>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="btnX">取 消</el-button>
+      <el-button type="primary" @click="btnOk">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import { userSave } from "@/utils/api";
+export default {
+  name: "tab8Dialog",
+  props: {
+    dialogVisible: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      ruleForm: {
+        id: null,
+        isEnabled: 1,
+        phone: "",
+        realName: "",
+        sex: 0,
+        userName: "",
+      },
+      rules: {
+        userName: [{ required: true, message: "不能为空", trigger: "blur" }],
+        realName: [{ required: true, message: "不能为空", trigger: "blur" }],
+        phone: [
+          { required: true, message: "不能为空", trigger: "blur" },
+          {
+            pattern: /^1[3-9]\d{9}$/,
+            message: "请输入合法手机号",
+            trigger: "blur",
+          },
+        ],
+      },
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {
+    // 父组件点击编辑的时候调用
+    async setRuleForm(item) {
+      this.ruleForm = { ...item };
+    },
+    // 点击取消
+    btnX() {
+      this.$refs.ruleForm.resetFields();
+      this.ruleForm = {
+        id: null,
+        isEnabled: 1,
+        phone: "",
+        realName: "",
+        sex: 0,
+        userName: "",
+      };
+      this.$emit("update:dialogVisible", false);
+    },
+    async btnOk() {
+      try {
+        await this.$refs.ruleForm.validate();
+        let res = await userSave(this.ruleForm);
+        if (res.code === 0) {
+          this.$emit("clickSon");
+          this.btnX();
+          this.$message.success("操作成功");
+        } else this.$message.warning(res.msg);
+      } catch (error) {
+        console.log(error);
+      }
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.hint {
+  color: red;
+  margin-left: 100px;
+  margin-top: -15px;
+  margin-bottom: 15px;
+}
+</style>

+ 184 - 0
src/views/Tab8/accredit.vue

@@ -0,0 +1,184 @@
+<template>
+  <div class="accredit">
+    <div class="crumbs">
+      <div>
+        <span @click="$router.push('/Layout/tab4')">用户 /</span>
+        <span class="active"> 授权 </span>
+      </div>
+      <div class="title">{{ $route.params.p }}</div>
+    </div>
+    <div class="search">
+      <div class="left">
+        <el-input
+          style="width: 380px"
+          v-model="pageData.searchKey"
+          placeholder="请输入项目名"
+        ></el-input>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          @click="getProjectList(pageData)"
+          >搜索</el-button
+        >
+      </div>
+      <div class="right">
+        <el-button type="success" @click="userAuth" :disabled="disBtn <= 1"
+          >授权</el-button
+        >
+      </div>
+    </div>
+    <div class="table">
+      <el-table
+        ref="table"
+        :data="tableData"
+        style="width: 100%"
+        @selection-change="selecChange"
+      >
+        <el-table-column type="selection" width="55"> </el-table-column>
+        <el-table-column label="序号" width="80">
+          <template slot-scope="scope">
+            {{ scope.$index + (pageData.pageNum - 1) * pageData.pageSize + 1 }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="name" label="项目名"> </el-table-column>
+        <el-table-column prop="remark" label="备注"> </el-table-column>
+      </el-table>
+    </div>
+    <!-- 分页器 -->
+    <div class="paging">
+      <el-pagination
+        :current-page="pageData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+        layout="prev, pager, next,sizes,jumper"
+        :total="total"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import { getProjectList, userDetail, userAuth } from "@/utils/api";
+export default {
+  name: "accredit",
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      total: 0,
+      dialogVisible: false,
+      tableData: [],
+      pageData: {
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: "",
+      },
+      selecArr: [],
+      // 用户id
+      userId: null,
+      userTxt: "",
+      userData: [],
+      // 当表格的选中状态改变了才让授权按钮取消禁用
+      disBtn: 0,
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {
+    selecArr() {
+      this.disBtn++;
+    },
+  },
+  //方法集合
+  methods: {
+    // 点击授权
+    async userAuth() {
+      let temp = [];
+      this.selecArr.forEach((v) => {
+        temp.push(v.id);
+      });
+      let res = await userAuth(temp.join(","), this.userId);
+      if (res.code === 0) {
+        this.$message.success("授权成功!");
+        this.disBtn=1
+      } else this.$message.warning(res.msg);
+    },
+    // 分页器
+    currentChange(val) {
+      this.pageData.pageNum = val;
+      this.getProjectList(this.pageData);
+    },
+    sizeChange(val) {
+      this.pageData.pageNum = 1;
+      this.pageData.pageSize = val;
+      this.getProjectList(this.pageData);
+    },
+    selecChange(val) {
+      this.selecArr = val;
+    },
+    // 封装一个获取表列表的方法
+    async getProjectList(data) {
+      let res = await getProjectList(data);
+      this.total = res.data.total;
+      this.tableData = res.data.records;
+      this.tableData.forEach((v) => {
+        if (this.userTxt.includes(v.id)) {
+          this.userData.push(v);
+        }
+      });
+      this.$nextTick(() => {
+        this.userData.forEach((v) => {
+          this.$refs.table.toggleRowSelection(v, true);
+        });
+      });
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  async created() {
+    // 获取已经得到授权的信息
+    this.userId = Number(this.$route.params.id);
+    let res = await userDetail(this.userId);
+    if (res.data.projectIds) this.userTxt = res.data.projectIds;
+    this.getProjectList(this.pageData);
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.accredit {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .search {
+    display: flex;
+    justify-content: space-between;
+    .left {
+      justify-content: space-between;
+      display: flex;
+      width: 500px;
+    }
+  }
+  .table {
+    /deep/.el-table__body-wrapper {
+      width: 1570px;
+      max-height: 585px;
+      overflow-y: auto;
+    }
+  }
+  .paging {
+    position: absolute;
+    right: 20px;
+    bottom: 40px;
+  }
+}
+</style>

+ 223 - 0
src/views/Tab8/index.vue

@@ -0,0 +1,223 @@
+<template>
+  <div class="tab8">
+    <div class="search">
+      <div class="left">
+        <el-input
+          style="width: 380px"
+          v-model="pageData.searchKey"
+          placeholder="请输入用户名"
+        ></el-input>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          @click="userList(pageData)"
+          >搜索</el-button
+        >
+      </div>
+      <div class="right">
+        <!-- <el-button type="danger" :disabled="selecArr.length === 0"
+          >删除用户</el-button
+        > -->
+        <el-button type="success" @click="dialogVisible = true"
+          >新增用户</el-button
+        >
+      </div>
+    </div>
+    <div class="table">
+      <el-table :data="tableData" style="width: 100%">
+        <!-- @selection-change="selecChange" -->
+        <!-- <el-table-column type="selection" width="55"> </el-table-column> -->
+        <el-table-column label="序号" width="80">
+          <template slot-scope="scope">
+            {{ scope.$index + (pageData.pageNum - 1) * pageData.pageSize + 1 }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="userName" label="账号"> </el-table-column>
+        <el-table-column prop="realName" label="姓名"> </el-table-column>
+        <el-table-column prop="phone" label="电话"> </el-table-column>
+
+        <el-table-column label="状态">
+          <template #default="{ row }">
+            {{ row.isEnabled ? "启用" : "禁用" }}
+          </template>
+        </el-table-column>
+        <el-table-column label="操作">
+          <template #default="{ row }">
+            <el-button
+              v-if="row.isAdmin !== 1"
+              type="text"
+              @click="$router.push(`/Layout/Accredit/${row.id}/${row.realName}`)"
+              >授权</el-button
+            >
+            <el-button
+              v-if="row.isAdmin !== 1"
+              type="text"
+              @click="editUser(row)"
+              >编辑</el-button
+            >
+            <el-button
+              v-if="row.isAdmin !== 1"
+              type="text"
+              style="color: #f56c6c"
+              @click="userRemoves(row.id)"
+              >删除</el-button
+            >
+            <el-button
+              v-if="row.isAdmin !== 1"
+              type="text"
+              @click="resetPass(row.id)"
+              >重置密码</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <!-- 分页器 -->
+    <div class="paging">
+      <el-pagination
+        :current-page="pageData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+        layout="prev, pager, next,sizes,jumper"
+        :total="total"
+      >
+      </el-pagination>
+    </div>
+    <!-- 点击新增和编辑出现的弹窗 -->
+    <Dialog
+      ref="projectRef"
+      :dialogVisible.sync="dialogVisible"
+      @clickSon="userList(pageData)"
+    />
+  </div>
+</template>
+
+<script>
+import Dialog from "./Dialog";
+import { userList, userRemoves, userResetPass } from "@/utils/api";
+export default {
+  name: "tab8",
+  components: { Dialog },
+  data() {
+    //这里存放数据
+    return {
+      total: 0,
+      dialogVisible: false,
+      tableData: [],
+      pageData: {
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: "",
+      },
+      // selecArr: [],
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {
+    // 点击编辑,调用子组件弹窗的方法
+    editUser(item) {
+      this.$refs.projectRef.setRuleForm(item);
+      this.dialogVisible = true;
+    },
+    // 点击重置密码
+    async resetPass(id) {
+      this.$confirm("确定重置吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(async () => {
+          let res = await userResetPass(id);
+          if (res.code === 0) {
+            this.$message.success("重置成功!");
+          } else this.$message.warning(res.msg);
+        })
+        .catch(() => {
+          this.$message.info("已取消重置");
+        });
+    },
+    // 点击删除项目
+    async userRemoves(id) {
+      this.$confirm("确定删除吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(async () => {
+          let res = await userRemoves(id);
+          if (res.code === 0) {
+            this.$message.success("删除成功!");
+            this.userList(this.pageData);
+          } else this.$message.warning(res.msg);
+        })
+        .catch(() => {
+          this.$message.info("已取消删除");
+        });
+    },
+    // 分页器
+    currentChange(val) {
+      this.pageData.pageNum = val;
+      this.userList(this.pageData);
+    },
+    sizeChange(val) {
+      this.pageData.pageNum = 1;
+      this.pageData.pageSize = val;
+      this.userList(this.pageData);
+    },
+    // selecChange(val) {
+    //   this.selecArr = val;
+    // },
+    // 封装一个获取表列表的方法
+    async userList(data) {
+      let res = await userList(data);
+      this.total = res.data.total;
+      this.tableData = res.data.records;
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.userList(this.pageData);
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.tab8 {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .search {
+    display: flex;
+    justify-content: space-between;
+    .left {
+      justify-content: space-between;
+      display: flex;
+      width: 500px;
+    }
+  }
+  .table {
+    /deep/.el-table__body-wrapper {
+      width: 1570px;
+      max-height: 585px;
+      overflow-y: auto;
+    }
+  }
+  .paging {
+    position: absolute;
+    right: 20px;
+    bottom: 40px;
+  }
+}
+</style>