fix(admin): 新增员工确认密码校验 (bug #24028)
| | |
| | | const loading = ref(false), visible = ref(false), saving = ref(false), editId = ref<number | string>() |
| | | const rows = ref<AdminStaff[]>([]), roles = ref<AdminRole[]>([]) |
| | | const filters = reactive({ name: '', mobile: '', role: '', status: '' }) |
| | | const form = reactive({ displayName: '', mobile: '', account: '', password: '', roleCode: '', positionName: '', customerWechat: '', status: 1 }) |
| | | const form = reactive({ displayName: '', mobile: '', account: '', password: '', confirmPassword: '', roleCode: '', positionName: '', customerWechat: '', status: 1 }) |
| | | const filtered = computed(() => rows.value.filter(r => (!filters.name || r.displayName.includes(filters.name)) && (!filters.mobile || (r.mobile || '').includes(filters.mobile)) && (!filters.role || r.roleCode === filters.role) && (!filters.status || String(r.status) === filters.status))) |
| | | const roleName = (code: string) => roles.value.find(r => r.roleCode === code)?.roleName || code |
| | | const formatDateTime = (value?: string) => value ? value.replace('T', ' ').slice(0, 19) : '' |
| | |
| | | const keepAccountCharacters = () => { form.account = form.account.replace(/[^A-Za-z0-9]/g, '').slice(0, 32) } |
| | | async function load() { loading.value = true; try { const result = await Promise.all([getAdminStaff(), getAdminRoles()]); rows.value = result[0]; roles.value = result[1].filter(r => r.status === 1) } finally { loading.value = false } } |
| | | function reset() { Object.assign(filters, { name: '', mobile: '', role: '', status: '' }) } |
| | | function create() { editId.value = undefined; Object.assign(form, { displayName: '', mobile: '', account: '', password: '', roleCode: roles.value[0]?.roleCode || '', positionName: '', customerWechat: '', status: 1 }); visible.value = true } |
| | | function edit(row: AdminStaff) { editId.value = row.id; Object.assign(form, { displayName: row.displayName, mobile: row.mobile || '', account: row.account, password: '', roleCode: row.roleCode, positionName: row.positionName || '', customerWechat: row.customerWechat || '', status: row.status }); visible.value = true } |
| | | async function save() { if (!form.displayName.trim() || !form.account.trim() || !form.roleCode || !form.positionName.trim()) return ElMessage.warning('请填写人员名称、登录账号、角色和职务'); if (!editId.value && form.password.length < 6) return ElMessage.warning('新建员工密码至少 6 位'); saving.value = true; try { const payload = { ...form, password: form.password || undefined }; if (editId.value) await updateAdminStaff(editId.value, payload); else await createAdminStaff({ ...payload, password: form.password }); ElMessage.success('保存成功'); visible.value = false; load() } finally { saving.value = false } } |
| | | function create() { editId.value = undefined; Object.assign(form, { displayName: '', mobile: '', account: '', password: '', confirmPassword: '', roleCode: roles.value[0]?.roleCode || '', positionName: '', customerWechat: '', status: 1 }); visible.value = true } |
| | | function edit(row: AdminStaff) { editId.value = row.id; Object.assign(form, { displayName: row.displayName, mobile: row.mobile || '', account: row.account, password: '', confirmPassword: '', roleCode: row.roleCode, positionName: row.positionName || '', customerWechat: row.customerWechat || '', status: row.status }); visible.value = true } |
| | | async function save() { if (!form.displayName.trim() || !form.account.trim() || !form.roleCode || !form.positionName.trim()) return ElMessage.warning('请填写人员名称、登录账号、角色和职务'); if (!editId.value && form.password.length < 6) return ElMessage.warning('新建员工密码至少 6 位'); if (!editId.value && form.password !== form.confirmPassword) return ElMessage.warning('两次输入的密码不一致'); saving.value = true; try { const { confirmPassword, ...formPayload } = form; const payload = { ...formPayload, password: form.password || undefined }; if (editId.value) await updateAdminStaff(editId.value, payload); else await createAdminStaff({ ...payload, password: form.password }); ElMessage.success('保存成功'); visible.value = false; load() } finally { saving.value = false } } |
| | | async function changeStatus(row: AdminStaff) { await updateAdminStaff(row.id, { displayName: row.displayName, mobile: row.mobile || '', account: row.account, roleCode: row.roleCode, positionName: row.positionName || '未设置', customerWechat: row.customerWechat || '', status: row.status === 1 ? 0 : 1 }); ElMessage.success(row.status === 1 ? '已禁用' : '已启用'); load() } |
| | | async function password(row: AdminStaff) { const result = await ElMessageBox.prompt('请输入 6-64 位新密码', `重置 ${row.displayName} 的密码`, { inputType: 'password', inputPattern: /^.{6,64}$/, inputErrorMessage: '密码长度为 6-64 位' }); await resetAdminStaffPassword(row.id, result.value); ElMessage.success('密码已重置') } |
| | | async function remove(row: AdminStaff) { await ElMessageBox.confirm(`确认删除员工“${row.displayName}”?`, '删除员工', { type: 'warning' }); await deleteAdminStaff(row.id); ElMessage.success('已删除'); load() } |
| | | onMounted(load) |
| | | </script> |
| | | <template><div class="page-stack"><section class="panel"><div class="panel-header"><h3>账号</h3></div><el-form class="filters" inline><el-form-item label="用户名称"><el-input v-model="filters.name" /></el-form-item><el-form-item label="用户电话"><el-input v-model="filters.mobile" /></el-form-item><el-form-item label="角色"><el-select v-model="filters.role" clearable placeholder="请选择"><el-option v-for="role in roles" :key="role.id" :label="role.roleName" :value="role.roleCode" /></el-select></el-form-item><el-form-item label="账号状态"><el-select v-model="filters.status" clearable placeholder="请选择"><el-option label="启用" value="1" /><el-option label="禁用" value="0" /></el-select></el-form-item><el-form-item><el-button :icon="Refresh" @click="reset">重置</el-button><el-button type="primary" :icon="Search">搜索</el-button></el-form-item></el-form><div class="tools"><el-button type="primary" :icon="Plus" @click="create">新增</el-button></div><el-table v-loading="loading" :data="filtered" stripe class="table"><el-table-column type="index" label="序号" width="60"/><el-table-column prop="displayName" label="人员名称" min-width="96"/><el-table-column prop="mobile" label="联系电话" min-width="118"/><el-table-column prop="account" label="登录账号" min-width="116"/><el-table-column label="角色" min-width="110"><template #default="{row}">{{ roleName(row.roleCode) }}</template></el-table-column><el-table-column prop="positionName" label="职务" min-width="92"/><el-table-column prop="customerWechat" label="客服微信" min-width="116"/><el-table-column label="状态" width="78"><template #default="{row}">{{row.status === 1 ? '启用' : '禁用'}}</template></el-table-column><el-table-column label="创建时间" min-width="155"><template #default="{ row }">{{ formatDateTime(row.createdAt) }}</template></el-table-column><el-table-column label="操作" width="225" fixed="right"><template #default="{row}"><el-button link type="primary" @click="edit(row)">编辑</el-button><el-button v-if="!isDefaultAdmin(row)" link type="primary" @click="changeStatus(row)">{{row.status === 1 ? '禁用' : '启用'}}</el-button><el-button link type="primary" @click="password(row)">重置密码</el-button><el-button v-if="!isDefaultAdmin(row)" link type="danger" @click="remove(row)">删除</el-button></template></el-table-column></el-table></section><el-dialog v-model="visible" :title="editId ? '编辑员工' : '新增员工'" width="560px" destroy-on-close><el-form label-width="92px"><el-form-item label="人员名称" required><el-input v-model="form.displayName"/></el-form-item><el-form-item label="联系电话"><el-input v-model="form.mobile" inputmode="numeric" maxlength="11" @input="keepMobileDigits"/></el-form-item><el-form-item label="登录账号" required><el-input v-model="form.account" :disabled="Boolean(editId)" maxlength="32" @input="keepAccountCharacters"/></el-form-item><el-form-item label="登录密码" :required="!editId"><el-input v-model="form.password" type="password" :placeholder="editId ? '留空则不修改' : '至少 6 位'"/></el-form-item><el-form-item label="角色" required><el-select v-model="form.roleCode" class="full"><el-option v-for="role in roles" :key="role.id" :label="role.roleName" :value="role.roleCode"/></el-select></el-form-item><el-form-item label="职务" required><el-input v-model="form.positionName"/></el-form-item><el-form-item label="客服微信"><el-input v-model="form.customerWechat"/></el-form-item><el-form-item label="账号状态"><el-switch v-model="form.status" :disabled="editingDefaultAdmin" :active-value="1" :inactive-value="0" active-text="启用" inactive-text="禁用"/></el-form-item></el-form><template #footer><el-button @click="visible=false">取消</el-button><el-button type="primary" :loading="saving" @click="save">保存</el-button></template></el-dialog></div></template> |
| | | <template><div class="page-stack"><section class="panel"><div class="panel-header"><h3>账号</h3></div><el-form class="filters" inline><el-form-item label="用户名称"><el-input v-model="filters.name" /></el-form-item><el-form-item label="用户电话"><el-input v-model="filters.mobile" /></el-form-item><el-form-item label="角色"><el-select v-model="filters.role" clearable placeholder="请选择"><el-option v-for="role in roles" :key="role.id" :label="role.roleName" :value="role.roleCode" /></el-select></el-form-item><el-form-item label="账号状态"><el-select v-model="filters.status" clearable placeholder="请选择"><el-option label="启用" value="1" /><el-option label="禁用" value="0" /></el-select></el-form-item><el-form-item><el-button :icon="Refresh" @click="reset">重置</el-button><el-button type="primary" :icon="Search">搜索</el-button></el-form-item></el-form><div class="tools"><el-button type="primary" :icon="Plus" @click="create">新增</el-button></div><el-table v-loading="loading" :data="filtered" stripe class="table"><el-table-column type="index" label="序号" width="60"/><el-table-column prop="displayName" label="人员名称" min-width="96"/><el-table-column prop="mobile" label="联系电话" min-width="118"/><el-table-column prop="account" label="登录账号" min-width="116"/><el-table-column label="角色" min-width="110"><template #default="{row}">{{ roleName(row.roleCode) }}</template></el-table-column><el-table-column prop="positionName" label="职务" min-width="92"/><el-table-column prop="customerWechat" label="客服微信" min-width="116"/><el-table-column label="状态" width="78"><template #default="{row}">{{row.status === 1 ? '启用' : '禁用'}}</template></el-table-column><el-table-column label="创建时间" min-width="155"><template #default="{ row }">{{ formatDateTime(row.createdAt) }}</template></el-table-column><el-table-column label="操作" width="225" fixed="right"><template #default="{row}"><el-button link type="primary" @click="edit(row)">编辑</el-button><el-button v-if="!isDefaultAdmin(row)" link type="primary" @click="changeStatus(row)">{{row.status === 1 ? '禁用' : '启用'}}</el-button><el-button link type="primary" @click="password(row)">重置密码</el-button><el-button v-if="!isDefaultAdmin(row)" link type="danger" @click="remove(row)">删除</el-button></template></el-table-column></el-table></section><el-dialog v-model="visible" :title="editId ? '编辑员工' : '新增员工'" width="560px" destroy-on-close><el-form label-width="92px"><el-form-item label="人员名称" required><el-input v-model="form.displayName"/></el-form-item><el-form-item label="联系电话"><el-input v-model="form.mobile" inputmode="numeric" maxlength="11" @input="keepMobileDigits"/></el-form-item><el-form-item label="登录账号" required><el-input v-model="form.account" :disabled="Boolean(editId)" maxlength="32" @input="keepAccountCharacters"/></el-form-item><el-form-item label="登录密码" :required="!editId"><el-input v-model="form.password" type="password" :placeholder="editId ? '留空则不修改' : '至少 6 位'"/></el-form-item><el-form-item v-if="!editId" label="确认密码" required><el-input v-model="form.confirmPassword" type="password" placeholder="请再次输入密码"/></el-form-item><el-form-item label="角色" required><el-select v-model="form.roleCode" class="full"><el-option v-for="role in roles" :key="role.id" :label="role.roleName" :value="role.roleCode"/></el-select></el-form-item><el-form-item label="职务" required><el-input v-model="form.positionName"/></el-form-item><el-form-item label="客服微信"><el-input v-model="form.customerWechat"/></el-form-item><el-form-item label="账号状态"><el-switch v-model="form.status" :disabled="editingDefaultAdmin" :active-value="1" :inactive-value="0" active-text="启用" inactive-text="禁用"/></el-form-item></el-form><template #footer><el-button @click="visible=false">取消</el-button><el-button type="primary" :loading="saving" @click="save">保存</el-button></template></el-dialog></div></template> |
| | | <style scoped>.filters{margin:14px 20px 0;padding:16px;border:1px solid #dce3ea;border-radius:4px}.filters :deep(.el-input),.filters :deep(.el-select){width:130px}.tools{display:flex;justify-content:flex-end;padding:10px 20px 14px}.table{margin:0 20px;width:calc(100% - 40px)}.full{width:100%}</style> |