chore: 初始化平台管理端

This commit is contained in:
msumshk
2026-01-29 04:21:09 +00:00
commit 914dcc4166
533 changed files with 104838 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
import request from '@/utils/http'
const GROUP_BASE_URL = '/api/admin/v1/dictionary/groups'
export function getGroups(params?: Api.Dictionary.DictionaryGroupQueryParams) {
return request.get<Api.Common.PageResult<Api.Dictionary.DictionaryGroupDto>>({
url: GROUP_BASE_URL,
params
})
}
export function getGroupById(groupId: string) {
return request.get<Api.Dictionary.DictionaryGroupDto>({
url: `${GROUP_BASE_URL}/${groupId}`
})
}
export function createGroup(data: Api.Dictionary.CreateDictionaryGroupRequest) {
return request.post<Api.Dictionary.DictionaryGroupDto>({
url: GROUP_BASE_URL,
data
})
}
export function updateGroup(groupId: string, data: Api.Dictionary.UpdateDictionaryGroupRequest) {
return request.put<Api.Dictionary.DictionaryGroupDto>({
url: `${GROUP_BASE_URL}/${groupId}`,
data
})
}
export function deleteGroup(groupId: string) {
return request.del<void>({
url: `${GROUP_BASE_URL}/${groupId}`
})
}
export function exportGroup(
groupId: string,
format: Api.Dictionary.DictionaryExportRequest['format']
) {
return request.post<Blob>({
url: `${GROUP_BASE_URL}/${groupId}/export`,
data: { format },
responseType: 'blob'
})
}
export function importGroup(
groupId: string,
payload: {
file: File
conflictMode?: Api.Dictionary.ConflictResolutionMode | string
format?: 'csv' | 'json'
}
) {
const formData = new FormData()
formData.append('File', payload.file)
if (payload.conflictMode) {
formData.append('ConflictMode', String(payload.conflictMode))
}
if (payload.format) {
formData.append('Format', payload.format)
}
return request.post<Api.Dictionary.DictionaryImportResultDto>({
url: `${GROUP_BASE_URL}/${groupId}/import`,
data: formData
})
}

View File

@@ -0,0 +1,33 @@
import request from '@/utils/http'
const GROUP_BASE_URL = '/api/admin/v1/dictionary/groups'
export function getItems(groupId: string) {
return request.get<Api.Dictionary.DictionaryItemDto[]>({
url: `${GROUP_BASE_URL}/${groupId}/items`
})
}
export function createItem(groupId: string, data: Api.Dictionary.CreateDictionaryItemRequest) {
return request.post<Api.Dictionary.DictionaryItemDto>({
url: `${GROUP_BASE_URL}/${groupId}/items`,
data
})
}
export function updateItem(
groupId: string,
itemId: string,
data: Api.Dictionary.UpdateDictionaryItemRequest
) {
return request.put<Api.Dictionary.DictionaryItemDto>({
url: `${GROUP_BASE_URL}/${groupId}/items/${itemId}`,
data
})
}
export function deleteItem(groupId: string, itemId: string) {
return request.del<void>({
url: `${GROUP_BASE_URL}/${groupId}/items/${itemId}`
})
}

View File

@@ -0,0 +1,70 @@
import request from '@/utils/http'
const LABEL_OVERRIDE_BASE_URL = '/api/admin/v1/dictionary/label-overrides'
// ==================== 租户端 API ====================
/**
* 获取当前租户的标签覆盖列表
*/
export function getTenantLabelOverrides() {
return request.get<Api.Dictionary.LabelOverrideDto[]>({
url: `${LABEL_OVERRIDE_BASE_URL}/tenant`
})
}
/**
* 租户创建/更新标签覆盖
*/
export function upsertTenantLabelOverride(data: Api.Dictionary.UpsertLabelOverrideRequest) {
return request.post<Api.Dictionary.LabelOverrideDto>({
url: `${LABEL_OVERRIDE_BASE_URL}/tenant`,
data
})
}
/**
* 租户删除标签覆盖
*/
export function deleteTenantLabelOverride(dictionaryItemId: string) {
return request.del<void>({
url: `${LABEL_OVERRIDE_BASE_URL}/tenant/${dictionaryItemId}`
})
}
// ==================== 平台端 API ====================
/**
* 获取指定租户的所有标签覆盖(平台管理员用)
*/
export function getPlatformLabelOverrides(
targetTenantId: string,
overrideType?: Api.Dictionary.OverrideType
) {
return request.get<Api.Dictionary.LabelOverrideDto[]>({
url: `${LABEL_OVERRIDE_BASE_URL}/platform/${targetTenantId}`,
params: { overrideType }
})
}
/**
* 平台强制覆盖租户字典项的标签
*/
export function upsertPlatformLabelOverride(
targetTenantId: string,
data: Api.Dictionary.UpsertLabelOverrideRequest
) {
return request.post<Api.Dictionary.LabelOverrideDto>({
url: `${LABEL_OVERRIDE_BASE_URL}/platform/${targetTenantId}`,
data
})
}
/**
* 平台删除对租户的强制覆盖
*/
export function deletePlatformLabelOverride(targetTenantId: string, dictionaryItemId: string) {
return request.del<void>({
url: `${LABEL_OVERRIDE_BASE_URL}/platform/${targetTenantId}/${dictionaryItemId}`
})
}

