refactor(user): 将VIP身份统一改为开发者标记

- 审核通过时不再新增角色,而是更新用户isDeveloper布尔标记
- 后端UserService新增markAsDeveloper方法,通过updateById设置isDeveloper
- UserController新增PUT接口更新开发者标记,权限使用sys:userRole:save
- 前端api新增setUserDeveloper调用新的审核接口
- vip-review页面移除角色相关代码,改为调用setUserDeveloper方法
- 约定开发者身份即sys_user.is_developer字段,不再依赖角色表记录
- app.config.ts追加开发者中心与平台管理相关页面路由
- 新增开发者中心、平台管理的多个API模块(apikey、appProduct、appDomain、developer请求等)
- 添加公共工具方法和复用组件用于开发者中心及平台管理功能
- 统一品牌名称为“威数谱软件”,更新文案及界面展现一致性
This commit is contained in:
2026-07-22 14:57:03 +08:00
parent 2ea16e22cf
commit 39d3b59434
24 changed files with 2015 additions and 95 deletions
+82
View File
@@ -0,0 +1,82 @@
// 工单(对齐 PC /developer/tickets 与 /admin/tickets,基址走 websopy-api)
import { get, post } from '@/utils/request'
import { WebsopyBaseUrl } from '@/config/app'
const BASE = '/app/ticket'
export interface Ticket {
ticketId?: number
ticketNo?: string
title?: string
productId?: number
productName?: string
status?: string
priority?: string
category?: string
assigneeName?: string
submitUserName?: string
replyCount?: number
hasUnread?: boolean
createTime?: string
[key: string]: any
}
export async function getMyTickets(params: any) {
const res = await get<any>(`${BASE}/my`, params, { baseUrl: WebsopyBaseUrl })
if (res?.code === 0) return res.data
return Promise.reject(new Error(res?.message || '加载失败'))
}
export async function getAllTickets(params: any) {
const res = await get<any>(BASE, params, { baseUrl: WebsopyBaseUrl })
if (res?.code === 0) return res.data
return Promise.reject(new Error(res?.message || '加载失败'))
}
export async function getTicketDetail(id: number) {
const res = await get<any>(`${BASE}/${id}`, undefined, { baseUrl: WebsopyBaseUrl })
if (res?.code === 0) return res.data
return Promise.reject(new Error(res?.message || '加载失败'))
}
export async function getTicketReplies(id: number) {
const res = await get<any>(`${BASE}/${id}/replies`, undefined, { baseUrl: WebsopyBaseUrl })
if (res?.code === 0) return res.data
return Promise.reject(new Error(res?.message || '加载失败'))
}
export async function submitTicket(data: any) {
const res = await post<any>(BASE, data, { baseUrl: WebsopyBaseUrl })
if (res?.code === 0) return res.data
return Promise.reject(new Error(res?.message || '提交失败'))
}
export async function replyTicket(id: number, content: string) {
const res = await post<any>(`${BASE}/${id}/reply`, { content }, { baseUrl: WebsopyBaseUrl })
if (res?.code === 0) return res.data
return Promise.reject(new Error(res?.message || '回复失败'))
}
export async function updateTicketStatus(id: number, status: string) {
const res = await post<any>(`${BASE}/${id}/status`, { status }, { baseUrl: WebsopyBaseUrl })
if (res?.code === 0) return res.message
return Promise.reject(new Error(res?.message || '操作失败'))
}
export async function assignTicket(id: number, assigneeId: number) {
const res = await post<any>(`${BASE}/${id}/assign`, { assigneeId }, { baseUrl: WebsopyBaseUrl })
if (res?.code === 0) return res.message
return Promise.reject(new Error(res?.message || '操作失败'))
}
export async function getTicketStats() {
const res = await get<any>(`${BASE}/stats`, undefined, { baseUrl: WebsopyBaseUrl })
if (res?.code === 0) return res.data
return Promise.reject(new Error(res?.message || '加载失败'))
}
export async function getTechStaffList() {
const res = await get<any>(`${BASE}/staffs`, undefined, { baseUrl: WebsopyBaseUrl })
if (res?.code === 0) return res.data
return Promise.reject(new Error(res?.message || '加载失败'))
}