Files
income_payments_client/src/views/system/modules/UserModal.vue
T
2021-09-27 19:20:17 +08:00

740 lines
26 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>
<a-drawer
:title="title"
:maskClosable="true"
:width="drawerWidth"
placement="right"
:closable="true"
@close="handleCancel"
:visible="visible"
style="height: 100%;overflow: auto;padding-bottom: 53px;">
<template slot="title">
<div style="width: 100%;">
<span>{{ title }}</span>
<span style="display:inline-block;width:calc(100% - 51px);padding-right:10px;text-align: right">
<a-button @click="toggleScreen" icon="appstore" style="height:20px;width:20px;border:0px"></a-button>
</span>
</div>
</template>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-item label="用户账号" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入用户账号" @change="event => event.target.value = event.target.value.trim()" :maxLength="50" v-decorator.trim="[ 'username', validatorRules.username]"
:readOnly="!!model.id" :disabled="disableSubmit" />
</a-form-item>
<template v-if="!model.id">
<a-form-item label="登录密码" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input type="password" placeholder="请输入登录密码" :maxLength="50" autocomplete='new-password'
@change="event => event.target.value = event.target.value.trim()" :disabled="disableSubmit" v-decorator="[ 'password',validatorRules.password]"/>
</a-form-item>
<a-form-item label="确认密码" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input type="password" @blur="handleConfirmBlur" :maxLength="50" placeholder="请输入确认密码" :disabled="disableSubmit"
@change="event => event.target.value = event.target.value.trim()" v-decorator="[ 'confirmpassword', validatorRules.confirmpassword]"/>
</a-form-item>
</template>
<a-form-item label="用户姓名" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入用户姓名" :disabled="disableSubmit" @change="event => event.target.value = event.target.value.trim()" :maxLength="50" v-decorator.trim="[ 'realname', validatorRules.realname]"/>
</a-form-item>
<!--<a-form-item label="工号" :labelCol="labelCol" :wrapperCol="wrapperCol">-->
<!--<a-input placeholder="请输入工号" v-decorator.trim="[ 'workNo', validatorRules.workNo]" />-->
<!--</a-form-item>-->
<!--<a-form-item label="职务" :labelCol="labelCol" :wrapperCol="wrapperCol">-->
<!--<j-select-position placeholder="请选择职务" :multiple="false" v-decorator="['post', {}]"/>-->
<!--</a-form-item>-->
<!-- <a-form-item label="角色分配" :labelCol="labelCol" :wrapperCol="wrapperCol" v-show="!roleDisabled">-->
<!-- <a-select-->
<!-- mode="multiple"-->
<!-- :disabled="departDisabled || disableSubmit"-->
<!-- style="width: 100%"-->
<!-- placeholder="请选择用户角色"-->
<!-- optionFilterProp="children"-->
<!-- v-model="selectedRole"-->
<!-- :getPopupContainer="(target) => target.parentNode">-->
<!-- <a-select-option v-for="(role,roleindex) in roleList" :key="roleindex.toString()" :value="role.id">-->
<!-- {{ role.roleName }}-->
<!-- </a-select-option>-->
<!-- </a-select>-->
<!-- </a-form-item>-->
<!-- update--begin--autor:wangshuai-----date:20200108------for新增身份和负责部门------ -->
<!-- <a-form-item label="身份" :labelCol="labelCol" :wrapperCol="wrapperCol">-->
<!-- <a-radio-group-->
<!-- v-model="identity"-->
<!-- @change="identityChange">-->
<!-- <a-radio value="1">普通用户</a-radio>-->
<!-- <a-radio value="2">上级</a-radio>-->
<!-- </a-radio-group>-->
<!-- </a-form-item>-->
<!-- <a-form-item label="组织机构" :labelCol="labelCol" :wrapperCol="wrapperCol">-->
<!-- <a-select-->
<!-- mode="multiple"-->
<!-- style="width: 100%"-->
<!-- placeholder="请选择组织机构"-->
<!-- v-model="departIds"-->
<!-- optionFilterProp="children"-->
<!-- :getPopupContainer="(target) => target.parentNode"-->
<!-- :dropdownStyle="{maxHeight:'200px',overflow:'auto'}"-->
<!-- :disabled="disableSubmit"-->
<!-- >-->
<!-- <a-select-option v-for="item in resultDepartOptions" :key="item.key" :value="item.key"-->
<!-- >{{ item.title }}-->
<!-- </a-select-option-->
<!-- >-->
<!-- </a-select>-->
<!-- </a-form-item>-->
<!-- <a-form-item label="性别" :labelCol="labelCol" :wrapperCol="wrapperCol" v-has="'user:sex'">-->
<!-- <a-select v-decorator="[ 'sex', {}]" placeholder="请选择性别" :disabled="disableSubmit" :getPopupContainer="(target) => target.parentNode">-->
<!-- <a-select-option :value="1"></a-select-option>-->
<!-- <a-select-option :value="2"></a-select-option>-->
<!-- </a-select>-->
<!-- </a-form-item>-->
<a-form-item
label="角色类型"
:labelCol="labelCol"
:wrapperCol="wrapperCol">
<a-tree-select
multiple
show-search
tree-default-expand-all
tree-node-filter-prop="title"
style="width:100%"
:dropdownStyle="{ maxHeight: '200px', overflow: 'auto' }"
:treeData="treeRoleData"
v-decorator="[ 'selectedroles', validatorRules.selectedroles]"
placeholder="请选择角色类型"
>
</a-tree-select>
</a-form-item>
<a-form-item
label="组织机构"
:labelCol="labelCol"
:wrapperCol="wrapperCol">
<a-tree-select
:multiple="false"
show-search
tree-default-expand-all
tree-node-filter-prop="title"
style="width:100%"
:dropdownStyle="{ maxHeight: '200px',maxWidth:'100px','overflow-x':'hidden',' overflo-y': 'auto' }"
:treeData="treeDepartData"
v-decorator="[ 'selecteddeparts', validatorRules.selecteddeparts]"
placeholder="请选择组织机构">
</a-tree-select>
</a-form-item>
<a-form-item label="邮箱" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入邮箱" :disabled="disableSubmit" @change="event => event.target.value = event.target.value.trim()" v-decorator="[ 'email', validatorRules.email]" :maxLength="50"/>
</a-form-item>
<a-form-item label="邮箱密码" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input-password placeholder="请输入邮箱密码" @change="event => event.target.value = event.target.value.trim()" v-decorator="[ 'emailPassword', validatorRules.emailPassword]" :maxLength="50"/>
</a-form-item>
<a-form-item label="手机号码" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入手机号码" @change="event => event.target.value = event.target.value.trim()" :disabled="isDisabledAuth('user:form:phone') || disableSubmit"
v-decorator="[ 'phone', validatorRules.phone]" :maxLength="11"/>
</a-form-item>
<!--<a-form-item label="座机" :labelCol="labelCol" :wrapperCol="wrapperCol">-->
<!--<a-input placeholder="请输入座机" v-decorator="[ 'telephone', validatorRules.telephone]"/>-->
<!--</a-form-item>-->
<!-- <a-form-item label="工作流引擎" :labelCol="labelCol" :wrapperCol="wrapperCol">-->
<!-- <j-dict-select-tag v-decorator="['activitiSync', {}]" placeholder="请选择是否同步工作流引擎" :type="'radio'"-->
<!-- :triggerChange="true" dictCode="activiti_sync"/>-->
<!-- </a-form-item>-->
</a-form>
</a-spin>
<div class="drawer-bootom-button" v-show="!disableSubmit">
<!-- <a-popconfirm title="确定放弃编辑?" @confirm="handleCancel" okText="确定" cancelText="取消">-->
<!-- -->
<!-- </a-popconfirm>-->
<a-button style="margin-right: .8rem" @click="handleCancel">取消</a-button>
<a-button @click="handleSubmit" type="primary" :loading="confirmLoading" :disabled="confirmLoading">提交</a-button>
</div>
</a-drawer>
</template>
<script>
import pick from 'lodash.pick'
import moment from 'moment'
import Vue from 'vue'
import {ACCESS_TOKEN} from '@/store/mutation-types'
import {getAction} from '@/api/manage'
import {addUser, editUser, queryUserRole, queryall,queryallRoles, queryDepartTreeList} from '@/api/api'
import {disabledAuthFilter} from '@/utils/authFilter'
import { passwordReg} from '@/utils/validate'
import {checkPhone,checkEmail,checkUserName} from '@/utils/validateOnly'
import { getRSAPublicKey } from '@/api/login.js'
import {encrypt} from '@/utils/util'
export default {
name: 'UserModal',
data() {
return {
departDisabled: false, //是否是我的部门调用该页面
roleDisabled: false, //是否是角色维护调用该页面
modalWidth: 800,
drawerWidth: 700,
modaltoggleFlag: true,
confirmDirty: false,
// 组织机构 下拉数据
treeDepartData:[],
// 角色类型下拉数据
treeRoleData:[],
selectedDepartKeys: [], //保存用户选择部门id
checkedDepartKeys: [],
checkedDepartNames: [], // 保存部门的名称 =>title
checkedDepartNameString: '', // 保存部门的名称 =>title
resultDepartOptions: [],
userId: '', //保存用户id
disableSubmit: false,
userDepartModel: {userId: '', departIdList: []}, // 保存SysUserDepart的用户部门中间表数据需要的对象
dateFormat: 'YYYY-MM-DD',
validatorRules: {
username: {
rules: [{
required: true, validator: this.validateUsername,
}],
validateTrigger: 'blur'
},
emailPassword:{
rules: [{
required: true,
message: '请输入邮箱密码'
}],
validateTrigger: 'blur'
},
password: {
rules: [{
required: true,
message: '请输入密码'
}, {
validator: this.validateToNextPassword,
}],
validateTrigger: 'blur'
},
confirmpassword: {
rules: [{
required: true, message: '请输入确认密码!',
}, {
validator: this.compareToFirstPassword,
}],
validateTrigger: 'blur'
},
realname: {rules: [{required: true, message: '请输入用户名称!'}], validateTrigger: 'blur'},
phone: {rules: [{required: true,validator: this.validatePhone}], validateTrigger: 'blur'},
email: {
rules: [{
required: true,
validator: this.validateEmail
},],
validateTrigger: 'blur'
},
selectedroles:{rules: [{required: true, message:'请选择角色类型'}], validateTrigger: ['change']},
selecteddeparts:{rules: [{required: true, message:'请选择组织机构'}], validateTrigger: ['change']}
// sex:{initialValue:((!this.model.sex)?"": (this.model.sex+""))}
},
departIdShow: false,
departIds: [], //负责部门id
title: '操作',
visible: false,
model: {},
roleList: [],
selectedRole: [],
labelCol: {
xs: {span: 24},
sm: {span: 5},
},
wrapperCol: {
xs: {span: 24},
sm: {span: 16},
},
uploadLoading: false,
confirmLoading: false,
headers: {},
form: this.$form.createForm(this),
picUrl: '',
url: {
fileUpload: window._CONFIG['domianURL'] + '/sys/common/upload',
userWithDepart: '/sys/user/userDepartList', // 引入为指定用户查看部门信息需要的url
userId: '/sys/user/generateUserId', // 引入生成添加用户情况下的url
syncUserByUserName: '/act/process/extActProcess/doSyncUserByUserName',//同步用户到工作流
// queryTenantList: '/sys/tenant/queryList'
},
identity: '1',
fileList: [],
tenantList: [],
currentTenant: [],
// 公钥
rsaPublicKey:''
}
},
created() {
const token = Vue.ls.get(ACCESS_TOKEN)
this.headers = {'X-Access-Token': token}
// this.initTenantList()
},
computed: {
uploadAction: function () {
return this.url.fileUpload
}
},
methods: {
isDisabledAuth(code) {
return disabledAuthFilter(code)
},
// initTenantList() {
// getAction(this.url.queryTenantList).then(res => {
// if (res.success) {
// this.tenantList = res.result
// }
// })
// },
//窗口最大化切换
toggleScreen() {
if (this.modaltoggleFlag) {
this.modalWidth = window.innerWidth
} else {
this.modalWidth = 800
}
this.modaltoggleFlag = !this.modaltoggleFlag
},
initialRoleList() {
queryall().then((res) => {
if (res.success) {
this.roleList = res.result
} else {
console.log(res.message)
}
})
},
loadUserRoles(userid) {
return new Promise(resolve => {
queryUserRole({userid: userid}).then((res) => {
if (res.success) {
resolve(res.result)
} else {
console.log(res.message)
}
})
})
},
refresh() {
this.selectedDepartKeys = []
this.checkedDepartKeys = []
this.checkedDepartNames = []
this.checkedDepartNameString = ''
this.userId = ''
this.resultDepartOptions = []
this.departId = []
this.departIdShow = false
this.currentTenant = []
},
add() {
this.picUrl = ''
this.refresh()
this.edit({activitiSync: '1'})
},
edit(record) {
this.resetScreenSize() // 调用此方法,根据屏幕宽度自适应调整抽屉的宽度
// 加载组织机构数据
this.loadDepartTreeData()
// 加载角色数据
this.loadRolesTreeData()
// 获取公钥
this.getPublicKey()
let that = this
that.initialRoleList()
that.checkedDepartNameString = ''
that.form.resetFields()
// eslint-disable-next-line no-prototype-builtins
if (record.hasOwnProperty('id')) {
that.loadUserRoles(record.id).then(res => {
that.form.setFieldsValue({selectedroles:res})
})
setTimeout(() => {
this.fileList = record.avatar
}, 5)
}
that.userId = record.id
that.visible = true
that.model = Object.assign({}, record)
// 组织机构修改成了单选,此处不需要了
if(record.departIds !== '' && record.id){
// 部门是数组的时候以逗号拼接
if(Object.prototype.toString.call(record.departIds) === '[object Array]') {
that.model.selecteddeparts = record.departIds.split(',')
} else {
that.model.selecteddeparts = record.departIds
}
}
that.$nextTick(() => {
that.form.setFieldsValue(pick(this.model, 'username', 'realname', 'email', 'phone', 'post','selecteddeparts','emailPassword'))
})
//身份为上级显示负责部门,否则不显示
if (this.model.userIdentity == '2') {
this.identity = '2'
this.departIdShow = true
} else {
this.identity = '1'
this.departIdShow = false
}
// 调用查询用户对应的部门信息的方法
that.checkedDepartKeys = []
that.loadCheckedDeparts()
//update-begin-author:taoyan date:2020710 for:多租户配置
if (!record.relTenantIds || record.relTenantIds.length == 0) {
this.currentTenant = []
} else {
this.currentTenant = record.relTenantIds.split(',').map(Number)
}
//update-end-author:taoyan date:2020710 for:多租户配置
},
// 组织机构下拉数据
loadDepartTreeData(){
const that = this
queryDepartTreeList().then((res) => {
if(res.success){
that.treeDepartData = []
let treeList = res.result
for(let a=0;a<treeList.length;a++){
let temp = treeList[a]
temp.isLeaf = temp.leaf
that.treeDepartData.push(temp)
}
}
})
},
// 角色下拉数据
loadRolesTreeData() {
const that = this
queryallRoles().then((res) => {
if(res.success){
that.treeRoleData = []
let treeList = res.result
for(let a=0;a<treeList.length;a++){
let temp = treeList[a]
temp.isLeaf = temp.leaf
that.treeRoleData.push(temp)
}
}
})
},
getPublicKey() {
// 获取公钥
getRSAPublicKey().then(res => {
this.rsaPublicKey = res.result
})
},
loadCheckedDeparts() {
let that = this
if (!that.userId) {
return
}
getAction(that.url.userWithDepart, {userId: that.userId}).then((res) => {
that.checkedDepartNames = []
if (res.success) {
var depart = []
var departId = []
for (let i = 0; i < res.result.length; i++) {
that.checkedDepartNames.push(res.result[i].title)
this.checkedDepartNameString = this.checkedDepartNames.join(',')
that.checkedDepartKeys.push(res.result[i].key)
//新增负责部门选择下拉框
depart.push({
key: res.result[i].key,
title: res.result[i].title
})
departId.push(res.result[i].key)
}
that.resultDepartOptions = depart
//判断部门id是否存在,不存在择直接默认当前所在部门
if (this.model.departIds) {
this.departIds = this.model.departIds.split(',')
} else {
this.departIds = departId
}
that.userDepartModel.departIdList = that.checkedDepartKeys
} else {
console.log(res.message)
}
})
},
close() {
this.$emit('close')
this.visible = false
this.disableSubmit = false
this.selectedRole = []
this.userDepartModel = {userId: '', departIdList: []}
this.checkedDepartNames = []
this.checkedDepartNameString = ''
this.checkedDepartKeys = []
this.selectedDepartKeys = []
this.resultDepartOptions = []
this.departIds = []
this.departIdShow = false
this.identity = '1'
this.fileList = []
},
moment,
handleSubmit() {
console.log('username',this.form.getFieldValue('username'))
const that = this
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
that.confirmLoading = true
console.log('values=======', values)
let formData = Object.assign(this.model, values)
if (that.fileList !== '') {
formData.avatar = that.fileList
} else {
formData.avatar = null
}
// 公钥参数
formData.rsaPublicKey = that.rsaPublicKey
// 新建 JSEncrypt 对象
formData.password =encrypt(that.rsaPublicKey,values.password)
formData.confirmpassword = formData.password
formData.phone = encrypt(that.rsaPublicKey,values.phone)
formData.email = encrypt(that.rsaPublicKey,values.email)
// 加密邮箱密码
formData.emailPassword = encrypt(that.rsaPublicKey,values.emailPassword)
//update-begin-author:taoyan date:2020710 for:多租户配置
formData.relTenantIds = this.currentTenant.length > 0 ? this.currentTenant.join(',') : ''
//update-end-author:taoyan date:2020710 for:多租户配置
formData.selectedroles = values.selectedroles.length > 0 ? values.selectedroles.join(',') : ''
// 部门由多选改成单选 所以不需要单独处理了,但为了历史数据可以使用,对values.selecteddeparts类型进行判断,如果是数组则以逗号分隔转成字符串,若是字符串则直接显示
if(Object.prototype.toString.call(values.selecteddeparts) === '[object Array]') {
formData.selecteddeparts = values.selecteddeparts.length > 0 ? values.selecteddeparts.join(',') : ''
}
// formData.selecteddeparts = values.selecteddeparts.length > 0 ? values.selecteddeparts.join(',') : ''
formData.userIdentity = this.identity
//如果是上级择传入departIds,否则为空
if (this.identity === '2') {
formData.departIds = this.departIds.join(',')
} else {
formData.departIds = ''
}
// that.addDepartsToUser(that,formData); // 调用根据当前用户添加部门信息的方法
let obj
if (!this.model.id) {
formData.id = this.userId
obj = addUser(formData)
} else {
obj = editUser(formData)
}
obj.then((res) => {
if (res.success) {
that.$message.success(res.message)
that.$emit('ok')
that.close()
} else {
that.$message.warning(res.message)
}
}).finally(() => {
that.confirmLoading = false
that.checkedDepartNames = []
that.userDepartModel.departIdList = {userId: '', departIdList: []}
})
}else {
that.confirmLoading = false
}
})
},
handleCancel() {
this.close()
},
validateToNextPassword(rule, value, callback) {
const form = this.form
if (!value) {
callback()
}
if (!passwordReg(value)) {
callback('密码长度至少8位,并包括数字、小写字母、大写字母和特殊符号4类中的3类')
}
if (value && this.confirmDirty) {
form.validateFields(['confirm'], {force: true})
}
callback()
},
compareToFirstPassword(rule, value, callback) {
const form = this.form
if (value && value !== form.getFieldValue('password')) {
callback('两次输入的密码不一样!')
} else {
callback()
}
},
validatePhone(rule, value, callback) {
checkPhone(value,this.userId).then(res => {
if(res.success){
callback()
}else {
callback(res.code === 500 ? '手机号已存在': res)
}
})
},
validateEmail(rule, value, callback) {
checkEmail(value,this.userId).then(res => {
if(res.success){
callback()
}else {
callback(res.code === 500 ? '邮箱已存在': res)
}
})
},
validateUsername(rule, value, callback) {
checkUserName(value,this.userId).then(res => {
if(res.success){
callback()
}else {
callback(res.code === 500 ? '用户已存在': res)
}
})
},
handleConfirmBlur(e) {
const value = e.target.value
this.confirmDirty = this.confirmDirty || !!value
},
normFile(e) {
console.log('Upload event:', e)
if (Array.isArray(e)) {
return e
}
return e && e.fileList
},
beforeUpload: function (file) {
var fileType = file.type
if (fileType.indexOf('image') < 0) {
this.$message.warning('请上传图片')
return false
}
//TODO 验证文件大小
},
handleChange(info) {
this.picUrl = ''
if (info.file.status === 'uploading') {
this.uploadLoading = true
return
}
if (info.file.status === 'done') {
var response = info.file.response
this.uploadLoading = false
console.log(response)
if (response.success) {
this.model.avatar = response.message
this.picUrl = 'Has no pic url yet'
} else {
this.$message.warning(response.message)
}
}
},
// 搜索用户对应的部门API
onSearch() {
this.$refs.departWindow.add(this.checkedDepartKeys, this.userId)
},
// 获取用户对应部门弹出框提交给返回的数据
modalFormOk(formData) {
this.checkedDepartNames = []
this.selectedDepartKeys = []
this.checkedDepartNameString = ''
this.userId = formData.userId
this.userDepartModel.userId = formData.userId
this.departIds = []
this.resultDepartOptions = []
var depart = []
for (let i = 0; i < formData.departIdList.length; i++) {
this.selectedDepartKeys.push(formData.departIdList[i].key)
this.checkedDepartNames.push(formData.departIdList[i].title)
this.checkedDepartNameString = this.checkedDepartNames.join(',')
//新增部门选择,如果上面部门选择后不为空直接付给负责部门
depart.push({
key: formData.departIdList[i].key,
title: formData.departIdList[i].title
})
this.departIds.push(formData.departIdList[i].key)
}
this.resultDepartOptions = depart
this.userDepartModel.departIdList = this.selectedDepartKeys
this.checkedDepartKeys = this.selectedDepartKeys //更新当前的选择keys
},
// 根据屏幕变化,设置抽屉尺寸
resetScreenSize() {
let screenWidth = document.body.clientWidth
if (screenWidth < 500) {
this.drawerWidth = screenWidth
} else {
this.drawerWidth = 700
}
},
identityChange(e) {
if (e.target.value === '1') {
this.departIdShow = false
} else {
this.departIdShow = true
}
}
}
}
</script>
<style scoped>
.avatar-uploader > .ant-upload {
width: 104px;
height: 104px;
}
.ant-upload-select-picture-card i {
font-size: 49px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
.ant-table-tbody .ant-table-row td {
padding-top: 10px;
padding-bottom: 10px;
}
.drawer-bootom-button {
position: absolute;
bottom: -8px;
width: 100%;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: right;
left: 0;
background: #fff;
border-radius: 0 0 2px 2px;
}
</style>