谢杰标 2 år sedan
förälder
incheckning
e7c34ee921
29 ändrade filer med 8061 tillägg och 11 borttagningar
  1. 11 4
      src/api/api.js
  2. 49 0
      src/api/dict/dictData.js
  3. 49 0
      src/api/dict/dictType.js
  4. 56 0
      src/api/system/menu.js
  5. 58 0
      src/api/system/roleInfoManagement.js
  6. 34 0
      src/api/system/userInformationManagement.js
  7. BIN
      src/assets/images/pdf@3x.png
  8. 181 0
      src/components/searchBox.vue
  9. 0 1
      src/components/searchBoxNew.vue
  10. 0 5
      src/components/tableList.vue
  11. 2 1
      src/store/modules/permission.js
  12. 495 0
      src/views/systemManagement/accountManagement/index.vue
  13. 519 0
      src/views/systemManagement/auditManagement/assignReviewers/index.vue
  14. 268 0
      src/views/systemManagement/mechanism/dislog.vue
  15. 286 0
      src/views/systemManagement/mechanism/index.vue
  16. 415 0
      src/views/systemManagement/myManagement/myProfile/index.vue
  17. 278 0
      src/views/systemManagement/registeredUser/index.vue
  18. 758 0
      src/views/systemManagement/roleManagement/index.vue
  19. 16 0
      src/views/systemSettings/accountManagement/index.vue
  20. 499 0
      src/views/systemSettings/department/index.vue
  21. 433 0
      src/views/systemSettings/dict/index.vue
  22. 454 0
      src/views/systemSettings/dictData/index.vue
  23. 476 0
      src/views/systemSettings/jobManagement/index.vue
  24. 506 0
      src/views/systemSettings/menu/index.vue
  25. 455 0
      src/views/systemSettings/modelPage/index.vue
  26. 255 0
      src/views/systemSettings/operationLog/index.vue
  27. 231 0
      src/views/systemSettings/personalCenter/index.vue
  28. 597 0
      src/views/systemSettings/roleInfoManagement/index.vue
  29. 680 0
      src/views/systemSettings/usermanagement/index.vue

+ 11 - 4
src/api/api.js

@@ -1,6 +1,13 @@
-
+import menu from "../api/system/menu";
+import roleInfoManagement from "../api/system/roleInfoManagement";
+import userInformationManagement from "../api/system/userInformationManagement";
+import dictData from "../api/dict/dictData";
+import dictType from "../api/dict/dictType";
 // 导入对应模块------------------------
 // 导入对应模块------------------------
 export default {
 export default {
-  
-
-}
+  ...menu,
+  ...dictData,
+  ...roleInfoManagement,
+  ...userInformationManagement,
+  ...dictType,
+};

+ 49 - 0
src/api/dict/dictData.js

@@ -0,0 +1,49 @@
+import request from '@/utils/request' //引入axios请求及拦截器
+export default {
+    //新增字典数据
+    adddictdata(data) {
+        return request({
+            url: '/system/dict/data',
+            method: 'post',
+            data
+        })
+    },
+    //删除字典数据
+    deldictdata(data) {
+        return request({
+            url: '/system/dict/data/delete/' + data,
+            method: 'post',
+        })
+    },
+    //修改保存字典数据
+    editdictdata(data) {
+        return request({
+            url: '/system/dict/data/edit',
+            method: 'post',
+            data
+        })
+    },
+    //获取字典数据列表
+    obtaindictdata(data) {
+        return request({
+            url: `/system/dict/data/list`,
+            method: 'get',
+            params: data
+        })
+    },
+    //根据字典类型查询字典数据信息
+    dictdatatypes(data) {
+        return request({
+            url: `/system/dict/data/type/`,
+            method: 'get',
+            params: data
+        })
+    },
+    //查询字典数据详细
+    getdictdata(data) {
+        return request({
+            url: `/system/dict/data/` + data,
+            method: 'get',
+        })
+    },
+}

+ 49 - 0
src/api/dict/dictType.js

@@ -0,0 +1,49 @@
+import request from '@/utils/request' //引入axios请求及拦截器
+export default {
+    //新增字典类型
+    adddicttype(data) {
+        return request({
+            url: '/system/dict/type',
+            method: 'post',
+            data
+        })
+    },
+    //删除字典类型
+    deldicttype(data) {
+        return request({
+            url: '/system/dict/type/delete/' + data,
+            method: 'post',
+        })
+    },
+    //修改字典类型
+    editdicttype(data) {
+        return request({
+            url: '/system/dict/type/edit',
+            method: 'post',
+            data
+        })
+    },
+    //获取字典类型列表
+    obtaindicttype(data) {
+        return request({
+            url: `/system/dict/type/list`,
+            method: 'get',
+            params: data
+        })
+    },
+    //获取字典选择框列表
+    obtaindictdatatypes(data) {
+        return request({
+            url: `/system/dict/type/optionselect`,
+            method: 'get',
+            params: data
+        })
+    },
+    //查询字典类型详细
+    getdicttype(data) {
+        return request({
+            url: '/system/dict/type/' + data,
+            method: 'get',
+        })
+    },
+}

+ 56 - 0
src/api/system/menu.js