View File

@@ -0,0 +1,35 @@
import request from '@/utils/http'
const METRICS_BASE_URL = '/api/admin/v1/dictionary/metrics'
export function getCacheStats(timeRange: '1h' | '24h' | '7d' = '1h') {
return request.get<{
totalHits: number
totalMisses: number
hitRatio: number
hitsByLevel: { l1: number; l2: number }
missesByLevel: { l1: number; l2: number }
averageQueryDurationMs: number
topQueriedDictionaries: Array<{ code: string; queryCount: number }>
}>({
url: `${METRICS_BASE_URL}/cache-stats`,
params: { timeRange }
})
}
export function getInvalidationEvents(params: {
page: number
pageSize: number
startDate?: string
endDate?: string
}) {
return request.get<Api.Common.PageResult<Api.Dictionary.CacheInvalidationLogDto>>({
url: `${METRICS_BASE_URL}/invalidation-events`,
params: {
page: params.page,
pageSize: params.pageSize,
startDate: params.startDate,
endDate: params.endDate
}
})
}

View File

@@ -0,0 +1,49 @@
import request from '@/utils/http'
const OVERRIDE_BASE_URL = '/api/admin/v1/dictionary/overrides'
export function getOverrides() {
return request.get<Api.Dictionary.OverrideConfigDto[]>({
url: OVERRIDE_BASE_URL
})
}
export function getOverride(groupCode: string) {
return request.get<Api.Dictionary.OverrideConfigDto>({
url: `${OVERRIDE_BASE_URL}/${groupCode}`
})
}
export function enableOverride(groupCode: string) {
return request.post<Api.Dictionary.OverrideConfigDto>({
url: `${OVERRIDE_BASE_URL}/${groupCode}/enable`,
data: {}
})
}
export function disableOverride(groupCode: string) {
return request.post<void>({
url: `${OVERRIDE_BASE_URL}/${groupCode}/disable`,
data: {}
})
}
export function updateHiddenItems(
groupCode: string,
hiddenItemIds: Api.Dictionary.DictionaryOverrideHiddenItemsRequest['hiddenItemIds']
) {
return request.put<Api.Dictionary.OverrideConfigDto>({
url: `${OVERRIDE_BASE_URL}/${groupCode}/hidden-items`,
data: { hiddenItemIds }
})
}
export function updateSortOrder(
groupCode: string,
sortOrder: Api.Dictionary.DictionaryOverrideSortOrderRequest['sortOrder']
) {
return request.put<Api.Dictionary.OverrideConfigDto>({
url: `${OVERRIDE_BASE_URL}/${groupCode}/sort-order`,
data: { sortOrder }
})
}

View File

@@ -0,0 +1,27 @@
import request from '@/utils/http'
const QUERY_BASE_URL = '/api/admin/v1/dictionaries'
const normalizeCode = (code: string) => code.trim().toLowerCase()
export async function getDictionary(code: string) {
const result = await batchGetDictionaries([code])
return result[code] ?? []
}
export async function batchGetDictionaries(codes: string[]) {
if (!codes.length) return {}
const result = await request.post<Record<string, Api.Dictionary.DictionaryItemDto[]>>({
url: `${QUERY_BASE_URL}/batch`,
data: { codes }
})
const mapped: Record<string, Api.Dictionary.DictionaryItemDto[]> = {}
codes.forEach((code) => {
const key = normalizeCode(code)
mapped[code] = result[key] ?? result[code] ?? []
})
return mapped
}