- 新增后台登录图形验证码功能,完善登录安全防护 - 新增登录rememberMe参数,控制Refresh Token的会话持久化策略 - 实现OSS私有桶媒体URL自动签名,统一处理图片资源的临时访问签名 - 新增素材库数据库表与上传API,规范媒体资源管理流程 - 统一前端UI图标使用@element-plus/icons-vue,重构布局图标组件 - 登录页新增验证码输入、刷新功能,添加账号记忆与记住密码逻辑 - 更新全套文档,补充API契约、技术决策记录与集成流程说明 - 修复多个业务页面的图标展示问题,新增认证流程相关测试用例
338 lines
7.7 KiB
TypeScript
338 lines
7.7 KiB
TypeScript
export type ApiResponse<T> = {
|
|
code: number;
|
|
msg: string;
|
|
data: T;
|
|
errorCode?: string;
|
|
details?: unknown;
|
|
};
|
|
|
|
export type ApiErrorResponse = {
|
|
code: number;
|
|
msg: string;
|
|
data: null;
|
|
errorCode?: string;
|
|
details?: unknown;
|
|
};
|
|
|
|
export type AdminUser = {
|
|
id: string;
|
|
email: string;
|
|
name: string;
|
|
role: string;
|
|
isActive?: boolean;
|
|
};
|
|
|
|
export type AdminMenu = {
|
|
id: string;
|
|
parentId?: string | null;
|
|
name: string;
|
|
type: "directory" | "page" | "button";
|
|
path?: string | null;
|
|
component?: string | null;
|
|
permission?: string | null;
|
|
icon?: string | null;
|
|
children?: AdminMenu[];
|
|
sortOrder?: number;
|
|
};
|
|
|
|
export type AdminProfile = {
|
|
user: AdminUser;
|
|
roles: Array<{ id: string; name: string; code: string; dataScope: string }>;
|
|
permissions: string[];
|
|
menus: AdminMenu[];
|
|
dataScopes: string[];
|
|
};
|
|
|
|
export type SystemUserItem = AdminUser & {
|
|
roleIds: string[];
|
|
deptIds: string[];
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type SystemRoleItem = {
|
|
id: string;
|
|
name: string;
|
|
code: string;
|
|
dataScope: "all" | "dept" | "dept_and_children" | "custom_dept" | "self";
|
|
description?: string | null;
|
|
isActive: boolean;
|
|
menuIds: string[];
|
|
deptIds: string[];
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type SystemMenuItem = {
|
|
id: string;
|
|
parentId?: string | null;
|
|
name: string;
|
|
type: "directory" | "page" | "button";
|
|
path?: string | null;
|
|
component?: string | null;
|
|
permission?: string | null;
|
|
icon?: string | null;
|
|
sortOrder: number;
|
|
isVisible: boolean;
|
|
isActive: boolean;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type SystemMenuTreeItem = SystemMenuItem & {
|
|
children?: SystemMenuTreeItem[];
|
|
};
|
|
|
|
export type SystemDeptItem = {
|
|
id: string;
|
|
parentId?: string | null;
|
|
name: string;
|
|
sortOrder: number;
|
|
isActive: boolean;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type SystemUserCreate = {
|
|
email: string;
|
|
name: string;
|
|
password: string;
|
|
isActive: boolean;
|
|
roleIds: string[];
|
|
deptIds: string[];
|
|
};
|
|
|
|
export type SystemUserPatch = Partial<Omit<SystemUserCreate, "email">>;
|
|
export type SystemRoleCreate = Omit<SystemRoleItem, "id" | "createdAt" | "updatedAt">;
|
|
export type SystemRolePatch = Partial<SystemRoleCreate>;
|
|
export type SystemMenuCreate = Omit<SystemMenuItem, "id" | "createdAt" | "updatedAt">;
|
|
export type SystemMenuPatch = Partial<SystemMenuCreate>;
|
|
export type SystemDeptCreate = Omit<SystemDeptItem, "id" | "createdAt" | "updatedAt">;
|
|
export type SystemDeptPatch = Partial<SystemDeptCreate>;
|
|
|
|
export type AuthPayload = {
|
|
token: string;
|
|
accessToken: string;
|
|
expiresIn: number;
|
|
user: AdminUser;
|
|
};
|
|
|
|
export type CaptchaPayload = {
|
|
captchaEnabled: boolean;
|
|
captchaId: string;
|
|
image: string;
|
|
expiresIn: number;
|
|
};
|
|
|
|
export type Dashboard = {
|
|
stats: { newLeadCount: number; leadCount: number };
|
|
recentLeads: Lead[];
|
|
};
|
|
|
|
export type Lead = {
|
|
id: string;
|
|
leadType: LeadType;
|
|
contactName?: string | null;
|
|
customerId?: string | null;
|
|
phone: string;
|
|
destination?: string | null;
|
|
travelDate?: string | null;
|
|
peopleCount?: number | null;
|
|
budgetMin?: number | null;
|
|
budgetMax?: number | null;
|
|
note?: string | null;
|
|
sourcePage?: string | null;
|
|
vehicleDemand?: VehicleDemand | null;
|
|
status: LeadStatus;
|
|
assignedUser?: { id: string; name: string } | null;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type LeadStatus = "new" | "assigned" | "contacted" | "planning" | "won" | "invalid";
|
|
export type LeadType = "general" | "vehicle";
|
|
export type VehicleDemand = {
|
|
serviceType: "charter" | "transfer";
|
|
charterDuration?: "halfDay" | "fullDay" | null;
|
|
travelDate: string;
|
|
pickupTime?: string | null;
|
|
pickupLocation: string;
|
|
dropoffLocation: string;
|
|
peopleCount: number;
|
|
luggageCount?: number | null;
|
|
vehicleOptionId?: string | null;
|
|
vehicleOptionTitle?: string | null;
|
|
specialRequirements?: string | null;
|
|
};
|
|
|
|
export type WanfaCategory = {
|
|
id: string;
|
|
label: string;
|
|
routes: WanfaRoute[];
|
|
};
|
|
|
|
export type WanfaRoute = {
|
|
id: string;
|
|
title: string;
|
|
subtitle: string;
|
|
image: string;
|
|
routeCount: number;
|
|
demandKeyword: string;
|
|
};
|
|
|
|
export type WanfaCategoryCreate = { label: string };
|
|
export type WanfaCategoryPatch = { label?: string };
|
|
export type WanfaRouteCreate = {
|
|
title: string;
|
|
subtitle: string;
|
|
image: string;
|
|
routeCount: number;
|
|
demandKeyword: string;
|
|
};
|
|
export type WanfaRoutePatch = Partial<WanfaRouteCreate>;
|
|
|
|
export type DetailRecord = {
|
|
id: string;
|
|
key: string;
|
|
eyebrow: string;
|
|
duration: string;
|
|
title: string;
|
|
subtitle: string;
|
|
intro: string;
|
|
highlights: string[];
|
|
included: string[];
|
|
excluded: string[];
|
|
notes: string[];
|
|
gallery: string[];
|
|
conciergeAdvisorId: string | null;
|
|
isActive: boolean;
|
|
sortOrder: number;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type DetailCreate = Omit<DetailRecord, "id" | "createdAt" | "updatedAt" | "sortOrder"> & { sortOrder?: number };
|
|
export type DetailPatch = Partial<DetailCreate>;
|
|
|
|
export type MediaAsset = {
|
|
id: string;
|
|
url: string;
|
|
name: string;
|
|
mimeType: string;
|
|
sizeBytes: number;
|
|
group: string;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type ConciergeAdvisor = {
|
|
id: string;
|
|
avatar?: string;
|
|
name: string;
|
|
role: string;
|
|
details?: Array<{ icon: string; label: string }>;
|
|
qrImage?: string;
|
|
isActive: boolean;
|
|
sortOrder?: number;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type ConciergeDetail = { icon: string; label: string };
|
|
export type ConciergeAdvisorCreate = {
|
|
avatar: string;
|
|
name: string;
|
|
role: string;
|
|
details: ConciergeDetail[];
|
|
qrImage: string;
|
|
isActive?: boolean;
|
|
sortOrder?: number;
|
|
};
|
|
export type ConciergeAdvisorPatch = Partial<ConciergeAdvisorCreate>;
|
|
|
|
export type SiteModule = "heroSlides" | "vehicleOptions";
|
|
|
|
export type HeroSlide = {
|
|
id: string;
|
|
title: string;
|
|
kicker: string | null;
|
|
image: string | null;
|
|
isActive: boolean;
|
|
sortOrder: number;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type VehicleOption = {
|
|
id: string;
|
|
title: string;
|
|
description: string | null;
|
|
image: string | null;
|
|
isActive: boolean;
|
|
sortOrder: number;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type SiteConfig = {
|
|
heroSlides: HeroSlide[];
|
|
vehicleOptions: VehicleOption[];
|
|
};
|
|
|
|
export type SiteConfigItem = HeroSlide | VehicleOption;
|
|
|
|
export type HomeWanfaRecommendation = {
|
|
id: string;
|
|
categoryId: string;
|
|
categoryLabel: string;
|
|
routeCount: number;
|
|
isActive: boolean;
|
|
sortOrder: number;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type HomeTeamBuilding = {
|
|
id: string;
|
|
tag: string;
|
|
title: string;
|
|
description: string;
|
|
image: string;
|
|
demandKeyword: string;
|
|
detailSubtitle?: string | null;
|
|
detailParagraphs?: string[] | null;
|
|
isActive: boolean;
|
|
sortOrder: number;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type HomeWildArchive = {
|
|
id: string;
|
|
title: string;
|
|
image: string;
|
|
images?: string[] | null;
|
|
demandKeyword: string;
|
|
isActive: boolean;
|
|
sortOrder: number;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type HomeWanfaRecommendationCreate = { categoryId: string; isActive: boolean; sortOrder?: number };
|
|
export type HomeWanfaRecommendationPatch = Partial<HomeWanfaRecommendationCreate>;
|
|
export type HomeTeamBuildingCreate = Omit<HomeTeamBuilding, "id" | "createdAt" | "updatedAt">;
|
|
export type HomeTeamBuildingPatch = Partial<HomeTeamBuildingCreate>;
|
|
export type HomeWildArchiveCreate = Omit<HomeWildArchive, "id" | "createdAt" | "updatedAt">;
|
|
export type HomeWildArchivePatch = Partial<HomeWildArchiveCreate>;
|
|
|
|
export type SiteItemPatch = {
|
|
title?: string | null;
|
|
kicker?: string | null;
|
|
image?: string | null;
|
|
description?: string | null;
|
|
steps?: string[];
|
|
isActive?: boolean;
|
|
sortOrder?: number;
|
|
};
|