tangjunhao il y a 3 mois
Parent
commit
d4c37f2a3d

+ 0 - 0
adi-ui/src/api/airopt/airoptpro.js


+ 150 - 0
adi-ui/src/api/airopt/airoptuser.js

@@ -0,0 +1,150 @@
+import request from '@/utils/request'
+import { parseStrEmpty } from "@/utils/ruoyi";
+
+export function getUserOnline() {
+  return request({
+    url: '/buss/user/online',
+    method: 'get'
+  })
+}
+
+// 查询用户列表
+export function listUser(query) {
+  return request({
+    url: '/buss/user/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询用户详细
+export function getUser(userId) {
+  return request({
+    url: '/buss/user/detail/' + parseStrEmpty(userId),
+    method: 'get'
+  })
+}
+
+// 新增用户
+export function addUser(data) {
+  return request({
+    url: '/buss/user',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改用户
+export function updateUser(data) {
+  return request({
+    url: '/buss/user/update',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除用户
+export function delUser(userId) {
+  return request({
+    url: '/buss/user/' + userId,
+    method: 'delete'
+  })
+}
+
+export function reUserpwd(userId) {
+  return request({
+    url: '/buss/user/repwd/' + userId,
+    method: 'put'
+  })
+}
+
+// 用户密码重置
+export function resetUserPwd(userId, password) {
+  const data = {
+    userId,
+    password
+  }
+  return request({
+    url: '/buss/user/resetPwd',
+    method: 'put',
+    data: data
+  })
+}
+
+// 用户状态修改
+export function changeUserStatus(userId, status) {
+  const data = {
+    userId,
+    status
+  }
+  return request({
+    url: '/buss/user/changeStatus',
+    method: 'put',
+    data: data
+  })
+}
+
+// 查询用户个人信息
+export function getUserProfile() {
+  return request({
+    url: '/buss/user/profile',
+    method: 'get'
+  })
+}
+
+// 修改用户个人信息
+export function updateUserProfile(data) {
+  return request({
+    url: '/buss/user/profile',
+    method: 'put',
+    data: data
+  })
+}
+
+// 用户密码重置
+export function updateUserPwd(oldPassword, newPassword) {
+  const data = {
+    oldPassword,
+    newPassword
+  }
+  return request({
+    url: '/buss/user/profile/updatePwd',
+    method: 'put',
+    data: data
+  })
+}
+
+// 用户头像上传
+export function uploadAvatar(data) {
+  return request({
+    url: '/buss/user/profile/avatar',
+    method: 'post',
+    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+    data: data
+  })
+}
+
+// 查询授权角色
+export function getAuthRole(userId) {
+  return request({
+    url: '/buss/user/authRole/' + userId,
+    method: 'get'
+  })
+}
+
+// 保存授权角色
+export function updateAuthRole(data) {
+  return request({
+    url: '/buss/user/authRole',
+    method: 'put',
+    params: data
+  })
+}
+
+// 查询部门下拉树结构
+export function deptTreeSelect() {
+  return request({
+    url: '/system/user/deptTree',
+    method: 'get'
+  })
+}

+ 2 - 2
adi-ui/src/layout/components/Navbar.vue

@@ -9,13 +9,13 @@
       <template v-if="device!=='mobile'">
         <search id="header-search" class="right-menu-item" />
 
-        <el-tooltip content="源码地址" effect="dark" placement="bottom">
+        <!-- <el-tooltip content="源码地址" effect="dark" placement="bottom">
           <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
         </el-tooltip>
 
         <el-tooltip content="文档地址" effect="dark" placement="bottom">
           <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
-        </el-tooltip>
+        </el-tooltip> -->
 
         <screenfull id="screenfull" class="right-menu-item hover-effect" />
 

+ 1 - 1
adi-ui/src/utils/ruoyi.js

@@ -193,7 +193,7 @@ export function tansParams(params) {
   for (const propName of Object.keys(params)) {
     const value = params[propName]
     var part = encodeURIComponent(propName) + "="
-    if (value !== null && value !== "" && typeof (value) !== "undefined") {
+    if (value !== null && typeof (value) !== "undefined") {
       if (typeof value === 'object') {
         for (const key of Object.keys(value)) {
           if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {

+ 0 - 0
adi-ui/src/views/airopt/airoptpro/index.vue


+ 511 - 0
adi-ui/src/views/airopt/airoptuser/index.vue

@@ -0,0 +1,511 @@
+<template>
+  <div class="app-container">
+    <el-row :gutter="20">
+      <splitpanes :horizontal="this.$store.getters.device === 'mobile'" class="default-theme">
+        <!--部门数据-->
+        <!-- <pane size="16">
+          <el-col>
+            <div class="head-container">
+              <el-input v-model="deptName" placeholder="请输入部门名称" clearable size="small" prefix-icon="el-icon-search" style="margin-bottom: 20px" />
+            </div>
+            <div class="head-container">
+              <el-tree :data="deptOptions" :props="defaultProps" :expand-on-click-node="false" :filter-node-method="filterNode" ref="tree" node-key="id" default-expand-all highlight-current @node-click="handleNodeClick" />
+            </div>
+          </el-col>
+        </pane> -->
+        <!--用户数据-->
+        <pane size="100">
+          <el-col>
+            <el-form :model="searchcontainer" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+              <el-form-item label="用户名称" prop="username">
+                <el-input v-model="searchcontainer.username" placeholder="请输入用户名称" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
+              </el-form-item>
+              <el-form-item label="用户昵称" prop="nickname">
+                <el-input v-model="searchcontainer.nickname" placeholder="请输入用户昵称" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
+              </el-form-item>
+              <el-form-item label="手机号码" prop="mobileNo">
+                <el-input v-model="searchcontainer.mobileNo" placeholder="请输入手机号码" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
+              </el-form-item>
+              <el-form-item label="邮箱" prop="email">
+                <el-input v-model="searchcontainer.email" placeholder="请输入邮箱" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
+              </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">
+              <el-col :span="1.5">
+                <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:user:add']">新增</el-button>
+              </el-col>
+              <el-col :span="1.5">
+                <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" v-hasPermi="['system:user:edit']">修改</el-button>
+              </el-col>
+              <el-col :span="1.5">
+                <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:user:remove']">删除</el-button>
+              </el-col>
+              <el-col :span="1.5">
+                <el-button type="info" plain icon="el-icon-upload2" size="mini" @click="handleImport" v-hasPermi="['system:user:import']">导入</el-button>
+              </el-col>
+              <el-col :span="1.5">
+                <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['system:user:export']">导出</el-button>
+              </el-col>
+              <el-col :span="1.5">
+                <el-button type="primary" plain size="mini" @click="handleOnline" >在线用户</el-button>
+              </el-col>
+              <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
+            </el-row>
+
+            <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
+              <el-table-column type="selection" width="50" align="center" />
+              <el-table-column label="编号" align="center" type="index" v-if="columns[0].visible" />
+              <el-table-column label="用户名称" align="center" key="username" prop="username" v-if="columns[1].visible" :show-overflow-tooltip="true" />
+              <el-table-column label="用户昵称" align="center" key="nickname" prop="nickname" v-if="columns[2].visible" :show-overflow-tooltip="true" />
+              <el-table-column label="手机号码" align="center" key="mobileNo" prop="mobileNo" v-if="columns[3].visible" width="120" />
+              <el-table-column label="创建时间" align="center" prop="regTime" v-if="columns[4].visible" width="160">
+                <template slot-scope="scope">
+                  <span>{{ parseTime(scope.row.regTime) }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
+                <template slot-scope="scope" v-if="scope.row.uid !== 1">
+                  <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:user:edit']">修改</el-button>
+                  <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['system:user:remove']">删除</el-button>
+                  <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']">
+                    <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button>
+                    <el-dropdown-menu slot="dropdown">
+                      <el-dropdown-item command="handleResetPwd" icon="el-icon-key" v-hasPermi="['system:user:resetPwd']">重置密码</el-dropdown-item>
+                      <el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check" v-hasPermi="['system:user:edit']">分配角色</el-dropdown-item>
+                    </el-dropdown-menu>
+                  </el-dropdown>
+                </template>
+              </el-table-column>
+            </el-table>
+
+            <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
+          </el-col>
+        </pane>
+      </splitpanes>
+    </el-row>
+
+    <!-- 添加或修改用户配置对话框 -->
+    <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="12">
+            <el-form-item label="用户昵称" prop="nickname">
+              <el-input v-model="form.nickname" placeholder="请输入用户昵称" maxlength="30" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="手机号码" prop="mobileNo">
+              <el-input v-model="form.mobileNo" placeholder="请输入手机号码" maxlength="11" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="公司" prop="company">
+              <el-input v-model="form.company" placeholder="请输入公司" maxlength="50" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="邮箱" prop="email">
+              <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item v-if="form.uid == undefined" label="用户名称" prop="username">
+              <el-input v-model="form.username" placeholder="请输入用户名称" maxlength="30" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item v-if="form.uid == undefined" label="用户密码" prop="password">
+              <el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="备注">
+              <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
+            </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>
+
+    <!-- 用户导入对话框 -->
+    <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
+      <el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+        <div class="el-upload__tip text-center" slot="tip">
+          <div class="el-upload__tip" slot="tip">
+            <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据
+          </div>
+          <span>仅允许导入xls、xlsx格式文件。</span>
+          <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板</el-link>
+        </div>
+      </el-upload>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitFileForm">确 定</el-button>
+        <el-button @click="upload.open = false">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus, deptTreeSelect, getUserOnline, reUserpwd } from "@/api/airopt/airoptuser"
+import { getToken } from "@/utils/auth"
+import Treeselect from "@riophae/vue-treeselect"
+import "@riophae/vue-treeselect/dist/vue-treeselect.css"
+import { Splitpanes, Pane } from "splitpanes"
+import "splitpanes/dist/splitpanes.css"
+
+export default {
+  name: 'Airoptuser',
+  dicts: ['sys_normal_disable', 'sys_user_sex'],
+  components: { Treeselect, Splitpanes, Pane },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 用户表格数据
+      userList: null,
+      // 弹出层标题
+      title: "",
+      // 所有部门树选项
+      deptOptions: undefined,
+      // 过滤掉已禁用部门树选项
+      enabledDeptOptions: undefined,
+      // 是否显示弹出层
+      open: false,
+      // 部门名称
+      deptName: undefined,
+      // 默认密码
+      initPassword: undefined,
+      // 日期范围
+      dateRange: [],
+      // 岗位选项
+      postOptions: [],
+      // 角色选项
+      roleOptions: [],
+      // 表单参数
+      form: {},
+      defaultProps: {
+        children: "children",
+        label: "label"
+      },
+      // 用户导入参数
+      upload: {
+        // 是否显示弹出层(用户导入)
+        open: false,
+        // 弹出层标题(用户导入)
+        title: "",
+        // 是否禁用上传
+        isUploading: false,
+        // 是否更新已经存在的用户数据
+        updateSupport: 0,
+        // 设置上传的请求头部
+        headers: { Authorization: "Bearer " + getToken() },
+        // 上传的地址
+        url: process.env.VUE_APP_BASE_API + "/system/user/importData"
+      },
+      searchcontainer: {
+        username: undefined,
+        nickname: undefined,
+        mobileNo: undefined,
+        email: undefined,
+      },
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        searchtag: ""
+      },
+      // 列信息
+      columns: [
+        { key: 0, label: `编号`, visible: true },
+        { key: 1, label: `用户名称`, visible: true },
+        { key: 2, label: `用户昵称`, visible: true },
+        { key: 3, label: `手机号码`, visible: true },
+        { key: 4, label: `创建时间`, visible: true }
+      ],
+      // 表单校验
+      rules: {
+        username: [
+          { required: true, message: "用户名称不能为空", trigger: "blur" },
+          { min: 2, max: 20, message: '用户名称长度必须介于 2 和 20 之间', trigger: 'blur' }
+        ],
+        nickname: [
+          { required: true, message: "用户昵称不能为空", trigger: "blur" }
+        ],
+        password: [
+          { required: true, message: "用户密码不能为空", trigger: "blur" },
+          { min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' },
+          { pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
+        ],
+        email: [
+          {
+            type: "email",
+            message: "请输入正确的邮箱地址",
+            trigger: ["blur", "change"]
+          }
+        ],
+        mobileNo: [
+          {
+            pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
+            message: "请输入正确的手机号码",
+            trigger: "blur"
+          }
+        ]
+      }
+    }
+  },
+  watch: {
+    // 根据名称筛选部门树
+    deptName(val) {
+      this.$refs.tree.filter(val)
+    }
+  },
+  created() {
+    this.getList()
+    this.getDeptTree()
+    this.getConfigKey("sys.user.initPassword").then(response => {
+      this.initPassword = response.msg
+    })
+  },
+  methods: {
+    /** 查询用户列表 */
+    getList() {
+      this.loading = true
+      this.queryParams.searchtag = this.searchcontainer.username || this.searchcontainer.nickname || this.searchcontainer.mobileNo || this.searchcontainer.email || ""
+      listUser(this.queryParams).then(response => {
+          this.userList = response.data.rows
+          this.total = response.data.total
+          this.loading = false
+        }
+      )
+    },
+    /** 查询部门下拉树结构 */
+    getDeptTree() {
+      deptTreeSelect().then(response => {
+        this.deptOptions = response.data
+        this.enabledDeptOptions = this.filterDisabledDept(JSON.parse(JSON.stringify(response.data)))
+      })
+    },
+    // 过滤禁用的部门
+    filterDisabledDept(deptList) {
+      return deptList.filter(dept => {
+        if (dept.disabled) {
+          return false
+        }
+        if (dept.children && dept.children.length) {
+          dept.children = this.filterDisabledDept(dept.children)
+        }
+        return true
+      })
+    },
+    // 筛选节点
+    filterNode(value, data) {
+      if (!value) return true
+      return data.label.indexOf(value) !== -1
+    },
+    // 节点单击事件
+    handleNodeClick(data) {
+      this.queryParams.deptId = data.id
+      this.handleQuery()
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false
+      this.reset()
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        uid: undefined,
+        username: undefined,
+        nickname: undefined,
+        password: undefined,
+        mobileNo: undefined,
+        company: undefined,
+        email: undefined,
+        remark: undefined,
+      }
+      this.resetForm("form")
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1
+      this.getList()
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm")
+      this.handleQuery()
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.userId)
+      this.single = selection.length != 1
+      this.multiple = !selection.length
+    },
+    // 更多操作触发
+    handleCommand(command, row) {
+      switch (command) {
+        case "handleResetPwd":
+          this.handleResetPwd(row)
+          break
+        case "handleAuthRole":
+          this.handleAuthRole(row)
+          break
+        default:
+          break
+      }
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset()
+      getUser().then(response => {
+        this.postOptions = response.posts
+        this.roleOptions = response.roles
+        this.open = true
+        this.title = "添加用户"
+        this.form.password = this.initPassword
+      })
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset()
+      const userId = row.uid || this.ids
+      console.log("userId", userId)
+      getUser(userId).then(response => {
+        this.form = response.data
+        console.log("form", this.form)
+        this.open = true
+        this.title = "修改用户"
+        this.form.password = ""
+      })
+    },
+    /** 重置密码按钮操作 */
+    // handleResetPwd(row) {
+    //   this.$prompt('请输入"' + row.userName + '"的新密码', "提示", {
+    //     confirmButtonText: "确定",
+    //     cancelButtonText: "取消",
+    //     closeOnClickModal: false,
+    //     inputPattern: /^.{5,20}$/,
+    //     inputErrorMessage: "用户密码长度必须介于 5 和 20 之间",
+    //     inputValidator: (value) => {
+    //       if (/<|>|"|'|\||\\/.test(value)) {
+    //         return "不能包含非法字符:< > \" ' \\\ |"
+    //       }
+    //     },
+    //   }).then(({ value }) => {
+    //       resetUserPwd(row.userId, value).then(response => {
+    //         this.$modal.msgSuccess("修改成功,新密码是:" + value)
+    //       })
+    //     }).catch(() => {})
+    // },
+    /** 重置密码按钮操作 */
+    handleResetPwd(row) {
+      const userId = row.uid
+      reUserpwd(userId).then(response => {
+        this.$modal.msgSuccess("重置成功!")
+      })
+    },
+    /** 分配角色操作 */
+    handleAuthRole: function(row) {
+      const userId = row.userId
+      this.$router.push("/system/user-auth/role/" + userId)
+    },
+    /** 提交按钮 */
+    submitForm: function() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.uid != undefined) {
+            updateUser(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功")
+              this.open = false
+              this.getList()
+            })
+          } else {
+            addUser(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功")
+              this.open = false
+              this.getList()
+            })
+          }
+        }
+      })
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const userIds = row.userId || this.ids
+      this.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?').then(function() {
+        return delUser(userIds)
+      }).then(() => {
+        this.getList()
+        this.$modal.msgSuccess("删除成功")
+      }).catch(() => {})
+    },
+    /** 在线用户按钮操作 */
+    handleOnline() {
+      getUserOnline().then(response => {
+        this.$modal.msgSuccess("在线用户:" + response.data.count)
+      })
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('system/user/export', {
+        ...this.queryParams
+      }, `user_${new Date().getTime()}.xlsx`)
+    },
+    /** 导入按钮操作 */
+    handleImport() {
+      this.upload.title = "用户导入"
+      this.upload.open = true
+    },
+    /** 下载模板操作 */
+    importTemplate() {
+      this.download('system/user/importTemplate', {
+      }, `user_template_${new Date().getTime()}.xlsx`)
+    },
+    // 文件上传中处理
+    handleFileUploadProgress(event, file, fileList) {
+      this.upload.isUploading = true
+    },
+    // 文件上传成功处理
+    handleFileSuccess(response, file, fileList) {
+      this.upload.open = false
+      this.upload.isUploading = false
+      this.$refs.upload.clearFiles()
+      this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true })
+      this.getList()
+    },
+    // 提交上传文件
+    submitFileForm() {
+      this.$refs.upload.submit()
+    }
+  }
+}
+</script>