Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
ca1b6df5
authored
Mar 29, 2023
by
fengjingtao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 用户管理review以后
parent
80d54079
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
597 additions
and
12 deletions
+597
-12
.vscode/settings.json
+21
-1
src/types/auto-components.d.ts
+0
-11
src/views/system/user/index0.vue
+576
-0
No files found.
.vscode/settings.json
View file @
ca1b6df5
...
@@ -40,5 +40,25 @@
...
@@ -40,5 +40,25 @@
"i18n-ally.displayLanguage"
:
"zh-CN"
,
"i18n-ally.displayLanguage"
:
"zh-CN"
,
"i18n-ally.enabledFrameworks"
:
[
"vue"
,
"react"
],
"i18n-ally.enabledFrameworks"
:
[
"vue"
,
"react"
],
"god.tsconfig"
:
"./tsconfig.json"
,
"god.tsconfig"
:
"./tsconfig.json"
,
"vue-i18n.i18nPaths"
:
"src/locales"
"vue-i18n.i18nPaths"
:
"src/locales"
,
"workbench.colorCustomizations"
:
{
"activityBar.activeBackground"
:
"#65c89b"
,
"activityBar.background"
:
"#65c89b"
,
"activityBar.foreground"
:
"#15202b"
,
"activityBar.inactiveForeground"
:
"#15202b99"
,
"activityBarBadge.background"
:
"#945bc4"
,
"activityBarBadge.foreground"
:
"#e7e7e7"
,
"commandCenter.border"
:
"#15202b99"
,
"sash.hoverBorder"
:
"#65c89b"
,
"statusBar.background"
:
"#42b883"
,
"statusBar.foreground"
:
"#15202b"
,
"statusBarItem.hoverBackground"
:
"#359268"
,
"statusBarItem.remoteBackground"
:
"#42b883"
,
"statusBarItem.remoteForeground"
:
"#15202b"
,
"titleBar.activeBackground"
:
"#42b883"
,
"titleBar.activeForeground"
:
"#15202b"
,
"titleBar.inactiveBackground"
:
"#42b88399"
,
"titleBar.inactiveForeground"
:
"#15202b99"
},
"peacock.color"
:
"#42b883"
}
}
src/types/auto-components.d.ts
View file @
ca1b6df5
...
@@ -23,8 +23,6 @@ declare module '@vue/runtime-core' {
...
@@ -23,8 +23,6 @@ declare module '@vue/runtime-core' {
DictTag
:
typeof
import
(
'./../components/DictTag/src/DictTag.vue'
)[
'default'
]
DictTag
:
typeof
import
(
'./../components/DictTag/src/DictTag.vue'
)[
'default'
]
Echart
:
typeof
import
(
'./../components/Echart/src/Echart.vue'
)[
'default'
]
Echart
:
typeof
import
(
'./../components/Echart/src/Echart.vue'
)[
'default'
]
Editor
:
typeof
import
(
'./../components/Editor/src/Editor.vue'
)[
'default'
]
Editor
:
typeof
import
(
'./../components/Editor/src/Editor.vue'
)[
'default'
]
ElAutoResizer
:
typeof
import
(
'element-plus/es'
)[
'ElAutoResizer'
]
ElAvatar
:
typeof
import
(
'element-plus/es'
)[
'ElAvatar'
]
ElBadge
:
typeof
import
(
'element-plus/es'
)[
'ElBadge'
]
ElBadge
:
typeof
import
(
'element-plus/es'
)[
'ElBadge'
]
ElButton
:
typeof
import
(
'element-plus/es'
)[
'ElButton'
]
ElButton
:
typeof
import
(
'element-plus/es'
)[
'ElButton'
]
ElButtonGroup
:
typeof
import
(
'element-plus/es'
)[
'ElButtonGroup'
]
ElButtonGroup
:
typeof
import
(
'element-plus/es'
)[
'ElButtonGroup'
]
...
@@ -54,31 +52,22 @@ declare module '@vue/runtime-core' {
...
@@ -54,31 +52,22 @@ declare module '@vue/runtime-core' {
ElForm
:
typeof
import
(
'element-plus/es'
)[
'ElForm'
]
ElForm
:
typeof
import
(
'element-plus/es'
)[
'ElForm'
]
ElFormItem
:
typeof
import
(
'element-plus/es'
)[
'ElFormItem'
]
ElFormItem
:
typeof
import
(
'element-plus/es'
)[
'ElFormItem'
]
ElIcon
:
typeof
import
(
'element-plus/es'
)[
'ElIcon'
]
ElIcon
:
typeof
import
(
'element-plus/es'
)[
'ElIcon'
]
ElImage
:
typeof
import
(
'element-plus/es'
)[
'ElImage'
]
ElImageViewer
:
typeof
import
(
'element-plus/es'
)[
'ElImageViewer'
]
ElImageViewer
:
typeof
import
(
'element-plus/es'
)[
'ElImageViewer'
]
ElInput
:
typeof
import
(
'element-plus/es'
)[
'ElInput'
]
ElInput
:
typeof
import
(
'element-plus/es'
)[
'ElInput'
]
ElInputNumber
:
typeof
import
(
'element-plus/es'
)[
'ElInputNumber'
]
ElLink
:
typeof
import
(
'element-plus/es'
)[
'ElLink'
]
ElLink
:
typeof
import
(
'element-plus/es'
)[
'ElLink'
]
ElOption
:
typeof
import
(
'element-plus/es'
)[
'ElOption'
]
ElOption
:
typeof
import
(
'element-plus/es'
)[
'ElOption'
]
ElPagination
:
typeof
import
(
'element-plus/es'
)[
'ElPagination'
]
ElPagination
:
typeof
import
(
'element-plus/es'
)[
'ElPagination'
]
ElPopover
:
typeof
import
(
'element-plus/es'
)[
'ElPopover'
]
ElPopover
:
typeof
import
(
'element-plus/es'
)[
'ElPopover'
]
ElRadio
:
typeof
import
(
'element-plus/es'
)[
'ElRadio'
]
ElRadioButton
:
typeof
import
(
'element-plus/es'
)[
'ElRadioButton'
]
ElRadioGroup
:
typeof
import
(
'element-plus/es'
)[
'ElRadioGroup'
]
ElRow
:
typeof
import
(
'element-plus/es'
)[
'ElRow'
]
ElRow
:
typeof
import
(
'element-plus/es'
)[
'ElRow'
]
ElScrollbar
:
typeof
import
(
'element-plus/es'
)[
'ElScrollbar'
]
ElScrollbar
:
typeof
import
(
'element-plus/es'
)[
'ElScrollbar'
]
ElSelect
:
typeof
import
(
'element-plus/es'
)[
'ElSelect'
]
ElSelect
:
typeof
import
(
'element-plus/es'
)[
'ElSelect'
]
ElSkeleton
:
typeof
import
(
'element-plus/es'
)[
'ElSkeleton'
]
ElSkeleton
:
typeof
import
(
'element-plus/es'
)[
'ElSkeleton'
]
ElSpace
:
typeof
import
(
'element-plus/es'
)[
'ElSpace'
]
ElSwitch
:
typeof
import
(
'element-plus/es'
)[
'ElSwitch'
]
ElSwitch
:
typeof
import
(
'element-plus/es'
)[
'ElSwitch'
]
ElTable
:
typeof
import
(
'element-plus/es'
)[
'ElTable'
]
ElTable
:
typeof
import
(
'element-plus/es'
)[
'ElTable'
]
ElTableColumn
:
typeof
import
(
'element-plus/es'
)[
'ElTableColumn'
]
ElTableColumn
:
typeof
import
(
'element-plus/es'
)[
'ElTableColumn'
]
ElTableV2
:
typeof
import
(
'element-plus/es'
)[
'ElTableV2'
]
ElTabPane
:
typeof
import
(
'element-plus/es'
)[
'ElTabPane'
]
ElTabPane
:
typeof
import
(
'element-plus/es'
)[
'ElTabPane'
]
ElTabs
:
typeof
import
(
'element-plus/es'
)[
'ElTabs'
]
ElTabs
:
typeof
import
(
'element-plus/es'
)[
'ElTabs'
]
ElTag
:
typeof
import
(
'element-plus/es'
)[
'ElTag'
]
ElTag
:
typeof
import
(
'element-plus/es'
)[
'ElTag'
]
ElTimeline
:
typeof
import
(
'element-plus/es'
)[
'ElTimeline'
]
ElTimelineItem
:
typeof
import
(
'element-plus/es'
)[
'ElTimelineItem'
]
ElTooltip
:
typeof
import
(
'element-plus/es'
)[
'ElTooltip'
]
ElTooltip
:
typeof
import
(
'element-plus/es'
)[
'ElTooltip'
]
ElTransfer
:
typeof
import
(
'element-plus/es'
)[
'ElTransfer'
]
ElTransfer
:
typeof
import
(
'element-plus/es'
)[
'ElTransfer'
]
ElTree
:
typeof
import
(
'element-plus/es'
)[
'ElTree'
]
ElTree
:
typeof
import
(
'element-plus/es'
)[
'ElTree'
]
...
...
src/views/system/user/index0.vue
0 → 100644
View file @
ca1b6df5
<
template
>
<div
class=
"flex"
>
<el-card
class=
"w-1/5 user"
:gutter=
"12"
shadow=
"always"
>
<template
#
header
>
<div
class=
"card-header"
>
<span>
部门列表
</span>
<XTextButton
title=
"修改部门"
@
click=
"handleDeptEdit()"
/>
</div>
</
template
>
<el-input
v-model=
"filterText"
placeholder=
"搜索部门"
/>
<el-scrollbar
height=
"650"
>
<el-tree
ref=
"treeRef"
node-key=
"id"
default-expand-all
:data=
"deptOptions"
:props=
"defaultProps"
:highlight-current=
"true"
:filter-node-method=
"filterNode"
:expand-on-click-node=
"false"
@
node-click=
"handleDeptNodeClick"
/>
</el-scrollbar>
</el-card>
<el-card
class=
"w-4/5 user"
style=
"margin-left: 10px"
:gutter=
"12"
shadow=
"hover"
>
<
template
#
header
>
<div
class=
"card-header"
>
<span>
{{
tableTitle
}}
</span>
</div>
</
template
>
<!-- 列表 -->
<XTable
@
register=
"registerTable"
>
<
template
#
toolbar_buttons
>
<!-- 操作:新增 -->
<XButton
type=
"primary"
preIcon=
"ep:zoom-in"
:title=
"t('action.add')"
v-hasPermi=
"['system:user:create']"
@
click=
"handleCreate()"
/>
<!-- 操作:导入用户 -->
<XButton
type=
"warning"
preIcon=
"ep:upload"
:title=
"t('action.import')"
v-hasPermi=
"['system:user:import']"
@
click=
"importDialogVisible = true"
/>
<!-- 操作:导出用户 -->
<XButton
type=
"warning"
preIcon=
"ep:download"
:title=
"t('action.export')"
v-hasPermi=
"['system:user:export']"
@
click=
"exportList('用户数据.xls')"
/>
</
template
>
<
template
#
status_default=
"{ row }"
>
<el-switch
v-model=
"row.status"
:active-value=
"0"
:inactive-value=
"1"
@
change=
"handleStatusChange(row)"
/>
</
template
>
<
template
#
actionbtns_default=
"{ row }"
>
<!-- 操作:编辑 -->
<XTextButton
preIcon=
"ep:edit"
:title=
"t('action.edit')"
v-hasPermi=
"['system:user:update']"
@
click=
"handleUpdate(row.id)"
/>
<!-- 操作:详情 -->
<XTextButton
preIcon=
"ep:view"
:title=
"t('action.detail')"
v-hasPermi=
"['system:user:update']"
@
click=
"handleDetail(row.id)"
/>
<el-dropdown
class=
"p-0.5"
v-hasPermi=
"[
'system:user:update-password',
'system:permission:assign-user-role',
'system:user:delete'
]"
>
<XTextButton
:title=
"t('action.more')"
postIcon=
"ep:arrow-down"
/>
<template
#
dropdown
>
<el-dropdown-menu>
<el-dropdown-item>
<!-- 操作:重置密码 -->
<XTextButton
preIcon=
"ep:key"
title=
"重置密码"
v-hasPermi=
"['system:user:update-password']"
@
click=
"handleResetPwd(row)"
/>
</el-dropdown-item>
<el-dropdown-item>
<!-- 操作:分配角色 -->
<XTextButton
preIcon=
"ep:key"
title=
"分配角色"
v-hasPermi=
"['system:permission:assign-user-role']"
@
click=
"handleRole(row)"
/>
</el-dropdown-item>
<el-dropdown-item>
<!-- 操作:删除 -->
<XTextButton
preIcon=
"ep:delete"
:title=
"t('action.del')"
v-hasPermi=
"['system:user:delete']"
@
click=
"deleteData(row.id)"
/>
</el-dropdown-item>
</el-dropdown-menu>
</
template
>
</el-dropdown>
</template>
</XTable>
</el-card>
</div>
<XModal
v-model=
"dialogVisible"
:title=
"dialogTitle"
>
<!-- 对话框(添加 / 修改) -->
<Form
v-if=
"['create', 'update'].includes(actionType)"
:rules=
"rules"
:schema=
"allSchemas.formSchema"
ref=
"formRef"
>
<
template
#
deptId=
"form"
>
<el-tree-select
node-key=
"id"
v-model=
"form['deptId']"
:props=
"defaultProps"
:data=
"deptOptions"
check-strictly
/>
</
template
>
<
template
#
postIds=
"form"
>
<el-select
v-model=
"form['postIds']"
multiple
:placeholder=
"t('common.selectText')"
>
<el-option
v-for=
"item in postOptions"
:key=
"item.id"
:label=
"item.name"
:value=
"(item.id as unknown as number)"
/>
</el-select>
</
template
>
</Form>
<!-- 对话框(详情) -->
<Descriptions
v-if=
"actionType === 'detail'"
:schema=
"allSchemas.detailSchema"
:data=
"detailData"
>
<
template
#
deptId=
"{ row }"
>
<el-tag>
{{
dataFormater
(
row
.
deptId
)
}}
</el-tag>
</
template
>
<
template
#
postIds=
"{ row }"
>
<template
v-if=
"row.postIds !== ''"
>
<el-tag
v-for=
"(post, index) in row.postIds"
:key=
"index"
index=
""
>
<template
v-for=
"postObj in postOptions"
>
{{
post
===
postObj
.
id
?
postObj
.
name
:
''
}}
</
template
>
</el-tag>
</template>
<
template
v-else
>
</
template
>
</template>
</Descriptions>
<!-- 操作按钮 -->
<
template
#
footer
>
<!-- 按钮:保存 -->
<XButton
v-if=
"['create', 'update'].includes(actionType)"
type=
"primary"
:title=
"t('action.save')"
:loading=
"loading"
@
click=
"submitForm()"
/>
<!-- 按钮:关闭 -->
<XButton
:loading=
"loading"
:title=
"t('dialog.close')"
@
click=
"dialogVisible = false"
/>
</
template
>
</XModal>
<!-- 分配用户角色 -->
<XModal
v-model=
"roleDialogVisible"
title=
"分配角色"
>
<el-form
:model=
"userRole"
label-width=
"140px"
:inline=
"true"
>
<el-form-item
label=
"用户名称"
>
<el-tag>
{{ userRole.username }}
</el-tag>
</el-form-item>
<el-form-item
label=
"用户昵称"
>
<el-tag>
{{ userRole.nickname }}
</el-tag>
</el-form-item>
<el-form-item
label=
"角色"
>
<el-transfer
v-model=
"userRole.roleIds"
:titles=
"['角色列表', '已选择']"
:props=
"{
key: 'id',
label: 'name'
}"
:data=
"roleOptions"
/>
</el-form-item>
</el-form>
<!-- 操作按钮 -->
<
template
#
footer
>
<!-- 按钮:保存 -->
<XButton
type=
"primary"
:title=
"t('action.save')"
:loading=
"loading"
@
click=
"submitRole()"
/>
<!-- 按钮:关闭 -->
<XButton
:title=
"t('dialog.close')"
@
click=
"roleDialogVisible = false"
/>
</
template
>
</XModal>
<!-- 导入 -->
<XModal
v-model=
"importDialogVisible"
:title=
"importDialogTitle"
>
<el-form
class=
"drawer-multiColumn-form"
label-width=
"150px"
>
<el-form-item
label=
"模板下载 :"
>
<XButton
type=
"primary"
prefix=
"ep:download"
title=
"点击下载"
@
click=
"handleImportTemp()"
/>
</el-form-item>
<el-form-item
label=
"文件上传 :"
>
<el-upload
ref=
"uploadRef"
:action=
"updateUrl + '?updateSupport=' + updateSupport"
:headers=
"uploadHeaders"
:drag=
"true"
:limit=
"1"
:multiple=
"true"
:show-file-list=
"true"
:disabled=
"uploadDisabled"
:before-upload=
"beforeExcelUpload"
:on-exceed=
"handleExceed"
:on-success=
"handleFileSuccess"
:on-error=
"excelUploadError"
:auto-upload=
"false"
accept=
"application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
>
<Icon
icon=
"ep:upload-filled"
/>
<div
class=
"el-upload__text"
>
将文件拖到此处,或
<em>
点击上传
</em></div>
<
template
#
tip
>
<div
class=
"el-upload__tip"
>
请上传 .xls , .xlsx 标准格式文件
</div>
</
template
>
</el-upload>
</el-form-item>
<el-form-item
label=
"是否更新已经存在的用户数据:"
>
<el-checkbox
v-model=
"updateSupport"
/>
</el-form-item>
</el-form>
<
template
#
footer
>
<!-- 按钮:保存 -->
<XButton
type=
"warning"
preIcon=
"ep:upload-filled"
:title=
"t('action.save')"
@
click=
"submitFileForm()"
/>
<!-- 按钮:关闭 -->
<XButton
:title=
"t('dialog.close')"
@
click=
"importDialogVisible = false"
/>
</
template
>
</XModal>
</template>
<
script
setup
lang=
"ts"
name=
"User"
>
import
type
{
ElTree
,
UploadRawFile
,
UploadInstance
}
from
'element-plus'
import
{
handleTree
,
defaultProps
}
from
'@/utils/tree'
import
download
from
'@/utils/download'
import
{
CommonStatusEnum
}
from
'@/utils/constants'
import
{
getAccessToken
,
getTenantId
}
from
'@/utils/auth'
import
type
{
FormExpose
}
from
'@/components/Form'
import
{
rules
,
allSchemas
}
from
'./user.data'
import
*
as
UserApi
from
'@/api/system/user'
import
{
listSimpleDeptApi
}
from
'@/api/system/dept'
import
{
listSimpleRolesApi
}
from
'@/api/system/role'
import
{
listSimplePostsApi
,
PostVO
}
from
'@/api/system/post'
import
{
aassignUserRoleApi
,
listUserRolesApi
,
PermissionAssignUserRoleReqVO
}
from
'@/api/system/permission'
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
queryParams
=
reactive
({
deptId
:
null
})
// ========== 列表相关 ==========
const
tableTitle
=
ref
(
'用户列表'
)
// 列表相关的变量
const
[
registerTable
,
{
reload
,
deleteData
,
exportList
}]
=
useXTable
({
allSchemas
:
allSchemas
,
params
:
queryParams
,
getListApi
:
UserApi
.
getUserPageApi
,
deleteApi
:
UserApi
.
deleteUserApi
,
exportListApi
:
UserApi
.
exportUserApi
})
// ========== 创建部门树结构 ==========
const
filterText
=
ref
(
''
)
const
deptOptions
=
ref
<
Tree
[]
>
([])
// 树形结构
const
treeRef
=
ref
<
InstanceType
<
typeof
ElTree
>>
()
const
getTree
=
async
()
=>
{
const
res
=
await
listSimpleDeptApi
()
deptOptions
.
value
.
push
(...
handleTree
(
res
))
}
const
filterNode
=
(
value
:
string
,
data
:
Tree
)
=>
{
if
(
!
value
)
return
true
return
data
.
name
.
includes
(
value
)
}
const
handleDeptNodeClick
=
async
(
row
:
{
[
key
:
string
]:
any
})
=>
{
queryParams
.
deptId
=
row
.
id
await
reload
()
}
const
{
push
}
=
useRouter
()
const
handleDeptEdit
=
()
=>
{
push
(
'/system/dept'
)
}
watch
(
filterText
,
(
val
)
=>
{
treeRef
.
value
!
.
filter
(
val
)
})
// ========== CRUD 相关 ==========
const
loading
=
ref
(
false
)
// 遮罩层
const
actionType
=
ref
(
''
)
// 操作按钮的类型
const
dialogVisible
=
ref
(
false
)
// 是否显示弹出层
const
dialogTitle
=
ref
(
'edit'
)
// 弹出层标题
const
formRef
=
ref
<
FormExpose
>
()
// 表单 Ref
const
postOptions
=
ref
<
PostVO
[]
>
([])
//岗位列表
// 获取岗位列表
const
getPostOptions
=
async
()
=>
{
const
res
=
await
listSimplePostsApi
()
postOptions
.
value
.
push
(...
res
)
}
const
dataFormater
=
(
val
)
=>
{
return
deptFormater
(
deptOptions
.
value
,
val
)
}
//部门回显
const
deptFormater
=
(
ary
,
val
:
any
)
=>
{
var
o
=
''
if
(
ary
&&
val
)
{
for
(
const
v
of
ary
)
{
if
(
v
.
id
==
val
)
{
o
=
v
.
name
if
(
o
)
return
o
}
else
if
(
v
.
children
?.
length
)
{
o
=
deptFormater
(
v
.
children
,
val
)
if
(
o
)
return
o
}
}
return
o
}
else
{
return
val
}
}
// 设置标题
const
setDialogTile
=
async
(
type
:
string
)
=>
{
dialogTitle
.
value
=
t
(
'action.'
+
type
)
actionType
.
value
=
type
dialogVisible
.
value
=
true
}
// 新增操作
const
handleCreate
=
async
()
=>
{
setDialogTile
(
'create'
)
// 重置表单
await
nextTick
()
if
(
allSchemas
.
formSchema
[
0
].
field
!==
'username'
)
{
unref
(
formRef
)?.
addSchema
(
{
field
:
'username'
,
label
:
'用户账号'
,
component
:
'Input'
},
0
)
unref
(
formRef
)?.
addSchema
(
{
field
:
'password'
,
label
:
'用户密码'
,
component
:
'InputPassword'
},
1
)
}
}
// 修改操作
const
handleUpdate
=
async
(
rowId
:
number
)
=>
{
setDialogTile
(
'update'
)
await
nextTick
()
unref
(
formRef
)?.
delSchema
(
'username'
)
unref
(
formRef
)?.
delSchema
(
'password'
)
// 设置数据
const
res
=
await
UserApi
.
getUserApi
(
rowId
)
unref
(
formRef
)?.
setValues
(
res
)
}
const
detailData
=
ref
()
// 详情操作
const
handleDetail
=
async
(
rowId
:
number
)
=>
{
// 设置数据
const
res
=
await
UserApi
.
getUserApi
(
rowId
)
detailData
.
value
=
res
await
setDialogTile
(
'detail'
)
}
// 提交按钮
const
submitForm
=
async
()
=>
{
const
elForm
=
unref
(
formRef
)?.
getElFormRef
()
if
(
!
elForm
)
return
elForm
.
validate
(
async
(
valid
)
=>
{
if
(
valid
)
{
// 提交请求
try
{
const
data
=
unref
(
formRef
)?.
formModel
as
UserApi
.
UserVO
if
(
actionType
.
value
===
'create'
)
{
loading
.
value
=
true
await
UserApi
.
createUserApi
(
data
)
message
.
success
(
t
(
'common.createSuccess'
))
}
else
{
loading
.
value
=
true
await
UserApi
.
updateUserApi
(
data
)
message
.
success
(
t
(
'common.updateSuccess'
))
}
dialogVisible
.
value
=
false
}
finally
{
// unref(formRef)?.setSchema(allSchemas.formSchema)
// 刷新列表
await
reload
()
loading
.
value
=
false
}
}
})
}
// 改变用户状态操作
const
handleStatusChange
=
async
(
row
:
UserApi
.
UserVO
)
=>
{
const
text
=
row
.
status
===
CommonStatusEnum
.
ENABLE
?
'启用'
:
'停用'
message
.
confirm
(
'确认要"'
+
text
+
'""'
+
row
.
username
+
'"用户吗?'
,
t
(
'common.reminder'
))
.
then
(
async
()
=>
{
row
.
status
=
row
.
status
===
CommonStatusEnum
.
ENABLE
?
CommonStatusEnum
.
ENABLE
:
CommonStatusEnum
.
DISABLE
await
UserApi
.
updateUserStatusApi
(
row
.
id
,
row
.
status
)
message
.
success
(
text
+
'成功'
)
// 刷新列表
await
reload
()
})
.
catch
(()
=>
{
row
.
status
=
row
.
status
===
CommonStatusEnum
.
ENABLE
?
CommonStatusEnum
.
DISABLE
:
CommonStatusEnum
.
ENABLE
})
}
// 重置密码
const
handleResetPwd
=
(
row
:
UserApi
.
UserVO
)
=>
{
message
.
prompt
(
'请输入"'
+
row
.
username
+
'"的新密码'
,
t
(
'common.reminder'
)).
then
(({
value
})
=>
{
UserApi
.
resetUserPwdApi
(
row
.
id
,
value
).
then
(()
=>
{
message
.
success
(
'修改成功,新密码是:'
+
value
)
})
})
}
// 分配角色
const
roleDialogVisible
=
ref
(
false
)
const
roleOptions
=
ref
()
const
userRole
=
reactive
({
id
:
0
,
username
:
''
,
nickname
:
''
,
roleIds
:
[]
})
const
handleRole
=
async
(
row
:
UserApi
.
UserVO
)
=>
{
userRole
.
id
=
row
.
id
userRole
.
username
=
row
.
username
userRole
.
nickname
=
row
.
nickname
// 获得角色拥有的权限集合
const
roles
=
await
listUserRolesApi
(
row
.
id
)
userRole
.
roleIds
=
roles
// 获取角色列表
const
roleOpt
=
await
listSimpleRolesApi
()
roleOptions
.
value
=
roleOpt
roleDialogVisible
.
value
=
true
}
// 提交
const
submitRole
=
async
()
=>
{
const
data
=
ref
<
PermissionAssignUserRoleReqVO
>
({
userId
:
userRole
.
id
,
roleIds
:
userRole
.
roleIds
})
await
aassignUserRoleApi
(
data
.
value
)
message
.
success
(
t
(
'common.updateSuccess'
))
roleDialogVisible
.
value
=
false
}
// ========== 导入相关 ==========
// TODO @星语:这个要不要把导入用户,封装成一个小组件?可选哈
const
importDialogVisible
=
ref
(
false
)
const
uploadDisabled
=
ref
(
false
)
const
importDialogTitle
=
ref
(
'用户导入'
)
const
updateSupport
=
ref
(
0
)
let
updateUrl
=
import
.
meta
.
env
.
VITE_BASE_URL
+
import
.
meta
.
env
.
VITE_API_URL
+
'/system/user/import'
const
uploadHeaders
=
ref
()
// 下载导入模版
const
handleImportTemp
=
async
()
=>
{
const
res
=
await
UserApi
.
importUserTemplateApi
()
download
.
excel
(
res
,
'用户导入模版.xls'
)
}
// 文件上传之前判断
const
beforeExcelUpload
=
(
file
:
UploadRawFile
)
=>
{
const
isExcel
=
file
.
type
===
'application/vnd.ms-excel'
||
file
.
type
===
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
const
isLt5M
=
file
.
size
/
1024
/
1024
<
5
if
(
!
isExcel
)
message
.
error
(
'上传文件只能是 xls / xlsx 格式!'
)
if
(
!
isLt5M
)
message
.
error
(
'上传文件大小不能超过 5MB!'
)
return
isExcel
&&
isLt5M
}
// 文件上传
const
uploadRef
=
ref
<
UploadInstance
>
()
const
submitFileForm
=
()
=>
{
uploadHeaders
.
value
=
{
Authorization
:
'Bearer '
+
getAccessToken
(),
'tenant-id'
:
getTenantId
()
}
uploadDisabled
.
value
=
true
uploadRef
.
value
!
.
submit
()
}
// 文件上传成功
const
handleFileSuccess
=
async
(
response
:
any
):
Promise
<
void
>
=>
{
if
(
response
.
code
!==
0
)
{
message
.
error
(
response
.
msg
)
return
}
importDialogVisible
.
value
=
false
uploadDisabled
.
value
=
false
const
data
=
response
.
data
let
text
=
'上传成功数量:'
+
data
.
createUsernames
.
length
+
';'
for
(
let
username
of
data
.
createUsernames
)
{
text
+=
'
<
' + username + '
>
'
}
text += '
更新成功数量:
' + data.updateUsernames.length + '
;
'
for (const username of data.updateUsernames) {
text += '
<
' + username + '
>
'
}
text += '
更新失败数量:
' + Object.keys(data.failureUsernames).length + '
;
'
for (const username in data.failureUsernames) {
text += '
<
' + username + '
:
' + data.failureUsernames[username] + '
>
'
}
message.alert(text)
await reload()
}
// 文件数超出提示
const handleExceed = (): void => {
message.error('
最多只能上传一个文件!
')
}
// 上传错误提示
const excelUploadError = (): void => {
message.error('
导入数据失败,请您重新上传!'
)
}
// ========== 初始化 ==========
onMounted
(
async
()
=>
{
await
getPostOptions
()
await
getTree
()
})
</
script
>
<
style
scoped
>
.user
{
height
:
780px
;
max-height
:
800px
;
}
.card-header
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
}
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment