优化用户列表界面,调整移动端和桌面端布局,增强用户体验,修复数据处理逻辑,确保积分余额字段正确显示。

This commit is contained in:
zyh
2025-08-28 10:08:11 +08:00
parent ecace6eb88
commit 602d88a5a2
2 changed files with 272 additions and 267 deletions

View File

@@ -546,3 +546,4 @@ export default {
color: #a3a6ad; color: #a3a6ad;
} }
</style> </style>

View File

@@ -201,8 +201,19 @@
/> />
</div> </div>
</el-card> </el-card>
</div>
<el-dialog v-model="visible" :title="isEdit ? '编辑用户' : '新增用户'" width="520px"> <!-- 统一弹窗(重要:放在两套容器之外;手机端全屏) -->
<el-dialog
v-model="visible"
:title="isEdit ? '编辑用户' : '新增用户'"
:width="isMobile ? '96vw' : '520px'"
:fullscreen="isMobile"
:append-to-body="true"
:destroy-on-close="true"
:close-on-click-modal="false"
top="8vh"
>
<el-form ref="formRef" :model="form" :rules="rules" label-width="88px"> <el-form ref="formRef" :model="form" :rules="rules" label-width="88px">
<el-form-item label="用户名" prop="username"> <el-form-item label="用户名" prop="username">
<el-input v-model.trim="form.username" :disabled="isEdit" placeholder="请输入用户名" /> <el-input v-model.trim="form.username" :disabled="isEdit" placeholder="请输入用户名" />
@@ -212,8 +223,8 @@
<el-option v-for="ut in userTypeOptions" :key="ut.value" :label="ut.label" :value="ut.value" /> <el-option v-for="ut in userTypeOptions" :key="ut.value" :label="ut.label" :value="ut.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="积分余额" prop="pointsBalance" v-if="form.userType === 'AGENT'"> <el-form-item v-if="form.userType === 'AGENT'" label="积分余额" prop="pointsBalance">
<el-input-number v-model="form.pointsBalance" :min="0" :max="999999" /> <el-input-number v-model.number="form.pointsBalance" :min="0" :max="999999" style="width: 100%" />
</el-form-item> </el-form-item>
<el-form-item v-if="!isEdit" label="初始密码" prop="password"> <el-form-item v-if="!isEdit" label="初始密码" prop="password">
<el-input v-model.trim="form.password" type="password" show-password placeholder="至少6位" /> <el-input v-model.trim="form.password" type="password" show-password placeholder="至少6位" />
@@ -229,7 +240,6 @@
</el-dialog> </el-dialog>
</div> </div>
</div> </div>
</div>
</template> </template>
<script setup> <script setup>
@@ -245,7 +255,6 @@ const list = ref([])
const total = ref(0) const total = ref(0)
const isMobile = ref(false) const isMobile = ref(false)
// 检测移动端
const checkMobile = () => { const checkMobile = () => {
isMobile.value = window.innerWidth <= 768 isMobile.value = window.innerWidth <= 768
} }
@@ -264,13 +273,12 @@ const userTypeOptions = ref([
{ value: 'AGENT', label: '代理商' } { value: 'AGENT', label: '代理商' }
]) ])
// 用户类型显示名称映射 // 显示名称映射
const userTypeDisplayMap = { const userTypeDisplayMap = {
'ADMIN': '管理员', 'ADMIN': '管理员',
'AGENT': '代理商' 'AGENT': '代理商'
} }
// 权限检查
const canViewUsers = computed(() => { const canViewUsers = computed(() => {
const permission = hasPermission(PERMISSIONS.USER_VIEW) const permission = hasPermission(PERMISSIONS.USER_VIEW)
console.log('canViewUsers:', permission, 'USER_VIEW:', PERMISSIONS.USER_VIEW) console.log('canViewUsers:', permission, 'USER_VIEW:', PERMISSIONS.USER_VIEW)
@@ -293,7 +301,6 @@ function unwrap(res) {
async function load() { async function load() {
console.log('开始加载用户数据,权限检查:', canViewUsers.value) console.log('开始加载用户数据,权限检查:', canViewUsers.value)
if (!canViewUsers.value) { if (!canViewUsers.value) {
ElMessage.warning('没有权限查看用户列表') ElMessage.warning('没有权限查看用户列表')
return return
@@ -301,11 +308,7 @@ async function load() {
loading.value = true loading.value = true
try { try {
// 根据OpenAPI文档参数映射pageSize -> size const params = { ...query, size: query.pageSize }
const params = {
...query,
size: query.pageSize
}
delete params.pageSize delete params.pageSize
console.log('请求参数:', params) console.log('请求参数:', params)
@@ -315,8 +318,15 @@ async function load() {
const data = unwrap(res) || {} const data = unwrap(res) || {}
console.log('解析后数据:', data) console.log('解析后数据:', data)
// 兼容后端返回两种分页结构 const rows = data.list || data.items || []
list.value = data.list || data.items || [] // 规范化字段:保证 pointsBalance 为 number
rows.forEach(r => {
if (r.userType === 'AGENT') {
r.pointsBalance = Number(r.pointsBalance || 0)
}
})
list.value = rows
total.value = data.total || data.totalCount || list.value.length total.value = data.total || data.totalCount || list.value.length
console.log('用户列表数据:', list.value) console.log('用户列表数据:', list.value)
@@ -346,7 +356,6 @@ function onReset() {
async function onToggle(row, val) { async function onToggle(row, val) {
try { try {
await setUserStatus(row.id, val) await setUserStatus(row.id, val)
// 更新 status 字段,保持与后端一致
row.status = val ? 'ENABLED' : 'DISABLED' row.status = val ? 'ENABLED' : 'DISABLED'
showSuccessMessage('状态已更新') showSuccessMessage('状态已更新')
} catch (e) { } catch (e) {
@@ -383,7 +392,6 @@ async function onResetPwd(row) {
inputErrorMessage: '请输入有效的密码' inputErrorMessage: '请输入有效的密码'
} }
) )
await resetUserPassword(row.id, newPassword) await resetUserPassword(row.id, newPassword)
showSuccessMessage('密码重置成功') showSuccessMessage('密码重置成功')
} catch (e) { } catch (e) {
@@ -411,11 +419,13 @@ const rules = {
{ required: () => !isEdit.value, message: '请输入初始密码', trigger: 'blur' }, { required: () => !isEdit.value, message: '请输入初始密码', trigger: 'blur' },
{ min: 6, message: '至少 6 位', trigger: 'blur' }, { min: 6, message: '至少 6 位', trigger: 'blur' },
], ],
pointsBalance: [{ pointsBalance: [
{
required: () => form.userType === 'AGENT', required: () => form.userType === 'AGENT',
message: '请输入积分余额', message: '请输入积分余额',
trigger: 'blur' trigger: 'change' // 关键el-input-number 用 change 更稳
}], }
],
} }
function openCreate() { function openCreate() {
@@ -436,27 +446,22 @@ function openEdit(row) {
Object.assign(form, { Object.assign(form, {
...row, ...row,
password: '', password: '',
pointsBalance: row.pointsBalance || 0, pointsBalance: Number(row.pointsBalance || 0),
// 将后端的 status 字段映射为前端的 enabled 字段
enabled: row.status === 'ENABLED' enabled: row.status === 'ENABLED'
}) })
visible.value = true visible.value = true
} }
function doSubmit() { function doSubmit() {
// 根据接口文档构建请求参数
const payload = { const payload = {
userType: form.userType, userType: form.userType,
username: form.username, username: form.username,
status: form.enabled ? 'ENABLED' : 'DISABLED', status: form.enabled ? 'ENABLED' : 'DISABLED',
pointsBalance: form.pointsBalance || 0 pointsBalance: Number(form.pointsBalance || 0)
} }
// 如果是新增用户,需要设置密码
if (!isEdit.value) { if (!isEdit.value) {
payload.password = form.password payload.password = form.password
} }
return isEdit.value return isEdit.value
? updateUser(form.id, payload) ? updateUser(form.id, payload)
: createUser(payload) : createUser(payload)
@@ -480,7 +485,7 @@ async function onSubmit() {
}) })
} }
// 监听用户类型变化,重置积分余额字段 // 监听类型变化,管理员清零积分
watch(() => form.userType, (newType) => { watch(() => form.userType, (newType) => {
if (newType === 'ADMIN') { if (newType === 'ADMIN') {
form.pointsBalance = 0 form.pointsBalance = 0
@@ -488,7 +493,6 @@ watch(() => form.userType, (newType) => {
}) })
onMounted(() => { onMounted(() => {
// 添加调试信息
console.log('用户管理页面加载') console.log('用户管理页面加载')
const auth = getCurrentUser() const auth = getCurrentUser()
const userType = getCurrentUserType() const userType = getCurrentUserType()