bonus-ui/src/views/system/user/index.vue

1512 lines
60 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-row :gutter="20">
<!--部门数据-->
<el-col :span="4" :xs="24">
<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>
<!--用户数据-->
<el-col :span="20" :xs="24">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="用户名称" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入用户名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input
v-model="queryParams.phonenumber"
placeholder="请输入手机号码"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="用户状态"
clearable
style="width: 240px"
>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="账户时效" prop="isPermanent">
<el-select
v-model="queryParams.isPermanent"
placeholder="用户状态"
clearable
style="width: 240px"
>
<el-option
v-for="dict in dict.type.sys_user_permanent"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</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="confirmPassword"
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>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
:columns="columns"
></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="userList"
@selection-change="handleSelectionChange"
:selectable="checkSelectable"
:row-class-name="getRowClassName"
>
<el-table-column
type="selection"
width="50"
align="center"
/>
<el-table-column label="序号" align="center" width="80" type="index">
<template slot-scope="scope">
<span>{{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}</span>
</template>
</el-table-column>
<el-table-column
label="用户编号"
align="center"
key="userId"
prop="userId"
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="deptName"
prop="dept.deptName"
v-if="columns[3].visible"
:show-overflow-tooltip="true"
/>
<el-table-column
label="手机号码"
align="center"
key="phonenumber"
prop="phonenumber"
v-if="columns[4].visible"
width="120"
>
<template slot-scope="scope">
<span>{{ hidePhone(scope.row.phonenumber) }}</span>
</template>
</el-table-column>
<el-table-column
label="状态"
align="center"
key="status"
v-if="columns[5].visible"
>
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
active-value="0"
inactive-value="1"
@change="handleStatusChange(scope.row)"
></el-switch>
</template>
</el-table-column>
<el-table-column
label="人脸照片"
align="center"
key="photoUrl"
v-if="columns[6].visible"
>
<template slot-scope="scope">
<img :src="scope.row.photoUrl" v-if="scope.row.photoUrl" alt="" style="width: 60px;height: 60px;" @click="openImg(scope.row)">
<span v-if="scope.row.faceStatus==0">未上传</span>
<span v-if="scope.row.faceStatus==2">上传失败</span>
</template>
</el-table-column>
<el-table-column label="账号时效" align="center">
<template slot-scope="scope">
<span>{{
scope.row.isPermanent == 1
? '长期账号'
: '临时账号'
}}</span>
</template>
</el-table-column>
<el-table-column
v-if="config.registersConfig.approvalStatus"
label="审批状态"
align="center"
>
<template slot-scope="scope">
<span>{{
scope.row.approvalStatus == 0
? '未审批'
: '已审批'
}}</span>
</template>
</el-table-column>
<el-table-column
label="创建时间"
align="center"
prop="createTime"
v-if="columns[7].visible"
width="160"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</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="
!hasSystemOrAuditrRole(scope.row.roles) &&
scope.row.userId !== 1 &&
scope.row.isBuiltIn !== '0'
"
>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="confirmPassword(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="handleUpFace"
icon="el-icon-key"
>人脸上传
</el-dropdown-item> -->
<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-item
v-if="scope.row.approvalStatus == 0"
command="approvalStatus"
icon="el-icon-circle-check"
v-hasPermi="['system:user:approval']"
>账号审批
</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>
</el-row>
<!-- 添加或修改用户配置对话框 -->
<el-dialog
:title="title"
:visible.sync="open"
width="750px"
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="deptId">
<treeselect
v-model="form.deptId"
:searchable="false"
:disable-branch-nodes="true"
:options="deptOptions"
:show-count="true"
placeholder="请选择归属部门"
noChildrenText="没有数据了"
noOptionsText="没有数据"
noResultsText="没有搜索结果"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="手机号码" prop="phonenumber">
<el-input
v-model="form.phonenumber"
placeholder="请输入手机号码"
maxlength="11"
/>
</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.userId == 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.userId == 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="12">
<el-form-item label="用户性别">
<el-select
v-model="form.sex" style="width: 100%;"
placeholder="请选择性别"
>
<el-option
v-for="dict in dict.type.sys_user_sex"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="用户类别">
<el-select v-model="form.userType" placeholder="请选择用户类别" style="width: 100%;">
<el-option
v-for="dict in dict.type.sys_user_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item label="APP用户">
<el-radio-group v-model="form.isCustomer">
<el-radio
v-for="item in isCustomerList"
:key="item.id"
:label="item.id"
>{{ item.name }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col> -->
<el-col :span="12">
<el-form-item label="岗位">
<el-select
v-model="form.postIds"
multiple style="width: 100%;"
placeholder="请选择岗位"
>
<el-option
v-for="item in postOptions"
:key="item.postId"
:label="item.postName"
:value="item.postId"
:disabled="item.status == 1"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="角色" prop="roleIds">
<el-select
v-model="form.roleIds"
multiple style="width: 100%;"
placeholder="请选择角色"
>
<el-option
v-for="item in roleOptions"
:key="item.roleId"
:label="item.roleName"
:value="item.roleId"
:disabled="
item.status == 1 || item.roleId === 1
"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="账号时效" prop="isPermanent">
<el-radio-group v-model="form.isPermanent">
<el-radio
v-for="dict in dict.type.sys_user_permanent"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="登录权限" prop="loginTypeArr">
<el-checkbox-group v-model="loginTypeArr">
<el-checkbox
v-for="dict in dict.type.sys_login_type"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="时效日期" prop="" v-if="form.isPermanent==0">
<el-date-picker
v-model="effectiveDateRange"
type="daterange"
align="right"
unlink-panels
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期" clearable
format="yyyy-MM-dd" style="width: 100%"
:picker-options="pickerOptions" >
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="人脸图片">
<el-upload
:http-request="
(obj) => imgUpLoad(obj, 'fileUrl')
"
action="#"
:limit="1"
:file-list="fileList"
:show-file-list="true"
list-type="picture-card"
accept=".png, .jpg, .jpeg"
:on-success="handleAvatarSuccess"
:before-upload="handleBeforeUpload"
:class="{ disabled: uploadDisabled }"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
>
<i
class="el-icon-plus avatar-uploader-icon"
></i>
</el-upload>
</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" :disabled="loadingBtn">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
<!-- 人脸上传弹窗 -->
<el-dialog title="上传人脸" :visible.sync="openFace" width="500px" append-to-body>
<el-form ref="baseForm" :model="baseForm" label-width="100px">
<el-row>
<el-col :span="12">
<el-form-item label="人脸图片">
<el-upload
:http-request="
(obj) => imgUpLoad(obj, 'fileUrl')
"
action="#"
:limit="1"
:file-list="fileList"
:show-file-list="true"
list-type="picture-card"
accept=".png, .jpg, .jpeg"
:on-success="handleAvatarSuccess"
:class="{ disabled: uploadDisabled }"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
>
<i
class="el-icon-plus avatar-uploader-icon"
></i>
</el-upload>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFace">确 定</el-button>
<el-button @click="openFace=false">取 消</el-button>
</div>
</el-dialog>
<el-dialog :visible.sync="dialogVisible" width="700px">
<img style="width: 100%;height: 100%;" :src="dialogImageUrl" alt="">
</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,
approvalStatus,
confirmPassword,
} from '@/api/system/user'
import { getToken } from '@/utils/auth'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { validateNewPassword } from '@/utils/validate'
import store from "@/store";
import { imgUpLoadTwo } from '@/api/system/upload'
import { decryptWithSM4,encryptWithSM4 } from '@/utils/sm';
export default {
name: 'User',
dicts: [
'sys_normal_disable',
'sys_user_sex',
'sys_user_type',
'sys_login_type',
'sys_user_permanent',
],
components: { Treeselect },
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 用户表格数据
userList: null,
// 弹出层标题
title: '',
// 部门树选项
deptOptions: undefined,
// 是否显示弹出层
open: false,
// 部门名称
deptName: undefined,
// 默认密码
initPassword: undefined,
// 日期范围
dateRange: [],
// 岗位选项
postOptions: [],
// 角色选项
roleOptions: [],
// 登录权限数组
loginTypeArr: [],
isCustomerList:[{id:"0",name:""},{id:"1",name:""}],
// 角色下拉多选限制数量
multipleLimit: 1,
// 表单参数
form: {},
effectiveDateRange: [new Date(),new Date().setDate(new Date().getDate() + 90)],//临时用户起止日期
pickerOptions: {
disabledDate(v) {
return v.getTime() < (new Date().getTime() - 86400000);// - 86400000是否包括当天
}
},
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',
},
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
userName: undefined,
phonenumber: undefined,
status: undefined,
isPermanent: undefined,
deptId: undefined,
},
// 列信息
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 },
{ key: 5, label: `状态`, visible: true },
{ key: 6, label: `人脸照片`, visible: true },
{ key: 7, 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',
},
],
email: [
{
type: 'email',
message: '请输入正确的邮箱地址',
trigger: ['blur', 'change'],
},
],
deptId: [
{
required: true,
message: '请选择归属部门',
trigger: 'blur',
},
],
phonenumber: [
{
required: true,
message: '手机号不能为空',
trigger: 'blur',
},
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: '请输入正确的手机号码',
trigger: 'blur',
},
],
loginTypeArr: [
{
required: true,
validator: this.validateLoginType,
trigger: 'change',
},
],
password: [
{
required: true,
message: '密码不能为空',
trigger: 'blur',
},
{ validator: validateNewPassword, trigger: 'blur' },
],
roleIds: [
{
required: true,
message: '请选择角色',
trigger: 'change',
},
]
},
openFace:false,
baseForm:{},
fileList:[],
checkUrlList: [],//图片
checkUrlNameList: [],//图片
dialogVisible:false,//图片弹窗
dialogImageUrl:"",//图片弹窗
loadingBtn:false,
// 是否显示cropper
visible: false,
options: {
img: store.getters.face, //裁剪图片的地址
autoCrop: true, // 是否默认生成截图框
autoCropWidth: 200, // 默认生成截图框宽度
autoCropHeight: 200, // 默认生成截图框高度
fixedBox: true, // 固定截图框大小 不允许改变
outputType:"png", // 默认生成截图为PNG格式
filename: 'face' // 文件名称
},
previews: {},
resizeHandler: null
}
},
computed: {
config() {
return (
JSON.parse(localStorage.getItem('systemConfig')) || {
registersConfig: {
phoneRegisters: true,
emailRegisters: true,
verificationCode: true,
approvalStatus: true,
},
}
) // 获取 JSON 对象
},
//图片上传1张后隐藏上传框
uploadDisabled() {
return this.checkUrlList.length > 0
},
},
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: {
/* 手机号码脱敏 */
hidePhone(phone) {
if (!phone) return ''
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
},
/* 表单登录权限自定义校验 */
validateLoginType(rule, value, callback) {
if (this.loginTypeArr.length > 0) {
callback()
} else {
callback(new Error('请至少选择一个登录权限'))
}
},
/** 查询用户列表 */
getList() {
this.loading = true
listUser(this.addDateRange(this.queryParams, this.dateRange)).then(
(response) => {
this.userList = response.rows
this.total = response.total
this.userList.forEach(item=>{
if(item.phonenumber){
this.$set(item,"phonenumber",decryptWithSM4(item.phonenumber))
}
})
this.loading = false
},
)
},
/** 查询部门下拉树结构 */
getDeptTree() {
deptTreeSelect().then((response) => {
this.deptOptions = this.filterTree(response.data)
})
},
filterTree(nodes) {
return nodes
.map((node) => {
if (node.children) {
node.children = this.filterTree(node.children)
}
return node
})
.filter((node) => node.status !== '1')
},
// 筛选节点
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
// 节点单击事件
handleNodeClick(data) {
this.queryParams.deptId = data.id
this.handleQuery()
},
//用户审批状态修改
handleApprovalStatus(row) {
this.$modal
.confirm('确认要审批' + row.userName + '"用户吗')
.then(function () {
return approvalStatus({ userId: row.userId })
})
.then(() => {
this.$modal.msgSuccess('审批成功')
this.getList()
})
.catch(function () {})
},
// 用户状态修改
handleStatusChange(row) {
let text = row.status === '0' ? '启用' : '停用'
this.$modal
.confirm('确认要"' + text + '""' + row.userName + '"用户吗')
.then(function () {
return changeUserStatus(row.userId, row.status)
})
.then(() => {
this.$modal.msgSuccess(text + '成功')
})
.catch(function () {
row.status = row.status === '0' ? '1' : '0'
})
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
userId: undefined,
deptId: undefined,
userName: undefined,
nickName: undefined,
password: undefined,
phonenumber: undefined,
email: undefined,
sex: undefined,
status: '0',
isCustomer: '0',
isPermanent:'1',
remark: undefined,
postIds: [],
roleIds: [],
roleId: null,
loginType: null,
}
this.effectiveDateRange = [new Date().setDate(new Date().getDate()),new Date().setDate(new Date().getDate() + 92)]
this.resetForm('form')
this.checkUrlList = []
this.checkUrlNameList = []
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.queryParams.deptId = undefined
this.$refs.tree.setCurrentKey(null)
this.handleQuery()
},
// 多选框选中数据
handleSelectionChange(selection) {
// 过滤掉不可选的行(虽然界面上不可选,但为了安全起见还是过滤一次)
const validSelection = selection.filter((row) =>
this.checkSelectable(row),
)
// 更新选中的roleId数组
this.ids = validSelection.map((item) => item.userId)
// 更新单选和多选状态
this.single = validSelection.length !== 1
this.multiple = !validSelection.length
},
// 更多操作触发
handleCommand(command, row) {
switch (command) {
case 'handleResetPwd':
this.confirmResetPwd(row)
break
case 'handleAuthRole':
this.handleAuthRole(row)
break
case 'approvalStatus':
this.handleApprovalStatus(row)
break
case 'handleUpFace':
this.handleUpFace(row)
break
default:
break
}
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.loginTypeArr.splice(0)
this.fileList=[]
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()
this.loginTypeArr.splice(0)
const userId = row.userId || this.ids
getUser(userId).then((response) => {
this.form = response.data
if(this.form.phonenumber){
this.$set(this.form,"phonenumber",decryptWithSM4(response.data.phonenumber))
}
if(this.form.email){
this.$set(this.form,"email",decryptWithSM4(response.data.email))
}
const loginType = response.data.loginType
if (loginType) {
this.loginTypeArr = loginType.split(',')
}
if(this.form.isPermanent==0){
this.effectiveDateRange = [new Date(this.form.effectiveStartDay).getTime(),new Date(this.form.effectiveEndDay).getTime()]
}
this.postOptions = response.posts
this.roleOptions = response.roles
this.$set(this.form, 'postIds', response.postIds)
this.$set(this.form, 'roleIds', response.roleIds)
// console.log(store.getters.face)
if(response.data.photoUrl&&response.data.photoUrl!=''){
this.fileList=[{url:response.data.photoUrl}]
this.checkUrlList=[response.data.photoUrl]
this.checkUrlNameList = []
}else{
this.fileList=[]
this.checkUrlList=[]
this.checkUrlNameList = []
}
this.open = true
this.title = '修改用户'
this.form.password = ''
})
},
confirmPassword(row) {
this.$prompt('请输入密码,鉴别用户', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
closeOnClickModal: false,
inputPattern: /^.{8,16}$/,
inputErrorMessage: '用户密码长度必须介于 8 16 之间',
inputValidator: (value) => {
// 调用 validateNewPassword 校验
const errorMessage = function (error) {
if (error) {
return error.message
} else {
console.log('验证通过')
}
}
validateNewPassword(null, value, errorMessage)
},
})
.then(({ value }) => {
confirmPassword(value).then((response) => {
this.$modal.msgSuccess('验证成功')
this.handleUpdate(row)
})
})
.catch(() => {})
},
confirmResetPwd(row) {
this.$prompt('请输入密码,鉴别用户', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
closeOnClickModal: false,
inputPattern: /^.{8,16}$/,
inputErrorMessage: '用户密码长度必须介于 8 16 之间',
inputValidator: (value) => {
// 调用 validateNewPassword 校验
const errorMessage = function (error) {
if (error) {
return error.message
} else {
console.log('验证通过')
}
}
validateNewPassword(null, value, errorMessage)
},
})
.then(({ value }) => {
confirmPassword(value).then((response) => {
this.$modal.msgSuccess('验证成功')
this.handleResetPwd(row)
})
})
.catch(() => {})
},
/** 重置密码按钮操作 */
handleResetPwd(row) {
this.$prompt('请输入"' + row.userName + '"的新密码', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
closeOnClickModal: false,
inputPattern: /^.{8,16}$/,
inputErrorMessage: '用户密码长度必须介于 8 16 之间',
inputValidator: (value) => {
// 调用 validateNewPassword 校验
const errorMessage = function (error) {
if (error) {
return error.message
} else {
console.log('验证通过')
}
}
validateNewPassword(null, value, errorMessage)
},
}).then(({ value }) => {
let password = encryptWithSM4(value)
resetUserPwd(row.userId, password).then((response) => {
this.$modal.msgSuccess('修改成功新密码是' + value)
})
}).catch(() => {})
},
/** 分配角色操作 */
handleAuthRole: function (row) {
const userId = row.userId
this.$router.push('/system/user-auth/role/' + userId)
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate((valid) => {
this.form.loginType = this.loginTypeArr.toString()
if(this.checkUrlList.length==0){
this.form.photoUrl = null
// this.$message.warning('请先上传人脸图片')
}else{
this.form.photoUrl = this.checkUrlList[0]
}
if(this.form.isPermanent==0){
this.form.effectiveStartDay = this.formatDate(this.effectiveDateRange[0])
this.form.effectiveEndDay = this.formatDate(this.effectiveDateRange[1])
}else{
this.form.effectiveStartDay = null
this.form.effectiveEndDay = null
}
let param = Object.assign({},this.form)
if (valid) {
if(param.phonenumber&&param.phonenumber!=""){
this.$set(param,"phonenumber",encryptWithSM4(param.phonenumber))
}
if(param.email&&param.email!=""){
this.$set(param,"email",encryptWithSM4(param.email))
}
if (param.userId != undefined) {
updateUser(param).then((response) => {
this.$modal.msgSuccess('修改成功')
this.open = false
this.getList()
})
} else {
addUser(param).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(() => {})
},
/** 导出按钮操作 */
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`,
).then((response) => {})
},
// 文件上传中处理
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()
},
hasSystemOrAuditrRole(roles) {
if (!roles || !Array.isArray(roles)) {
return false // 如果 roles 为空或不是数组,返回 false
}
return roles.some(
(role) =>
role.roleKey === 'systemAdmin' || role.roleKey === 'audit',
) // 检查是否存在 roleKey 为 admin 的角色
},
// 检查行是否可选
checkSelectable(row) {
return !(
row.userId === 1 ||
row.isBuiltIn === '0' ||
this.hasSystemOrAuditrRole(row.roles)
)
},
getRowClassName(row) {
return !this.checkSelectable(row) ? 'disabled-row' : ''
},
//-----人脸上传------
handleUpFace(row){
console.log(row)
const userId = row.userId || this.ids
getUser(userId).then((response) => {
this.baseForm = response.data
this.openFace = true
})
},
submitFace(){
// console.log(this.baseForm)
console.log(this.checkUrlList)
if(this.checkUrlList.length==0){
this.$message.warning('请先上传人脸图片')
}else{
this.baseForm.photoUrl = this.checkUrlList[0]
updateUser(this.baseForm).then((response) => {
this.$modal.msgSuccess('上传成功')
store.commit('SET_FACE', this.checkUrlList[0]);
this.openFace = false;
this.getList()
})
}
},
// 图片上传
imgUpLoad(param, name, index) {
// console.log(param,'image')
param.type = 'face'
this.loadingBtn=true
imgUpLoadTwo(param).then((res) => {
if (res.code == 200) {
this.checkUrlList.push(res.data.url)
this.checkUrlNameList.push(res.data.name)
} else {
this.$modal.msgError(res.msg)
}
this.loadingBtn=false
})
.catch((error) => {
this.$modal.msgError(error)
this.loadingBtn=false
})
},
handleAvatarSuccess(res, file) {
console.log('success')
},
// 上传之前
handleBeforeUpload(file) {
const isLt = file.size / 1024 / 1024 < 5
if (!isLt) {
this.$modal.msgError(`图片大小不能超过 5 MB`)
return false
}
},
handleExceed(files, fileList) {
this.$message.warning('最多只可以上传一张图片')
},
handleRemove(file, fileList) {
let sum = 0
this.checkUrlNameList.forEach((item, index) => {
if (item == file.name) {
sum = index
}
})
this.checkUrlNameList.splice(sum, 1)
this.checkUrlList.splice(sum, 1)
},
//图片点击查看
handlePictureCardPreview(file) {
console.log(file)
this.dialogImageUrl = file.url
this.dialogVisible = true
},
openImg(row) {
console.log(row)
this.dialogImageUrl = row.photoUrl
this.dialogVisible = true
},
//日期
formatDate(sdate) {
let date = new Date(sdate);
// 格式化为 YYYY-MM-DD
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
},
}
</script>
<style lang="scss" scoped>
//隐藏图片上传框的css
::v-deep.disabled {
.el-upload--picture-card {
display: none;
}
}
.disabled-row {
background-color: #f5f7fa !important;
color: #909399;
cursor: not-allowed;
}
.disabled-row .el-checkbox__input {
cursor: not-allowed !important;
}
.disabled-row:hover td {
background-color: #f5f7fa !important;
}
</style>