初始化
This commit is contained in:
@@ -0,0 +1,309 @@
|
||||
<template>
|
||||
<div class="form-page">
|
||||
<el-page-header @back="handleBack" :title="isEdit ? '编辑用户' : '新增用户'" />
|
||||
<el-divider />
|
||||
|
||||
<el-card shadow="never" class="form-card">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
|
||||
<!-- ===== 基本信息 ===== -->
|
||||
<el-divider content-position="left"><span class="section-label">基本信息</span></el-divider>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input v-model="form.username" placeholder="请输入用户名" :disabled="isEdit" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="真实姓名" prop="realName">
|
||||
<el-input v-model="form.realName" placeholder="请输入真实姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="form.email" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="手机号">
|
||||
<el-input v-model="form.phone" placeholder="请输入手机号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="岗位">
|
||||
<el-input v-model="form.post" placeholder="请输入岗位" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item v-if="!isEdit" label="密码" prop="password">
|
||||
<el-input v-model="form.password" type="password" placeholder="请输入密码" show-password />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-switch v-model="form.status" :active-value="1" :inactive-value="0" active-text="启用" inactive-text="禁用" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- ===== 系统 & 角色绑定(仅编辑模式) ===== -->
|
||||
<template v-if="isEdit">
|
||||
<el-divider content-position="left"><span class="section-label">系统绑定</span></el-divider>
|
||||
|
||||
<el-form-item label="绑定系统">
|
||||
<el-checkbox-group v-model="bindSystemIds" @change="onSystemChange">
|
||||
<el-checkbox
|
||||
v-for="sys in allSystems"
|
||||
:key="sys.systemId"
|
||||
:label="sys.systemId"
|
||||
>
|
||||
{{ sys.systemName }}
|
||||
<el-tag size="small" type="info" style="margin-left:4px">{{ sys.systemCode }}</el-tag>
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider content-position="left"><span class="section-label">角色分配</span></el-divider>
|
||||
<p class="hint-text">先选择系统,再为该用户分配该系统下的角色</p>
|
||||
|
||||
<el-form-item label="选择系统">
|
||||
<el-select
|
||||
v-model="roleSystemId"
|
||||
placeholder="请选择系统"
|
||||
clearable
|
||||
style="width:280px"
|
||||
@change="onRoleSystemChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="sys in allSystems"
|
||||
:key="sys.systemId"
|
||||
:label="sys.systemName + ' (' + sys.systemCode + ')'"
|
||||
:value="sys.systemId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="roleSystemId" label="分配角色">
|
||||
<el-checkbox-group v-model="assignRoleIds">
|
||||
<el-checkbox
|
||||
v-for="r in currentRoleList"
|
||||
:key="r.id"
|
||||
:label="r.id"
|
||||
>
|
||||
{{ r.roleName }}
|
||||
<span style="color:var(--text-muted);font-size:12px;margin-left:4px">{{ r.roleCode }}</span>
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
<el-empty v-if="currentRoleList.length === 0" description="该系统下暂无角色" :image-size="60" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<!-- ===== 按钮 ===== -->
|
||||
<el-divider />
|
||||
<div class="form-footer">
|
||||
<el-button @click="handleBack">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">保存</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, reactive, ref, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import request from '@/utils/request'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const isEdit = ref(false)
|
||||
const editId = ref<string>()
|
||||
const submitLoading = ref(false)
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
const form = reactive({
|
||||
username: '',
|
||||
realName: '',
|
||||
email: '',
|
||||
phone: '',
|
||||
post: '',
|
||||
password: '',
|
||||
status: 1,
|
||||
})
|
||||
|
||||
const rules = computed<FormRules>(() => ({
|
||||
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
||||
realName: [{ required: true, message: '请输入真实姓名', trigger: 'blur' }],
|
||||
email: [{ required: true, message: '请输入邮箱', trigger: 'blur' }],
|
||||
password: isEdit.value ? [] : [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '请选择状态', trigger: 'change' }],
|
||||
}))
|
||||
|
||||
// ===== 系统绑定 =====
|
||||
const allSystems = ref<any[]>([])
|
||||
const bindSystemIds = ref<string[]>([])
|
||||
|
||||
async function fetchAllSystems() {
|
||||
try {
|
||||
const res = await request.get('/zgapi/v1/auth/system/list')
|
||||
allSystems.value = res.data ?? []
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
async function fetchUserSystems() {
|
||||
if (!editId.value) return
|
||||
try {
|
||||
const res = await request.get(`/zgapi/v1/admin/user/${editId.value}/system`)
|
||||
bindSystemIds.value = res.data ?? []
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
async function onSystemChange(_val: string[]) {
|
||||
// 用户取消勾选系统时,清除该系统下的角色选择
|
||||
await saveSystems()
|
||||
}
|
||||
|
||||
async function saveSystems() {
|
||||
if (!editId.value) return
|
||||
try {
|
||||
await request.post(`/zgapi/v1/admin/user/${editId.value}/system`, bindSystemIds.value)
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
// ===== 角色分配 =====
|
||||
const roleSystemId = ref<string>()
|
||||
const assignRoleIds = ref<string[]>([])
|
||||
const currentRoleList = ref<any[]>([])
|
||||
|
||||
async function onRoleSystemChange(sysId: string | undefined) {
|
||||
assignRoleIds.value = []
|
||||
if (!sysId) { currentRoleList.value = []; return }
|
||||
|
||||
// 加载该系统下的角色列表
|
||||
try {
|
||||
const res = await request.post('/zgapi/v1/admin/role/page', { page: 1, pageSize: 999, systemId: sysId })
|
||||
currentRoleList.value = res.data?.records ?? []
|
||||
} catch {
|
||||
currentRoleList.value = []
|
||||
}
|
||||
|
||||
// 加载用户在该系统下的已有角色
|
||||
if (!editId.value) return
|
||||
try {
|
||||
const res = await request.get(`/zgapi/v1/admin/user/${editId.value}/role/${sysId}`)
|
||||
assignRoleIds.value = res.data ?? []
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
async function saveRoles() {
|
||||
if (!editId.value || !roleSystemId.value) return
|
||||
try {
|
||||
await request.post(`/zgapi/v1/admin/user/${editId.value}/role`, assignRoleIds.value, {
|
||||
params: { systemId: roleSystemId.value }
|
||||
})
|
||||
ElMessage.success('角色已保存')
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
// ===== 加载与提交 =====
|
||||
async function loadData() {
|
||||
const id = route.params.id as string
|
||||
if (!id) { isEdit.value = false; return }
|
||||
|
||||
isEdit.value = true
|
||||
editId.value = id
|
||||
|
||||
try {
|
||||
const res = await request.get(`/zgapi/v1/admin/user/${editId.value}`)
|
||||
const data = res.data
|
||||
if (data) {
|
||||
Object.assign(form, {
|
||||
username: data.username ?? '',
|
||||
realName: data.realName ?? '',
|
||||
email: data.email ?? '',
|
||||
phone: data.phone ?? '',
|
||||
post: data.post ?? '',
|
||||
password: '',
|
||||
status: data.status ?? 1,
|
||||
})
|
||||
setTimeout(() => formRef.value?.clearValidate(), 0)
|
||||
}
|
||||
} catch {
|
||||
ElMessage.error('加载用户信息失败')
|
||||
router.back()
|
||||
}
|
||||
}
|
||||
|
||||
function handleBack() { router.back() }
|
||||
|
||||
async function handleSubmit() {
|
||||
const valid = await formRef.value?.validate().catch(() => false)
|
||||
if (!valid) return
|
||||
|
||||
submitLoading.value = true
|
||||
try {
|
||||
const payload: any = {
|
||||
username: form.username,
|
||||
realName: form.realName,
|
||||
email: form.email,
|
||||
phone: form.phone,
|
||||
post: form.post,
|
||||
status: form.status,
|
||||
}
|
||||
if (isEdit.value) {
|
||||
await request.put('/zgapi/v1/admin/user', { ...payload, id: editId.value })
|
||||
// 保存系统绑定
|
||||
await saveSystems()
|
||||
// 如果有选择角色系统,保存角色
|
||||
if (roleSystemId.value) await saveRoles()
|
||||
ElMessage.success('用户信息已保存')
|
||||
} else {
|
||||
await request.post('/zgapi/v1/admin/user', { ...payload, password: form.password })
|
||||
ElMessage.success('新增成功')
|
||||
}
|
||||
router.back()
|
||||
} catch (e: any) {
|
||||
const msg = e?.response?.data?.msg || e?.message
|
||||
if (msg && msg !== '请求失败') ElMessage.error(msg)
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchAllSystems()
|
||||
await loadData()
|
||||
if (isEdit.value) {
|
||||
await fetchUserSystems()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.form-page { display:flex; flex-direction:column; }
|
||||
:deep(.el-page-header) { margin-bottom:4px; }
|
||||
:deep(.el-page-header + .el-divider) { margin:0 0 20px; }
|
||||
|
||||
.form-card { max-width:860px; margin:0 auto; width:100%; }
|
||||
|
||||
.section-label { font-size:15px; font-weight:600; color:var(--text-primary); }
|
||||
|
||||
.hint-text { font-size:13px; color:var(--text-muted); margin-bottom:16px; }
|
||||
|
||||
.form-footer { display:flex; justify-content:flex-end; gap:12px; }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.form-card { max-width: 100%; padding: 0 8px; }
|
||||
.form-footer { flex-direction: column; }
|
||||
.form-footer .el-button { width: 100%; }
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user