diff --git a/src/config/menus.js b/src/config/menus.js index 24093e7..923d5cb 100644 --- a/src/config/menus.js +++ b/src/config/menus.js @@ -6,8 +6,14 @@ export const menus = [ }, { path: '/ticket', - title: '工单处理', - icon: 'DataBoard' + title: '工单管理', + icon: 'Tickets', + children: [ + { + path: '/ticket/list', + title: '工单列表' + } + ] }, { path: '/user', @@ -18,10 +24,6 @@ export const menus = [ path: '/user/list', title: '用户列表' }, - { - path: '/user/balance', - title: '用户余额管理' - }, { path: '/user/group', title: '用户组管理' diff --git a/src/router/index.js b/src/router/index.js index 571f32a..4f4f41b 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -39,7 +39,27 @@ const routes = [ title: '工单管理', icon: 'Tickets' }, - component: () => import('../views/ticket/TicketChat.vue'), + redirect: '/ticket/list', + children: [ + { + path: 'list', + name: 'TicketList', + component: () => import('../views/ticket/TicketList.vue'), + meta: { + title: '工单列表' + } + }, + { + path: 'detail', + name: 'TicketDetail', + component: () => import('../views/ticket/TicketDetail.vue'), + meta: { + title: '工单详情', + hidden: true, + activeMenu: '/ticket/list' + } + } + ] }, // ACS管理路由 diff --git a/src/views/ticket/TicketDetail.vue b/src/views/ticket/TicketDetail.vue new file mode 100644 index 0000000..4d123e1 --- /dev/null +++ b/src/views/ticket/TicketDetail.vue @@ -0,0 +1,875 @@ + + + + + + 返回列表 + + + + {{ ticketInfo.username?.charAt(0) }} + + {{ ticketInfo.username }} + 创建于 {{ ticketInfo.createTime }} + + + + + + {{ ticketInfo.username?.charAt(0) }} + + {{ userDetail?.UserName || ticketInfo.username }} + UID: {{ ticketInfo.userId }} + + + + + + 手机号 + {{ userDetail?.Phone || '-' }} + + + 邮箱 + {{ userDetail?.Email || '-' }} + + + 实名状态 + + {{ userDetail?.RealName?.Status === 1 ? '已实名' : '未实名' }} + + + + 用户组 + {{ userDetail?.UserGroup?.Name || '-' }} + + + + + 查看完整资料 + + + + {{ ticketInfo.title }} + + + 工单号: {{ ticketInfo.id }} + + {{ getStatusText(ticketInfo.status) }} + + + 结束工单 + + + + + + + + + + {{ ticketInfo?.username?.charAt(0) || 'U' }} + + + {{ message.content }} + + + + {{ formatMessageTime(message.time) }} + + + A + + + + + + + + + + + + × + + + + + + + {{ reply.title }} + + + + + + + + + + 图片 + + + Ctrl + Enter 发送 + + 发送 + + + + + + + + + + + + + + + + + + + + diff --git a/src/views/ticket/TicketList.vue b/src/views/ticket/TicketList.vue new file mode 100644 index 0000000..c09bc62 --- /dev/null +++ b/src/views/ticket/TicketList.vue @@ -0,0 +1,353 @@ + + + + + + + 全部 {{ stats.total }} + + + 待处理 {{ stats.pending }} + + + 处理中 {{ stats.processing }} + + + 已回复 {{ stats.replied }} + + + 已完成 {{ stats.completed }} + + + + + 刷新 + + + + + + + + + + {{ row.username?.charAt(0) }} + {{ row.username }} + + + + + + + + {{ getStatusText(row.status) }} + + + + + + + + + 回复 + + + 结束 + + + + + + + + + + + + + + + diff --git a/src/views/user/UserBalance.vue b/src/views/user/UserBalance.vue index 0bd1f4a..252784a 100644 --- a/src/views/user/UserBalance.vue +++ b/src/views/user/UserBalance.vue @@ -1,315 +1,112 @@ - - - - - - - - - - - 已加载 {{ userList.length }} / {{ userTotalCount }} 个用户 - - - - - - - - - - - {{ item.UserName }} - - - - {{ item.Email }} - - - ID: {{ item.UserId }} - - - - - - - - 正在加载更多用户... - - - - - - - - - 点击加载更多用户 - - - - - - - - - 已加载全部 {{ userTotalCount }} 个用户 - - - - - - - - {{ userSearchKey ? '未找到匹配的用户' : '暂无用户数据' }} - - - - - - - 查询 - - 重置 - - 刷新 - - - - - - - 暂无用户数据,请先添加用户 - - - 共加载 {{ countData }} 个用户,请选择要查询的用户 - - - 当前选中: {{ getCurrentUserName() }} (ID: {{ queryParams.user_id }}) - + + + + 用户余额管理 + + {{ getCurrentUserName() }} + ID: {{ queryParams.user_id }} - + + 刷新数据 + + - - - - - - - - - - - - - - {{ getBalanceTypeName(balance.type) }} - {{ getBalanceTypeDesc(balance.type) }} - - - - - 当前余额 - - ¥ - {{ (balance.price/100).toFixed(2) || 0 }} - - - - - - 余额ID - {{ balance.id }} - - - 更新时间 - {{ formatDateTime(balance.UpdatedAt) }} - - - - - - 修改 - - - 记录 - - - - - - + + + + + {{ getBalanceTypeName(balance.type) }} + ID: {{ balance.id }} + + + + ¥ + {{ (balance.price / 100).toFixed(2) }} + + 更新于 {{ formatDateTime(balance.UpdatedAt) }} + + + - - - - 余额变动记录 - - 添加记录 - - - - - - - - - {{ row.BalanceId || '-' }} - - - - - - - - - - - {{ getBalanceTypeByRecordId(row.BalanceId) }} - - - ({{ row.Type }}) + + + 余额变动记录 + + + + + + + {{ getBalanceTypeByRecordId(row.BalanceId) }} + + + + + 增加 + 减少 + + + + + + {{ row.Change ? '+' : '-' }}¥{{ (row.Price / 100).toFixed(2) }} - - - - - - - - 增加 - - - - 减少 - - {{ row.Change }} - - - - - - {{ row.Change == true ? '+' : '-' }}¥{{ (row.Price/100).toFixed(2) || 0 }} - - - - - - - ¥{{ ((row.BalanceAfter || 0) / 100).toFixed(2) }} - - - - - - - {{ formatDateTime(row.CreatedAt) }} - - - - - - - + + + + + ¥{{ ((row.BalanceAfter || 0) / 100).toFixed(2) }} + + + + + + {{ formatDateTime(row.CreatedAt) }} + + + + + + + + + - - - - - - - - - - - + + + + - + ¥ @@ -335,45 +132,25 @@ - - - - + + + + - - - - - - + + - - - - - - ¥ - - - + 增加 减少 + + + ¥ + + @@ -387,71 +164,70 @@ - - - diff --git a/src/views/user/UserDetail.vue b/src/views/user/UserDetail.vue index 3784779..f9f456e 100644 --- a/src/views/user/UserDetail.vue +++ b/src/views/user/UserDetail.vue @@ -393,6 +393,10 @@ const Edit = EditIcon const route = useRoute() const router = useRouter() +// 引入tagsViewStore +import { useTagsViewStore } from '@/store/tagsViewStore' +const tagsViewStore = useTagsViewStore() + // 用户信息 const userInfo = ref({}) const loading = ref(false) @@ -546,6 +550,8 @@ const refreshData = () => { // 返回上一页 const goBack = () => { + // 关闭当前tab + tagsViewStore.delVisitedView(route) router.go(-1) } diff --git a/src/views/user/UserList.vue b/src/views/user/UserList.vue index f298ae6..d3c8083 100644 --- a/src/views/user/UserList.vue +++ b/src/views/user/UserList.vue @@ -129,6 +129,7 @@ 修改密码 修改用户组 实名信息 + 余额管理 登录记录 操作记录 模拟登录 @@ -512,12 +513,24 @@ const fetchUserList = async () => { const res = await getUserList(queryParams) console.log("获取用户列表:", res) if (res.data.code === 200) { - userList.value = res.data.data.data || [] + // 映射 API 返回的字段到组件使用的字段格式 + userList.value = (res.data.data.data || []).map(user => ({ + UserId: user.user_id, + UserName: user.user_name, + Phone: user.phone, + Email: user.email, + Sex: user.sex, + Age: user.age, + IsAdmin: user.is_admin, + CoverID: user.cover_id, + avatarUrl: user.cover || '', // 直接使用 cover 字段作为头像 URL + UserGroup: user.user_group, + RealName: user.real_name, + IsDeleted: user.is_deleted, + CreatedAt: user.created_at + })) console.log("用户列表:", userList.value) total.value = res.data.data.all_count || 0 - - // 为每个用户加载头像URL - await loadAvatarsForUsers() } } catch (error) { ElMessage.error('获取用户列表失败') @@ -526,26 +539,6 @@ const fetchUserList = async () => { } } -// 为用户列表加载头像URL -const loadAvatarsForUsers = async () => { - const promises = userList.value.map(async (user) => { - if (user.CoverID) { - try { - const res = await getFileDetail({ file_id: user.CoverID }) - if (res.data.code === 200) { - user.avatarUrl = res.data.data.url - } - } catch (error) { - console.error('加载头像失败:', error) - user.avatarUrl = '' - } - } else { - user.avatarUrl = '' - } - }) - await Promise.all(promises) -} - // 查询用户列表 const handleQuery = () => { queryParams.page = 1 @@ -676,6 +669,9 @@ const handleCommand = (command, row) => { case 'realname': handleRealnameModify(row) break + case 'balance': + handleBalanceManage(row) + break case 'loginHistory': handleLoginHistory(row) break @@ -691,6 +687,14 @@ const handleCommand = (command, row) => { } } +// 余额管理 +const handleBalanceManage = (row) => { + router.push({ + path: '/user/balance', + query: { user_id: row.UserId } + }) +} + // 模拟登录 const handleSimulateLogin = async (row) => {
{{ userSearchKey ? '未找到匹配的用户' : '暂无用户数据' }}