Skip to content

Commit 6ce9ab8

Browse files
fessorgitee-org
authored andcommitted
feat: ep重写用户管理
Signed-off-by: fessor <[email protected]>
1 parent 72ddb0c commit 6ce9ab8

File tree

5 files changed

+960
-495
lines changed

5 files changed

+960
-495
lines changed

src/views/system/user/AddForm.vue

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
<template>
2+
<!-- 添加或修改参数配置对话框 -->
3+
<el-dialog
4+
:title="title"
5+
:modelValue="modelValue"
6+
width="600px"
7+
append-to-body
8+
@close="closeDialog"
9+
>
10+
<el-form ref="formRef" :model="formData" :rules="rules" label-width="80px">
11+
<el-row>
12+
<el-col :span="12">
13+
<el-form-item label="用户昵称" prop="nickname">
14+
<el-input v-model="formData.nickname" placeholder="请输入用户昵称" />
15+
</el-form-item>
16+
</el-col>
17+
<el-col :span="12">
18+
<el-form-item label="归属部门" prop="deptId">
19+
<el-tree-select
20+
node-key="id"
21+
v-model="formData.deptId"
22+
:data="deptOptions"
23+
:props="defaultProps"
24+
check-strictly
25+
placeholder="请选择归属部门"
26+
/>
27+
</el-form-item>
28+
</el-col>
29+
</el-row>
30+
<el-row>
31+
<el-col :span="12">
32+
<el-form-item label="手机号码" prop="mobile">
33+
<el-input v-model="formData.mobile" placeholder="请输入手机号码" maxlength="11" />
34+
</el-form-item>
35+
</el-col>
36+
<el-col :span="12">
37+
<el-form-item label="邮箱" prop="email">
38+
<el-input v-model="formData.email" placeholder="请输入邮箱" maxlength="50" />
39+
</el-form-item>
40+
</el-col>
41+
</el-row>
42+
<el-row>
43+
<el-col :span="12">
44+
<el-form-item v-if="formData.id === undefined" label="用户名称" prop="username">
45+
<el-input v-model="formData.username" placeholder="请输入用户名称" />
46+
</el-form-item>
47+
</el-col>
48+
<el-col :span="12">
49+
<el-form-item v-if="formData.id === undefined" label="用户密码" prop="password">
50+
<el-input
51+
v-model="formData.password"
52+
placeholder="请输入用户密码"
53+
type="password"
54+
show-password
55+
/>
56+
</el-form-item>
57+
</el-col>
58+
</el-row>
59+
<el-row>
60+
<el-col :span="12">
61+
<el-form-item label="用户性别">
62+
<el-select v-model="formData.sex" placeholder="请选择">
63+
<el-option
64+
v-for="dict in sexDictDatas"
65+
:key="parseInt(dict.value)"
66+
:label="dict.label"
67+
:value="parseInt(dict.value)"
68+
/>
69+
</el-select>
70+
</el-form-item>
71+
</el-col>
72+
<el-col :span="12">
73+
<el-form-item label="岗位">
74+
<el-select v-model="formData.postIds" multiple placeholder="请选择">
75+
<el-option
76+
v-for="item in postOptions"
77+
:key="item.id"
78+
:label="item.name"
79+
:value="item.id"
80+
/>
81+
</el-select>
82+
</el-form-item>
83+
</el-col>
84+
</el-row>
85+
<el-row>
86+
<el-col :span="24">
87+
<el-form-item label="备注">
88+
<el-input v-model="formData.remark" type="textarea" placeholder="请输入内容" />
89+
</el-form-item>
90+
</el-col>
91+
</el-row>
92+
</el-form>
93+
<template #footer>
94+
<div class="dialog-footer">
95+
<el-button type="primary" @click="submitForm">确 定</el-button>
96+
<el-button @click="cancel">取 消</el-button>
97+
</div>
98+
</template>
99+
</el-dialog>
100+
</template>
101+
<script lang="ts" setup>
102+
import { PostVO } from '@/api/system/post'
103+
import { createUserApi, updateUserApi } from '@/api/system/user'
104+
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
105+
import { defaultProps } from '@/utils/tree'
106+
import { ElForm, FormItemRule } from 'element-plus'
107+
import { Arrayable } from 'element-plus/es/utils'
108+
109+
type Form = InstanceType<typeof ElForm>
110+
interface Props {
111+
deptOptions?: Tree[]
112+
postOptions?: PostVO[] //岗位列表
113+
modelValue: boolean
114+
formInitValue?: Recordable & Partial<typeof initParams>
115+
}
116+
117+
const props = withDefaults(defineProps<Props>(), {
118+
deptOptions: () => [],
119+
postOptions: () => [],
120+
modelValue: false,
121+
formInitValue: () => ({})
122+
})
123+
const emits = defineEmits(['update:modelValue', 'success'])
124+
125+
const { t } = useI18n() // 国际化
126+
const message = useMessage() // 消息弹窗
127+
// 弹出层标题
128+
const title = computed(() => {
129+
return formData.value?.id ? '修改用户' : '添加用户'
130+
})
131+
132+
// 性别字典
133+
const sexDictDatas = getDictOptions(DICT_TYPE.SYSTEM_USER_SEX)
134+
135+
// 表单初始化参数
136+
const initParams = {
137+
nickname: '',
138+
deptId: '',
139+
mobile: '',
140+
email: '',
141+
id: undefined,
142+
username: '',
143+
password: '',
144+
sex: 1,
145+
postIds: [],
146+
remark: '',
147+
status: '0',
148+
roleIds: []
149+
}
150+
151+
// 校验规则
152+
const rules = {
153+
username: [{ required: true, message: '用户名称不能为空', trigger: 'blur' }],
154+
nickname: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }],
155+
password: [{ required: true, message: '用户密码不能为空', trigger: 'blur' }],
156+
email: [
157+
{
158+
type: 'email',
159+
message: "'请输入正确的邮箱地址",
160+
trigger: ['blur', 'change']
161+
}
162+
],
163+
mobile: [
164+
{
165+
pattern: /^(?:(?:\+|00)86)?1(?:3[\d]|4[5-79]|5[0-35-9]|6[5-7]|7[0-8]|8[\d]|9[189])\d{8}$/,
166+
message: '请输入正确的手机号码',
167+
trigger: 'blur'
168+
}
169+
]
170+
} as Partial<Record<string, Arrayable<FormItemRule>>>
171+
const formRef = ref<Form | null>()
172+
const formData = ref<Recordable>({ ...initParams })
173+
watch(
174+
() => props.formInitValue,
175+
(val) => {
176+
formData.value = { ...val }
177+
},
178+
{ deep: true }
179+
)
180+
181+
const resetForm = () => {
182+
let form = formRef?.value
183+
if (!form) return
184+
formData.value = { ...initParams }
185+
form && (form as Form).resetFields()
186+
}
187+
const closeDialog = () => {
188+
emits('update:modelValue', false)
189+
}
190+
// 操作成功
191+
const operateOk = () => {
192+
emits('success', true)
193+
closeDialog()
194+
}
195+
const submitForm = () => {
196+
let form = formRef.value as Form
197+
form.validate(async (valid) => {
198+
let data = formData.value
199+
if (valid) {
200+
try {
201+
if (data?.id !== undefined) {
202+
await updateUserApi(data)
203+
message.success(t('common.updateSuccess'))
204+
operateOk()
205+
} else {
206+
await createUserApi(data)
207+
message.success(t('common.createSuccess'))
208+
operateOk()
209+
}
210+
} catch (err) {
211+
console.error(err)
212+
}
213+
}
214+
})
215+
}
216+
const cancel = () => {
217+
closeDialog()
218+
}
219+
220+
defineExpose({
221+
resetForm
222+
})
223+
</script>

