初始化2

This commit is contained in:
2026-04-08 17:10:58 +08:00
commit 4986d90eb9
532 changed files with 112617 additions and 0 deletions

68
app/api/ticket/index.ts Normal file
View File

@@ -0,0 +1,68 @@
import request from '@/utils/request'
import type {
Ticket,
TicketReply,
TicketSubmitForm,
TicketReplyForm,
TicketAssignForm,
TicketStatusForm,
TicketQueryParams,
TicketStats,
} from './model'
const BASE = '/api/app/ticket'
/** 分页查询工单列表(客户端:查自己的) */
export async function getMyTickets(params: TicketQueryParams) {
return request.get<{ list: Ticket[]; count: number }>(`${BASE}/my`, { params })
}
/** 分页查询工单列表(技术人员:查所有/分配给自己的) */
export async function getAllTickets(params: TicketQueryParams) {
return request.get<{ list: Ticket[]; count: number }>(`${BASE}/list`, { params })
}
/** 获取工单详情 */
export async function getTicketDetail(ticketId: number) {
return request.get<Ticket>(`${BASE}/${ticketId}`)
}
/** 提交工单 */
export async function submitTicket(data: TicketSubmitForm) {
return request.post<Ticket>(`${BASE}/submit`, data)
}
/** 更新工单状态(技术人员) */
export async function updateTicketStatus(data: TicketStatusForm) {
return request.put(`${BASE}/status`, data)
}
/** 分配工单给技术人员(管理员) */
export async function assignTicket(data: TicketAssignForm) {
return request.put(`${BASE}/assign`, data)
}
/** 关闭工单(提交人) */
export async function closeTicket(ticketId: number) {
return request.put(`${BASE}/${ticketId}/close`)
}
/** 获取工单回复列表 */
export async function getTicketReplies(ticketId: number) {
return request.get<TicketReply[]>(`${BASE}/${ticketId}/replies`)
}
/** 提交工单回复 */
export async function replyTicket(data: TicketReplyForm) {
return request.post(`${BASE}/reply`, data)
}
/** 获取工单统计 */
export async function getTicketStats(params?: { productId?: number }) {
return request.get<TicketStats>(`${BASE}/stats`, { params })
}
/** 获取技术人员列表(用于分配) */
export async function getTechStaffList() {
return request.get<{ userId: number; nickname: string; avatar: string }[]>(`${BASE}/staff-list`)
}

View File

@@ -0,0 +1,103 @@
/** 工单优先级 */
export type TicketPriority = 'low' | 'normal' | 'high' | 'urgent'
/** 工单状态 */
export type TicketStatus = 'pending' | 'assigned' | 'processing' | 'resolved' | 'closed' | 'rejected'
/** 工单分类 */
export type TicketCategory = 'bug' | 'feature' | 'consultation' | 'complaint' | 'other'
/** 工单列表项 */
export interface Ticket {
ticketId: number
ticketNo: string // 工单编号 TK-202403xxxxxx
title: string
content: string
productId: number // 关联应用ID
productName?: string // 应用名称(前端展示用)
category: TicketCategory
priority: TicketPriority
status: TicketStatus
attachments?: string[] // 附件URL列表
// 提交方
submitUserId: number
submitUserName?: string
submitUserAvatar?: string
// 分配方
assigneeId?: number
assigneeName?: string
assigneeAvatar?: string
// 时间
createTime: string
updateTime: string
resolvedTime?: string
closedTime?: string
// 回复数
replyCount: number
// 是否已读(对当前用户)
hasUnread?: boolean
}
/** 工单回复 */
export interface TicketReply {
replyId: number
ticketId: number
content: string
attachments?: string[]
userId: number
userName?: string
userAvatar?: string
isStaff: boolean // 是否是客服/技术人员
createTime: string
}
/** 提交工单表单 */
export interface TicketSubmitForm {
title: string
content: string
productId: number
category: TicketCategory
priority: TicketPriority
attachments?: string[]
}
/** 工单回复表单 */
export interface TicketReplyForm {
ticketId: number
content: string
attachments?: string
}
/** 分配工单表单 */
export interface TicketAssignForm {
ticketId: number
assigneeId: number
}
/** 更新状态表单 */
export interface TicketStatusForm {
ticketId: number
status: TicketStatus
remark?: string
}
/** 工单查询参数 */
export interface TicketQueryParams {
productId?: number
status?: TicketStatus
category?: TicketCategory
priority?: TicketPriority
assigneeId?: number
keywords?: string
page?: number
limit?: number
}
/** 工单统计 */
export interface TicketStats {
total: number
pending: number
processing: number
resolved: number
closed: number
}