diff --git a/src/App.vue b/src/App.vue index a7cf44c..cf6b1d4 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,14 +2,18 @@ import { onLaunch } from '@dcloudio/uni-app' import { useUserStore } from './store/user' +/** 应用启动时检查隐私协议并尝试获取用户信息 */ onLaunch(() => { // #ifdef MP-WEIXIN // 仅真机检查隐私协议,模拟器中跳过(getPrivacySetting 在模拟器会触发框架级 timeout) + // wx 为微信小程序运行时全局对象,在 #ifdef MP-WEIXIN 下始终可用 try { - const deviceInfo = wx.getDeviceInfo() - if (deviceInfo.platform !== 'devtools' && typeof wx.getPrivacySetting === 'function') { - wx.getPrivacySetting({ - success: (res: any) => { + // @ts-expect-error wx — WeChat 运行时全局对象,类型不由 TypeScript 覆盖 + const _wx: any = wx + const deviceInfo = _wx.getDeviceInfo() + if (deviceInfo.platform !== 'devtools' && typeof _wx.getPrivacySetting === 'function') { + _wx.getPrivacySetting({ + success: (res: UniNamespace.GetPrivacySettingSuccessCallbackResult) => { if (res.needAuthorization) { uni.setStorageSync('needPrivacy', true) } else { diff --git a/src/api/request.ts b/src/api/request.ts index 30df83e..6f26a7b 100644 --- a/src/api/request.ts +++ b/src/api/request.ts @@ -4,13 +4,13 @@ import { API_BASE, TOKEN_KEY } from '../config' interface RequestOptions { url: string method?: 'GET' | 'POST' | 'PUT' | 'DELETE' - data?: any + data?: object header?: Record needToken?: boolean } /** 后端统一响应格式 */ -interface ResponseData { +interface ResponseData { code: number msg: string data: T @@ -20,7 +20,7 @@ interface ResponseData { /** 从本地存储获取 token */ function getToken(): string { - return uni.getStorageSync(TOKEN_KEY) || '' + return (uni.getStorageSync(TOKEN_KEY) as string) || '' } /** 保存 token 到本地存储 */ @@ -34,7 +34,7 @@ function removeToken(): void { } /** 通用请求函数 */ -function request(options: RequestOptions): Promise { +function request(options: RequestOptions): Promise { return new Promise((resolve, reject) => { const { url, method = 'GET', data, needToken = true } = options @@ -57,9 +57,9 @@ function request(options: RequestOptions): Promise { uni.request({ url: fullUrl, method, - data, + data: data as AnyObject, header, - success: (res: any) => { + success: (res: UniApp.RequestSuccessCallbackResult) => { const result = res.data as ResponseData // HTTP 状态码检查 @@ -87,27 +87,31 @@ function request(options: RequestOptions): Promise { reject(new Error(`HTTP ${res.statusCode}`)) } }, - fail: (err: any) => { + fail: (err: UniApp.GeneralCallbackResult) => { uni.showToast({ title: '网络连接失败', icon: 'none' }) - reject(err) + reject(new Error(err.errMsg)) } }) }) } -function get(url: string, data?: any, needToken = true): Promise { +/** GET 请求 */ +function get(url: string, data?: object, needToken = true): Promise { return request({ url, method: 'GET', data, needToken }) } -function post(url: string, data?: any, needToken = true): Promise { +/** POST 请求 */ +function post(url: string, data?: object, needToken = true): Promise { return request({ url, method: 'POST', data, needToken }) } -function put(url: string, data?: any, needToken = true): Promise { +/** PUT 请求 */ +function put(url: string, data?: object, needToken = true): Promise { return request({ url, method: 'PUT', data, needToken }) } -function del(url: string, data?: any, needToken = true): Promise { +/** DELETE 请求 */ +function del(url: string, data?: object, needToken = true): Promise { return request({ url, method: 'DELETE', data, needToken }) } diff --git a/src/components/AnnouncementModal.vue b/src/components/announcement-modal.vue similarity index 97% rename from src/components/AnnouncementModal.vue rename to src/components/announcement-modal.vue index 835215e..be9794b 100644 --- a/src/components/AnnouncementModal.vue +++ b/src/components/announcement-modal.vue @@ -46,6 +46,7 @@ const emit = defineEmits<{ const show = ref(false) +/** modelValue 变化时控制入场/离场动画 */ watch(() => props.modelValue, (val) => { if (val) { nextTick(() => { show.value = true }) @@ -54,6 +55,7 @@ watch(() => props.modelValue, (val) => { } }) +/** 关闭弹窗(离场动画完成后 emit) */ function close() { show.value = false setTimeout(() => { emit('update:modelValue', false) }, 280) diff --git a/src/components/McGlass.vue b/src/components/mc-glass.vue similarity index 100% rename from src/components/McGlass.vue rename to src/components/mc-glass.vue diff --git a/src/packages/content/pages/notice-list.vue b/src/packages/content/pages/notice-list.vue index cfd8312..da3ec92 100644 --- a/src/packages/content/pages/notice-list.vue +++ b/src/packages/content/pages/notice-list.vue @@ -34,7 +34,7 @@ diff --git a/src/store/user.ts b/src/store/user.ts index 15682fb..7093613 100644 --- a/src/store/user.ts +++ b/src/store/user.ts @@ -5,11 +5,13 @@ import { wxLogin as apiWxLogin, getUserInfo as apiGetUserInfo } from '../api/use import type { UserInfo } from '../api/types' import { TOKEN_KEY, REFRESH_TOKEN_KEY } from '../config' +/** 用户认证状态 store(跨页面共享 token 和登录状态) */ export const useUserStore = defineStore('user', () => { const token = ref(getToken()) const refreshToken = ref(uni.getStorageSync(REFRESH_TOKEN_KEY) || '') const userInfo = ref(null) + /** 是否已登录 */ const isLogin = computed(() => !!token.value) /** 微信授权登录(接收 loginCode + phoneCode) */ @@ -22,7 +24,7 @@ export const useUserStore = defineStore('user', () => { return result } - /** 获取用户信息 */ + /** 获取当前用户信息并缓存到 store */ async function fetchUserInfo() { if (!token.value) return const info = await apiGetUserInfo() @@ -30,7 +32,7 @@ export const useUserStore = defineStore('user', () => { return info } - /** 退出登录 */ + /** 退出登录(清除 token 和用户信息) */ function logout() { token.value = '' refreshToken.value = '' diff --git a/src/utils/index.ts b/src/utils/index.ts index 7b23b67..1a4fd57 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,8 +1,10 @@ +/** 数字补零(用于日期格式化) */ const formatNumber = (n: number): string => { const str = n.toString() return str[1] ? str : '0' + str } +/** 格式化日期时间为 `YYYY/M/D HH:mm:ss` */ function formatTime(date: Date | number | string): string { const d = new Date(date) const year = d.getFullYear() @@ -14,6 +16,7 @@ function formatTime(date: Date | number | string): string { return `${year}/${month}/${day} ${[hour, minute, second].map(formatNumber).join(':')}` } +/** 显示 Toast 提示 */ function showToast(title: string, icon: 'success' | 'loading' | 'error' | 'none' = 'none'): void { uni.showToast({ title, @@ -22,14 +25,17 @@ function showToast(title: string, icon: 'success' | 'loading' | 'error' | 'none' }) } +/** 跳转到指定页面 */ function navigateTo(url: string): void { uni.navigateTo({ url }) } +/** 重定向到指定页面 */ function redirectTo(url: string): void { uni.redirectTo({ url }) } +/** 切换到 tabBar 页面 */ function switchTab(url: string): void { uni.switchTab({ url }) }