From c6be29d756ac51860c45eacaacd89b259ddec250 Mon Sep 17 00:00:00 2001 From: Boen_Shi Date: Thu, 18 Jun 2026 23:16:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=B7=A5=E5=8D=95):=20=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E5=B7=A5=E5=8D=95=E7=B3=BB=E7=BB=9F=E7=9A=84=E7=BC=96=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components.d.ts | 4 + src/api/auth.ts | 1 + src/api/tickets.ts | 31 +++ src/layouts/MainLayout.vue | 2 + src/pages/LoginPage.vue | 10 +- src/pages/TicketsPage.vue | 477 +++++++++++++++++++++++++++++++++++++ src/pages/UsersPage.vue | 20 +- src/router/index.ts | 1 + 8 files changed, 543 insertions(+), 3 deletions(-) create mode 100644 src/api/tickets.ts create mode 100644 src/pages/TicketsPage.vue diff --git a/components.d.ts b/components.d.ts index 1df8123..efcc8dd 100644 --- a/components.d.ts +++ b/components.d.ts @@ -15,6 +15,7 @@ declare module 'vue' { ElAvatar: typeof import('element-plus/es')['ElAvatar'] ElButton: typeof import('element-plus/es')['ElButton'] ElCard: typeof import('element-plus/es')['ElCard'] + ElCascader: typeof import('element-plus/es')['ElCascader'] ElCascaderPanel: typeof import('element-plus/es')['ElCascaderPanel'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] ElCollapse: typeof import('element-plus/es')['ElCollapse'] @@ -46,6 +47,9 @@ declare module 'vue' { ElTabPane: typeof import('element-plus/es')['ElTabPane'] ElTabs: typeof import('element-plus/es')['ElTabs'] ElTag: typeof import('element-plus/es')['ElTag'] + ElTimeline: typeof import('element-plus/es')['ElTimeline'] + ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem'] + ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElUpload: typeof import('element-plus/es')['ElUpload'] HelloWorld: typeof import('./src/components/HelloWorld.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] diff --git a/src/api/auth.ts b/src/api/auth.ts index 3352b3a..7a7b710 100644 --- a/src/api/auth.ts +++ b/src/api/auth.ts @@ -18,6 +18,7 @@ interface ApplyAccountPayload { phone: string password: string password_confirmation: string + application_note?: string } interface MeData { diff --git a/src/api/tickets.ts b/src/api/tickets.ts new file mode 100644 index 0000000..d8dd66a --- /dev/null +++ b/src/api/tickets.ts @@ -0,0 +1,31 @@ +import request from '@/axios' + +export const ticketsApi = { + list(params: Record = {}) { + return request.get('/tickets', { params }) + }, + detail(id: number) { + return request.get(`/tickets/${id}`) + }, + create(data: Record) { + return request.post('/tickets', data) + }, + update(id: number, data: Record) { + return request.put(`/tickets/${id}`, data) + }, + reply(id: number, content: string) { + return request.post(`/tickets/${id}/messages`, { content }) + }, + categories(params: Record = {}) { + return request.get('/ticket-categories', { params }) + }, + createCategory(data: Record) { + return request.post('/ticket-categories', data) + }, + updateCategory(id: number, data: Record) { + return request.put(`/ticket-categories/${id}`, data) + }, + removeCategory(id: number) { + return request.delete(`/ticket-categories/${id}`) + }, +} diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index 225036f..0bdfb32 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -36,6 +36,7 @@ 角色管理 权限管理 服务器资源 + 工单系统 堡垒机账号 访问日志 OAuth 客户端 @@ -62,6 +63,7 @@ const route = useRoute() const router = useRouter() const authStore = useAuthStore() const { hasPermission } = authStore +const canAccessTickets = computed(() => hasPermission('tickets.use') || hasPermission('platform.tickets.view') || hasPermission('platform.tickets.manage')) const siteTitleConfig = useConfigKey(CONFIG_KEY_SITE_TITLE, DEFAULT_SITE_TITLE) const siteTitle = computed(() => (siteTitleConfig.value || DEFAULT_SITE_TITLE).trim() || DEFAULT_SITE_TITLE) diff --git a/src/pages/LoginPage.vue b/src/pages/LoginPage.vue index b98d7c2..2d4fe10 100644 --- a/src/pages/LoginPage.vue +++ b/src/pages/LoginPage.vue @@ -63,6 +63,9 @@ + + +