Initial project

This commit is contained in:
Timi
2025-07-08 16:33:11 +08:00
parent 1a5a16be74
commit f862530142
80 changed files with 8301 additions and 129 deletions
+110
View File
@@ -0,0 +1,110 @@
import { Resizer } from "~/index";
// true 为手机
const isPhone = ref(false);
// true 为平板
const isTablet = ref(false);
// true 为桌面
const isDesktop = ref(false);
// true 为大屏幕
const isLargeScreen = ref(false);
// true 为竖屏
const isVertical = ref(false);
// true 为横屏
const isHorizontal = ref(false);
// 宽高比
const aspectRatio = ref(0);
// true 为超宽屏
const isUltrawide = ref(false);
// true 为近似方屏
const isSquare = ref(false);
// 当前断点
const currentBreakpoint = ref<"xs" | "sm" | "md" | "lg" | "xl">("lg");
// 当前屏幕宽度
const screenWidth = ref(0);
// 当前屏幕高度
const screenHeight = ref(0);
// 短屏幕(高度小于 500
const isShortScreen = ref(false);
// true 为启用移动端布局
const isMobileLayout = ref(false);
/** 断点配置,单位:px */
enum Breakpoints {
/** 超小设备 */
XS = 480,
/** 手机 */
SM = 650,
/** 平板 */
MD = 768,
/** 笔记本 */
LG = 1024,
/** 大屏幕 */
XL = 1440
}
Resizer.addListener("DEVICE_SIZE", (width, height) => {
screenWidth.value = width;
screenHeight.value = height;
// 设备类型
isPhone.value = width < Breakpoints.SM;
isTablet.value = width >= Breakpoints.SM && width < Breakpoints.LG;
isDesktop.value = width >= Breakpoints.LG;
isLargeScreen.value = width >= Breakpoints.XL;
// 屏幕方向
isVertical.value = width < height;
isHorizontal.value = !isVertical.value;
// 宽高比特征
aspectRatio.value = width / height;
isUltrawide.value = 2 <= aspectRatio.value; // 21:9 ≈ 2.33
isSquare.value = 0.9 < aspectRatio.value && aspectRatio.value < 1.1;
// 布局相关
isShortScreen.value = height < 500;
isMobileLayout.value = width < Breakpoints.MD;
if (Breakpoints.XL <= width) {
currentBreakpoint.value = "xl";
} else if (Breakpoints.LG <= width) {
currentBreakpoint.value = "lg";
} else if (Breakpoints.MD <= width) {
currentBreakpoint.value = "md";
} else if (Breakpoints.SM <= width) {
currentBreakpoint.value = "sm";
} else {
currentBreakpoint.value = "xs";
}
});
const deviceStore = {
isPhone,
isTablet,
isDesktop,
isLargeScreen,
isVertical,
isHorizontal,
aspectRatio,
isUltrawide,
isSquare,
currentBreakpoint,
screenWidth,
screenHeight,
isShortScreen,
isMobileLayout
};
export {
deviceStore
};
+77
View File
@@ -0,0 +1,77 @@
import { LoginResponse, LoginToken, LoginUser, Storage, UserAPI, UserToken } from "timi-web";
const loginUser = reactive<LoginUser>({
token: undefined,
user: undefined
});
function isLogged(): boolean {
return !!loginUser.user;
}
async function login4Token(token: LoginToken): Promise<LoginResponse | null> {
loginUser.token = token;
// 未过期
try {
const resp = await UserAPI.login4Token();
await updateToken(resp);
return resp;
} catch (e) {
await logout();
}
return null;
}
async function login4Storage(): Promise<LoginResponse | null> {
if (!loginUser.user && (loginUser.token || Storage.has("token"))) {
// 未登录,储存有令牌
const token = Storage.getJSON("token") as UserToken;
if (new Date().getTime() < token.expireAt) {
return await login4Token(token);
}
}
return null;
}
async function updateToken(loginResponse: LoginResponse): Promise<void> {
loginUser.token = {
id: loginResponse.id,
value: loginResponse.token,
expireAt: loginResponse.expireAt
};
loginUser.user = await UserAPI.view(loginResponse.id);
Storage.setJSON("token", {
value: loginUser.token.value,
expireAt: loginUser.token.expireAt
} as UserToken);
}
async function logout(): Promise<void> {
await UserAPI.logout();
loginUser.token = undefined;
loginUser.user = undefined;
Storage.remove("token");
}
async function reloadProfile() {
if (loginUser.token && loginUser.token.id) {
loginUser.user = await UserAPI.view(loginUser.token.id);
}
}
const userStore = {
loginUser,
isLogged,
login4Token,
login4Storage,
updateToken,
logout,
reloadProfile
};
export {
userStore
};