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:
@@ -0,0 +1,49 @@
|
||||
// API Key 管理(对齐 PC /developer/apikeys,基址走 websopy-api)
|
||||
import { get, post, put, del } from '@/utils/request'
|
||||
import { WebsopyBaseUrl } from '@/config/app'
|
||||
|
||||
const BASE = '/app/apikey'
|
||||
|
||||
export interface AppApiKey {
|
||||
id: number
|
||||
name: string
|
||||
apiKey: string
|
||||
keyPrefix?: string
|
||||
status: number // 0正常 1禁用
|
||||
scopes?: string
|
||||
expireTime?: string
|
||||
lastUsedAt?: string
|
||||
usageCount?: number
|
||||
remark?: string
|
||||
createTime?: string
|
||||
}
|
||||
|
||||
export async function pageAppApiKey(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 createAppApiKey(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 updateAppApiKeyStatus(id: number, status: number) {
|
||||
const res = await put<any>(`${BASE}/${id}/status?status=${status}`, {}, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.message
|
||||
return Promise.reject(new Error(res?.message || '操作失败'))
|
||||
}
|
||||
|
||||
export async function removeAppApiKey(id: number) {
|
||||
const res = await del<any>(`${BASE}/${id}`, {}, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.message
|
||||
return Promise.reject(new Error(res?.message || '删除失败'))
|
||||
}
|
||||
|
||||
export async function getAppApiKeyStats() {
|
||||
const res = await get<any>(`${BASE}/stats`, undefined, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '加载失败'))
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// 个性域名绑定(对齐 PC /admin/domain-bindings,基址走 websopy-api)
|
||||
import { get, post } from '@/utils/request'
|
||||
import { WebsopyBaseUrl } from '@/config/app'
|
||||
|
||||
const BASE = '/app/domain'
|
||||
|
||||
export interface AppDomain {
|
||||
id?: number
|
||||
tenantId?: number
|
||||
productId?: number
|
||||
domain?: string
|
||||
targetIp?: string
|
||||
recordType?: string
|
||||
status?: number // 0待解析 1校验中 2已生效 3已拒绝 4已停用
|
||||
dnsStatus?: number
|
||||
dnsIp?: string
|
||||
proxyConfigured?: number
|
||||
rejectReason?: string
|
||||
tenantName?: string
|
||||
createTime?: string
|
||||
}
|
||||
|
||||
/** 管理端列表 */
|
||||
export async function pageAppDomain(params: any) {
|
||||
const res = await get<any>(`${BASE}/admin/list`, params, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '加载失败'))
|
||||
}
|
||||
|
||||
export async function verifyDomain(id: number) {
|
||||
const res = await post<any>(`${BASE}/verify/${id}`, {}, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '校验失败'))
|
||||
}
|
||||
|
||||
export async function setProxy(id: number) {
|
||||
const res = await post<any>(`${BASE}/proxy/${id}`, {}, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '操作失败'))
|
||||
}
|
||||
|
||||
export async function activeDomain(id: number) {
|
||||
const res = await post<any>(`${BASE}/active/${id}`, {}, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '操作失败'))
|
||||
}
|
||||
|
||||
export async function rejectDomain(id: number, reason: string) {
|
||||
const res = await post<any>(`${BASE}/reject/${id}`, { reason }, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.message
|
||||
return Promise.reject(new Error(res?.message || '操作失败'))
|
||||
}
|
||||
|
||||
export async function disableDomain(id: number) {
|
||||
const res = await post<any>(`${BASE}/disable/${id}`, {}, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.message
|
||||
return Promise.reject(new Error(res?.message || '操作失败'))
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// 应用产品(对齐 PC /developer/apps 与 /admin 应用管理,基址走 websopy-api)
|
||||
import { get, post } from '@/utils/request'
|
||||
import { WebsopyBaseUrl } from '@/config/app'
|
||||
|
||||
const BASE = '/app/product'
|
||||
|
||||
export interface AppProduct {
|
||||
productId?: number
|
||||
productName?: string
|
||||
productCode?: string
|
||||
appType?: number
|
||||
description?: string
|
||||
logo?: string
|
||||
publishStatus?: string
|
||||
status?: number
|
||||
adminUrl?: string
|
||||
homeUrl?: string
|
||||
createTime?: string
|
||||
userId?: number
|
||||
tenantId?: number
|
||||
rejectReason?: string
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
/** 我的应用(创建者) */
|
||||
export async function getMyApps(params: any) {
|
||||
const res = await get<any>(`${BASE}/my/page`, params, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '加载失败'))
|
||||
}
|
||||
|
||||
/** 开发者应用列表 */
|
||||
export async function getDeveloperApps(params?: any) {
|
||||
const res = await get<any>(`${BASE}/list`, params, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '加载失败'))
|
||||
}
|
||||
|
||||
/** 创建应用 */
|
||||
export async function addAppProduct(data: any) {
|
||||
const res = await post<any>(`${BASE}/create`, data, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '创建失败'))
|
||||
}
|
||||
|
||||
/** 发布审核列表(管理端,publishStatus=pending_review) */
|
||||
export async function pagePublishReviews(params: any) {
|
||||
const res = await get<any>(`${BASE}/page`, { ...params, publishStatus: 'pending_review' }, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '加载失败'))
|
||||
}
|
||||
|
||||
/** 全部应用(管理端) */
|
||||
export async function pageAllApps(params: any) {
|
||||
const res = await get<any>(`${BASE}/page`, params, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '加载失败'))
|
||||
}
|
||||
|
||||
/** 审核通过 */
|
||||
export async function approvePublishReview(id: number) {
|
||||
const res = await post<any>(`${BASE}/approve/${id}`, {}, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.message
|
||||
return Promise.reject(new Error(res?.message || '操作失败'))
|
||||
}
|
||||
|
||||
/** 审核拒绝 */
|
||||
export async function rejectPublishReview(params: { productId: number; rejectReason: string }) {
|
||||
const res = await post<any>(
|
||||
`${BASE}/reject/${params.productId}?reason=${encodeURIComponent(params.rejectReason)}`,
|
||||
{},
|
||||
{ baseUrl: WebsopyBaseUrl }
|
||||
)
|
||||
if (res?.code === 0) return res.message
|
||||
return Promise.reject(new Error(res?.message || '操作失败'))
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
// 开发者权限申请 & Git 账号(对齐 PC /developer/requests、/git 与 /admin/git-review,基址走 websopy-api)
|
||||
import { get, post, put } from '@/utils/request'
|
||||
import { WebsopyBaseUrl } from '@/config/app'
|
||||
|
||||
const BASE = '/app/developer'
|
||||
|
||||
export interface PermissionRequest {
|
||||
id?: number
|
||||
userId?: number
|
||||
gitUsername?: string
|
||||
repo?: string
|
||||
repoName?: string
|
||||
reason?: string
|
||||
status?: string // pending / approved / rejected
|
||||
createTime?: string
|
||||
reviewedAt?: string
|
||||
reviewerName?: string
|
||||
rejectReason?: string
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export interface GitAccount {
|
||||
id?: number
|
||||
userId?: number
|
||||
username?: string
|
||||
email?: string
|
||||
status?: string // pending / verified / rejected
|
||||
verificationNote?: string
|
||||
tenantId?: number
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
// ============ 权限申请 ============
|
||||
export async function pagePermissionRequests(params: any) {
|
||||
const res = await get<any>(`${BASE}/permission-requests`, params, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '加载失败'))
|
||||
}
|
||||
|
||||
export async function getPermissionRequestStats() {
|
||||
const res = await get<any>(`${BASE}/permission-requests/stats`, undefined, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '加载失败'))
|
||||
}
|
||||
|
||||
export async function getAvailableRepos() {
|
||||
const res = await get<any>(`${BASE}/available-repos`, undefined, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '加载失败'))
|
||||
}
|
||||
|
||||
export async function submitPermissionRequest(data: any) {
|
||||
const res = await post<any>(`${BASE}/permission-requests`, data, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '提交失败'))
|
||||
}
|
||||
|
||||
export async function approvePermissionRequest(id: number) {
|
||||
const res = await put<any>(`${BASE}/permission-requests/${id}/approve`, {}, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.message
|
||||
return Promise.reject(new Error(res?.message || '操作失败'))
|
||||
}
|
||||
|
||||
export async function rejectPermissionRequest(id: number, reason: string) {
|
||||
const res = await put<any>(`${BASE}/permission-requests/${id}/reject`, { reason }, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.message
|
||||
return Promise.reject(new Error(res?.message || '操作失败'))
|
||||
}
|
||||
|
||||
// ============ Git 账号 ============
|
||||
export async function saveGitAccount(data: any) {
|
||||
const res = await post<any>(`${BASE}/git-account`, data, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '提交失败'))
|
||||
}
|
||||
|
||||
export async function getGitAccountStatus() {
|
||||
const res = await get<any>(`${BASE}/git-account/status`, undefined, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '加载失败'))
|
||||
}
|
||||
|
||||
export async function getGiteaInfo() {
|
||||
const res = await get<any>(`${BASE}/gitea-info`, undefined, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '加载失败'))
|
||||
}
|
||||
|
||||
// ============ 管理端 ============
|
||||
export async function pageGitAccounts(params: any) {
|
||||
const res = await get<any>(`${BASE}/git-accounts`, params, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.data
|
||||
return Promise.reject(new Error(res?.message || '加载失败'))
|
||||
}
|
||||
|
||||
export async function approveGitAccount(id: number) {
|
||||
const res = await put<any>(`${BASE}/git-accounts/${id}/approve`, {}, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.message
|
||||
return Promise.reject(new Error(res?.message || '操作失败'))
|
||||
}
|
||||
|
||||
export async function rejectGitAccount(id: number, reason: string) {
|
||||
const res = await put<any>(`${BASE}/git-accounts/${id}/reject`, { reason }, { baseUrl: WebsopyBaseUrl })
|
||||
if (res?.code === 0) return res.message
|
||||
return Promise.reject(new Error(res?.message || '操作失败'))
|
||||
}
|
||||
@@ -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 || '加载失败'))
|
||||
}
|
||||
@@ -115,6 +115,20 @@ export async function updateUser(data: User) {
|
||||
return Promise.reject(new Error(res.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将用户标记为开发者(审核通过时调用,直接更新用户标记位,不新增角色)
|
||||
*/
|
||||
export async function setUserDeveloper(userId: number) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
SERVER_API_URL + '/system/user/developer/' + userId,
|
||||
{}
|
||||
);
|
||||
if (res.code === 0) {
|
||||
return res.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user