src/views/system/user/ImportForm.vue

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<template>
2+
<el-dialog
3+
:title="upload.title"
4+
:modelValue="modelValue"
5+
width="400px"
6+
append-to-body
7+
@close="closeDialog"
8+
>
9+
<el-upload
10+
ref="uploadRef"
11+
accept=".xlsx, .xls"
12+
:limit="1"
13+
:headers="upload.headers"
14+
:action="upload.url + '?updateSupport=' + upload.updateSupport"
15+
:disabled="upload.isUploading"
16+
:on-progress="handleFileUploadProgress"
17+
:on-success="handleFileSuccess"
18+
:on-exceed="handleExceed"
19+
:on-error="excelUploadError"
20+
:auto-upload="false"
21+
drag
22+
>
23+
<Icon icon="ep:upload" />
24+
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
25+
<template #tip>
26+
<div class="el-upload__tip text-center">
27+
<div class="el-upload__tip">
28+
<el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据
29+
</div>
30+
31+
<span>仅允许导入xls、xlsx格式文件。</span>
32+
<el-link
33+
type="primary"
34+
:underline="false"
35+
style="font-size: 12px; vertical-align: baseline"
36+
@click="importTemplate"
37+
>下载模板</el-link
38+
>
39+
</div>
40+
</template>
41+
</el-upload>
42+
<template #footer>
43+
<div class="dialog-footer">
44+
<el-button type="primary" @click="submitFileForm">确 定</el-button>
45+
<el-button @click="cancel">取 消</el-button>
46+
</div>
47+
</template>
48+
</el-dialog>
49+
</template>
50+
51+
<script lang="ts" setup>
52+
import { importUserTemplateApi } from '@/api/system/user'
53+
import { getAccessToken, getTenantId } from '@/utils/auth'
54+
import download from '@/utils/download'
55+
56+
interface Props {
57+
modelValue: boolean
58+
}
59+
60+
// const props =
61+
withDefaults(defineProps<Props>(), {
62+
modelValue: false
63+
})
64+
65+
const emits = defineEmits(['update:modelValue', 'success'])
66+
67+
const message = useMessage() // 消息弹窗
68+
69+
const uploadRef = ref()
70+
71+
// 用户导入参数
72+
const upload = reactive({
73+
// // 是否显示弹出层(用户导入)
74+
// open: false,
75+
// 弹出层标题(用户导入)
76+
title: '用户导入',
77+
// 是否禁用上传
78+
isUploading: false,
79+
// 是否更新已经存在的用户数据
80+
updateSupport: 0,
81+
// 设置上传的请求头部
82+
headers: {
83+
Authorization: 'Bearer ' + getAccessToken(),
84+
'tenant-id': getTenantId()
85+
},
86+
// 上传的地址
87+
url: import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/system/user/import'
88+
})
89+
90+
// 文件上传中处理
91+
const handleFileUploadProgress = () => {
92+
upload.isUploading = true
93+
}
94+
// 文件上传成功处理
95+
const handleFileSuccess = (response: any) => {
96+
if (response.code !== 0) {
97+
message.error(response.msg)
98+
return
99+
}
100+
upload.isUploading = false
101+
uploadRef.value?.clearFiles()
102+
// 拼接提示语
103+
const data = response.data
104+
let text = '上传成功数量:' + data.createUsernames.length + ';'
105+
for (let username of data.createUsernames) {
106+
text += '< ' + username + ' >'
107+
}
108+
text += '更新成功数量:' + data.updateUsernames.length + ';'
109+
for (const username of data.updateUsernames) {
110+
text += '< ' + username + ' >'
111+
}
112+
text += '更新失败数量:' + Object.keys(data.failureUsernames).length + ';'
113+
for (const username in data.failureUsernames) {
114+
text += '< ' + username + ': ' + data.failureUsernames[username] + ' >'
115+
}
116+
message.alert(text)
117+
emits('success')
118+
closeDialog()
119+
}
120+
121+
// 文件数超出提示
122+
const handleExceed = (): void => {
123+
message.error('最多只能上传一个文件!')
124+
}
125+
// 上传错误提示
126+
const excelUploadError = (): void => {
127+
message.error('导入数据失败,请您重新上传!')
128+
}
129+
130+
/** 下载模板操作 */
131+
const importTemplate = async () => {
132+
try {
133+
const res = await importUserTemplateApi()
134+
download.excel(res, '用户导入模版.xls')
135+
} catch (error) {
136+
console.error(error)
137+
}
138+
}
139+
140+
/* 弹框按钮操作 */
141+
// 点击取消
142+
const cancel = () => {
143+
closeDialog()
144+
}
145+
// 关闭弹窗
146+
const closeDialog = () => {
147+
emits('update:modelValue', false)
148+
}
149+
// 提交上传文件
150+
const submitFileForm = () => {
151+
uploadRef.value?.submit()
152+
}
153+
</script>

0 commit comments

Comments
 (0)