This commit is contained in:
Timi
2026-07-31 15:28:13 +08:00
parent fc816e2d84
commit 2cf33d1003
8 changed files with 106 additions and 16 deletions
+9 -5
View File
@@ -1,8 +1,12 @@
import {Attachment, CaptchaData, LoginRequest, LoginResponse, RegisterRequest, UpdatePasswordRequest, User, UserAttachType} from "../types";
import type {Attachment, CaptchaData, LoginRequest, LoginResponse, RegisterRequest, UpdatePasswordRequest, User} from "../types";
import {UserAttachType} from "../types";
import {axios} from "./BaseAPI";
import CommonAPI from "./CommonAPI";
const BASE_URI = "/user";
type UserAttachmentOwner = {
attachmentList?: readonly Attachment[];
};
async function register(req: CaptchaData<RegisterRequest>): Promise<LoginResponse> {
return await axios.post(`${BASE_URI}/register`, req);
@@ -31,7 +35,7 @@ async function logout(): Promise<void> {
return await axios.post(`${BASE_URI}/logout`);
}
async function updateCurrent(req: User): Promise<LoginResponse> {
async function updateCurrent(req: Partial<User>): Promise<LoginResponse> {
return await axios.post(`${BASE_URI}/current/update`, req);
}
@@ -49,19 +53,19 @@ async function view(id: string): Promise<User> {
return await axios.post(`${BASE_URI}/view/${id}`);
}
function getAvatarURL(user?: User) {
function getAvatarURL(user?: UserAttachmentOwner) {
if (user?.attachmentList) {
return findAttachmentByType(user.attachmentList, [UserAttachType.AVATAR, UserAttachType.DEFAULT_AVATAR]);
}
}
function getWrapperURL(user?: User) {
function getWrapperURL(user?: UserAttachmentOwner) {
if (user?.attachmentList) {
return findAttachmentByType(user.attachmentList, [UserAttachType.WRAPPER, UserAttachType.DEFAULT_WRAPPER]);
}
}
function findAttachmentByType(attachmentList: Attachment[], types: UserAttachType[]) {
function findAttachmentByType(attachmentList: readonly Attachment[], types: UserAttachType[]) {
for (let i = 0; i < attachmentList.length; i++) {
const attachType = attachmentList[i].attachType as UserAttachType | undefined;
const id = attachmentList[i].id;
+25 -2
View File
@@ -16,12 +16,35 @@ export type AccessMatchMode = "and" | "or";
let _storageKey = "loginUser";
function normalizeAccessList(list?: string[]): string[] {
type AccessItem = string | {
moduleCode?: string;
code?: string;
};
function normalizeAccessItem(item?: AccessItem): string {
if (!item) {
return "";
}
if (typeof item === "string") {
return item.trim();
}
const code = item.code?.trim();
if (!code) {
return "";
}
const moduleCode = item.moduleCode?.trim();
return moduleCode && !code.includes(":") ? `${moduleCode}:${code}` : code;
}
function normalizeAccessList(list?: AccessItem[]): string[] {
if (!list?.length) {
return [];
}
return list
.map(item => item?.trim())
.map(normalizeAccessItem)
.filter((item): item is string => !!item);
}
+2 -2
View File
@@ -23,8 +23,8 @@ export type Page<T> = {
index: number;
size: number;
orderMap?: { [K in keyof T]?: OrderType };
equalsExample?: T;
likesExample?: T;
equalsExample?: Partial<T>;
likesExample?: Partial<T>;
}
export enum OrderType {
+29
View File
@@ -7,6 +7,15 @@ export type ScrollListener = {
bottom: number;
}
export type ScrollBottomListenerOptions = {
/** 距离底部小于等于该值时触发 */
distance?: number;
/** 返回 true 时才触发 */
canLoad?: () => boolean;
}
export default class Scroller {
private static instance: Scroller;
@@ -53,6 +62,26 @@ export default class Scroller {
Scroller.getInstance().listeners.set(name, listener);
}
/**
* 添加触底监听
*
* @param name 事件名
* @param listener 触底回调
* @param options 触底配置
*/
public static addBottomListener(name: string, listener: (event: ScrollListener) => void | Promise<void>, options: ScrollBottomListenerOptions = {}) {
const distance = options.distance ?? 120;
Scroller.addListener(name, event => {
if (distance < event.bottom) {
return;
}
if (options.canLoad && !options.canLoad()) {
return;
}
void listener(event);
});
}
/**
* 移除监听
*
+4
View File
@@ -30,6 +30,10 @@ export default class Text {
return template.replace(/\$\{(\w+)}/g, (_, key) => variables[key]);
}
public static pad(value: number | string, length = 2, fill = "0"): string {
return value.toString().padStart(length, fill);
}
public static unitCompact(val: number | string | null | undefined, unit: string, fixed = 0): string {
return this.unit(val, unit, fixed, true);
};
+25 -6
View File
@@ -1,4 +1,5 @@
import Toolkit from "./Toolkit";
import Text from "./Text";
export default class Time {
@@ -15,6 +16,25 @@ export default class Time {
return new Date().getTime();
}
public static toTimestamp(date: Date): number {
return date.getTime();
}
public static toDateObject(unix?: number): Date | undefined {
if (!unix) {
return undefined;
}
return new Date(unix);
}
public static formatDate(date: Date): string {
return `${date.getFullYear()}-${Text.pad(date.getMonth() + 1)}-${Text.pad(date.getDate())}`;
}
public static formatDateTime(date: Date): string {
return `${this.formatDate(date)} ${Text.pad(date.getHours())}:${Text.pad(date.getMinutes())}`;
}
/**
* Unix 时间戳转日期
*
@@ -22,8 +42,7 @@ export default class Time {
*/
public static toDate(unix?: number): string {
if (!unix) return "";
const d = new Date(unix);
return `${d.getFullYear()}-${(d.getMonth() + 1).toString().padStart(2, "0")}-${d.getDate().toString().padStart(2, "0")}`;
return this.formatDate(new Date(unix));
}
/**
@@ -34,13 +53,13 @@ export default class Time {
public static toTime(unix?: number): string {
if (!unix) return "";
const d = new Date(unix);
return `${d.getHours().toString().padStart(2, "0")}:${d.getMinutes().toString().padStart(2, "0")}`;
return `${Text.pad(d.getHours())}:${Text.pad(d.getMinutes())}`;
}
public static toShortTime(unix?: number): string {
if (!unix) return "";
const d = new Date(unix);
return `${d.getMinutes().toString().padStart(2, "0")}:${d.getSeconds().toString().padStart(2, "0")}`;
return `${Text.pad(d.getMinutes())}:${Text.pad(d.getSeconds())}`;
}
/**
@@ -131,9 +150,9 @@ export default class Time {
const minutes = Math.floor((seconds % 3600) / 60);
const second = seconds % 60;
if (0 < hours) {
return `${hours}:${minutes.toString().padStart(2, "0")}:${second.toString().padStart(2, "0")}`;
return `${hours}:${Text.pad(minutes)}:${Text.pad(second)}`;
}
return `${minutes.toString().padStart(2, "0")}:${second.toString().padStart(2, "0")}`;
return `${Text.pad(minutes)}:${Text.pad(second)}`;
}
/**
+11
View File
@@ -398,4 +398,15 @@ export default class Toolkit {
}
return JSON.stringify(JSON.parse(jsonStr), null, 4);
}
public static downloadBlob(blob: Blob, fileName: string): void {
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
link.remove();
window.setTimeout(() => URL.revokeObjectURL(url), 1000);
}
}