@@ -0,0 +1,56 @@
+import request from '@/utils/request' //引入axios请求及拦截器
+export default {
+    //新增菜单
+    addsystemmenu(data) {
+        return request({
+            url: '/system/menu',
+            method: 'post',
+            data
+        })
+    },
+    //删除菜单
+    delsystemmenu(data) {
+        return request({
+            url: '/system/menu/delete/' + data,
+            method: 'post',
+        })
+    },
+    //修改菜单
+    editsystemmenu(data) {
+        return request({
+            url: '/system/menu/edit',
+            method: 'post',
+            data
+        })
+    },
+    //获取菜单列表
+    getsystemmenu(data) {
+        return request({
+            url: '/system/menu/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //加载对应角色菜单列表树
+    roleMenuTreeselect(data) {
+        return request({
+            url: `/system/menu/roleMenuTreeselect/` + data,
+            method: 'get',
+        })
+    },
+    //获取菜单下拉树列表
+    enutreeselect(data) {
+        return request({
+            url: `/system/menu/treeselect/`,
+            method: 'get',
+            params: data
+        })
+    },
+    //根据菜单编号获取详细信息
+    enutreeselectmenu(data) {
+        return request({
+            url: `/system/menu/` + data,
+            method: 'get',
+        })
+    },
+}

+ 58 - 0
src/api/system/roleInfoManagement.js

@@ -0,0 +1,58 @@
+import request from '@/utils/request' //引入axios请求及拦截器
+export default {
+    //新增角色
+    addRole(data) {
+        return request({
+            url: '/system/role',
+            method: 'post',
+            data
+        })
+    },
+    //状态修改
+    changeStatusRole(data) {
+        return request({
+            url: '/system/role/changeStatus',
+            method: 'post',
+            data
+        })
+    },
+    //修改保存数据权限
+    dataScopeRole(data) {
+        return request({
+            url: '/system/role/dataScope',
+            method: 'post',
+            data
+        })
+    },
+    //修改保存角色
+    editRole(data) {
+        return request({
+            url: '/system/role/edit',
+            method: 'post',
+            data
+        })
+    },
+    //角色列表
+    obtainRoleList(data) {
+        return request({
+            url: '/system/role/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //获取角色选择框列表
+    obtainRoleOptionselect(data) {
+        return request({
+            url: '/system/role/optionselect',
+            method: 'get',
+            params: data
+        })
+    },
+    //根据角色编号获取详细信息
+    obtainRoleId(data) {
+        return request({
+            url: `/system/role/` + data,
+            method: 'get',
+        })
+    },
+}

+ 34 - 0
src/api/system/userInformationManagement.js

@@ -0,0 +1,34 @@
+import request from '@/utils/request' //引入axios请求及拦截器
+export default {
+    //新增用户
+    addUser(data) {
+        return request({
+            url: '/system/user',
+            method: 'post',
+            data
+        })
+    },
+    //更新用户
+    editUser(data) {
+        return request({
+            url: '/system/user/edit',
+            method: 'post',
+            data
+        })
+    },
+    //获取用户列表
+    obtainUserList(data) {
+        return request({
+            url: '/system/user/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //获取用户详细
+    obtainUserDetails(data) {
+        return request({
+            url: `/system/user/` + data,
+            method: 'get',
+        })
+    },
+}

BIN
src/assets/images/pdf@3x.png


+ 181 - 0
src/components/searchBox.vue

@@ -0,0 +1,181 @@
+<template>
+  <div id="searchBox">
+    <div class="inputListBox">
+      <el-form :inline="true" :model="formData" class="demo-form-inline">
+        <el-form-item
+          v-for="(item, index) in formList"
+          :key="index"
+          :label="item.label"
+        >
+          <el-select
+            v-if="item.scope === 'select'"
+            v-model="formData[item.prop]"
+            :placeholder="item.placeholder"
+            :size="size"
+          >
+            <el-option
+              v-for="(items, indexs) in item.options"
+              :key="indexs"
+              :label="items.label"
+              :value="items.value"
+            ></el-option>
+          </el-select>
+          <div v-else-if="item.scope === 'numList'">
+            <el-input-number
+            :controls="false"
+            v-model="formData[item.prop1]"
+            controls-position="right"
+            :min="0"
+            :max="100"
+            size="small"
+             @change="handleChanges(formData[item.prop1],formData[item.prop2])"
+          ></el-input-number>~
+          <el-input-number
+          :controls="false"
+            v-model="formData[item.prop2]"
+            controls-position="right"
+            :min="0"
+            :max="100"
+            size="small"
+            @change="handleChanges(formData[item.prop1],formData[item.prop2])"
+          ></el-input-number>
+          </div>
+          <el-input-number
+            v-else-if="item.scope === 'inputNumber'"
+            v-model="formData[item.prop]"
+            controls-position="right"
+            :min="0"
+            :max="100"
+            size="small"
+          ></el-input-number>
+          <el-cascader
+            v-else-if="item.scope === 'cascader'"
+            v-model="formData[item.prop]"
+            :options="item.options"
+            :size="size"
+            :props="{
+              label: item.props.label,
+              value: item.props.value,
+              checkStrictly: true,
+              emitPath: false,
+            }"
+          ></el-cascader>
+          <el-date-picker
+            v-else-if="item.scope === 'datePicker'"
+            v-model="formData[item.prop]"
+            type="datetimerange"
+            :picker-options="pickerOptions"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            align="right"
+            :size="size"
+            value-format="timestamp"
+          >
+          </el-date-picker>
+          <el-date-picker
+            v-else-if="item.scope === 'datePickerA'"
+            v-model="formData[item.prop]"
+            type="datetime"
+            :size="size"
+            placeholder="选择日期时间"
+            value-format="timestamp"
+          >
+          </el-date-picker>
+          <el-input
+            v-else
+            v-model="formData[item.prop]"
+            :placeholder="item.placeholder"
+            :size="size"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+    </div>
+    <el-form :inline="true" class="btnListBox">
+      <el-form-item>
+        <el-button :size="size" type="primary" @click="search">查询</el-button>
+        <el-button :size="size" @click="init">重置</el-button>
+      </el-form-item></el-form
+    >
+  </div>
+</template>
+
+<script>
+export default {
+  props: ["formList"], //参考文档 component.md
+  data() {
+    return {
+      size: "medium", //输入框尺寸类型
+      formData: {}, //表单数据收集
+      pickerOptions: {
+        //日期选择器近期功能
+        shortcuts: [
+          {
+            text: "最近一周",
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+              picker.$emit("pick", [start, end]);
+            },
+          },
+          {
+            text: "最近一个月",
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+              picker.$emit("pick", [start, end]);
+            },
+          },
+          {
+            text: "最近三个月",
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+              picker.$emit("pick", [start, end]);
+            },
+          },
+        ],
+      },
+    };
+  },
+  created(){
+    var self = this
+    document.onkeydown = function (e) {
+      var key = window.event.keyCode;
+      if (key === 13) {
+        self.search();
+      }
+    };
+  },
+  methods: {
+    //搜索
+    search() {
+      this.$emit("search", this.formData);
+    },
+    //重置
+    init() {
+      this.formData = {};
+      this.$emit("init");
+    },
+    handleChanges(int1,int2){
+      if(int1 !== undefined && int2 !== undefined){
+        if(int1 > int2){
+          this.$message.error('请规范输入取值范围')
+        }
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+#searchBox {
+  display: flex;
+  .inputListBox {
+    flex: 1;
+  }
+}
+</style>

+ 0 - 1
src/components/searchBoxNew.vue

@@ -494,7 +494,6 @@
 
 
 <script>
 <script>
 import { mapGetters } from "vuex";
 import { mapGetters } from "vuex";
-import handout from "../newApi/handout";
 export default {
 export default {
   props: [
   props: [
     "formList",
     "formList",

+ 0 - 5
src/components/tableList.vue

@@ -454,9 +454,6 @@
               >
               >
             </el-popover>
             </el-popover>
           </ul>
           </ul>
-          <div v-else-if="item.scope === 'htmlInfo'">
-            <bankMsg ref="bankMsg" :bankMsg="scope.row" />
-          </div>
           <div v-else-if="item.scope === 'video'">
           <div v-else-if="item.scope === 'video'">
             <i
             <i
               v-if="scope.row[item.prop][item.prop1] !== null"
               v-if="scope.row[item.prop][item.prop1] !== null"
@@ -1148,9 +1145,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
-import bankMsg from "./bankMsg";
 export default {
 export default {
-  components: { bankMsg },
   props: [
   props: [
     "tableSets",
     "tableSets",
     "tableData",
     "tableData",

+ 2 - 1
src/store/modules/permission.js

@@ -61,7 +61,8 @@ const permission = {
       return new Promise((resolve) => {
       return new Promise((resolve) => {
         // 向后端请求路由数据
         // 向后端请求路由数据
         getRouters().then((res) => {
         getRouters().then((res) => {
-          res.data = [];
+          // console.log(res.data);
+          res.data = [res.data[4]];
           const sdata = JSON.parse(JSON.stringify(res.data));
           const sdata = JSON.parse(JSON.stringify(res.data));
           const rdata = JSON.parse(JSON.stringify(res.data));
           const rdata = JSON.parse(JSON.stringify(res.data));
           const sidebarRoutes = filterAsyncRouter(sdata);
           const sidebarRoutes = filterAsyncRouter(sdata);

+ 495 - 0
src/views/systemManagement/accountManagement/index.vue

@@ -0,0 +1,495 @@
+<template>
+  <div id="accountManagement">
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+      @addClick="addClick"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="addClick(props.scope.row, 0)"
+          >修改</el-button
+        >
+        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="pageSize"
+      :currentPage="currentPage"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="560px"
+      :show-close="false"
+      :close-on-click-modal="false"
+      @close="onClose"
+      @closed="loadingClose"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="110px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item label="账号名称" prop="userName">
+            <el-input
+              v-model="listData.userName"
+              placeholder="请输入账号名称"
+              clearable
+              :style="{ width: '100%' }"
+            >
+            </el-input>
+          </el-form-item>
+          <el-form-item
+            label="账号密码"
+            :prop="statusPop === 1 ? 'password' : ''"
+          >
+            <el-input
+              v-model="listData.password"
+              placeholder="请输入账号密码"
+              clearable
+              :style="{ width: '100%' }"
+            >
+            </el-input>
+          </el-form-item>
+          <el-form-item label="真实姓名" prop="nickName">
+            <el-input
+              v-model="listData.nickName"
+              placeholder="请输入真实姓名"
+              clearable
+              :style="{ width: '100%' }"
+            >
+            </el-input>
+          </el-form-item>
+          <el-form-item label="手机号码" prop="phonenumber">
+            <el-input
+              v-model="listData.phonenumber"
+              placeholder="请输入手机号码"
+              clearable
+              :style="{ width: '100%' }"
+            >
+            </el-input>
+          </el-form-item>
+          <el-form-item label="邮箱" prop="email">
+            <el-input
+              v-model="listData.email"
+              placeholder="请输入邮箱"
+              clearable
+              :style="{ width: '100%' }"
+            >
+            </el-input>
+          </el-form-item>
+          <el-form-item label="角色名称" prop="roleIds">
+            <el-select
+              multiple
+              v-model="listData.roleIds"
+              placeholder="请选择角色名称"
+              clearable
+              :style="{ width: '100%' }"
+            >
+              <el-option
+                v-for="(item, index) in roleList"
+                :key="index"
+                :label="item.roleName"
+                :value="item.roleId"
+                :disabled="item.disabled"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="状态" prop="status">
+            <el-radio-group v-model="listData.status" size="medium">
+              <el-radio
+                v-for="(item, index) in statusOptions"
+                :key="index"
+                :label="item.value"
+                :disabled="item.disabled"
+                >{{ item.label }}</el-radio
+              >
+            </el-radio-group>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button
+          type="primary"
+          v-if="statusPop !== 2"
+          :loading="disabledBtn"
+          @click="submit('listData')"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+import searchBox from "@/components/searchBox";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "AccountManagement",
+  components: { searchBox, tableList, pagination },
+  data() {
+    return {
+      disabledBtn: false,
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "账号管理",
+        index: 0,
+        ch: "条",
+        num: false,
+        choice: true,
+        addHide: false,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "用户编码",
+          prop: "code",
+          hidden: true,
+        },
+        {
+          label: "账号名称",
+          prop: "userName",
+          hidden: true,
+        },
+        {
+          label: "角色名称",
+          prop: "roles",
+          prop1: "roleName",
+          scope: "aboutChapter",
+          hidden: true,
+        },
+        {
+          label: "真实姓名",
+          prop: "nickName",
+          hidden: true,
+        },
+        {
+          label: "手机号码",
+          prop: "phonenumber",
+          hidden: true,
+        },
+        {
+          label: "邮箱",
+          prop: "email",
+          hidden: true,
+        },
+        {
+          label: "状态",
+          prop: "status",
+          hidden: true,
+          scope: "status",
+        },
+      ],
+      listData: {},
+      rules: {
+        userName: [
+          {
+            required: true,
+            message: "请输入账号名称",
+            trigger: "blur",
+          },
+        ],
+        password: [
+          {
+            required: true,
+            message: "请输入账号密码",
+            trigger: "blur",
+          },
+        ],
+        nickName: [
+          {
+            required: true,
+            message: "请输入真实姓名",
+            trigger: "blur",
+          },
+        ],
+        phonenumber: [
+          {
+            required: false,
+            message: "请输入手机号码",
+            trigger: "blur",
+          },
+          {
+            pattern: /^1[34578]\d{9}$/,
+            message: "请输入正确手机号",
+            trigger: "blur",
+          },
+        ],
+        email: [
+          {
+            required: false,
+            message: "请输入邮箱",
+            trigger: "blur",
+          },
+        ],
+        roleIds: [
+          {
+            required: true,
+            message: "请选择角色名称",
+            trigger: "change",
+          },
+        ],
+        status: [
+          {
+            required: true,
+            message: "状态不能为空",
+            trigger: "change",
+          },
+        ],
+      },
+      statusOptions: [
+        {
+          label: "启用",
+          value: 1,
+        },
+        {
+          label: "关闭",
+          value: 0,
+        },
+      ],
+      statusPop: 1,
+      dialogVisible: false,
+      listData: {},
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      pageSize: 10, //每页多少条数据
+      currentPage: 1, //当前页码
+    };
+  },
+  computed: { ...mapGetters(["roleList"]) },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    search(v) {
+      this.loading = true;
+      var data = {
+        statusArray: "0,1",
+        pageSize: this.pageSize,
+        pageNum: this.currentPage,
+      };
+      this.$api
+        .obtainUserList(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search();
+    },
+    addClick(v, int) {
+      if (v === undefined) {
+        this.statusPop = 1;
+        this.listData = {
+          status: 1,
+        };
+      } else {
+        this.statusPop = int;
+        this.listData = JSON.parse(JSON.stringify(v));
+      }
+      this.$nextTick(() => {
+        this.$refs.listData.clearValidate();
+      });
+      this.dialogVisible = true;
+    },
+    del(v) {
+      this.$confirm("此操作将删除该岗位, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          // var data = JSON.parse(JSON.stringify(v));
+          // data.menuIds = [];
+          // data.status = "-1";
+          var data = {
+            userId: v.userId,
+            status: -1,
+            userName: v.userName,
+            roleIds: [],
+          };
+          this.$api.editUser(data).then((res) => {
+            if (res.code === 200) {
+              this.$message.success("删除成功");
+              this.search();
+              this.dialogVisible = false;
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    onClose() {
+      this.$refs["listData"].resetFields();
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (!valid) return;
+        this.disabledBtn = true;
+        if (this.listData.userId) {
+          this.$api
+            .editUser(this.listData)
+            .then((res) => {
+              this.$message.success("修改成功");
+              this.search();
+              this.close();
+            })
+            .catch(() => {
+              this.disabledBtn = false;
+            });
+        } else {
+          this.$api
+            .addUser(this.listData)
+            .then((res) => {
+              this.$message.success("新增成功");
+              this.search();
+              this.close();
+            })
+            .catch(() => {
+              this.disabledBtn = false;
+            });
+        }
+      });
+    },
+    handleSizeChange(v) {
+      this.pageSize = v;
+      this.currentPage = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.currentPage = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>
+

+ 519 - 0
src/views/systemManagement/auditManagement/assignReviewers/index.vue

@@ -0,0 +1,519 @@
+<template>
+  <div id="assignReviewers">
+    <div class="floatSty">
+      <div class="headsty">资料审核管理</div>
+      <div class="dis_sty">
+        <div class="btnSty" @click="getInfo(1)">资料审核</div>
+        <!-- <div class="btnSty" @click="getInfo(2)">盖章资料审核</div> -->
+      </div>
+    </div>
+    <div class="floatSty">
+      <div class="headsty">网课学习管理</div>
+      <div class="dis_sty">
+        <div class="btnSty" @click="getInfo(2)">学时审核</div>
+      </div>
+    </div>
+    <div class="floatSty">
+      <div class="headsty">订单管理</div>
+      <div class="dis_sty">
+        <div class="btnSty" @click="getInfo(3)">退款审核</div>
+      </div>
+    </div>
+    <div style="clear: both"></div>
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="610px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">{{ getName(statePop) }}</div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialogVisible = false"
+          />
+        </div>
+      </div>
+      <div>
+        <el-row :gutter="20">
+          <el-col :span="12" class="leftBox">
+            <div
+              v-for="(item, index) in educationType"
+              :key="index"
+              style="margin-bottom: 6px"
+            >
+              <div
+                @click="getFist(item.id)"
+                style="cursor: pointer; margin-bottom: 6px"
+              >
+                <i
+                  :class="
+                    item.id === activeFist
+                      ? 'el-icon-caret-bottom'
+                      : 'el-icon-caret-right'
+                  "
+                ></i>
+                {{ item.onlyName }}
+              </div>
+              <ul
+                v-if="item.id === activeFist"
+                style="margin: 0px; padding-left: 18px"
+              >
+                <li
+                  v-for="(items, indexs) in item.children"
+                  :key="indexs"
+                  style="margin-bottom: 4px; cursor: pointer"
+                  :style="businessId === items.id ? 'color:red;' : ''"
+                  @click="getapiUserList(items)"
+                >
+                  {{ items.onlyName }}
+                </li>
+                <li v-if="!item.children.length" style="color: blue">
+                  暂无选项
+                </li>
+              </ul>
+            </div>
+          </el-col>
+          <el-col :span="12" v-if="businessId">
+            <el-select
+              v-model="activeUserid"
+              placeholder="请选择审核人"
+              @change="editUserList"
+            >
+              <el-option
+                v-for="(item, index) in options"
+                :key="index"
+                :label="item.nickName"
+                :value="item.userId"
+                :disabled="userList1.indexOf(item.userId) !== -1"
+              >
+              </el-option>
+            </el-select>
+            <ul style="max-height: 300px; overflow: auto">
+              <li
+                v-for="(item, index) in userList1"
+                :key="index"
+                class="userName"
+              >
+                {{ getuserName(item) }}
+                <i
+                  class="el-icon-error clearSty"
+                  @click="userList1.splice(index, 1)"
+                ></i>
+                <div style="clear: both"></div>
+              </li>
+            </ul>
+            <div v-if="statePop === 2 || statePop === 3">
+              <el-select
+                v-model="activeUserid"
+                placeholder="请选择复审人"
+                @change="editUserLists"
+              >
+                <el-option
+                  v-for="(item, index) in options"
+                  :key="index"
+                  :label="item.nickName"
+                  :value="item.userId"
+                  :disabled="userList2.indexOf(item.userId) !== -1"
+                >
+                </el-option>
+              </el-select>
+              <ul style="max-height: 300px; overflow: auto">
+                <li
+                  v-for="(item, index) in userList2"
+                  :key="index"
+                  class="userName"
+                >
+                  {{ getuserName(item) }}
+                  <i
+                    class="el-icon-error clearSty"
+                    @click="userList2.splice(index, 1)"
+                  ></i>
+                  <div style="clear: both"></div>
+                </li>
+              </ul>
+            </div>
+            <div style="text-align: center">
+              <el-button size="mini" @click="submits">确定</el-button>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">取 消</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      dialogVisible: false,
+      statePop: "",
+      educationType: [],
+      options: [], //审核人列表
+      activeUserid: "", //select的v-model绑定值
+      activeFist: "", //当前选中教育类型ID
+      businessId: "",
+      userList1: [],
+      userList2: [],
+    };
+  },
+  mounted() {
+    this.getTypes();
+  },
+  methods: {
+    /**
+     *
+     * @param {Number} int
+     * @remards 点击教育类型触发
+     */
+    getFist(int) {
+      if (this.activeFist === int) {
+        this.activeFist = "";
+      } else {
+        this.activeFist = int;
+      }
+    },
+    /**
+     * 确定提交修改
+     */
+    submits() {
+      if (!this.userList1.length) {
+        this.$message.warning("请选择指派审核人");
+        return;
+      }
+
+      if (this.statePop === 2 || this.statePop === 3) {
+        if (!this.userList2.length) {
+          this.$message.warning("请选择指派复审人");
+          return;
+        }
+      }
+      /**
+       * 提交api
+       */
+      if (this.statePop === 1) {
+        let ays = {
+          id: this.businessId,
+          profileTpUserIds: this.userList1.toString(),
+          // userList2: this.userList2,
+        };
+        this.$api.editcourseBusinessProfileTpUserIds(ays).then((res) => {
+          this.$message.success("指派成功");
+        });
+      }
+      if (this.statePop === 2) {
+        let ays = {
+          id: this.businessId,
+          periodUserIds: this.userList1.toString(),
+          periodConfirmUserIds: this.userList2.toString(),
+        };
+        this.$api.editcourseBusinessPeriodUserIds(ays).then((res) => {
+          this.$message.success("指派成功");
+        });
+      }
+      if (this.statePop === 3) {
+        let ays = {
+          id: this.businessId,
+          refundUserIds: this.userList1.toString(),
+          refundConfirmUserIds: this.userList2.toString(),
+        };
+        this.$api.editRefundPeriodUserIdsCourseBusiness(ays).then((res) => {
+          this.$message.success("指派成功");
+        });
+      }
+    },
+    /**
+     *
+     * @param {Number} int
+     * @remards 新增审核人
+     */
+    editUserList(int) {
+      this.userList1.push(int);
+      this.activeUserid = "";
+    },
+    /**
+     *
+     * @param {Number} int
+     * @remards 新增复审人
+     */
+    editUserLists(int) {
+      this.userList2.push(int);
+      this.activeUserid = "";
+    },
+    /**
+     * 点击业务层次获取对应审核人
+     */
+    getapiUserList(item) {
+      this.businessId = item.id;
+      /**
+       * 模拟数据
+       */
+      this.userList1 = [];
+      this.userList2 = [];
+      this.$api
+        .inquiresystemUserbusinessPeopleList({ id: item.id })
+        .then((res) => {
+          this.options = res.rows;
+          this.$api.obtainbusiness(item.id).then((result) => {
+            if (this.statePop === 1) {
+              if (result.data.profileTpUserIds) {
+                this.userList1 = result.data.profileTpUserIds
+                  .split(",")
+                  .map(Number);
+              }
+            }
+            if (this.statePop === 2) {
+              if (result.data.periodUserIds) {
+                this.userList1 = result.data.periodUserIds
+                  .split(",")
+                  .map(Number);
+              }
+              if (result.data.periodConfirmUserIds) {
+                this.userList2 = result.data.periodConfirmUserIds
+                  .split(",")
+                  .map(Number);
+              }
+            }
+            if (this.statePop === 3) {
+              if (result.data.refundUserIds) {
+                this.userList1 = result.data.refundUserIds
+                  .split(",")
+                  .map(Number);
+              }
+              if (result.data.refundConfirmUserIds) {
+                this.userList2 = result.data.refundConfirmUserIds
+                  .split(",")
+                  .map(Number);
+              }
+            }
+          });
+        });
+    },
+    /**
+     * 获取教育类型及业务层次
+     */
+    getTypes() {
+      this.$api.inquireCourseEducationType({ status: 1 }).then((res) => {
+        this.$api.inquirebusinessList({ status: 1 }).then((result) => {
+          result.rows.forEach((items) => {
+            items.onlyName = items.projectName + "-" + items.businessName;
+            res.rows.forEach((ite, ide) => {
+              ite.onlyName = ite.educationName;
+              ite.checked = false;
+              if (!ite.children) {
+                ite.children = [];
+              }
+              if (items.educationId === ite.id) {
+                ite.children.push(items);
+              }
+            });
+          });
+          this.educationType = res.rows;
+        });
+      });
+    },
+    /**
+     * 获取标题
+     */
+    getName(int) {
+      var ast = "";
+      switch (int) {
+        case 1:
+          ast = "资料审核-指派审核人";
+          break;
+        case 2:
+          ast = "学时审核-指派审核人";
+          break;
+        case 3:
+          ast = "退款审核-指派审核人";
+          break;
+        default:
+          break;
+      }
+      return ast;
+    },
+    /**
+     * 转换审核人名字
+     */
+    getuserName(int) {
+      var ast = "";
+      for (let i = 0; i < this.options.length; i++) {
+        if (this.options[i].userId === int) {
+          return this.options[i].nickName;
+        }
+      }
+    },
+    /**
+     *
+     * @param {Number} int 1资料审核2学时审核
+     * 初始化窗口数据
+     */
+    getInfo(int) {
+      this.statePop = int;
+      this.activeFist = "";
+      this.activeUserid = "";
+      this.businessId = "";
+      this.userList1 = [];
+      this.userList2 = [];
+      this.dialogVisible = true;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.leftBox {
+  border: 1px solid #999;
+  border-radius: 4px;
+  overflow-y: auto;
+  max-height: 400px;
+  padding: 10px;
+}
+.floatSty {
+  float: left;
+  margin-right: 20px;
+  margin-bottom: 20px;
+  border-radius: 4px;
+  overflow: hidden;
+  border: 1px solid #999;
+  .headsty {
+    height: 30px;
+    line-height: 30px;
+    background-color: #eee;
+    color: #333;
+    text-align: center;
+    font-size: 14px;
+  }
+  .dis_sty {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding: 20px;
+    .btnSty {
+      padding: 0px 10px;
+      height: 28px;
+      line-height: 28px;
+      text-align: center;
+      border-radius: 4px;
+      border: 1px solid #999;
+      font-size: 14px;
+      margin-bottom: 10px;
+      cursor: pointer;
+      transition: all 0.2s;
+      &:hover {
+        background-color: #f4f4f4;
+      }
+    }
+  }
+}
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+.userName {
+  display: table;
+  border-radius: 4px;
+  border: 1px solid #999;
+  margin: 0px 6px 6px 0px;
+  padding: 0px 8px;
+  height: 26px;
+  line-height: 26px;
+  font-size: 14px;
+  .clearSty {
+    color: red;
+    cursor: pointer;
+    font-size: 14px;
+  }
+}
+</style>

+ 268 - 0
src/views/systemManagement/mechanism/dislog.vue

@@ -0,0 +1,268 @@
+<template>
+  <div>
+    <BaseDialog
+      width="800px"
+      :isShow.sync="isShow"
+      :title="activeData.tenantId ? '修改' : '新增'"
+      @submit="submitForm"
+      @close="close"
+    >
+      <el-form
+        :model="formData"
+        :rules="rules"
+        ref="formData"
+        label-width="100px"
+        class="demo-ruleForm"
+      >
+        <el-form-item label="机构名称:" prop="tenantName">
+          <el-input
+            clearable
+            v-model="formData.tenantName"
+            placeholder="输入机构名称"
+          ></el-input> </el-form-item
+        ><el-form-item label="h5域名:" prop="hostH5"
+          ><el-input
+            clearable
+            v-model="formData.hostH5"
+            placeholder="输入h5域名"
+          ></el-input></el-form-item
+        ><el-form-item label="PC域名:" prop="hostPc"
+          ><el-input
+            clearable
+            v-model="formData.hostPc"
+            placeholder="输入PC域名"
+          ></el-input
+        ></el-form-item>
+        <el-form-item label="账期设置:" required>
+          <el-col :span="9">
+            <el-form-item label="" prop="billType">
+              <el-select
+                v-model="formData.billType"
+                placeholder="选择账期类型"
+                clearable
+              >
+                <el-option label="月度" :value="1"> </el-option
+                ><el-option label="季度" :value="2"> </el-option
+                ><el-option label="半年" :value="3"> </el-option>
+                <el-option label="年度" :value="4"> </el-option>
+              </el-select> </el-form-item
+          ></el-col>
+          <el-col :span="9"
+            ><el-form-item label="" prop="billDay">
+              <el-select
+                v-model="formData.billDay"
+                placeholder="选择次月"
+                clearable
+              >
+                <el-option
+                  v-for="(item, index) in days"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option>
+              </el-select> </el-form-item
+          ></el-col>
+        </el-form-item>
+        <el-form-item label="收款账号:" required>
+          <el-col :span="9">
+            <el-form-item
+              label=""
+              :prop="'accountList.' + 0 + '.openingName'"
+              :rules="rules['openingName']"
+            >
+              <el-input
+                clearable
+                v-model="formData.accountList[0].openingName"
+                placeholder="输入开户名"
+              ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="9">
+            <el-form-item
+              label=""
+              :prop="'accountList.' + 0 + '.openingBank'"
+              :rules="rules['openingBank']"
+            >
+              <el-input
+                clearable
+                v-model="formData.accountList[0].openingBank"
+                placeholder="输入开户行"
+              ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="9">
+            <el-form-item
+              label=""
+              :prop="'accountList.' + 0 + '.proceedsAccount'"
+              :rules="rules['proceedsAccount']"
+            >
+              <el-input
+                style="margin-top: 20px"
+                clearable
+                v-model="formData.accountList[0].proceedsAccount"
+                placeholder="输入账号"
+              ></el-input>
+            </el-form-item>
+          </el-col>
+        </el-form-item>
+        <el-form-item label="开票信息:" required>
+          <el-col :span="9">
+            <el-form-item
+              label=""
+              :prop="'invoiceBo.' + 'invoiceType'"
+              :rules="rules['invoiceType']"
+            >
+              <el-select
+                v-model="formData.invoiceBo.invoiceType"
+                placeholder="选择发票类型"
+                clearable
+              >
+                <el-option label="普票" :value="1"> </el-option
+                ><el-option label="专票" :value="2"> </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="9">
+            <el-form-item
+              label=""
+              :prop="'invoiceBo.' + 'invoice'"
+              :rules="rules['invoice']"
+              ><el-input
+                clearable
+                v-model="formData.invoiceBo.invoice"
+                placeholder="输入发票抬头(企业或个人)"
+              ></el-input> </el-form-item
+          ></el-col>
+          <el-col :span="9">
+            <el-form-item
+              label=""
+              :prop="'invoiceBo.' + 'taxpayer'"
+              :rules="rules['taxpayer']"
+            >
+              <el-input
+                style="margin-top: 20px"
+                clearable
+                v-model="formData.invoiceBo.taxpayer"
+                placeholder="输入纳税人"
+              ></el-input> </el-form-item
+          ></el-col>
+        </el-form-item>
+      </el-form>
+    </BaseDialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "",
+  props: {
+    dialogVisible: {
+      type: Boolean,
+      default: false,
+    },
+    activeData: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      formData: {
+        accountList: [{}],
+        invoiceBo: {},
+      },
+      rules: {
+        tenantName: [
+          { required: true, message: "请输入机构名称", trigger: "blur" },
+        ],
+        billType: [
+          { required: true, message: "请选择账期类型", trigger: "change" },
+        ],
+        billDay: [
+          { required: true, message: "请选择次月日期", trigger: "change" },
+        ],
+        openingName: [
+          { required: true, message: "请输入开户名", trigger: "blur" },
+        ],
+        openingBank: [
+          { required: true, message: "请输入开户行", trigger: "blur" },
+        ],
+        proceedsAccount: [
+          { required: true, message: "请输入账号", trigger: "blur" },
+        ],
+        invoiceType: [
+          { required: true, message: "请选择发票类型", trigger: "change" },
+        ],
+        invoice: [
+          { required: true, message: "请输入发票抬头", trigger: "blur" },
+        ],
+        taxpayer: [
+          { required: true, message: "请输入纳税人", trigger: "blur" },
+        ],
+      },
+      days: [],
+    };
+  },
+  mounted() {
+    this.getDays();
+  },
+
+  methods: {
+    //获取天数 从第6天算起 至31日
+    getDays() {
+      for (let i = 6; i <= 31; i++) {
+        this.days.push({ label: i + "日", value: i });
+      }
+    },
+    init() {
+      this.formData = JSON.parse(JSON.stringify(this.activeData));
+      this.formData.accountList = this.formData.accountList || [{}];
+      this.formData.invoiceBo = this.formData.invoiceBo || {};
+    },
+    close() {
+      this.$refs["formData"].resetFields();
+    },
+    submitForm() {
+      this.$refs["formData"].validate((valid) => {
+        if (valid) {
+          this.$api[
+            this.activeData.tenantId ? "systemtenantedittop" : "systemtenantadd"
+          ](this.formData).then((res) => {
+            this.$message.success("成功");
+            this.isShow = false;
+            this.$emit("search");
+          });
+        } else {
+          return false;
+        }
+      });
+    },
+  },
+  computed: {
+    isShow: {
+      get() {
+        if (this.dialogVisible) {
+          this.init();
+        }
+        return this.dialogVisible;
+      },
+      set(val) {
+        this.$emit("update:dialogVisible", false);
+      },
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.el-input {
+  width: 220px;
+  margin-right: 10px;
+}
+.el-select {
+  width: 220px;
+  margin-right: 10px;
+}
+</style>

+ 286 - 0
src/views/systemManagement/mechanism/index.vue

@@ -0,0 +1,286 @@
+<template>
+  <div id="mechanism">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    />
+    <table-list
+      rowKey="id"
+      ref="tableList"
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+      @addClick="addClick"
+    >
+      <template slot="status" slot-scope="props">
+        <el-popover placement="right" width="650" trigger="click">
+          <el-table border :data="props.scope.row.accountList">
+            <el-table-column
+              type="index"
+              label="序号"
+              width="70"
+              align="center"
+              header-align="center"
+            >
+            </el-table-column>
+            <el-table-column
+              width="120"
+              property="openingBank"
+              label="开户银行"
+              align="center"
+            ></el-table-column>
+            <el-table-column
+              width="180"
+              property="openingName"
+              label="开户名称"
+              align="center"
+            ></el-table-column>
+            <el-table-column
+              property="proceedsAccount"
+              label="收款账号"
+              align="center"
+            ></el-table-column>
+          </el-table>
+          <el-button
+            slot="reference"
+            type="text"
+            :disabled="
+              !props.scope.row.accountList ||
+              props.scope.row.accountList.length === 0
+            "
+            >查看</el-button
+          >
+        </el-popover>
+      </template>
+      <template slot="domainName" slot-scope="props">
+        <p>移动端:{{ props.scope.row.hostH5 }}</p>
+        <p>电脑端:{{ props.scope.row.hostPc }}</p>
+      </template>
+      <template slot="accountPeriodSetting" slot-scope="props">
+        <p>
+          {{ getBillType(props.scope.row.billType) }},次月{{
+            props.scope.row.billDay || " "
+          }}日
+        </p>
+      </template>
+      <template slot="invoiceInformation" slot-scope="props">
+        <p>
+          发票类型:<span v-if="props.scope.row.invoiceBo !== null">
+            {{
+              props.scope.row.invoiceBo["invoiceType"] === 1
+                ? "普票"
+                : props.scope.row.invoiceBo["invoiceType"] === 2
+                ? "专票"
+                : ""
+            }}</span
+          >
+        </p>
+        <p>
+          发票抬头:<span v-if="props.scope.row.invoiceBo !== null">{{
+            props.scope.row.invoiceBo["invoice"]
+          }}</span>
+        </p>
+        <p>企业名称:{{ props.scope.row.tenantName }}</p>
+        <p>
+          纳税人:<span v-if="props.scope.row.invoiceBo !== null">{{
+            props.scope.row.invoiceBo["taxpayer"]
+          }}</span>
+        </p>
+      </template>
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="addClick(props.scope.row)"
+          >修改</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize.sync="formData.pageSize"
+      :currentPage.sync="formData.pageNum"
+      @search="search"
+    />
+    <dislog
+      :dialogVisible.sync="dialogVisible"
+      @search="search"
+      :activeData="activeData"
+    ></dislog>
+  </div>
+</template>
+
+<script>
+import dislog from "./dislog.vue";
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "Mechanism",
+  components: { searchBoxNew, tableList, pagination, dislog },
+  data() {
+    return {
+      loading: false,
+      navText: {
+        title: "机构列表",
+        index: 0,
+        ch: "条",
+        num: true,
+        choice: false,
+        addHide: false,
+        custom: false,
+      },
+      formList: [
+        {
+          prop: "tenantid",
+          placeholder: "请选择机构名称",
+          scope: "systemtenantlist",
+        },
+      ],
+      formData: {},
+      tableSet: [
+        {
+          label: "机构名称",
+          prop: "tenantName",
+          hidden: true,
+        },
+        {
+          label: "网站域名",
+          prop: "address",
+          hidden: true,
+          scope: "solt",
+          soltName: "domainName",
+        },
+        {
+          label: "账期设置",
+          prop: "address",
+          hidden: true,
+          scope: "solt",
+          soltName: "accountPeriodSetting",
+        },
+        {
+          label: "分成模式",
+          prop: "divideModel",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "机构分成",
+              value: 1,
+            },
+            {
+              label: "业务员分成",
+              value: 2,
+            },
+          ],
+        },
+        {
+          label: "是否有商户号",
+          prop: "commercialTenant",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "是",
+              value: 1,
+            },
+            {
+              label: "否",
+              value: 0,
+            },
+          ],
+        },
+        {
+          label: "银行账号信息",
+          prop: "accountList",
+          hidden: true,
+          scope: "solt",
+          soltName: "status",
+        },
+        {
+          label: "发票信息",
+          prop: "address",
+          hidden: true,
+          scope: "solt",
+          soltName: "invoiceInformation",
+        },
+      ],
+      tableData: [],
+      total: 0,
+      dialogVisible: false,
+      activeData: {},
+    };
+  },
+  created() {
+    this.search(2);
+  },
+  methods: {
+    getBillType(e) {
+      var a = "";
+      switch (e) {
+        case 1:
+          a = "月份";
+          break;
+        case 2:
+          a = "季度";
+          break;
+        case 3:
+          a = "半年";
+          break;
+        case 4:
+          a = "年度";
+          break;
+
+        default:
+          break;
+      }
+      return a;
+    },
+    addClick(data) {
+      this.activeData = data || {};
+      this.dialogVisible = true;
+    },
+    search(v) {
+      this.loading = true;
+      if (v === 2) {
+        this.formData = {
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      this.$api
+        .systemtenantlist(this.formData)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search(2);
+    },
+    del(v) {
+      this.$alert(
+        "确定删除此内容?<br />内容删除后将无法恢复,请慎重考虑",
+        "提示",
+        {
+          dangerouslyUseHTMLString: true,
+        }
+      )
+        .then(() => {})
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 415 - 0
src/views/systemManagement/myManagement/myProfile/index.vue

@@ -0,0 +1,415 @@
+<template>
+  <div id="myProfile" v-if="userInfo.length">
+    <div class="lisStys" v-for="(item, index) in lists" :key="index">
+      <span class="leftSty">{{ item.label }}</span>
+      <template v-if="item.prop === 'roles'">
+        <span
+          v-for="(items, indexs) in userInfo[0].user[item.prop]"
+          :key="indexs"
+          >{{ items.roleName
+          }}{{
+            indexs === userInfo[0].user[item.prop].length - 1 ? "" : "、"
+          }}</span
+        >
+      </template>
+      <span v-else-if="item.value === 2">******</span>
+      <span v-else-if="item.prop === 'status'">{{
+        userInfo[0].user[item.prop] == 1 ? "有效" : "失效"
+      }}</span>
+      <img
+        class="imgBoxs"
+        v-else-if="item.prop === 'avatar'"
+        :src="$methodsTools.splitImgHost(userInfo[0].user[item.prop])"
+      />
+      <span v-else>{{ userInfo[0].user[item.prop] }}</span>
+      <span
+        v-if="item.value !== 6 && item.value !== 7 && item.value !== 0"
+        class="btnsty"
+        @click="openBoxs(userInfo[0].user[item.prop], item.value)"
+        >修改</span
+      >
+      <label v-if="item.value === 0"
+        ><span class="btnsty">修改</span
+        ><input
+          ref="file"
+          type="file"
+          style="display: none"
+          @change="uploadImgs"
+      /></label>
+    </div>
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="560px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ changeName }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="110px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item v-if="int === 1" label="账号名称" prop="userName">
+            <el-input v-model="listData.userName"></el-input>
+          </el-form-item>
+          <div v-if="int === 2">
+            <el-form-item label="原密码" prop="oldPassword">
+              <el-input v-model="listData.oldPassword"></el-input>
+            </el-form-item>
+            <el-form-item label="新密码" prop="password">
+              <el-input v-model="listData.password"></el-input>
+            </el-form-item>
+            <el-form-item label="确认密码" prop="againPassword">
+              <el-input v-model="listData.againPassword"></el-input>
+            </el-form-item>
+          </div>
+          <el-form-item v-if="int === 3" label="真实姓名" prop="nickName">
+            <el-input v-model="listData.nickName"></el-input>
+          </el-form-item>
+          <el-form-item v-if="int === 4" label="手机号码" prop="phonenumber">
+            <el-input v-model="listData.phonenumber"></el-input> </el-form-item
+          ><el-form-item v-if="int === 5" label="邮箱" prop="email">
+            <el-input v-model="listData.email"></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button type="primary" @click="submit('listData')">确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+export default {
+  data() {
+    var validatePass = (rule, value, callback) => {
+      var testPass = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{12,20}$/;
+      if (!value) {
+        callback(new Error("请输入密码"));
+      } else if (!testPass.test(value)) {
+        callback(new Error("密码至少为12位的数字和字母混合"));
+      } else {
+        if (this.listData.againPassword != "") {
+          this.$refs.listData.validateField("againPassword");
+        }
+        callback();
+      }
+    };
+    var validatePass2 = (rule, value, callback) => {
+      var testPass = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{12,20}$/;
+      if (!value) {
+        callback(new Error("请再次输入密码"));
+      } else if (!testPass.test(value)) {
+        callback(new Error("密码至少为12位的数字和字母混合"));
+      } else if (value !== this.listData.password) {
+        callback(new Error("两次输入密码不一致!"));
+      } else {
+        callback();
+      }
+    };
+    return {
+      dialogVisible: false,
+      lists: [
+        {
+          label: "账号头像:",
+          prop: "avatar",
+          value: 0,
+        },
+        {
+          label: "账号名称:",
+          prop: "userName",
+          value: 1,
+        },
+        {
+          label: "账号密码:",
+          value: 2,
+        },
+        {
+          label: "真实姓名:",
+          prop: "nickName",
+          value: 3,
+        },
+        {
+          label: "手机号码:",
+          prop: "phonenumber",
+          value: 4,
+        },
+        {
+          label: "E-mail:",
+          prop: "email",
+          value: 5,
+        },
+        {
+          label: "角色:",
+          prop: "roles",
+          value: 6,
+        },
+        {
+          label: "状态:",
+          prop: "status",
+          value: 7,
+        },
+      ],
+      int: 0,
+      rules: {
+        userName: [
+          { required: true, message: "请输入账号名称", trigger: "blur" },
+        ],
+        oldPassword: [
+          { required: true, message: "请输入原密码", trigger: "blur" },
+        ],
+        // password: [
+        //   { required: true, validator: validatePass, trigger: "blur" },
+        // ],
+        // againPassword: [
+        //   { required: true, validator: validatePass2, trigger: "blur" },
+        // ],
+        nickName: [
+          { required: true, message: "请输入真实姓名", trigger: "blur" },
+        ],
+      },
+      listData: {},
+    };
+  },
+  computed: {
+    ...mapGetters(["userInfo"]),
+    changeName() {
+      var names;
+      switch (this.int) {
+        case 1:
+          names = "修改账号名称";
+          break;
+        case 2:
+          names = "修改密码";
+          break;
+        case 3:
+          names = "修改真实姓名";
+          break;
+        case 4:
+          names = "修改手机号码";
+          break;
+        case 5:
+          names = "修改邮箱";
+          break;
+        default:
+          break;
+      }
+      return names;
+    },
+  },
+  methods: {
+    uploadImgs(e) {
+      var self = this;
+      var file = self.$refs.file[0].files[0];
+      if (file.size > 0.3 * 1024 * 1024) {
+        self.$message.error("图片不得大于300kb");
+        return;
+      }
+      var type = self.$refs.file[0].value.toLowerCase().split(".").splice(-1);
+      if (
+        type[0] != "jpg" &&
+        type[0] != "png" &&
+        type[0] != "jpeg" &&
+        type[0] != "gif"
+      ) {
+        self.$message.error("上传格式需为:.jpg/.png/.jpeg/gif");
+        return;
+      }
+      this.$upload.upload(file, 0).then((res) => {
+        self.listData.avatar = res;
+        self.roleForm();
+      });
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.roleForm();
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    roleForm() {
+      var self = this;
+      this.listData.userId = this.userInfo[0].user.userId;
+      this.listData.userName = this.userInfo[0].user.userName;
+      this.$api.editUser(this.listData).then((res) => {
+        this.$message.success("修改成功");
+        if (this.int === 2) {
+          self.$store.dispatch("outLogin").then(() => {});
+          return;
+        }
+        this.$store.dispatch("fenleiCart");
+        this.dialogVisible = false;
+      });
+    },
+    //删除cookie (名称)
+    delCookie(name) {
+      var exp = new Date();
+      exp.setTime(exp.getTime() - 1);
+      var cval = cookie.getCookie(name);
+      if (cval != null)
+        document.cookie =
+          name + "=" + ";expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+    openBoxs(value, int) {
+      this.int = int;
+      switch (int) {
+        case 3:
+          this.listData = {
+            nickName: value,
+          };
+          break;
+        case 4:
+          this.listData = {
+            phonenumber: value,
+          };
+          break;
+        case 5:
+          this.listData = {
+            email: value,
+          };
+          break;
+        default:
+          this.listData = {};
+          break;
+      }
+      this.dialogVisible = true;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.lisStys {
+  font-size: 14px;
+  color: #333;
+  margin-bottom: 6px;
+  .leftSty {
+    display: inline-block;
+    width: 80px;
+    text-align: end;
+  }
+  .btnsty {
+    transition: all 0.2s;
+    cursor: pointer;
+    font-size: 12px;
+    color: #a4a4a4;
+    &:hover {
+      color: skyblue;
+    }
+  }
+}
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+.imgBoxs {
+  width: 100px;
+  height: 100px;
+  border-radius: 50%;
+  background-color: #fff;
+}
+</style>

+ 278 - 0
src/views/systemManagement/registeredUser/index.vue

@@ -0,0 +1,278 @@
+<template>
+  <div id="registeredUser">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    />
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name:"RegisteredUser",
+  components: { searchBoxNew, tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "注册用户",
+        index: 0,
+        ch: "条",
+        num: false,
+        choice: true,
+        tableHide: true,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          prop: "nickname",
+          placeholder: "请输入用户昵称",
+        },
+      ],
+      formData: {
+        status: "0,1",
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "用户编码",
+          prop: "studentCode",
+          hidden: true,
+        },
+        {
+          label: "头像",
+          prop: "avatar",
+          hidden: true,
+          scope: "img",
+        },
+        {
+          label: "昵称",
+          prop: "nickname",
+          hidden: true,
+        },
+        {
+          label: "性别",
+          prop: "sex",
+          hidden: true,
+          scope: "sex",
+        },
+        // {
+        //   label: "年龄",
+        //   prop: "payWay",
+        //   hidden: true,
+        // },
+        {
+          label: "姓名",
+          prop: "realname",
+          hidden: true,
+        },
+        {
+          label: "身份证",
+          prop: "idCard",
+          hidden: true,
+        },
+        {
+          label: "手机号码",
+          prop: "telphone",
+          hidden: true,
+        },
+        {
+          label: "所在城市",
+          prop1: "province",
+          prop2: "city",
+          prop3: "district",
+          hidden: true,
+          scope: "address",
+        },
+        {
+          label: "注册时间",
+          prop: "createTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "归属来源",
+          prop: "registerPlat",
+          hidden: true,
+          scope: "ptai",
+        },
+        {
+          label: "历史购课数量",
+          prop: "orderNum",
+          hidden: true,
+        },
+        {
+          label: "最后一次登录时间",
+          prop: "lastLoginTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      pageSize: 10, //每页多少条数据
+      currentPage: 1, //当前页码
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 2) {
+        this.formData = {
+          status: "0,1",
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      this.$api
+        .inquireappuserlists(this.formData)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search(2);
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>
+

+ 758 - 0
src/views/systemManagement/roleManagement/index.vue

@@ -0,0 +1,758 @@
+<template>
+  <div id="roleManagement">
+    <!-- <search-box :formList="formList" @search="search" @init="init" /> -->
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      @addClick="addClick"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <!-- <el-button type="text" @click="addClick(props.scope.row, 2)"
+          >详情</el-button
+        > -->
+        <el-button type="text" @click="addClick(props.scope.row, 0)"
+          >编辑</el-button
+        >
+        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="pageSize"
+      :currentPage="currentPage"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogVisible"
+      width="860px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-row :gutter="10">
+          <el-form
+            label-position="right"
+            label-width="100px"
+            :model="listData"
+            :rules="rules"
+            ref="listData"
+            ><el-col
+              :span="12"
+              v-for="(items, indexs) in listitem"
+              :key="indexs"
+            >
+              <el-form-item :label="items.label" :prop="items.prop">
+                <el-radio-group
+                  v-if="items.scope === 'status'"
+                  v-model="listData[items.prop]"
+                >
+                  <el-radio
+                    v-for="(item, index) in items.options"
+                    :key="index"
+                    :label="item.value"
+                    :disabled="statusPop === 2"
+                    >{{ item.label }}</el-radio
+                  >
+                </el-radio-group>
+                <div v-else-if="items.scope === 'tree'">
+                  <el-checkbox
+                    v-model="menuExpand"
+                    @change="handleCheckedTreeExpand($event, 'menu')"
+                    >展开/折叠</el-checkbox
+                  >
+                  <el-checkbox
+                    v-model="menuNodeAll"
+                    @change="handleCheckedTreeNodeAll($event, 'menu')"
+                    >全选/全不选</el-checkbox
+                  >
+                  <!-- <el-checkbox
+                v-model="listData.menuCheckStrictly"
+                @change="handleCheckedTreeConnect($event, 'menu')"
+                >父子联动</el-checkbox
+              > -->
+                  <el-tree
+                    class="tree-border"
+                    :data="menuOptions"
+                    show-checkbox
+                    ref="menu"
+                    node-key="id"
+                    empty-text="加载中,请稍后"
+                    :props="defaultProps"
+                  ></el-tree>
+                </div>
+                <div v-else-if="items.scope === 'treeInfo'">
+                  <el-checkbox
+                    v-model="menuExpandInfo"
+                    @change="handleCheckedTreeExpandInfo($event, 'info')"
+                    >展开/折叠</el-checkbox
+                  >
+                  <el-checkbox
+                    v-model="menuNodeAllInfo"
+                    @change="handleCheckedTreeNodeAllInfo($event, 'info')"
+                    >全选/全不选</el-checkbox
+                  >
+                  <!-- <el-checkbox
+                v-model="listData.menuCheckStrictly"
+                @change="handleCheckedTreeConnect($event, 'menu')"
+                >父子联动</el-checkbox
+              > -->
+                  <!-- :check-strictly="!listData.menuCheckStrictly"👇 -->
+                  <div style="position: relative">
+                    <el-tooltip
+                      effect="light"
+                      class="item"
+                      placement="bottom-start"
+                    >
+                      <div slot="content">
+                        适用模块: <br />1.工作台
+                        <br />2.商品管理(课程查询列表)
+                        <br />3.网课学习管理(班级管理、学时审核管理、学员资料变更、学员推送数据、学习账号标记、学习学时记录)
+                        <br />4.资料审核管理(填写资料审核)
+                        <br />5.考试管理(报考数据)
+                      </div>
+                      <i
+                        class="el-icon-warning-outline"
+                        style="
+                          position: absolute;
+                          font-size: 24px;
+                          font-weight: bold;
+                          color: red;
+                          top: 0px;
+                          left: -31px;
+                          z-index: 9;
+                        "
+                      ></i>
+                    </el-tooltip>
+                    <el-tree
+                      class="tree-border"
+                      :data="menuOptionsInfo"
+                      show-checkbox
+                      ref="info"
+                      node-key="onlyId"
+                      empty-text="加载中,请稍后"
+                      :props="defaultProps"
+                    >
+                    </el-tree>
+                  </div>
+                </div>
+                <el-input
+                  :disabled="statusPop === 2"
+                  v-else-if="items.scope === 'textarea'"
+                  type="textarea"
+                  v-model="listData[items.prop]"
+                ></el-input>
+                <el-input-number
+                  style="width: 100%"
+                  :disabled="statusPop === 2"
+                  v-else-if="items.scope === 'numberIndex'"
+                  v-model="listData[items.prop]"
+                  controls-position="right"
+                  :min="0"
+                  :max="99"
+                ></el-input-number>
+                <el-input
+                  :disabled="statusPop === 2"
+                  v-else
+                  v-model="listData[items.prop]"
+                ></el-input>
+              </el-form-item> </el-col></el-form
+        ></el-row>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button
+          type="primary"
+          :loading="disabledBtn"
+          v-if="statusPop !== 2"
+          @click="submit('listData')"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import searchBox from "@/components/searchBox";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "RoleManagement",
+  components: { searchBox, tableList, pagination },
+  data() {
+    return {
+      disabledBtn: false,
+      keys: [],
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "角色管理",
+        index: 0,
+        ch: "种",
+        num: false,
+        choice: false,
+        addHide: false,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          label: "角色名称",
+          prop: "roleName",
+          placeholder: "请输入角色名称",
+        },
+        {
+          label: "权限字符",
+          prop: "roleKey",
+          placeholder: "请输入权限字符",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          placeholder: "请选择状态",
+          scope: "select",
+          options: [
+            {
+              label: "启用",
+              value: "1",
+            },
+            {
+              label: "停用",
+              value: "0",
+            },
+          ],
+        },
+      ],
+      // 表单
+      tableSet: [
+        {
+          label: "角色编号",
+          prop: "roleId",
+          hidden: true,
+        },
+        {
+          label: "角色名称",
+          prop: "roleName",
+          hidden: true,
+        },
+        {
+          label: "权限字符",
+          prop: "roleKey",
+          hidden: true,
+        },
+        {
+          label: "显示顺序",
+          prop: "roleSort",
+          hidden: true,
+        },
+        {
+          label: "状态",
+          prop: "status",
+          hidden: true,
+          scope: "status",
+        },
+        {
+          label: "创建时间",
+          prop: "createTime",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      pageSize: 10, //每页多少条数据
+      currentPage: 1, //当前页码
+      menuExpand: false,
+      menuNodeAll: false,
+      menuExpandInfo: false,
+      menuNodeAllInfo: false,
+      defaultProps: {
+        children: "children",
+        label: "label",
+      },
+      menuOptions: [], //菜单列表
+      menuOptionsInfo: [], //数据池列表
+      // 弹窗字段
+      listitem: [
+        {
+          label: "角色名称",
+          prop: "roleName",
+        },
+        {
+          label: "权限字符",
+          prop: "roleKey",
+        },
+        {
+          label: "角色顺序",
+          prop: "roleSort",
+          scope: "numberIndex",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          scope: "status",
+          options: [
+            {
+              label: "启用",
+              value: "1",
+            },
+            {
+              label: "关闭",
+              value: "0",
+            },
+          ],
+        },
+        {
+          label: "菜单权限",
+          prop: "menuIds",
+          scope: "tree",
+        },
+        {
+          label: "数据池权限",
+          prop: "keys",
+          scope: "treeInfo",
+        },
+        {
+          label: "备注",
+          prop: "remark",
+          scope: "textarea",
+        },
+      ],
+      //   弹窗数据
+      listData: {},
+      statusPop: -1,
+      dialogVisible: false,
+      //表单验证
+      rules: {
+        roleName: [
+          { required: true, message: "请输入岗位名称", trigger: "blur" },
+        ],
+        roleKey: [
+          { required: true, message: "请输入岗位编码", trigger: "blur" },
+        ],
+        roleSort: [
+          { required: true, message: "请输入岗位顺序", trigger: "blur" },
+        ],
+        status: [{ required: true, message: "请选择状态", trigger: "change" }],
+        // remark: [{ required: true, message: "请填写备注", trigger: "blur" }],
+      },
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    search(v) {
+      this.loading = true;
+      if (v === undefined) {
+        v = {
+          statusArray: "0,1",
+          pageSize: this.pageSize,
+          pageNum: this.currentPage,
+        };
+      }
+      var data = {
+        roleKey: v.roleKey || "",
+        roleName: v.roleName || "",
+        statusArray: v.status === undefined ? "0,1" : v.status,
+        pageSize: this.pageSize,
+        pageNum: this.currentPage,
+      };
+      this.$api
+        .obtainRoleList(data)
+        .then((res) => {
+          this.tableData = res.rows.sort(this.sortBy("postSort", true));
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search();
+    },
+    del(v) {
+      this.$confirm("此操作将删除该岗位, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          var data = JSON.parse(JSON.stringify(v));
+          data.menuIds = [];
+          data.status = "-1";
+          this.$api.editRole(data).then((res) => {
+            if (res.code === 200) {
+              this.$message.success("删除成功");
+              this.search();
+              this.$store.commit("EDICROLELIST");
+              this.dialogVisible = false;
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    addClick(v, int) {
+      var self = this;
+      self.initData();
+      if (v === undefined) {
+        self.statusPop = 1;
+        self.getMenuList();
+        self.getMenuListInfo();
+        self.dialogVisible = true;
+        self.$nextTick(() => {
+          self.$refs.listData.clearValidate();
+        });
+      } else {
+        self.statusPop = int;
+        var data = v.roleId;
+        self.$api.obtainRoleId(data).then(async (res) => {
+          if (res.code === 200) {
+            const getCheckList = await self.getUserMenuList(v.roleId);
+            self.menuOptions = getCheckList.menus;
+            getCheckList.checkedKeys.forEach((v) => {
+              self.$nextTick(() => {
+                self.$refs.menu[0].setChecked(v, true, false);
+              });
+            });
+            self.listData = res.data;
+            self.dialogVisible = true;
+            await self.getMenuListInfo();
+            if (res.data.businessIds) {
+              res.data.businessIds.forEach((v) => {
+                self.$nextTick(() => {
+                  self.$refs.info[0].setChecked("yw-" + v, true, false);
+                });
+              });
+            }
+            self.$nextTick(() => {
+              self.$refs.listData.clearValidate();
+            });
+          }
+        });
+      }
+    },
+    getMenuList() {
+      this.$api.enutreeselect().then((res) => {
+        this.menuOptions = res.data;
+      });
+    },
+    getMenuListInfo() {
+      var self = this;
+      return new Promise((resolve, reject) => {
+        var ary1 = [];
+        self.$api.inquireCourseEducationType({ status: 1 }).then((res) => {
+          res.rows.forEach((item) => {
+            item.label = item.educationName;
+            item.onlyId = "jy-" + item.id;
+            item.children = [];
+          });
+          ary1 = res.rows;
+          self.$api.inquirebusinessList({ status: 1 }).then((result) => {
+            result.rows.forEach((items) => {
+              items.label = items.projectName + items.businessName;
+              items.onlyId = "yw-" + items.id;
+              ary1.forEach((ite) => {
+                if (items.educationId === ite.id) {
+                  ite.children.push(items);
+                }
+              });
+            });
+            self.menuOptionsInfo = ary1;
+            resolve();
+          });
+        });
+      });
+    },
+    getUserMenuList(v) {
+      return new Promise((resolve, reject) => {
+        this.$api.roleMenuTreeselect(v).then((result) => {
+          resolve(result);
+        });
+      });
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    rulesTableSumbit() {
+      this.disabledBtn = true;
+      this.listData.menuIds = this.getMenuAllCheckedKeys();
+      this.listData.businessIds = this.getMenuAllCheckedKeysInfo();
+      if (!this.listData.businessIds.length) {
+        this.disabledBtn = false;
+        return this.$message.error("请勾选数据池");
+      }
+      var data = this.listData;
+      if (this.statusPop === 1) {
+        this.$api
+          .addRole(data)
+          .then((res) => {
+            if (res.code === 200) {
+              this.$message.success("新增成功");
+              this.search();
+              this.$store.commit("EDICROLELIST");
+              this.dialogVisible = false;
+            }
+          })
+          .catch(() => {
+            this.disabledBtn = false;
+          });
+      }
+      if (this.statusPop === 0) {
+        this.$api
+          .editRole(data)
+          .then((res) => {
+            if (res.code === 200) {
+              this.$message.success("修改成功");
+              this.search();
+              this.$store.commit("EDICROLELIST");
+              this.dialogVisible = false;
+            }
+          })
+          .catch(() => {
+            this.disabledBtn = false;
+          });
+      }
+    },
+    close() {
+      this.initData();
+      this.dialogVisible = false;
+    },
+    initData() {
+      this.menuExpand = false;
+      this.menuNodeAll = false;
+      this.listData = {
+        roleId: undefined,
+        roleName: undefined,
+        roleKey: undefined,
+        roleSort: 0,
+        status: "",
+        menuIds: [],
+        deptIds: [],
+        menuCheckStrictly: true,
+        deptCheckStrictly: true,
+        remark: undefined,
+      };
+    },
+    sortBy(attr, rev) {
+      //第二个参数没有传递 默认升序排列
+      if (rev == undefined) {
+        rev = 1;
+      } else {
+        rev = rev ? 1 : -1;
+      }
+
+      return function (a, b) {
+        a = a[attr];
+        b = b[attr];
+        if (a < b) {
+          return rev * -1;
+        }
+        if (a > b) {
+          return rev * 1;
+        }
+        return 0;
+      };
+    },
+    // 树权限(展开/折叠)
+    handleCheckedTreeExpand(value, type) {
+      if (type == "menu") {
+        let treeList = this.menuOptions;
+        for (let i = 0; i < treeList.length; i++) {
+          this.$refs.menu[0].store.nodesMap[treeList[i].id].expanded = value;
+        }
+      }
+    },
+    // 树权限(全选/全不选)
+    handleCheckedTreeNodeAll(value, type) {
+      if (type == "menu") {
+        this.$refs.menu[0].setCheckedNodes(value ? this.menuOptions : []);
+      }
+    },
+    // 数据池树权限(展开/折叠)
+    handleCheckedTreeExpandInfo(value, type) {
+      if (type == "info") {
+        let treeList = this.menuOptionsInfo;
+        for (let i = 0; i < treeList.length; i++) {
+          this.$refs.info[0].store.nodesMap[treeList[i].onlyId].expanded =
+            value;
+        }
+      }
+    },
+    // 数据池树权限(全选/全不选)
+    handleCheckedTreeNodeAllInfo(value, type) {
+      if (type == "info") {
+        this.$refs.info[0].setCheckedNodes(value ? this.menuOptionsInfo : []);
+      }
+    },
+    // 树权限(父子联动)
+    handleCheckedTreeConnect(value, type) {
+      if (type == "menu") {
+        this.listData.menuCheckStrictly = value ? true : false;
+      }
+    },
+    // 所有菜单节点数据
+    getMenuAllCheckedKeys() {
+      // 目前被选中的菜单节点
+      let checkedKeys = this.$refs.menu[0].getCheckedKeys();
+      // 半选中的菜单节点
+      let halfCheckedKeys = this.$refs.menu[0].getHalfCheckedKeys();
+      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
+      return checkedKeys;
+    },
+    getMenuAllCheckedKeysInfo() {
+      // 目前被选中的菜单节点
+      let checkedKeys = this.$refs.info[0].getCheckedKeys();
+      // 半选中的菜单节点
+      let halfCheckedKeys = this.$refs.info[0].getHalfCheckedKeys();
+      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
+      let ary = [];
+      checkedKeys.forEach((item) => {
+        var ast = item.split("-");
+        if (ast[0] === "yw") {
+          ary.push(parseInt(ast[1]));
+        }
+      });
+      return ary;
+    },
+    handleSizeChange(v) {
+      this.pageSize = v;
+      this.currentPage = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.currentPage = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+.tree-border {
+  max-height: 450px;
+  overflow: auto;
+  margin-top: 5px;
+  border: 1px solid #e5e6e7;
+  background: #ffffff none;
+  border-radius: 4px;
+}
+</style>
+

+ 16 - 0
src/views/systemSettings/accountManagement/index.vue

@@ -0,0 +1,16 @@
+<template>
+  <!-- 账号管理 -->
+  <div id="accountManagement">账号管理</div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  },
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+</style>

+ 499 - 0
src/views/systemSettings/department/index.vue

@@ -0,0 +1,499 @@
+<template>
+  <div id="department">
+    <search-box :formList="formList" @search="search" @init="init" />
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      @addClick="addClick"
+      :loading="loading"
+      :rowKey="rowKey"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="addClick(props.scope.row, 2)"
+          >新增</el-button
+        >
+        <el-button type="text" @click="addClick(props.scope.row, 0)"
+          >修改</el-button
+        >
+        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+      </template>
+    </table-list>
+    <!-- <pagination
+      :total="total"
+      :pageSize="pageSize"
+      :currentPage="currentPage"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    /> -->
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="480px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "添加下级" }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="80px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item
+            v-for="(items, indexs) in listitem"
+            :key="indexs"
+            :label="items.label"
+            :prop="items.prop"
+          >
+            <el-radio-group
+              v-if="items.scope === 'status'"
+              v-model="listData[items.prop]"
+            >
+              <el-radio
+                v-for="(item, index) in items.options"
+                :key="index"
+                :label="item.value"
+                >{{ item.label }}</el-radio
+              >
+            </el-radio-group>
+            <treeselect
+              v-else-if="items.scope === 'selectMore'"
+              v-model="listData[items.prop]"
+              :options="optionsCascader"
+              :normalizer="normalizer"
+              :show-count="true"
+              placeholder="选择上级菜单"
+            />
+            <el-input-number
+              style="width: 100%"
+              v-else-if="items.scope === 'numberIndex'"
+              v-model="listData[items.prop]"
+              controls-position="right"
+              :min="0"
+              :max="99"
+            ></el-input-number>
+            <el-input v-else v-model="listData[items.prop]"></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button type="primary" @click="submit('listData')">确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+
+import searchBox from "@/components/searchBox";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  components: { Treeselect, searchBox, tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      rowKey: "deptId",
+      navText: {
+        title: "部门管理",
+        index: 0,
+        ch: "条",
+        num: false,
+        choice: false,
+        addHide: false,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          label: "部门名称",
+          prop: "deptName",
+          placeholder: "请输入部门名称",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          placeholder: "请选择状态",
+          scope: "select",
+          options: [
+            {
+              label: "启用",
+              value: 1,
+            },
+            {
+              label: "停用",
+              value: 0,
+            },
+          ],
+        },
+      ],
+      // 表单
+      tableSet: [
+        {
+          label: "部门名称",
+          prop: "deptName",
+          hidden: true,
+        },
+        {
+          label: "排序",
+          prop: "orderNum",
+          hidden: true,
+        },
+        {
+          label: "状态",
+          prop: "status",
+          hidden: true,
+          scope: "status",
+        },
+        {
+          label: "创建时间",
+          prop: "createTime",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      pageSize: 999, //每页多少条数据
+      currentPage: 1, //当前页码
+      // 弹窗字段
+      listitem: [
+        {
+          label: "上级部门",
+          prop: "parentId",
+          scope: "selectMore",
+        },
+        {
+          label: "部门名称",
+          prop: "deptName",
+        },
+        {
+          label: "显示排序",
+          prop: "orderNum",
+          scope: "numberIndex",
+        },
+        {
+          label: "负责人",
+          prop: "leader",
+        },
+        {
+          label: "联系电话",
+          prop: "phone",
+        },
+        {
+          label: "邮箱",
+          prop: "email",
+        },
+        {
+          label: "部门状态",
+          prop: "status",
+          scope: "status",
+          options: [
+            {
+              label: "启用",
+              value: "1",
+            },
+            {
+              label: "关闭",
+              value: "0",
+            },
+          ],
+        },
+      ],
+      //   弹窗数据
+      listData: {},
+      statusPop: -1,
+      dialogVisible: false,
+      optionsCascader: [], //弹窗分类数据
+      //表单验证
+      rules: {
+        parentId: [
+          { required: true, message: "请选择上级部门", trigger: "change" },
+        ],
+        deptName: [
+          { required: true, message: "请输入部门名称", trigger: "blur" },
+        ],
+        orderNum: [
+          { required: true, message: "请输入显示排序", trigger: "blur" },
+        ],
+        // leader: [{ required: true, message: "请填写负责人", trigger: "blur" }],
+        status: [
+          { required: true, message: "请选择部门状态", trigger: "change" },
+        ],
+      },
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    search(v) {
+      this.loading = true;
+      if (v === undefined) {
+        v = {
+          statusArray: "0,1",
+          pageSize: this.pageSize,
+          pageNum: this.currentPage,
+        };
+      }
+      var data = {
+        deptName: v.deptName || "",
+        statusArray: v.status === undefined ? "0,1" : v.status,
+        pageSize: this.pageSize,
+        pageNum: this.currentPage,
+      };
+      this.$api
+        .obtainDeptList(data)
+        .then((res) => {
+          this.initSelect();
+          this.tableData = this.handleTree(
+            res.data,
+            "deptId",
+            "parentId",
+            "children"
+          );
+          this.total = res.data.length;
+          this.navText.index = res.data.length;
+          this.loading = false;
+        })
+        .catch((err) => {
+          this.loading = false;
+        });
+    },
+    initSelect() {
+      var data = {
+        deptName: "",
+        statusArray: "0,1",
+        pageSize: this.pageSize,
+        pageNum: this.currentPage,
+      };
+      this.$api
+        .obtainDeptList(data)
+        .then((res) => {
+          var bf = [
+            {
+              deptId: 0,
+              parentId: null,
+              deptName: "主分类",
+            },
+          ];
+          bf = bf.concat(res.data);
+          this.optionsCascader = this.handleTree(
+            bf,
+            "deptId",
+            "parentId",
+            "children"
+          );
+        })
+        .catch((err) => {});
+    },
+    init() {
+      this.search();
+    },
+    del(v) {
+      this.$confirm("此操作将删除该条部门数据, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          var data = v;
+          data.status = -1;
+          this.$api.editDept(data).then((res) => {
+            if (res.code === 200) {
+              this.$message.success("删除成功");
+              this.search();
+              this.dialogVisible = false;
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    addClick(v, int) {
+      if (v === undefined) {
+        this.statusPop = 1;
+        this.listData = {};
+      } else {
+        this.statusPop = int;
+        if (int === 2) {
+          this.listData = {
+            parentId: v.deptId,
+          };
+        } else {
+          var data = v.deptId;
+          this.$api.obtainDeptId(data).then((res) => {
+            this.listData = res.data;
+          });
+        }
+      }
+      this.$nextTick(() => {
+        this.$refs.listData.clearValidate();
+      });
+      this.dialogVisible = true;
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    rulesTableSumbit() {
+      var data = this.listData;
+      if (this.statusPop === 0) {
+        this.$api.editDept(data).then((res) => {
+          if (res.code === 200) {
+            this.$message.success("修改成功");
+            this.search();
+            this.dialogVisible = false;
+          }
+        });
+      } else {
+        this.$api.addDept(data).then((res) => {
+          if (res.code === 200) {
+            this.$message.success("新增成功");
+            this.search();
+            this.dialogVisible = false;
+          }
+        });
+      }
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+    normalizer(node) {
+      if (node.children && !node.children.length) {
+        delete node.children;
+      }
+      return {
+        id: node.deptId,
+        label: node.deptName,
+        children: node.children,
+      };
+    },
+    handleSizeChange(v) {
+      this.pageSize = v;
+      this.currentPage = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.currentPage = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>
+

+ 433 - 0
src/views/systemSettings/dict/index.vue

@@ -0,0 +1,433 @@
+<template>
+  <div id="dict">
+    <search-box :formList="formList" @search="search" @init="init" />
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      @addClick="addClick"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="addClick(props.scope.row, 2)"
+          >详情</el-button
+        >
+        <el-button type="text" @click="addClick(props.scope.row, 0)"
+          >修改</el-button
+        >
+        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="pageSize"
+      :currentPage="currentPage"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="560px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="80px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item
+            v-for="(items, indexs) in listitem"
+            :key="indexs"
+            :label="items.label"
+            :prop="items.prop"
+          >
+            <el-radio-group
+              v-if="items.scope === 'status'"
+              v-model="listData[items.prop]"
+            >
+              <el-radio
+                v-for="(item, index) in items.options"
+                :key="index"
+                :label="item.value"
+                :disabled="statusPop === 2"
+                >{{ item.label }}</el-radio
+              >
+            </el-radio-group>
+            <el-input
+              :disabled="statusPop === 2"
+              v-else-if="items.scope === 'textarea'"
+              type="textarea"
+              v-model="listData[items.prop]"
+            ></el-input>
+            <el-input
+              :disabled="statusPop === 2"
+              v-else
+              v-model="listData[items.prop]"
+            ></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button
+          type="primary"
+          v-if="statusPop !== 2"
+          @click="submit('listData')"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import searchBox from "@/components/searchBox";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  components: { searchBox, tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "字典类型",
+        index: 0,
+        ch: "条",
+        num: false,
+        choice: true,
+        addHide: false,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      tableSet: [
+        {
+          label: "字典编号",
+          prop: "dictId",
+          hidden: true,
+        },
+        {
+          label: "字典名称",
+          prop: "dictName",
+          hidden: true,
+        },
+        {
+          label: "字典类型",
+          prop: "dictType",
+          hidden: true,
+          scope: "jumpPage",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          hidden: true,
+          scope: "status",
+        },
+        {
+          label: "备注",
+          prop: "remark",
+          hidden: true,
+        },
+      ], //表头信息
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      pageSize: 10, //每页多少条数据
+      currentPage: 1, //当前页码
+      formList: [
+        {
+          label: "字典名称",
+          prop: "dictName",
+          placeholder: "请输入字典名称",
+        },
+        {
+          label: "字典类型",
+          prop: "dictType",
+          placeholder: "请输入字典类型",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          placeholder: "请选择状态",
+          scope: "select",
+          options: [
+            {
+              label: "启用",
+              value: 1,
+            },
+            {
+              label: "停用",
+              value: 0,
+            },
+          ],
+        },
+      ], //搜索
+      listitem: [
+        {
+          label: "字典名称",
+          prop: "dictName",
+        },
+        {
+          label: "字典类型",
+          prop: "dictType",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          scope: "status",
+          options: [
+            {
+              label: "启用",
+              value: "1",
+            },
+            {
+              label: "关闭",
+              value: "0",
+            },
+          ],
+        },
+        {
+          label: "备注",
+          prop: "remark",
+          scope: "textarea",
+        },
+      ],
+      statusPop: -1,
+      dialogVisible: false,
+      listData: {},
+      rules: {
+        dictName: [
+          { required: true, message: "请输入字典名称", trigger: "blur" },
+          {
+            min: 2,
+            max: 10,
+            message: "长度在 2 到 10 个字符",
+            trigger: "blur",
+          },
+        ],
+        dictType: [
+          { required: true, message: "请输入字典类型", trigger: "blur" },
+        ],
+        status: [{ required: true, message: "请选择状态", trigger: "change" }],
+        remark: [{ required: true, message: "请填写备注", trigger: "blur" }],
+      },
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    search(v) {
+      if (v === undefined) {
+        v = {
+          statusArray: "0,1",
+          pageSize: this.pageSize,
+          pageNum: this.currentPage,
+        };
+      }
+      var data = {
+        dictName: v.dictName || "",
+        dictType: v.dictType || "",
+        statusArray: v.status === undefined ? "0,1" : v.status,
+        pageSize: this.pageSize,
+        pageNum: this.currentPage,
+      };
+      this.loading = true;
+      this.$api
+        .obtaindicttype(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+          this.loading = false;
+        })
+        .catch((err) => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search();
+    },
+    del(v) {
+      this.$confirm("此操作将删除该字典类型, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          var data = JSON.parse(JSON.stringify(v));
+          data.status = "-1";
+          this.$api.editdicttype(data).then((res) => {
+            this.$message.success("删除成功");
+            this.search();
+            this.dialogVisible = false;
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    addClick(v, int) {
+      if (v === undefined) {
+        this.statusPop = 1;
+        this.listData = {};
+      } else {
+        this.statusPop = int;
+        var data = v.dictId;
+        this.$api.getdicttype(data).then((res) => {
+          this.listData = res.data;
+        });
+      }
+      this.$nextTick(() => {
+        this.$refs.listData.clearValidate();
+      });
+      this.dialogVisible = true;
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    rulesTableSumbit() {
+      if (this.statusPop === 1) {
+        this.$api.adddicttype(this.listData).then((res) => {
+          this.$message.success("新增成功");
+          this.dialogVisible = false;
+          this.search();
+        });
+      }
+      if (this.statusPop === 0) {
+        this.$api.editdicttype(this.listData).then((res) => {
+          this.$message.success("修改成功");
+          this.dialogVisible = false;
+          this.search();
+        });
+      }
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+    handleSizeChange(v) {
+      this.pageSize = v;
+      this.currentPage = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.currentPage = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>
+

+ 454 - 0
src/views/systemSettings/dictData/index.vue

@@ -0,0 +1,454 @@
+<template>
+  <div id="dictData">
+    <search-box :formList="formList" @search="search" @init="init" />
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      @addClick="addClick"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="addClick(props.scope.row, 2)"
+          >详情</el-button
+        >
+        <el-button type="text" @click="addClick(props.scope.row, 0)"
+          >修改</el-button
+        >
+        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="pageSize"
+      :currentPage="currentPage"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="560px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="80px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item
+            v-for="(items, indexs) in listitem"
+            :key="indexs"
+            :label="items.label"
+            :prop="items.prop"
+          >
+            <el-radio-group
+              v-if="items.scope === 'status'"
+              v-model="listData[items.prop]"
+            >
+              <el-radio
+                v-for="(item, index) in items.options"
+                :key="index"
+                :label="item.value"
+                :disabled="statusPop === 2"
+                >{{ item.label }}</el-radio
+              >
+            </el-radio-group>
+            <el-input
+              :disabled="statusPop === 2"
+              v-else-if="items.scope === 'textarea'"
+              type="textarea"
+              v-model="listData[items.prop]"
+            ></el-input>
+            <el-input-number
+              :disabled="statusPop === 2"
+              v-else-if="items.scope === 'InputNumber'"
+              v-model.number="listData[items.prop]"
+              controls-position="right"
+              :min="items.min"
+              :max="items.max"
+            ></el-input-number>
+            <el-input
+              :disabled="statusPop === 2 || items.scope === 'disable'"
+              v-else
+              v-model="listData[items.prop]"
+            ></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button
+          type="primary"
+          v-if="statusPop !== 2"
+          @click="submit('listData')"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import searchBox from "@/components/searchBox";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  components: { searchBox, tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "字典类型",
+        index: 0,
+        ch: "条",
+        num: false,
+        choice: true,
+        addHide: false,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      tableSet: [
+        {
+          label: "字典编号",
+          prop: "dictCode",
+          hidden: true,
+        },
+        {
+          label: "字典标签",
+          prop: "dictLabel",
+          hidden: true,
+        },
+        {
+          label: "字典键值",
+          prop: "dictValue",
+          hidden: true,
+        },
+        {
+          label: "字典排序",
+          prop: "dictSort",
+          hidden: true,
+        },
+        {
+          label: "状态",
+          prop: "status",
+          hidden: true,
+          scope: "status",
+        },
+        {
+          label: "备注",
+          prop: "remark",
+          hidden: true,
+        },
+      ], //表头信息
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      pageSize: 10, //每页多少条数据
+      currentPage: 1, //当前页码
+      formList: [
+        {
+          label: "字典标签",
+          prop: "dictLabel",
+          placeholder: "请输入字典标签",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          placeholder: "请选择状态",
+          scope: "select",
+          options: [
+            {
+              label: "启用",
+              value: 1,
+            },
+            {
+              label: "停用",
+              value: 0,
+            },
+          ],
+        },
+      ], //搜索
+      listitem: [
+        {
+          label: "字典类型",
+          prop: "dictType",
+          scope: "disable",
+        },
+        {
+          label: "数据标签",
+          prop: "dictLabel",
+        },
+        {
+          label: "数据键值",
+          prop: "dictValue",
+        },
+        {
+          label: "显示排序",
+          prop: "dictSort",
+          scope: "InputNumber",
+          min: 0,
+          max: 999,
+        },
+        {
+          label: "状态",
+          prop: "status",
+          scope: "status",
+          options: [
+            {
+              label: "启用",
+              value: "1",
+            },
+            {
+              label: "停用",
+              value: "0",
+            },
+          ],
+        },
+        {
+          label: "备注",
+          prop: "remark",
+          scope: "textarea",
+        },
+      ],
+      statusPop: -1,
+      dialogVisible: false,
+      listData: {},
+      rules: {
+        dictType: [
+          { required: true, message: "请输入字典类型", trigger: "blur" },
+        ],
+        dictLabel: [
+          { required: true, message: "请输入字典名称", trigger: "blur" },
+        ],
+        dictValue: [{ required: true, message: "数据键值不能为空" }],
+        dictSort: [
+          { required: true, message: "显示排序不能为空" },
+          { type: "number", message: "显示排序必须为数字值" },
+        ],
+        status: [{ required: true, message: "请选择状态", trigger: "change" }],
+        remark: [{ required: true, message: "请填写备注", trigger: "blur" }],
+      },
+      paramsData: this.$route.query,
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    search(v) {
+      if (v === undefined) {
+        v = {
+          statusArray: "0,1",
+          pageSize: this.pageSize,
+          pageNum: this.currentPage,
+        };
+      }
+      var data = {
+        dictName: v.dictName || "",
+        dictTypeId: this.paramsData.dictId,
+        statusArray: v.status === undefined ? "0,1" : v.status,
+        pageSize: this.pageSize,
+        pageNum: this.currentPage,
+      };
+      this.loading = true;
+      this.$api
+        .obtaindictdata(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+          this.loading = false;
+        })
+        .catch((err) => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search();
+    },
+    del(v) {
+      this.$confirm("此操作将删除该字典类型, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          var data = JSON.parse(JSON.stringify(v));
+          data.status = -1;
+          this.$api.editdictdata(data).then((res) => {
+            this.$message.success("删除成功");
+            this.search();
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    addClick(v, int) {
+      if (v === undefined) {
+        this.statusPop = 1;
+        this.listData = {
+          dictTypeId: this.paramsData.dictId,
+          dictType: this.paramsData.dictType,
+        };
+      } else {
+        this.statusPop = int;
+        var data = v.dictCode;
+        this.$api.getdictdata(data).then((res) => {
+          this.listData = res.data;
+        });
+      }
+      this.dialogVisible = true;
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    rulesTableSumbit() {
+      if (this.statusPop === 1) {
+        this.$api.adddictdata(this.listData).then((res) => {
+          this.$message.success("新增成功");
+          this.$refs["listData"].resetFields();
+          this.dialogVisible = false;
+          this.search();
+        });
+      }
+      if (this.statusPop === 0) {
+        this.$api.editdictdata(this.listData).then((res) => {
+          this.$message.success("修改成功");
+          this.$refs["listData"].resetFields();
+          this.dialogVisible = false;
+          this.search();
+        });
+      }
+    },
+    close() {
+      this.dialogVisible = false;
+      this.$refs["listData"].resetFields();
+    },
+    handleSizeChange(v) {
+      this.pageSize = v;
+      this.currentPage = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.currentPage = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>
+

+ 476 - 0
src/views/systemSettings/jobManagement/index.vue

@@ -0,0 +1,476 @@
+<template>
+  <div id="jobManagement">
+    <search-box :formList="formList" @search="search" @init="init" />
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      @addClick="addClick"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="addClick(props.scope.row, 2)"
+          >详情</el-button
+        >
+        <el-button type="text" @click="addClick(props.scope.row, 0)"
+          >修改</el-button
+        >
+        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="pageSize"
+      :currentPage="currentPage"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="560px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="80px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item
+            v-for="(items, indexs) in listitem"
+            :key="indexs"
+            :label="items.label"
+            :prop="items.prop"
+          >
+            <el-radio-group
+              v-if="items.scope === 'status'"
+              v-model="listData[items.prop]"
+            >
+              <el-radio
+                v-for="(item, index) in items.options"
+                :key="index"
+                :label="item.value"
+                :disabled="statusPop === 2"
+                >{{ item.label }}</el-radio
+              >
+            </el-radio-group>
+            <el-input
+              :disabled="statusPop === 2"
+              v-else-if="items.scope === 'textarea'"
+              type="textarea"
+              v-model="listData[items.prop]"
+            ></el-input>
+            <el-input-number
+              style="width: 100%"
+              :disabled="statusPop === 2"
+              v-else-if="items.scope === 'numberIndex'"
+              v-model="listData[items.prop]"
+              controls-position="right"
+              :min="0"
+              :max="99"
+            ></el-input-number>
+            <el-input
+              :disabled="statusPop === 2"
+              v-else
+              v-model="listData[items.prop]"
+            ></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button
+          type="primary"
+          v-if="statusPop !== 2"
+          @click="submit('listData')"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import searchBox from "@/components/searchBox";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  components: { searchBox, tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "当前岗位",
+        index: 0,
+        ch: "种",
+        num: false,
+        choice: false,
+        addHide: false,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          label: "岗位编码",
+          prop: "postCode",
+          placeholder: "请输入岗位编码",
+        },
+        {
+          label: "岗位名称",
+          prop: "postName",
+          placeholder: "请输入岗位名称",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          placeholder: "请选择状态",
+          scope: "select",
+          options: [
+            {
+              label: "启用",
+              value: "1",
+            },
+            {
+              label: "停用",
+              value: "0",
+            },
+          ],
+        },
+      ],
+      // 表单
+      tableSet: [
+        {
+          label: "岗位编号",
+          prop: "postId",
+          hidden: true,
+        },
+        {
+          label: "岗位编码",
+          prop: "postCode",
+          hidden: true,
+        },
+        {
+          label: "岗位名称",
+          prop: "postName",
+          hidden: true,
+        },
+        {
+          label: "岗位排序",
+          prop: "postSort",
+          hidden: true,
+        },
+        {
+          label: "状态",
+          prop: "status",
+          hidden: true,
+          scope: "status",
+        },
+        {
+          label: "创建时间",
+          prop: "createTime",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      pageSize: 10, //每页多少条数据
+      currentPage: 1, //当前页码
+      // 弹窗字段
+      listitem: [
+        {
+          label: "岗位名称",
+          prop: "postName",
+        },
+        {
+          label: "岗位编码",
+          prop: "postCode",
+        },
+        {
+          label: "岗位顺序",
+          prop: "postSort",
+          scope: "numberIndex",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          scope: "status",
+          options: [
+            {
+              label: "启用",
+              value: "1",
+            },
+            {
+              label: "关闭",
+              value: "0",
+            },
+          ],
+        },
+        {
+          label: "备注",
+          prop: "remark",
+          scope: "textarea",
+        },
+      ],
+      //   弹窗数据
+      listData: {},
+      statusPop: -1,
+      dialogVisible: false,
+      //表单验证
+      rules: {
+        postName: [
+          { required: true, message: "请输入岗位名称", trigger: "blur" },
+        ],
+        postCode: [
+          { required: true, message: "请输入岗位编码", trigger: "blur" },
+        ],
+        postSort: [
+          { required: true, message: "请输入岗位顺序", trigger: "blur" },
+        ],
+        status: [{ required: true, message: "请选择状态", trigger: "change" }],
+        // remark: [{ required: true, message: "请填写备注", trigger: "blur" }],
+      },
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    search(v) {
+      this.loading = true;
+      if (v === undefined) {
+        v = {
+          statusArray: "0,1",
+          pageSize: this.pageSize,
+          pageNum: this.currentPage,
+        };
+      }
+      var data = {
+        postCode: v.postCode || "",
+        postName: v.postName || "",
+        statusArray: v.status === undefined ? "0,1" : v.status,
+        pageSize: this.pageSize,
+        pageNum: this.currentPage,
+      };
+      this.$api.inquiresystempostList(data).then((res) => {
+        this.tableData = res.rows.sort(this.sortBy("postSort", true));
+        this.total = res.total;
+        this.navText.index = res.total;
+      }).finally(()=>{
+        this.loading = false;
+      })
+    },
+    init() {
+      this.search();
+    },
+    del(v) {
+      this.$confirm("此操作将删除该岗位, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          var data = JSON.parse(JSON.stringify(v));
+          data.status = -1;
+          this.$api.editsystempost(data).then((res) => {
+            if (res.code === 200) {
+              this.$message.success("删除成功");
+              this.search();
+              this.dialogVisible = false;
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    addClick(v, int) {
+      if (v === undefined) {
+        this.statusPop = 1;
+        this.listData = {};
+        this.dialogVisible = true;
+      } else {
+        this.statusPop = int;
+        var data = v.postId;
+        this.$api.obtainsystempost(data).then((res) => {
+          if (res.code === 200) {
+            this.listData = res.data;
+            this.dialogVisible = true;
+          }
+        });
+      }
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    rulesTableSumbit() {
+      var data = this.listData;
+      if (this.statusPop === 1) {
+        this.$api.addsystempost(data).then((res) => {
+          if (res.code === 200) {
+            this.$message.success("新增成功");
+            this.search();
+            this.dialogVisible = false;
+          }
+        });
+      }
+      if (this.statusPop === 0) {
+        this.$api.editsystempost(data).then((res) => {
+          if (res.code === 200) {
+            this.$message.success("修改成功");
+            this.search();
+            this.dialogVisible = false;
+          }
+        });
+      }
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+    sortBy(attr, rev) {
+      //第二个参数没有传递 默认升序排列
+      if (rev == undefined) {
+        rev = 1;
+      } else {
+        rev = rev ? 1 : -1;
+      }
+
+      return function (a, b) {
+        a = a[attr];
+        b = b[attr];
+        if (a < b) {
+          return rev * -1;
+        }
+        if (a > b) {
+          return rev * 1;
+        }
+        return 0;
+      };
+    },
+    handleSizeChange(v) {
+      this.pageSize = v;
+      this.currentPage = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.currentPage = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>
+

+ 506 - 0
src/views/systemSettings/menu/index.vue

@@ -0,0 +1,506 @@
+<template>
+  <div class="app-container">
+    <el-form
+      :model="queryParams"
+      ref="queryForm"
+      :inline="true"
+      v-show="showSearch"
+    >
+      <el-form-item label="菜单名称" prop="menuName">
+        <el-input
+          v-model="queryParams.menuName"
+          placeholder="请输入菜单名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select
+          v-model="queryParams.status"
+          placeholder="菜单状态"
+          clearable
+          size="small"
+        >
+          <el-option
+            v-for="dict in statusOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
+          >搜索</el-button
+        >
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8" style="display: flex; align-item: center">
+      <el-button
+        type="primary"
+        plain
+        icon="el-icon-plus"
+        size="mini"
+        style="margin-right: 10px"
+        @click="handleAdd"
+        >新增</el-button
+      >
+      <right-toolbar
+        :showSearch.sync="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
+    </el-row>
+
+    <el-table
+      v-loading="loading"
+      :data="menuList"
+      row-key="menuId"
+      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+    >
+      <el-table-column
+        prop="menuName"
+        label="菜单名称"
+        :show-overflow-tooltip="true"
+        width="160"
+      ></el-table-column>
+      <el-table-column prop="icon" label="图标" align="center" width="100">
+        <template slot-scope="scope">
+          <svg-icon :icon-class="scope.row.icon" />
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="orderNum"
+        label="排序"
+        width="60"
+      ></el-table-column>
+      <el-table-column
+        prop="perms"
+        label="权限标识"
+        :show-overflow-tooltip="true"
+      ></el-table-column>
+      <el-table-column
+        prop="component"
+        label="组件路径"
+        :show-overflow-tooltip="true"
+      ></el-table-column>
+      <el-table-column
+        prop="status"
+        label="状态"
+        :formatter="statusFormat"
+        width="80"
+      ></el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="操作"
+        align="center"
+        class-name="small-padding fixed-width"
+      >
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            >修改</el-button
+          >
+          <!-- v-if="scope.row.menuType === 'M'" -->
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-plus"
+            @click="handleAdd(scope.row)"
+            >新增</el-button
+          >
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            >删除</el-button
+          >
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 添加或修改菜单对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="上级菜单">
+              <treeselect
+                v-model="form.parentId"
+                :options="menuOptions"
+                :normalizer="normalizer"
+                :show-count="true"
+                placeholder="选择上级菜单"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="菜单类型" prop="menuType">
+              <el-radio-group v-model="form.menuType">
+                <el-radio label="M">目录</el-radio>
+                <el-radio label="C" :disabled="form.menuType == 'M' && form.children.length > 0">菜单</el-radio>
+                <el-radio label="F">按钮</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item v-if="form.menuType != 'F'" label="菜单图标">
+              <el-popover
+                placement="bottom-start"
+                width="460"
+                trigger="click"
+                @show="$refs['iconSelect'].reset()"
+              >
+                <IconSelect ref="iconSelect" @selected="selected" />
+                <el-input
+                  slot="reference"
+                  v-model="form.icon"
+                  placeholder="点击选择图标"
+                  readonly
+                >
+                  <svg-icon
+                    v-if="form.icon"
+                    slot="prefix"
+                    :icon-class="form.icon"
+                    class="el-input__icon"
+                    style="height: 32px; width: 16px"
+                  />
+                  <i
+                    v-else
+                    slot="prefix"
+                    class="el-icon-search el-input__icon"
+                  />
+                </el-input>
+              </el-popover>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="菜单名称" prop="menuName">
+              <el-input v-model="form.menuName" placeholder="请输入菜单名称" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="显示排序" prop="orderNum">
+              <el-input-number
+                v-model="form.orderNum"
+                controls-position="right"
+                :min="0"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item v-if="form.menuType != 'F'" label="是否外链">
+              <el-radio-group v-model="form.isFrame">
+                <el-radio label="0">是</el-radio>
+                <el-radio label="1">否</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item
+              v-if="form.menuType != 'F'"
+              label="路由地址"
+              prop="path"
+            >
+              <el-input v-model="form.path" placeholder="请输入路由地址" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.menuType == 'C'">
+            <el-form-item label="组件路径" prop="component">
+              <el-input v-model="form.component" placeholder="请输入组件路径" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item v-if="form.menuType != 'M'" label="权限标识">
+              <el-input
+                v-model="form.perms"
+                placeholder="请权限标识"
+                maxlength="50"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item v-if="form.menuType != 'F'" label="显示状态">
+              <el-radio-group v-model="form.visible">
+                <el-radio
+                  v-for="dict in visibleOptions"
+                  :key="dict.dictValue"
+                  :label="dict.dictValue"
+                  >{{ dict.dictLabel }}</el-radio
+                >
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item v-if="form.menuType != 'F'" label="菜单状态">
+              <el-radio-group v-model="form.status">
+                <el-radio
+                  v-for="dict in statusOptions"
+                  :key="dict.dictValue"
+                  :label="dict.dictValue"
+                  >{{ dict.dictLabel }}</el-radio
+                >
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item v-if="form.menuType == 'C'" label="是否缓存">
+              <el-radio-group v-model="form.isCache">
+                <el-radio label="0">缓存</el-radio>
+                <el-radio label="1">不缓存</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import IconSelect from "@/components/IconSelect";
+
+export default {
+  name: "Menu",
+  components: { Treeselect, IconSelect },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 菜单表格树数据
+      menuList: [],
+      // 菜单树选项
+      menuOptions: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 显示状态数据字典
+      visibleOptions: [],
+      // 菜单状态数据字典
+      statusOptions: [],
+      // 查询参数
+      queryParams: {
+        menuName: undefined,
+        visible: undefined,
+      },
+      showListMenu:[],
+      // 表单参数
+      form: {
+        children : []
+      },
+      // 表单校验
+      rules: {
+        menuName: [
+          { required: true, message: "菜单名称不能为空", trigger: "blur" },
+        ],
+        orderNum: [
+          { required: true, message: "菜单顺序不能为空", trigger: "blur" },
+        ],
+        path: [
+          { required: true, message: "路由地址不能为空", trigger: "blur" },
+        ],
+      },
+    };
+  },
+  created() {
+    this.getList();
+    this.$api.obtaindictdata({ dictType: "sys_show_hide" }).then((response) => {
+      this.visibleOptions = response.rows;
+    });
+    this.$api
+      .obtaindictdata({ dictType: "sys_normal_disable" })
+      .then((response) => {
+        this.statusOptions = response.rows;
+      });
+  },
+  methods: {
+    // 选择图标
+    selected(name) {
+      this.form.icon = name;
+    },
+    /** 查询菜单列表 */
+    getList() {
+      this.loading = true;
+      this.$api.getsystemmenu(this.queryParams).then((response) => {
+        this.menuList = this.handleTree(response.data, "menuId");
+        this.showListMenu = response.data
+        this.loading = false;
+      });
+    },
+    /** 转换菜单数据结构 */
+    normalizer(node) {
+      if (node.children && !node.children.length) {
+        delete node.children;
+      }
+      return {
+        id: node.menuId,
+        label: node.menuName,
+        children: node.children,
+      };
+    },
+    // /** 查询菜单下拉树结构 */
+    // getTreeselect() {
+    //   this.$api.getsystemmenu().then((response) => {
+    //     this.menuOptions = [];
+    //     const menu = { menuId: 0, menuName: "主类目", children: [] };
+    //     response = response.data.filter((item,index) => {
+    //       return item.menuType == 'M'
+    //     })
+    //     menu.children = this.handleTree(response, "menuId");
+    //     this.menuOptions.push(menu);
+    //   });
+    // },
+    /** 查询菜单下拉树结构 */
+    getTreeselect() {
+      this.$api.getsystemmenu().then(response => {
+        this.menuOptions = [];
+        const menu = { menuId: 0, menuName: '主类目', children: [] };
+        menu.children = this.handleTree(response.data, "menuId");
+        this.menuOptions.push(menu);
+      });
+    },
+    // 显示状态字典翻译
+    visibleFormat(row, column) {
+      if (row.menuType == "F") {
+        return "";
+      }
+      console.log("this.visibleOptions, row.visible",this.visibleOptions, row.visible)
+      return this.selectDictLabel(this.visibleOptions, row.visible);
+    },
+    // 菜单状态字典翻译
+    statusFormat(row, column) {
+      if (row.menuType == "F") {
+        return "";
+      }
+      console.log("this.statusOptions, row.status",this.statusOptions, row.status)
+      return this.selectDictLabel(this.statusOptions, row.status);
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        children:[],
+        menuId: undefined,
+        parentId: 0,
+        menuName: undefined,
+        icon: undefined,
+        menuType: "M",
+        orderNum: undefined,
+        isFrame: "1",
+        isCache: "0",
+        visible: "0",
+        status: "0",
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /** 新增按钮操作 */
+    handleAdd(row) {
+      this.reset();
+      this.getTreeselect();
+      if (row != null && row.menuId && row.menuType === 'M') {
+        this.form.parentId = row.menuId;
+      } else {
+        this.form.parentId = 0;
+      }
+      this.open = true;
+      this.title = "添加菜单";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      var self = this
+      this.reset();
+      this.getTreeselect();
+      this.$api.enutreeselectmenu(row.menuId).then((response) => {
+        var children = self.showListMenu.filter(item => {
+          return item.parentId === response.data.menuId
+        })
+        response.data.children = children
+        self.form = response.data;
+        self.open = true;
+        self.title = "修改菜单";
+      });
+    },
+    /** 提交按钮 */
+    submitForm: function () {
+      this.$refs["form"].validate((valid) => {
+        if (valid) {
+          if (this.form.menuId != undefined) {
+            // if(this.form.component.length === 0){
+            //   this.form.component = ''
+            // }
+            this.$api.editsystemmenu(this.form).then((response) => {
+              // this.$message.success("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            this.$api.addsystemmenu(this.form).then((response) => {
+              // this.$message.success("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      var self = this;
+      this.$confirm(
+        '是否确认删除名称为"' + row.menuName + '"的数据项?',
+        "警告",
+        {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        }
+      )
+        .then(function () {
+          return self.$api.delsystemmenu(row.menuId);
+        })
+        .then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        });
+    },
+  },
+};
+</script>

+ 455 - 0
src/views/systemSettings/modelPage/index.vue

@@ -0,0 +1,455 @@
+<template>
+  <div id="dict">
+    <search-box :formList="formList" @search="search" @init="init" />
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      @addClick="addClick"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="addClick(props.scope.row, 2)"
+          >详情</el-button
+        >
+        <el-button type="text" @click="addClick(props.scope.row, 0)"
+          >修改</el-button
+        >
+        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="pageSize"
+      :currentPage="currentPage"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="560px"
+      :show-close="false"
+      :before-close="close"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="80px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item
+            v-for="(items, indexs) in listitem"
+            :key="indexs"
+            :label="items.label"
+            :prop="items.prop"
+          >
+            <el-radio-group
+              v-if="items.scope === 'status'"
+              v-model="listData[items.prop]"
+            >
+              <el-radio
+                v-for="(item, index) in items.options"
+                :key="index"
+                :label="item.value"
+                :disabled="statusPop === 2"
+                >{{ item.label }}</el-radio
+              >
+            </el-radio-group>
+            <el-input
+              :disabled="statusPop === 2"
+              v-else-if="items.scope === 'textarea'"
+              type="textarea"
+              v-model="listData[items.prop]"
+            ></el-input>
+            <el-input
+              :disabled="statusPop === 2"
+              v-else
+              v-model="listData[items.prop]"
+            ></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button
+          type="primary"
+          v-if="statusPop !== 2"
+          @click="submit('listData')"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import searchBox from "@/components/searchBox";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  components: { searchBox, tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "字典类型",
+        index: 0,
+        ch: "条",
+        num: false,
+        choice: true,
+        addHide: false,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          label: "字典名称",
+          prop: "dictName",
+          placeholder: "请输入字典名称",
+        },
+        {
+          label: "字典类型",
+          prop: "dictType",
+          placeholder: "请输入字典类型",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          placeholder: "请选择状态",
+          scope: "select",
+          options: [
+            {
+              label: "启用",
+              value: 1,
+            },
+            {
+              label: "停用",
+              value: 0,
+            },
+          ],
+        },
+      ],
+      // 表单
+      tableSet: [
+        {
+          label: "字典编号",
+          prop: "dictId",
+          hidden: true,
+        },
+        {
+          label: "字典名称",
+          prop: "dictName",
+          hidden: true,
+        },
+        {
+          label: "字典类型",
+          prop: "dictType",
+          hidden: true,
+          scope: "jumpPage",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          hidden: true,
+          scope: "status",
+        },
+        {
+          label: "备注",
+          prop: "remark",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      pageSize: 10, //每页多少条数据
+      currentPage: 1, //当前页码
+      // 弹窗字段
+      listitem: [
+        {
+          label: "字典名称",
+          prop: "dictName",
+        },
+        {
+          label: "字典类型",
+          prop: "dictType",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          scope: "status",
+          options: [
+            {
+              label: "启用",
+              value: "1",
+            },
+            {
+              label: "关闭",
+              value: "0",
+            },
+          ],
+        },
+        {
+          label: "备注",
+          prop: "remark",
+          scope: "textarea",
+        },
+      ],
+      //   弹窗数据
+      listData: {},
+      statusPop: -1,
+      dialogVisible: false,
+      //表单验证
+      rules: {
+        dictName: [
+          { required: true, message: "请输入字典名称", trigger: "blur" },
+          {
+            min: 2,
+            max: 10,
+            message: "长度在 2 到 10 个字符",
+            trigger: "blur",
+          },
+        ],
+        dictType: [
+          { required: true, message: "请输入字典类型", trigger: "blur" },
+        ],
+        status: [{ required: true, message: "请选择状态", trigger: "change" }],
+        remark: [{ required: true, message: "请填写备注", trigger: "blur" }],
+      },
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    search(v) {
+      this.loading = true;
+      if (v === undefined) {
+        v = {
+          statusArray: "0,1",
+          pageSize: this.pageSize,
+          pageNum: this.currentPage,
+        };
+      }
+      var data = {
+        dictName: v.dictName || "",
+        dictType: v.dictType || "",
+        statusArray: v.status === undefined ? "0,1" : v.status,
+        pageSize: this.pageSize,
+        pageNum: this.currentPage,
+      };
+      this.tableData = [
+        {
+          createBy: "admin",
+          createTime: "2021-05-08 14:45:46",
+          dictId: 1,
+          dictName: "用户性别",
+          dictType: "sys_user_sex",
+          pageNum: null,
+          pageSize: null,
+          params: {},
+          remark: "用户性别列表",
+          status: "1",
+          statusArray: null,
+          updateBy: "admin",
+          updateTime: "2021-06-09 15:55:04",
+        },
+      ].finally(()=>{
+        this.loading = false;
+      })
+    },
+    init() {
+      this.search();
+    },
+    del(v) {
+      this.$confirm("此操作将删除该字典类型, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.$message.success("删除成功");
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    addClick(v, int) {
+      if (v === undefined) {
+        this.statusPop = 1;
+        this.listData = {};
+      } else {
+        this.statusPop = int;
+        var data = v.dictId;
+        this.listData = {
+          createBy: "admin",
+          createTime: "2021-05-08 14:45:46",
+          dictId: 1,
+          dictName: "用户性别",
+          dictType: "sys_user_sex",
+          pageNum: null,
+          pageSize: null,
+          params: {},
+          remark: "用户性别列表",
+          status: "1",
+          statusArray: null,
+          updateBy: "admin",
+          updateTime: "2021-06-09 15:55:04",
+        };
+      }
+      this.dialogVisible = true;
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    rulesTableSumbit() {
+      if (this.statusPop === 1) {
+        this.$message.success("新增成功");
+        this.dialogVisible = false;
+      }
+      if (this.statusPop === 0) {
+        this.$message.success("修改成功");
+        this.dialogVisible = false;
+      }
+    },
+    close() {
+      if (this.statusPop === 2) {
+        this.dialogVisible = false;
+        return;
+      }
+      this.$confirm("是否关闭该窗口", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.dialogVisible = false;
+        })
+        .catch(() => {});
+    },
+    handleSizeChange(v) {
+      this.pageSize = v;
+      this.currentPage = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.currentPage = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>
+

+ 255 - 0
src/views/systemSettings/operationLog/index.vue

@@ -0,0 +1,255 @@
+<template>
+  <div id="operationLog">
+    <search-box :formList="formList" @search="search" @init="init" />
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      @addClick="addClick"
+      :loading="loading"
+    >
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="pageSize"
+      :currentPage="currentPage"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import searchBox from "@/components/searchBox";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  components: { searchBox, tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "操作日志",
+        index: 0,
+        ch: "条",
+        num: true,
+        choice: true,
+        addHide: true,
+        tableHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      tableSet: [
+        {
+          label: "账号",
+          prop: "operName",
+          hidden: true,
+        },
+        {
+          label: "模块",
+          prop: "title",
+          hidden: true,
+        },
+        {
+          label: "操作类型",
+          prop: "operUrl",
+          hidden: true,
+          scope: "cType",
+        },
+        {
+          label: "操作内容",
+          prop: "operContent",
+          hidden: true,
+        },
+        {
+          label: "操作时间",
+          prop: "operTime",
+          hidden: true,
+        },
+        {
+          label: "附件",
+          prop: "fileUrl",
+          hidden: true,
+          scope: "downLoad",
+        },
+        {
+          label: "IP",
+          prop: "operIp",
+          hidden: true,
+        },
+        {
+          label: "浏览器",
+          prop: "browser",
+          hidden: true,
+        },
+      ], //表头信息
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      pageSize: 10, //每页多少条数据
+      currentPage: 1, //当前页码
+      formList: [
+        {
+          label: "操作模块",
+          prop: "title",
+          placeholder: "请输入操作模块",
+        },
+        {
+          label: "账号",
+          prop: "operName",
+          placeholder: "请输入账号",
+        },
+      ], //搜索栏
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    totalScores() {},
+    search(v) {
+      if (v === undefined) {
+        v = {
+          pageSize: this.pageSize,
+          pageNum: this.currentPage,
+        };
+      }
+      var data = {
+        title: v.title || '',
+        operName: v.operName || '',
+        pageSize: this.pageSize,
+        pageNum: this.currentPage,
+      };
+      this.loading = true;
+      this.$api
+        .inquiremonitoroperlogList(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+          this.loading = false;
+        })
+        .catch((err) => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search()
+    },
+    del() {},
+    addClick(v, int) {},
+    submit() {},
+    close() {
+      this.$confirm("是否关闭该窗口", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {})
+        .catch(() => {});
+    },
+    handleSizeChange(v) {
+      this.pageSize = v;
+      this.currentPage = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.currentPage = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

+ 231 - 0
src/views/systemSettings/personalCenter/index.vue

@@ -0,0 +1,231 @@
+<template>
+  <!-- 个人中心 -->
+  <div id="personalCenter">
+    <el-form label-width="80px" style="margin-left: 20px">
+      <el-form-item
+        v-for="(item, index) in lists"
+        :key="index"
+        :label="item.label"
+      >
+        <span v-if="item.scope === 'password'">******</span>
+        <span v-else>{{ formLabelAlign[item.prop] }}</span>
+      </el-form-item>
+    </el-form>
+    <el-button
+      type="success"
+      size="small"
+      style="margin-left: 100px"
+      @click="changeUserInfo"
+      >修改</el-button
+    >
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="560px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">修改</div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close"/>
+        </div>
+      </div>
+      <div>
+        <el-form label-width="80px">
+          <el-form-item
+            v-for="(items, indexs) in lists"
+            :key="indexs"
+            :label="items.label"
+          >
+            <el-input
+              :disabled="items.scope === 'user'"
+              style="width: 280px"
+              :placeholder="items.placeholder"
+              v-model="bfdata[items.prop]"
+            ></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button type="primary" @click="submit">确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      formLabelAlign: {},
+      dialogVisible: false,
+      lists: [
+        {
+          label: "账号",
+          prop: "userName",
+          scope: "user",
+        },
+        {
+          label: "账号名称",
+          prop: "nickName",
+          placeholder: "请输入账号名称",
+        },
+        {
+          label: "密码",
+          prop: "password",
+          scope: "password",
+          placeholder: "请输入新密码",
+        },
+        {
+          label: "手机号",
+          prop: "phonenumber",
+          placeholder: "请输入新手机号",
+        },
+      ],
+      bfdata: {},
+    };
+  },
+  created() {
+    this.init();
+  },
+  methods: {
+    init() {
+      this.formLabelAlign = {
+        nickName: this.$store.state.userInfo[0].user.nickName,
+        userName: this.$store.state.userInfo[0].user.userName,
+        phonenumber: this.$store.state.userInfo[0].user.phonenumber,
+      };
+    },
+    changeUserInfo() {
+      var bf = JSON.stringify(this.formLabelAlign);
+      this.bfdata = JSON.parse(bf);
+      this.dialogVisible = true;
+    },
+    close() {
+          this.dialogVisible = false;
+          this.init();
+    },
+    submit() {
+      var self = this
+      var testPhone = /^1[3-9](\d){9}$/;
+      if (this.bfdata.userName.length === 0) {
+        this.$message.error("请输入账号名称");
+        return;
+      }
+      if (!testPhone.test(this.bfdata.phonenumber)) {
+        this.$message.error("请输入正确手机号");
+        return;
+      }
+      if (this.formLabelAlign.phonenumber === this.bfdata.phonenumber) {
+        delete this.bfdata.phonenumber;
+      }
+      this.bfdata.userId = this.$store.state.userInfo[0].user.userId;
+      this.$api.editsystemuser(this.bfdata).then((res) => {
+        if (res.code === 200) {
+          self.$message.success("修改成功!");
+          self.dialogVisible = false;
+          self.$store.dispatch('GetUserInfo').then(() => {
+            self.init();
+      })
+        } else {
+          self.dialogVisible = false;
+          self.init();
+        }
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

+ 597 - 0
src/views/systemSettings/roleInfoManagement/index.vue

@@ -0,0 +1,597 @@
+<template>
+  <div id="roleInfoManagement">
+    <search-box :formList="formList" @search="search" @init="init" />
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      @addClick="addClick"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="addClick(props.scope.row, 2)"
+          >详情</el-button
+        >
+        <el-button type="text" @click="addClick(props.scope.row, 0)"
+          >修改</el-button
+        >
+        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="pageSize"
+      :currentPage="currentPage"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="460px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="80px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item
+            v-for="(items, indexs) in listitem"
+            :key="indexs"
+            :label="items.label"
+            :prop="items.prop"
+          >
+            <el-radio-group
+              v-if="items.scope === 'status'"
+              v-model="listData[items.prop]"
+            >
+              <el-radio
+                v-for="(item, index) in items.options"
+                :key="index"
+                :label="item.value"
+                :disabled="statusPop === 2"
+                >{{ item.label }}</el-radio
+              >
+            </el-radio-group>
+            <div v-else-if="items.scope === 'tree'">
+              <el-checkbox
+                v-model="menuExpand"
+                @change="handleCheckedTreeExpand($event, 'menu')"
+                >展开/折叠</el-checkbox
+              >
+              <el-checkbox
+                v-model="menuNodeAll"
+                @change="handleCheckedTreeNodeAll($event, 'menu')"
+                >全选/全不选</el-checkbox
+              >
+              <el-checkbox
+                v-model="listData.menuCheckStrictly"
+                @change="handleCheckedTreeConnect($event, 'menu')"
+                >父子联动</el-checkbox
+              >
+              <el-tree
+                class="tree-border"
+                :data="menuOptions"
+                show-checkbox
+                ref="menu"
+                node-key="id"
+                :check-strictly="!listData.menuCheckStrictly"
+                empty-text="加载中,请稍后"
+                :props="defaultProps"
+              ></el-tree>
+            </div>
+            <el-input
+              :disabled="statusPop === 2"
+              v-else-if="items.scope === 'textarea'"
+              type="textarea"
+              v-model="listData[items.prop]"
+            ></el-input>
+            <el-input-number
+              style="width: 100%"
+              :disabled="statusPop === 2"
+              v-else-if="items.scope === 'numberIndex'"
+              v-model="listData[items.prop]"
+              controls-position="right"
+              :min="0"
+              :max="99"
+            ></el-input-number>
+            <el-input
+              :disabled="statusPop === 2"
+              v-else
+              v-model="listData[items.prop]"
+            ></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button
+          type="primary"
+          v-if="statusPop !== 2"
+          @click="submit('listData')"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import searchBox from "@/components/searchBox";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  components: { searchBox, tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "角色管理",
+        index: 0,
+        ch: "种",
+        num: false,
+        choice: false,
+        addHide: false,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          label: "角色名称",
+          prop: "roleName",
+          placeholder: "请输入角色名称",
+        },
+        {
+          label: "权限字符",
+          prop: "roleKey",
+          placeholder: "请输入权限字符",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          placeholder: "请选择状态",
+          scope: "select",
+          options: [
+            {
+              label: "启用",
+              value: "1",
+            },
+            {
+              label: "停用",
+              value: "0",
+            },
+          ],
+        },
+      ],
+      // 表单
+      tableSet: [
+        {
+          label: "角色编号",
+          prop: "roleId",
+          hidden: true,
+        },
+        {
+          label: "角色名称",
+          prop: "roleName",
+          hidden: true,
+        },
+        {
+          label: "权限字符",
+          prop: "roleKey",
+          hidden: true,
+        },
+        {
+          label: "显示顺序",
+          prop: "roleSort",
+          hidden: true,
+        },
+        {
+          label: "状态",
+          prop: "status",
+          hidden: true,
+          scope: "status",
+        },
+        {
+          label: "创建时间",
+          prop: "createTime",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      pageSize: 10, //每页多少条数据
+      currentPage: 1, //当前页码
+      menuExpand: false,
+      menuNodeAll: false,
+      defaultProps: {
+        children: "children",
+        label: "label",
+      },
+      menuOptions: [], //菜单列表
+      // 弹窗字段
+      listitem: [
+        {
+          label: "角色名称",
+          prop: "roleName",
+        },
+        {
+          label: "权限字符",
+          prop: "roleKey",
+        },
+        {
+          label: "角色顺序",
+          prop: "roleSort",
+          scope: "numberIndex",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          scope: "status",
+          options: [
+            {
+              label: "启用",
+              value: "1",
+            },
+            {
+              label: "关闭",
+              value: "0",
+            },
+          ],
+        },
+        {
+          label: "菜单权限",
+          prop: "menuIds",
+          scope: "tree",
+        },
+        {
+          label: "备注",
+          prop: "remark",
+          scope: "textarea",
+        },
+      ],
+      //   弹窗数据
+      listData: {},
+      statusPop: -1,
+      dialogVisible: false,
+      //表单验证
+      rules: {
+        roleName: [
+          { required: true, message: "请输入岗位名称", trigger: "blur" },
+        ],
+        roleKey: [
+          { required: true, message: "请输入岗位编码", trigger: "blur" },
+        ],
+        roleSort: [
+          { required: true, message: "请输入岗位顺序", trigger: "blur" },
+        ],
+        status: [{ required: true, message: "请选择状态", trigger: "change" }],
+        // remark: [{ required: true, message: "请填写备注", trigger: "blur" }],
+      },
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    search(v) {
+      this.loading = true;
+      if (v === undefined) {
+        v = {
+          statusArray: "0,1",
+          pageSize: this.pageSize,
+          pageNum: this.currentPage,
+        };
+      }
+      var data = {
+        roleKey: v.roleKey || "",
+        roleName: v.roleName || "",
+        statusArray: v.status === undefined ? "0,1" : v.status,
+        pageSize: this.pageSize,
+        pageNum: this.currentPage,
+      };
+      this.$api.obtainRoleList(data).then((res) => {
+        this.tableData = res.rows.sort(this.sortBy("postSort", true));
+        this.total = res.total;
+        this.navText.index = res.total;
+      }).finally(()=>{
+        this.loading = false;
+      })
+    },
+    init() {
+      this.search();
+    },
+    del(v) {
+      this.$confirm("此操作将删除该岗位, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          var data = JSON.parse(JSON.stringify(v));
+          data.menuIds = [];
+          data.status = "-1";
+          this.$api.editRole(data).then((res) => {
+            if (res.code === 200) {
+              this.$message.success("删除成功");
+              this.search();
+              this.dialogVisible = false;
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    addClick(v, int) {
+      var self = this;
+      self.initData();
+      if (v === undefined) {
+        self.statusPop = 1;
+        self.getMenuList();
+        self.dialogVisible = true;
+        self.$nextTick(() => {
+          self.$refs.listData.clearValidate();
+        });
+      } else {
+        self.statusPop = int;
+        var data = v.roleId;
+        self.$api.obtainRoleId(data).then(async (res) => {
+          if (res.code === 200) {
+            const getCheckList = await self.getUserMenuList(v.roleId);
+            self.menuOptions = getCheckList.menus;
+            getCheckList.checkedKeys.forEach((v) => {
+              self.$nextTick(() => {
+                self.$refs.menu[0].setChecked(v, true, false);
+              });
+            });
+            self.listData = res.data;
+            self.dialogVisible = true;
+            self.$nextTick(() => {
+              self.$refs.listData.clearValidate();
+            });
+          }
+        });
+      }
+    },
+    getMenuList() {
+      this.$api.enutreeselect().then((res) => {
+        this.menuOptions = res.data;
+      });
+    },
+    getUserMenuList(v) {
+      return new Promise((resolve, reject) => {
+        this.$api.roleMenuTreeselect(v).then((result) => {
+          resolve(result);
+        });
+      });
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    rulesTableSumbit() {
+      this.listData.menuIds = this.getMenuAllCheckedKeys();
+      var data = this.listData;
+      if (this.statusPop === 1) {
+        this.$api.addRole(data).then((res) => {
+          if (res.code === 200) {
+            this.$message.success("新增成功");
+            this.search();
+            this.dialogVisible = false;
+          }
+        });
+      }
+      if (this.statusPop === 0) {
+        this.$api.editRole(data).then((res) => {
+          if (res.code === 200) {
+            this.$message.success("修改成功");
+            this.search();
+            this.dialogVisible = false;
+          }
+        });
+      }
+    },
+    close() {
+      this.initData();
+      this.dialogVisible = false;
+    },
+    initData() {
+      this.menuExpand = false;
+      this.menuNodeAll = false;
+      this.listData = {
+        roleId: undefined,
+        roleName: undefined,
+        roleKey: undefined,
+        roleSort: 0,
+        status: "",
+        menuIds: [],
+        deptIds: [],
+        menuCheckStrictly: true,
+        deptCheckStrictly: true,
+        remark: undefined,
+      };
+    },
+    sortBy(attr, rev) {
+      //第二个参数没有传递 默认升序排列
+      if (rev == undefined) {
+        rev = 1;
+      } else {
+        rev = rev ? 1 : -1;
+      }
+
+      return function (a, b) {
+        a = a[attr];
+        b = b[attr];
+        if (a < b) {
+          return rev * -1;
+        }
+        if (a > b) {
+          return rev * 1;
+        }
+        return 0;
+      };
+    },
+    // 树权限(展开/折叠)
+    handleCheckedTreeExpand(value, type) {
+      if (type == "menu") {
+        let treeList = this.menuOptions;
+        for (let i = 0; i < treeList.length; i++) {
+          this.$refs.menu[0].store.nodesMap[treeList[i].id].expanded = value;
+        }
+      }
+    },
+    // 树权限(全选/全不选)
+    handleCheckedTreeNodeAll(value, type) {
+      if (type == "menu") {
+        this.$refs.menu[0].setCheckedNodes(value ? this.menuOptions : []);
+      }
+    },
+    // 树权限(父子联动)
+    handleCheckedTreeConnect(value, type) {
+      if (type == "menu") {
+        this.listData.menuCheckStrictly = value ? true : false;
+      }
+    },
+    // 所有菜单节点数据
+    getMenuAllCheckedKeys() {
+      // 目前被选中的菜单节点
+      let checkedKeys = this.$refs.menu[0].getCheckedKeys();
+      // 半选中的菜单节点
+      let halfCheckedKeys = this.$refs.menu[0].getHalfCheckedKeys();
+      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
+      return checkedKeys;
+    },
+    handleSizeChange(v) {
+      this.pageSize = v;
+      this.currentPage = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.currentPage = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+.tree-border {
+  margin-top: 5px;
+  border: 1px solid #e5e6e7;
+  background: #ffffff none;
+  border-radius: 4px;
+}
+</style>
+

+ 680 - 0
src/views/systemSettings/usermanagement/index.vue

@@ -0,0 +1,680 @@
+<template>
+  <div id="usermanagement">
+    <el-row :gutter="20">
+      <el-col :span="4">
+        <el-input
+          v-model="filterText"
+          size="small"
+          placeholder="请输入内容"
+          clearable
+          prefix-icon="el-icon-search"
+        ></el-input>
+        <el-tree
+          class="filter-tree"
+          :data="dataDs"
+          :props="defaultProps"
+          default-expand-all
+          :filter-node-method="filterNode"
+          ref="tree"
+          :expand-on-click-node="false"
+          @node-click="getTreeDepart"
+        >
+        </el-tree>
+      </el-col>
+      <el-col :span="20">
+        <search-box :formList="formList" @search="search" @init="init" />
+        <table-list
+          :tableSets="tableSet"
+          :tableData="tableData"
+          :navText="navText"
+          @addClick="addClick"
+          :loading="loading"
+        >
+          <template slot="btn" slot-scope="props">
+            <!-- <el-button type="text" @click="addClick(props.scope.row, 2)"
+              >详情</el-button
+            > -->
+            <el-button type="text" @click="addClick(props.scope.row, 0)"
+              >修改</el-button
+            >
+            <el-button type="text" @click="del(props.scope.row)"
+              >删除</el-button
+            >
+            <el-button type="text" @click="Reset(props.scope.row)"
+              >重置</el-button
+            >
+          </template>
+        </table-list>
+        <pagination
+          :total="total"
+          :pageSize="pageSize"
+          :currentPage="currentPage"
+          @handleSizeChange="handleSizeChange"
+          @handleCurrentChange="handleCurrentChange"
+        />
+        <el-dialog
+          :visible.sync="dialogVisible"
+          width="560px"
+          :show-close="false"
+          :close-on-click-modal="false"
+        >
+          <div slot="title" class="hearders">
+            <div class="leftTitle">
+              {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
+            </div>
+            <div class="rightBoxs">
+              <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+            </div>
+          </div>
+          <div>
+            <el-form
+              label-position="right"
+              label-width="80px"
+              :model="listData"
+              :rules="rules"
+              ref="listData"
+            >
+              <el-form-item
+                v-for="(items, indexs) in listitem"
+                :key="indexs"
+                :label="items.label"
+                :prop="items.prop"
+              >
+                <el-radio-group
+                  v-if="items.scope === 'status'"
+                  v-model="listData[items.prop]"
+                >
+                  <el-radio
+                    v-for="(item, index) in items.options"
+                    :key="index"
+                    :label="item.value"
+                    :disabled="statusPop === 2"
+                    >{{ item.label }}</el-radio
+                  >
+                </el-radio-group>
+                <treeselect
+                  v-else-if="items.scope === 'selectMore'"
+                  v-model="listData[items.prop]"
+                  :options="dataDs"
+                  :show-count="true"
+                  placeholder="选择上级菜单"
+                />
+                <el-input
+                  :disabled="statusPop === 2"
+                  v-else-if="items.scope === 'textarea'"
+                  type="textarea"
+                  v-model="listData[items.prop]"
+                ></el-input>
+                <el-select
+                  v-else-if="items.scope === 'moreSelect'"
+                  v-model="listData[items.prop]"
+                  multiple
+                  placeholder="请选择"
+                >
+                  <el-option
+                    v-for="item in items.options"
+                    :key="item[items.option.value]"
+                    :label="item[items.option.label]"
+                    :value="item[items.option.value]"
+                  >
+                  </el-option>
+                </el-select>
+                <el-select
+                  v-else-if="items.scope === 'select'"
+                  v-model="listData[items.prop]"
+                  placeholder="请选择"
+                >
+                  <el-option
+                    v-for="(item, index) in dictManages.sys_user_sex"
+                    :key="index"
+                    :label="item"
+                    :value="item"
+                  >
+                  </el-option>
+                </el-select>
+                <el-input
+                  :disabled="statusPop === 2 || statusPop === 0"
+                  v-else-if="items.scope === 'userNames'"
+                  v-model="listData[items.prop]"
+                  ><template slot="append">登入账号</template></el-input
+                >
+                <el-input
+                  :disabled="statusPop === 2"
+                  v-else
+                  v-model="listData[items.prop]"
+                ></el-input>
+              </el-form-item>
+            </el-form>
+          </div>
+          <span slot="footer" class="dialog-footer">
+            <el-button @click="close">取 消</el-button>
+            <el-button
+              type="primary"
+              v-if="statusPop !== 2"
+              @click="submit('listData')"
+              >确 定</el-button
+            >
+          </span>
+        </el-dialog>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import searchBox from "@/components/searchBox";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+import { mapGetters } from "vuex";
+export default {
+  components: { Treeselect, searchBox, tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "用户信息",
+        index: 0,
+        ch: "条",
+        num: false,
+        choice: true,
+        addHide: false,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      filterText: "",
+      dataDs: [],
+      defaultProps: {
+        children: "children",
+        label: "label",
+      },
+      deptId: "",
+      //搜索
+      formList: [
+        {
+          label: "用户名称",
+          prop: "userName",
+          placeholder: "请输入用户名称",
+        },
+        {
+          label: "手机号码",
+          prop: "phonenumber",
+          placeholder: "请输入手机号码",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          placeholder: "请选择状态",
+          scope: "select",
+          options: [
+            {
+              label: "启用",
+              value: 1,
+            },
+            {
+              label: "停用",
+              value: 0,
+            },
+          ],
+        },
+      ],
+      // 表单
+      tableSet: [
+        {
+          label: "用户编号",
+          prop: "userId",
+          hidden: true,
+        },
+        {
+          label: "用户名称",
+          prop: "userName",
+          hidden: true,
+        },
+        {
+          label: "用户昵称",
+          prop: "nickName",
+          hidden: true,
+        },
+        {
+          label: "部门",
+          prop: "deptName",
+          hidden: true,
+        },
+        {
+          label: "手机号码",
+          prop: "phonenumber",
+          hidden: true,
+        },
+        {
+          label: "状态",
+          prop: "status",
+          hidden: true,
+          scope: "status",
+        },
+      ],
+      tableData: [], //表单数据
+      optionsCascader: [], //弹窗分类数据
+      total: 0, //一共多少条
+      pageSize: 10, //每页多少条数据
+      currentPage: 1, //当前页码
+      // 弹窗字段
+      listitem: [
+        {
+          label: "归属部门",
+          prop: "deptId",
+          scope: "selectMore",
+        },
+        {
+          label: "用户名称",
+          prop: "userName",
+          scope: "userNames",
+        },
+        {
+          label: "用户昵称",
+          prop: "nickName",
+        },
+        {
+          label: "手机号码",
+          prop: "phonenumber",
+        },
+        {
+          label: "邮箱",
+          prop: "email",
+        },
+        {
+          label: "用户性别",
+          prop: "sex",
+          scope: "select",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          scope: "status",
+          options: [
+            {
+              label: "启用",
+              value: "1",
+            },
+            {
+              label: "关闭",
+              value: "0",
+            },
+          ],
+        },
+        {
+          label: "岗位",
+          prop: "postIds",
+          option: {
+            label: "postName",
+            value: "postId",
+          },
+          options: [],
+          scope: "moreSelect",
+          show: true,
+        },
+        {
+          label: "角色",
+          prop: "roleIds",
+          option: {
+            label: "roleName",
+            value: "roleId",
+          },
+          options: [],
+          scope: "moreSelect",
+          show: true,
+        },
+        {
+          label: "备注",
+          prop: "remark",
+          scope: "textarea",
+        },
+      ],
+      listData: {},
+      statusPop: -1,
+      dialogVisible: false,
+      //表单验证
+      rules: {
+        deptId: [
+          { required: true, message: "请选择归属部门", trigger: "blur" },
+        ],
+        userName: [
+          { required: true, message: "请输入用户名称", trigger: "blur" },
+        ],
+        nickName: [
+          { required: true, message: "请输入用户昵称", trigger: "blur" },
+        ],
+        phonenumber: [
+          { required: true, message: "请输入手机号码", trigger: "blur" },
+        ],
+        email: [{ required: true, message: "请输入邮箱", trigger: "blur" }],
+        sex: [{ required: true, message: "请选择性别", trigger: "change" }],
+        status: [{ required: true, message: "请选择状态", trigger: "change" }],
+        postIds: [{ required: true, message: "请选择岗位", trigger: "change" }],
+        roleIds: [{ required: true, message: "请选择角色", trigger: "change" }],
+        remark: [{ required: true, message: "请填写备注", trigger: "blur" }],
+      },
+    };
+  },
+  computed: { ...mapGetters(["dictManages"]) },
+  watch: {
+    filterText(val) {
+      this.$refs.tree.filter(val);
+    },
+  },
+  mounted() {
+    this.search();
+    this.initTree();
+  },
+  methods: {
+    //重置密码
+    Reset(v) {
+      this.$prompt("请输入新密码", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+      })
+        .then(({ value }) => {
+          var data = {
+            deptId: v.deptId,
+            userName: v.userName,
+            nickName: v.nickName,
+            userId: v.userId,
+            password: value,
+          };
+          this.$api.editUser(data).then((res) => {
+            if (res.code === 200) {
+              this.$message({
+                type: "success",
+                message: "密码已重置",
+              });
+              this.search();
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "取消输入",
+          });
+        });
+    },
+    //   获取部门
+    initTree() {
+      var data = {
+        statusArray: "0,1",
+      };
+      this.$api.obtainDeptTreeselect(data).then((res) => {
+        this.dataDs = res.data;
+      });
+    },
+    // 对树节点进行筛选时执行的方法
+    filterNode(value, data) {
+      if (!value) return true;
+      return data.label.indexOf(value) !== -1;
+    },
+    //点击菜单栏
+    getTreeDepart(options) {
+      this.deptId = options.id;
+      this.search();
+    },
+    //搜索
+    search(v) {
+      this.loading = true;
+      if (v === undefined) {
+        v = {
+          statusArray: "0,1",
+          pageSize: this.pageSize,
+          pageNum: this.currentPage,
+        };
+      }
+      var data = {
+        deptId: this.deptId || "",
+        userName: v.userName || "",
+        phonenumber: v.phonenumber || "",
+        statusArray: v.status === undefined ? "0,1" : v.status,
+        pageSize: this.pageSize,
+        pageNum: this.currentPage,
+      };
+      this.$api
+        .obtainUserList(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+          res.rows.forEach((item, index) => {
+            if (item.dept) {
+              this.tableData[index].deptName = item.dept.deptName;
+            }
+          });
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    //重置
+    init() {
+      this.search();
+    },
+    //删除用户信息
+    del(v) {
+      this.$confirm("此操作将删除该用户信息, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          var data = {
+            deptId: v.deptId,
+            userName: v.userName,
+            nickName: v.nickName,
+            userId: v.userId,
+            status: "-1",
+          };
+          this.$api.editUser(data).then((res) => {
+            if (res.code === 200) {
+              this.$message.success("删除成功");
+              this.search();
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    //初始数据
+    getOptionsRole() {
+      var data = {
+        statusArray: "0,1",
+      };
+      this.$api.inquiresystempostList(data).then((res) => {
+        this.listitem.forEach((item, index) => {
+          if (item.prop === "postIds") {
+            item.options = res.rows;
+          }
+        });
+      });
+      this.$api.obtainRoleList(data).then((res) => {
+        this.listitem.forEach((item, index) => {
+          if (item.prop === "roleIds") {
+            item.options = res.rows;
+          }
+        });
+      });
+      // this.listitem.forEach((item, index) => {
+      //   if (item.label === "用户性别") {
+      //     // item.options = this.UserDict['sys_user_sex'];
+      //   }
+      // });
+    },
+    //开启窗口
+    addClick(v, int) {
+      this.getOptionsRole();
+      if (v === undefined) {
+        this.statusPop = 1;
+        this.listData = {};
+      } else {
+        this.statusPop = int;
+        var data = v.userId;
+        this.$api.obtainUserDetails(data).then((res) => {
+          this.listData = res.data;
+          this.listData.roleIds = res.roleIds;
+          this.listData.postIds = res.postIds;
+          this.listData.sex = res.data.sex;
+        });
+      }
+      this.$nextTick(() => {
+        this.$refs.listData.clearValidate();
+      });
+      this.dialogVisible = true;
+    },
+    //表单验证
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    //提交表单
+    rulesTableSumbit() {
+      if (this.statusPop === 1) {
+        this.$api.addUser(this.listData).then((res) => {
+          if (res.code === 200) {
+            this.search();
+            this.$message.success("新增成功");
+            this.dialogVisible = false;
+            this.resetForm();
+          }
+        });
+      }
+      if (this.statusPop === 0) {
+        this.$api.editUser(this.listData).then((res) => {
+          if (res.code === 200) {
+            this.search();
+            this.$message.success("修改成功");
+            this.dialogVisible = false;
+            this.resetForm();
+          }
+        });
+      }
+    },
+    // 关闭窗口
+    close() {
+      this.dialogVisible = false;
+      this.resetForm();
+    },
+    //重置表单验证
+    resetForm() {
+      this.$refs["listData"].resetFields();
+    },
+    handleSizeChange(v) {
+      this.pageSize = v;
+      this.currentPage = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.currentPage = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>