refactor API export

This commit is contained in:
Timi
2026-08-21 16:34:39 +08:00
parent 175838f7c5
commit 98ab992728
11 changed files with 335 additions and 399 deletions
+6 -9
View File
@@ -1,5 +1,10 @@
<template>
<div class="root">
<pass-time-label :timestamp="1786694772700" underline />
<br>
<pass-time-label :timestamp="1786694772700" only-date />
<br>
<pass-time-label :timestamp="1786694772700" only-time />
<copyright />
</div>
</template>
@@ -7,17 +12,9 @@
<script lang="ts" setup>
import {axios, Copyright, SettingMapper} from "timi-web";
import CommonAPI from "../src/api/CommonAPI";
import PassTimeLabel from "../src/components/passtime-label/index.vue";
onMounted(async () => {
const result = await CommonAPI.settingMap({
"SYSTEM": [
"SETTING_TTL"
]
});
SettingMapper.appendSettingMap(result);
console.log(SettingMapper.getValue("SYSTEM", "SETTING_TTL").value);
})
</script>
+21 -23
View File
@@ -1,27 +1,25 @@
import type { Article } from "../types";
import { axios } from "./BaseAPI";
/**
* 获取文章
*
* @param id 文章 ID
* @returns 文章数据
*/
async function view(id: string): Promise<Article> {
return axios.get(`/article/${id}`);
}
/**
* 喜欢文章,后端有限调用,1240ms 一次
*
* @param id 文章 ID
* @returns 最新喜欢数量
*/
async function like(id: string): Promise<number> {
return axios.get(`/article/like/${id}`);
}
export default {
view,
like
export const ArticleAPI = {
/**
* 获取文章
*
* @param id 文章 ID
* @returns 文章数据
*/
async view(id: string): Promise<Article> {
return axios.get(`/article/${id}`);
},
/**
* 喜欢文章,后端有限调用,1240ms 一次
*
* @param id 文章 ID
* @returns 最新喜欢数量
*/
async like(id: string): Promise<number> {
return axios.get(`/article/like/${id}`);
}
};
export default ArticleAPI;
+51 -49
View File
@@ -4,55 +4,57 @@ import CommonAPI from "./CommonAPI";
const BASE_URI = "/attach";
/**
* 上传临时附件
*
* @param file 文件或文件列表
* @param ttl 有效期
* @returns 临时附件列表
*/
async function upload(file: File | File[], ttl?: string): Promise<TempFile[]> {
const formData = new FormData();
const fileList = Array.isArray(file) ? file : [file];
for (const item of fileList) {
formData.append("file", item);
}
if (ttl) {
formData.append("ttl", ttl);
}
return await axios.post(`${BASE_URI}/temp/upload`, formData);
}
/**
* 按业务差分更新附件
*
* @param req 更新请求
*/
async function updateByBizId(req: BizIdUpdate): Promise<void> {
return await axios.post(`${BASE_URI}/update/biz/id`, req);
}
/**
* 按业务查询附件列表
*
* @param bizType 业务类型
* @param bizId 业务 ID
* @param attachTypeList 附件类型列表
*/
async function listByBizId(bizType: string, bizId: string, attachTypeList?: string[]): Promise<Attachment[]> {
return await axios.get(`${BASE_URI}/list/biz/id`, {
params: {
bizType,
bizId,
attachTypeList
export const AttachmentAPI = {
/**
* 上传临时附件
*
* @param file 文件或文件列表
* @param ttl 有效期
* @returns 临时附件列表
*/
async upload(file: File | File[], ttl?: string): Promise<TempFile[]> {
const formData = new FormData();
const fileList = Array.isArray(file) ? file : [file];
for (const item of fileList) {
formData.append("file", item);
}
});
}
if (ttl) {
formData.append("ttl", ttl);
}
return await axios.post(`${BASE_URI}/temp/upload`, formData);
},
/**
* 按业务差分更新附件
*
* @param req 更新请求
*/
async updateByBizId(req: BizIdUpdate): Promise<void> {
return await axios.post(`${BASE_URI}/update/biz/id`, req);
},
/**
* 按业务查询附件列表
*
* @param bizType 业务类型
* @param bizId 业务 ID
* @param attachTypeList 附件类型列表
*/
async listByBizId(bizType: string, bizId: string, attachTypeList?: string[]): Promise<Attachment[]> {
return await axios.get(`${BASE_URI}/list/biz/id`, {
params: {
bizType,
bizId,
attachTypeList
}
});
},
export default {
upload,
updateByBizId,
listByBizId,
getReadURL: CommonAPI.getAttachmentReadAPI,
getTempReadURL: CommonAPI.getAttachmentTempReadAPI
getReadURL(id: string): string {
return CommonAPI.getAttachmentReadAPI(id);
},
getTempReadURL(id: string): string {
return CommonAPI.getAttachmentTempReadAPI(id);
}
};
export default AttachmentAPI;
+9 -11
View File
@@ -3,15 +3,13 @@ import { axios } from "./BaseAPI";
const BASE_URI = "/comment";
async function page(page: Page<Comment>): Promise<PageResult<Comment>> {
return axios.post(`${BASE_URI}/list`, page);
}
async function create(captchaData: CaptchaData<Comment>): Promise<void> {
return axios.post(`${BASE_URI}/create`, captchaData);
}
export default {
page,
create,
export const CommentAPI = {
async page(page: Page<Comment>): Promise<PageResult<Comment>> {
return axios.post(`${BASE_URI}/list`, page);
},
async create(captchaData: CaptchaData<Comment>): Promise<void> {
return axios.post(`${BASE_URI}/create`, captchaData);
}
};
export default CommentAPI;
+31 -33
View File
@@ -9,39 +9,37 @@ function getBaseURI(): string {
return baseURL.replace(/\/$/, "");
}
const getCaptchaAPI = () => `${getBaseURI()}/captcha`;
async function captcha(width: number, height: number): Promise<CaptchaResult> {
return await axios.get(`/captcha?width=${width}&height=${height}`);
}
const getAttachmentReadAPI = (id: string) => `${getBaseURI()}/attach/read/${id}`;
const getAttachmentTempReadAPI = (id: string) => `${getBaseURI()}/attach/temp/read?id=${id}`;
async function settingMap(map: Record<string, string[]>): Promise<Map<string, Map<string, Setting>>> {
const raw = await axios.post("/setting/map", map);
const moduleMap = new Map<string, Map<string, Setting>>();
if (!raw || typeof raw !== "object") {
export const CommonAPI = {
getCaptchaAPI(): string {
return `${getBaseURI()}/captcha`;
},
async captcha(width: number, height: number): Promise<CaptchaResult> {
return await axios.get(`/captcha?width=${width}&height=${height}`);
},
getAttachmentReadAPI(id: string): string {
return `${getBaseURI()}/attach/read/${id}`;
},
getAttachmentTempReadAPI(id: string): string {
return `${getBaseURI()}/attach/temp/read?id=${id}`;
},
async settingMap(map: Record<string, string[]>): Promise<Map<string, Map<string, Setting>>> {
const raw = await axios.post("/setting/map", map);
const moduleMap = new Map<string, Map<string, Setting>>();
if (!raw || typeof raw !== "object") {
return moduleMap;
}
for (const [module, settingRawMap] of Object.entries(raw as Record<string, unknown>)) {
if (!settingRawMap || typeof settingRawMap !== "object") {
continue;
}
const settingMap = new Map<string, Setting>();
for (const [key, setting] of Object.entries(settingRawMap as Record<string, Setting>)) {
settingMap.set(key, setting);
}
moduleMap.set(module, settingMap);
}
return moduleMap;
}
for (const [module, settingRawMap] of Object.entries(raw as Record<string, unknown>)) {
if (!settingRawMap || typeof settingRawMap !== "object") {
continue;
}
const settingMap = new Map<string, Setting>();
for (const [key, setting] of Object.entries(settingRawMap as Record<string, Setting>)) {
settingMap.set(key, setting);
}
moduleMap.set(module, settingMap);
}
return moduleMap;
}
export default {
getCaptchaAPI,
captcha,
getAttachmentReadAPI,
getAttachmentTempReadAPI,
settingMap
};
export default CommonAPI;
+6 -6
View File
@@ -3,10 +3,10 @@ import { axios } from "./BaseAPI";
const BASE_URI = "/git/developer";
async function get(): Promise<Developer> {
return axios.post(`${BASE_URI}`);
}
export default {
get
export const DeveloperAPI = {
async get(): Promise<Developer> {
return axios.post(`${BASE_URI}`);
}
};
export default DeveloperAPI;
+40 -40
View File
@@ -1,51 +1,51 @@
import { axios } from "./BaseAPI";
import type { NotifyDetail, Page, PageResult } from "../types";
import type { CaptchaData, Notify, NotifyDetail, Page, PageResult } from "../types";
const BASE_URI = "/notify/internal";
/** 查询当前用户的站内通知详情。 */
async function internalDetail(id: string): Promise<NotifyDetail> {
return await axios.post(`${BASE_URI}/detail`, undefined, {
params: { id }
});
}
export const NotifyAPI = {
/** 查询当前用户的站内通知。 */
async function listInternal(page?: Page<NotifyDetail>, unreadOnly = false): Promise<PageResult<NotifyDetail>> {
return await axios.post(`${BASE_URI}/internal`, page, {
params: { unreadOnly }
});
}
async smsSend(captchaData: CaptchaData<Notify>) {
return await axios.post("/sms/captcha/create", captchaData);
},
/** 查询当前用户未读站内通知数量。 */
async function countUnreadInternal(): Promise<number> {
return await axios.post(`${BASE_URI}/unread/count`);
}
/** 查询当前用户站内通知详情。 */
async internalDetail(id: string): Promise<NotifyDetail> {
return await axios.post(`${BASE_URI}/detail`, undefined, {
params: { id }
});
},
/** 标记当前用户的一条站内通知已读。 */
async function markInternalRead(id: string): Promise<void> {
await axios.post(`${BASE_URI}/read`, undefined, {
params: { id }
});
}
/** 查询当前用户的站内通知。 */
async listInternal(page?: Page<NotifyDetail>, unreadOnly = false): Promise<PageResult<NotifyDetail>> {
return await axios.post(`${BASE_URI}/internal`, page, {
params: { unreadOnly }
});
},
/** 删除当前用户的一条站内通知。 */
async function deleteInternal(id: string): Promise<void> {
await axios.post(`${BASE_URI}/delete`, undefined, {
params: { id }
});
}
/** 查询当前用户未读站内通知数量。 */
async countUnreadInternal(): Promise<number> {
return await axios.post(`${BASE_URI}/unread/count`);
},
/** 标记当前用户全部站内通知已读。 */
async function markAllInternalRead(): Promise<void> {
await axios.post(`${BASE_URI}/read/all`);
}
/** 标记当前用户的一条站内通知已读。 */
async markInternalRead(id: string): Promise<void> {
await axios.post(`${BASE_URI}/read`, undefined, {
params: { id }
});
},
export default {
internalDetail,
listInternal,
countUnreadInternal,
markInternalRead,
deleteInternal,
markAllInternalRead
/** 删除当前用户的一条站内通知。 */
async deleteInternal(id: string): Promise<void> {
await axios.post(`${BASE_URI}/delete`, undefined, {
params: { id }
});
},
/** 标记当前用户全部站内通知已读。 */
async markAllInternalRead(): Promise<void> {
await axios.post(`${BASE_URI}/read/all`);
}
};
export default NotifyAPI;
+23 -31
View File
@@ -3,35 +3,27 @@ import type { ModuleCode, Page, PageResult, Permission, PermissionPayload } from
const BASE_URI = "/user/permission";
async function list(req: Page<Permission>): Promise<PageResult<Permission>> {
return axios.post(`${BASE_URI}/list`, req);
}
async function create(req: PermissionPayload): Promise<void> {
return axios.post(`${BASE_URI}/create`, req);
}
async function update(req: PermissionPayload): Promise<void> {
return axios.post(`${BASE_URI}/update`, req);
}
async function remove(id: string): Promise<void> {
return axios.post(`${BASE_URI}/delete`, undefined, {
params: { id }
});
}
/** 查询当前登录用户在指定模块内可转授的权限。 */
async function grantableList(moduleCode: ModuleCode): Promise<Permission[]> {
return await axios.post(`${BASE_URI}/grantable/list`, undefined, {
params: { moduleCode }
});
}
export default {
list,
create,
update,
remove,
grantableList
export const PermissionAPI = {
async list(req: Page<Permission>): Promise<PageResult<Permission>> {
return axios.post(`${BASE_URI}/list`, req);
},
async create(req: PermissionPayload): Promise<void> {
return axios.post(`${BASE_URI}/create`, req);
},
async update(req: PermissionPayload): Promise<void> {
return axios.post(`${BASE_URI}/update`, req);
},
async remove(id: string): Promise<void> {
return axios.post(`${BASE_URI}/delete`, undefined, {
params: { id }
});
},
/** 查询当前登录用户在指定模块内可转授的权限。 */
async grantableList(moduleCode: ModuleCode): Promise<Permission[]> {
return await axios.post(`${BASE_URI}/grantable/list`, undefined, {
params: { moduleCode }
});
}
};
export default PermissionAPI;
+88 -120
View File
@@ -3,124 +3,92 @@ import type { ModuleCode, Page, PageResult, Permission, Role, RolePayload, Autho
const BASE_URI = "/user/role";
async function list(req: Page<Role>): Promise<PageResult<Role>> {
return axios.post(`${BASE_URI}/list`, req);
}
async function detail(id: string): Promise<Role> {
return axios.post(`${BASE_URI}/detail`, undefined, {
params: { id }
});
}
async function create(req: RolePayload): Promise<void> {
return axios.post(`${BASE_URI}/create`, req);
}
async function update(req: RolePayload): Promise<void> {
return axios.post(`${BASE_URI}/update`, req);
}
async function remove(id: string): Promise<void> {
return axios.post(`${BASE_URI}/delete`, undefined, {
params: { id }
});
}
/** 查询当前登录用户在模块内可管理的角色。 */
async function manageableList(moduleCode: ModuleCode): Promise<Role[]> {
return await axios.post(`${BASE_URI}/manageable/list`, undefined, {
params: { moduleCode }
});
}
/** 查询当前登录用户在模块内可授权给账号的角色。 */
async function grantableList(moduleCode: ModuleCode): Promise<Role[]> {
return await axios.post(`${BASE_URI}/grantable/list`, undefined, {
params: { moduleCode }
});
}
/** 查询当前登录用户直属角色详情,不按可管理范围过滤。 */
async function currentDetailList(moduleCode?: ModuleCode): Promise<Role[]> {
return await axios.post(`${BASE_URI}/current/detail/list`, undefined, {
params: { moduleCode }
});
}
/** 查询当前登录用户可以给目标角色配置的直接权限 P 候选项。 */
async function grantablePermissionList(roleId: string): Promise<Permission[]> {
return await axios.post(`${BASE_URI}/permission/grantable/list`, undefined, {
params: { roleId }
});
}
/** 查询目标角色当前可继续转授的权限 D。 */
async function delegationList(roleId: string): Promise<Permission[]> {
return await axios.post(`${BASE_URI}/delegation/list`, undefined, {
params: { roleId }
});
}
/** 查询当前登录用户可以给目标角色配置的 D 候选项。 */
async function grantableDelegationList(roleId: string): Promise<Permission[]> {
return await axios.post(`${BASE_URI}/delegation/grantable/list`, undefined, {
params: { roleId }
});
}
/** 覆盖保存目标角色可继续转授的权限 D。 */
async function updateDelegation(req: Pick<RolePayload, "id" | "delegationPermissionIdList">): Promise<void> {
await axios.post(`${BASE_URI}/delegation/update`, req);
}
/** 查询目标角色可选管理父级。 */
async function parentGrantableList(roleId: string): Promise<Role[]> {
return await axios.post(`${BASE_URI}/parent/grantable/list`, undefined, {
params: { roleId }
});
}
/** 保存目标角色管理父级。 */
async function updateParent(req: Pick<RolePayload, "id" | "parentRoleId">): Promise<void> {
await axios.post(`${BASE_URI}/parent/update`, req);
}
async function authorizedList(userId: string, moduleCode?: ModuleCode): Promise<Role[]> {
return axios.post(`${BASE_URI}/authorized/list`, undefined, {
params: {
userId,
moduleCode
}
});
}
async function authorize(req: AuthorizeUserRole): Promise<void> {
return axios.post(`${BASE_URI}/authorized/create`, req);
}
async function authorizedPermission(userId: string): Promise<Permission[]> {
return axios.post(`${BASE_URI}/authorized/permission`, undefined, {
params: { userId }
});
}
export default {
list,
detail,
create,
update,
remove,
manageableList,
grantableList,
currentDetailList,
grantablePermissionList,
delegationList,
grantableDelegationList,
updateDelegation,
parentGrantableList,
updateParent,
authorizedList,
authorize,
authorizedPermission
export const RoleAPI = {
async list(req: Page<Role>): Promise<PageResult<Role>> {
return axios.post(`${BASE_URI}/list`, req);
},
async detail(id: string): Promise<Role> {
return axios.post(`${BASE_URI}/detail`, undefined, {
params: { id }
});
},
async create(req: RolePayload): Promise<void> {
return axios.post(`${BASE_URI}/create`, req);
},
async update(req: RolePayload): Promise<void> {
return axios.post(`${BASE_URI}/update`, req);
},
async remove(id: string): Promise<void> {
return axios.post(`${BASE_URI}/delete`, undefined, {
params: { id }
});
},
/** 查询当前登录用户在模块内可管理的角色。 */
async manageableList(moduleCode: ModuleCode): Promise<Role[]> {
return await axios.post(`${BASE_URI}/manageable/list`, undefined, {
params: { moduleCode }
});
},
/** 查询当前登录用户在模块内可授权给账号的角色。 */
async grantableList(moduleCode: ModuleCode): Promise<Role[]> {
return await axios.post(`${BASE_URI}/grantable/list`, undefined, {
params: { moduleCode }
});
},
/** 查询当前登录用户直属角色详情,不按可管理范围过滤。 */
async currentDetailList(moduleCode?: ModuleCode): Promise<Role[]> {
return await axios.post(`${BASE_URI}/current/detail/list`, undefined, {
params: { moduleCode }
});
},
/** 查询当前登录用户可以给目标角色配置的直接权限 P 候选项。 */
async grantablePermissionList(roleId: string): Promise<Permission[]> {
return await axios.post(`${BASE_URI}/permission/grantable/list`, undefined, {
params: { roleId }
});
},
/** 查询目标角色当前可继续转授的权限 D。 */
async delegationList(roleId: string): Promise<Permission[]> {
return await axios.post(`${BASE_URI}/delegation/list`, undefined, {
params: { roleId }
});
},
/** 查询当前登录用户可以给目标角色配置的 D 候选项。 */
async grantableDelegationList(roleId: string): Promise<Permission[]> {
return await axios.post(`${BASE_URI}/delegation/grantable/list`, undefined, {
params: { roleId }
});
},
/** 覆盖保存目标角色可继续转授的权限 D。 */
async updateDelegation(req: Pick<RolePayload, "id" | "delegationPermissionIdList">): Promise<void> {
await axios.post(`${BASE_URI}/delegation/update`, req);
},
/** 查询目标角色可选管理父级。 */
async parentGrantableList(roleId: string): Promise<Role[]> {
return await axios.post(`${BASE_URI}/parent/grantable/list`, undefined, {
params: { roleId }
});
},
/** 保存目标角色管理父级。 */
async updateParent(req: Pick<RolePayload, "id" | "parentRoleId">): Promise<void> {
await axios.post(`${BASE_URI}/parent/update`, req);
},
async authorizedList(userId: string, moduleCode?: ModuleCode): Promise<Role[]> {
return axios.post(`${BASE_URI}/authorized/list`, undefined, {
params: {
userId,
moduleCode
}
});
},
async authorize(req: AuthorizeUserRole): Promise<void> {
return axios.post(`${BASE_URI}/authorized/create`, req);
},
async authorizedPermission(userId: string): Promise<Permission[]> {
return axios.post(`${BASE_URI}/authorized/permission`, undefined, {
params: { userId }
});
}
};
export default RoleAPI;
+51 -68
View File
@@ -10,63 +10,6 @@ type UpdateCurrentRequest = Omit<Partial<User>, "gender"> & {
gender?: Gender | "";
};
async function register(req: CaptchaData<RegisterRequest>): Promise<LoginResponse> {
return await axios.post(`${BASE_URI}/register`, req);
}
/**
* 登录
*
* @param req 验证码登录对象
* @returns LoginResponse
*/
async function login(req: CaptchaData<LoginRequest>): Promise<LoginResponse> {
return await axios.post(`${BASE_URI}/login`, req);
}
/**
* 验证是否已登录
*
* @returns true 为已登录
*/
async function loginByToken(): Promise<LoginResponse> {
return await axios.post(`${BASE_URI}/login/token`);
}
async function logout(): Promise<void> {
return await axios.post(`${BASE_URI}/logout`);
}
async function updateCurrent(req: UpdateCurrentRequest): Promise<LoginResponse> {
return await axios.post(`${BASE_URI}/current/update`, req);
}
async function updatePassword(req: UpdatePasswordRequest): Promise<void> {
return await axios.post(`${BASE_URI}/update/password`, req);
}
/**
* 获取用户数据
*
* @param id 用户 ID
* @returns 用户数据
*/
async function view(id: string): Promise<User> {
return await axios.post(`${BASE_URI}/view/${id}`);
}
function getAvatarURL(user?: UserAttachmentOwner) {
if (user?.attachmentList) {
return findAttachmentByType(user.attachmentList, "AVATAR");
}
}
function getWrapperURL(user?: UserAttachmentOwner) {
if (user?.attachmentList) {
return findAttachmentByType(user.attachmentList, "WRAPPER");
}
}
function findAttachmentByType(attachmentList: readonly Attachment[], ...types: UserAttachType[]) {
for (let i = 0; i < attachmentList.length; i++) {
const attachType = attachmentList[i].attachType as UserAttachType | undefined;
@@ -77,15 +20,55 @@ function findAttachmentByType(attachmentList: readonly Attachment[], ...types: U
}
}
export default {
register,
login,
loginByToken,
logout,
updateCurrent,
updatePassword,
view,
getAvatarURL,
getWrapperURL
export const UserAPI = {
async register(req: CaptchaData<RegisterRequest>): Promise<LoginResponse> {
return await axios.post(`${BASE_URI}/register`, req);
},
/**
* 登录
*
* @param req 验证码登录对象
* @returns LoginResponse
*/
async login(req: CaptchaData<LoginRequest>): Promise<LoginResponse> {
return await axios.post(`${BASE_URI}/login`, req);
},
/**
* 验证是否已登录
*
* @returns true 为已登录
*/
async loginByToken(): Promise<LoginResponse> {
return await axios.post(`${BASE_URI}/login/token`);
},
async logout(): Promise<void> {
return await axios.post(`${BASE_URI}/logout`);
},
async updateCurrent(req: UpdateCurrentRequest): Promise<LoginResponse> {
return await axios.post(`${BASE_URI}/current/update`, req);
},
async updatePassword(req: UpdatePasswordRequest): Promise<void> {
return await axios.post(`${BASE_URI}/update/password`, req);
},
/**
* 获取用户数据
*
* @param id 用户 ID
* @returns 用户数据
*/
async view(id: string): Promise<User> {
return await axios.post(`${BASE_URI}/view/${id}`);
},
getAvatarURL(user?: UserAttachmentOwner) {
if (user?.attachmentList) {
return findAttachmentByType(user.attachmentList, "AVATAR");
}
},
getWrapperURL(user?: UserAttachmentOwner) {
if (user?.attachmentList) {
return findAttachmentByType(user.attachmentList, "WRAPPER");
}
}
};
export default UserAPI;
+9 -9
View File
@@ -1,9 +1,9 @@
export { default as ArticleAPI } from "./ArticleAPI";
export { default as AttachmentAPI } from "./AttachmentAPI";
export { default as CommentAPI } from "./CommentAPI";
export { default as CommonAPI } from "./CommonAPI";
export { default as DeveloperAPI } from "./DeveloperAPI";
export { default as NotifyAPI } from "./NotifyAPI";
export { default as PermissionAPI } from "./PermissionAPI";
export { default as RoleAPI } from "./RoleAPI";
export { default as UserAPI } from "./UserAPI";
export { ArticleAPI } from "./ArticleAPI";
export { AttachmentAPI } from "./AttachmentAPI";
export { CommentAPI } from "./CommentAPI";
export { CommonAPI } from "./CommonAPI";
export { DeveloperAPI } from "./DeveloperAPI";
export { NotifyAPI } from "./NotifyAPI";
export { PermissionAPI } from "./PermissionAPI";
export { RoleAPI } from "./RoleAPI";
export { UserAPI } from "./UserAPI";