diff --git a/.env/.env.development b/.env/.env.development index db362faf..8446ac1a 100644 --- a/.env/.env.development +++ b/.env/.env.development @@ -1,3 +1,3 @@ VITE_NAME = "开发环境" VITE_BASIC_URL = "https://meowchat.xhpolaris.com" -VITE_XH_ENV = "test" \ No newline at end of file +VITE_ENABLE_DEBUG = true \ No newline at end of file diff --git a/.env/.env.production b/.env/.env.production index ad220c1a..3aa6df1e 100644 --- a/.env/.env.production +++ b/.env/.env.production @@ -1,3 +1,2 @@ VITE_NAME = "生产环境" VITE_BASIC_URL = "https://meowchat.xhpolaris.com" -VITE_XH_ENV = "pro" diff --git a/src/apis/auth/auth-interfaces.ts b/src/apis/auth/auth-interfaces.ts index 94eca44d..2ab09a4e 100644 --- a/src/apis/auth/auth-interfaces.ts +++ b/src/apis/auth/auth-interfaces.ts @@ -13,9 +13,10 @@ export interface SignInReq { authId: string; password?: string; verifyCode?: string; + appId: number; } -export interface SignInResp { +export interface GignInResp { userId: string; accessToken: string; accessExpire: number; diff --git a/src/apis/auth/auth.ts b/src/apis/auth/auth.ts index 5fe18734..3b885104 100644 --- a/src/apis/auth/auth.ts +++ b/src/apis/auth/auth.ts @@ -4,27 +4,37 @@ import { SetPasswordReq, SetPasswordResp, SignInReq, - SignInResp + GignInResp } from "./auth-interfaces"; +import { getPrefetchData } from "@/apis/prefetch"; /** * @description * @param req */ export function signIn(req: SignInReq) { - return new Promise((resolve, reject) => { - uni.request({ - url: "/auth/sign_in", - data: req, - method: "POST", - success(res: UniNamespace.RequestSuccessCallbackResult) { - if (res.statusCode !== 200) { - reject(res); + return new Promise((resolve, reject) => { + getPrefetchData() + .then((res) => { + if (!res.signInResp) { + return Promise.reject(); } - const data = res.data as SignInResp; - resolve(data); - } - }); + resolve(res.signInResp); + }) + .catch(() => { + uni.request({ + url: "/auth/sign_in", + data: req, + method: "POST", + success(res: UniNamespace.RequestSuccessCallbackResult) { + if (res.statusCode !== 200) { + reject(res); + } + const data = res.data as GignInResp; + resolve(data); + } + }); + }); }); } diff --git a/src/apis/collection/collection-interfaces.ts b/src/apis/collection/collection-interfaces.ts index fd08818a..a9ef784b 100644 --- a/src/apis/collection/collection-interfaces.ts +++ b/src/apis/collection/collection-interfaces.ts @@ -3,18 +3,7 @@ import { Cat, CatPreview } from "../schemas"; export interface GetCatPreviewsReq { page: number; communityId: string; -} - -export interface SearchCatPreviewsReq { - communityId: string; - page: number; - keyword: string; -} - -export interface SearchCatPreviewsResp { - cats: CatPreview[]; - code: number; - msg: string; + keyword?: string; } export interface GetCatPreviewsResp { diff --git a/src/apis/collection/collection.ts b/src/apis/collection/collection.ts index 2b689e31..bc2e22df 100644 --- a/src/apis/collection/collection.ts +++ b/src/apis/collection/collection.ts @@ -12,9 +12,7 @@ import { GetImageByCatReq, GetImageByCatResp, NewCatReq, - NewCatResp, - SearchCatPreviewsReq, - SearchCatPreviewsResp + NewCatResp } from "./collection-interfaces"; import { PictureStyle } from "@/apis/cos/cos-interface"; @@ -80,30 +78,6 @@ export async function getCatPreviews(req: GetCatPreviewsReq) { }); } -/** - * @description - * @param req - */ -export async function searchCatPreviews(req: SearchCatPreviewsReq) { - return await new Promise((resolve, reject) => { - uni.request({ - url: "/collection/search_cat", - data: req, - method: "GET", - success(res: UniNamespace.RequestSuccessCallbackResult) { - if (res.statusCode !== 200) { - reject(res); - } - const data = res.data as SearchCatPreviewsResp; - data.cats.forEach((cat) => { - cat.avatarUrl += PictureStyle.thumbnail; - }); - resolve(data); - } - }); - }); -} - /** * @description * @param req diff --git a/src/apis/comment/comment-interfaces.ts b/src/apis/comment/comment-interfaces.ts index 133691d8..9d47a266 100644 --- a/src/apis/comment/comment-interfaces.ts +++ b/src/apis/comment/comment-interfaces.ts @@ -2,7 +2,7 @@ import { Comment } from "@/apis/schemas"; export interface GetCommentsReq { // 作用域,如动态、帖子、评论 - scope: string; + type: CommentType; page: number; id: string; } @@ -17,10 +17,26 @@ export interface GetCommentsResp { export interface NewCommentReq { text: string; id: string; - scope: string; + firstLevelId?: string; + type: CommentType; } export interface NewCommentResp { code: number; msg: string; } + +export interface DeleteCommentReq { + commentId: string; +} + +export interface DeleteCommentResp { + code: number; + msg: string; +} + +export enum CommentType { + Comment = 1, + Post = 2, + Moment = 3 +} diff --git a/src/apis/comment/comment.ts b/src/apis/comment/comment.ts index 42f9e583..2b8f4aff 100644 --- a/src/apis/comment/comment.ts +++ b/src/apis/comment/comment.ts @@ -1,4 +1,6 @@ import { + DeleteCommentReq, + DeleteCommentResp, GetCommentsReq, GetCommentsResp, NewCommentReq, @@ -51,7 +53,7 @@ export async function getComments(req: GetCommentsReq) { * @description * @param req */ -export async function deleteCommment(req: object) { +export async function deleteComment(req: DeleteCommentReq) { return await new Promise((resolve, reject) => { uni.request({ url: "/comment/delete_comment", @@ -61,7 +63,7 @@ export async function deleteCommment(req: object) { if (res.statusCode !== 200) { reject(res); } - const data = res.data as GetCommentsResp; + const data = res.data as DeleteCommentResp; resolve(data); } }); diff --git a/src/apis/community/community.ts b/src/apis/community/community.ts index ebbd375a..e881dd5f 100644 --- a/src/apis/community/community.ts +++ b/src/apis/community/community.ts @@ -2,6 +2,7 @@ import { ListCommunityReq, ListCommunityResp } from "@/apis/community/community-interfaces"; +import { getPrefetchData } from "@/apis/prefetch"; let cache: ListCommunityResp | null; @@ -25,19 +26,30 @@ export async function listCommunity(req: ListCommunityReq) { return; } - uni.request({ - url: "/community/list_community", - data: req, - method: "GET", - success(res: UniNamespace.RequestSuccessCallbackResult) { - if (res.statusCode !== 200) { - reject(res); + getPrefetchData() + .then((res) => { + if (!res.listCommunityResp) { + return Promise.reject(); } - const data = res.data as ListCommunityResp; - cache = data; - resolve(data); - } - }); + cache = res.listCommunityResp; + resolve(res.listCommunityResp); + }) + .catch((reason) => { + console.log(reason); + uni.request({ + url: "/community/list_community", + data: req, + method: "GET", + success(res: UniNamespace.RequestSuccessCallbackResult) { + if (res.statusCode !== 200) { + reject(res); + } + const data = res.data as ListCommunityResp; + cache = data; + resolve(data); + } + }); + }); }); } diff --git a/src/apis/moment/moment-components.ts b/src/apis/moment/moment-components.ts index 6b8c808f..c4e2a2ed 100644 --- a/src/apis/moment/moment-components.ts +++ b/src/apis/moment/moment-components.ts @@ -9,19 +9,6 @@ export interface DeleteMomentResp { msg: string; } -export interface SearchMomentPreviewsReq { - page: number; - keyword: string; - communityId: string; - Authorization?: string; -} - -export interface SearchMomentPreviewsResp { - moments: Moment[]; - code: number; - msg: string; -} - export interface NewMomentReq { id?: string; // 留空表示创建 title: string; @@ -38,13 +25,16 @@ export interface NewMomentResp { } export interface GetMomentPreviewsReq { - backward?: number; - communityId: string; + communityId?: string; isParent?: number; + onlyUserId?: string; + keyword?: string; + + backward?: number; lastToken?: string; limit?: number; - onlyUserId?: string; - page: number; + page?: number; + offset?: number; } export interface GetMomentPreviewsResp { diff --git a/src/apis/moment/moment.ts b/src/apis/moment/moment.ts index 9aa652c8..87a3b3ad 100644 --- a/src/apis/moment/moment.ts +++ b/src/apis/moment/moment.ts @@ -6,9 +6,7 @@ import { GetMomentPreviewsReq, GetMomentPreviewsResp, NewMomentReq, - NewMomentResp, - SearchMomentPreviewsReq, - SearchMomentPreviewsResp + NewMomentResp } from "./moment-components"; import { PictureStyle } from "@/apis/cos/cos-interface"; @@ -82,23 +80,6 @@ export async function getMomentPreviews(req: GetMomentPreviewsReq) { }); } -export async function searchMomentPreviews(req: SearchMomentPreviewsReq) { - return await new Promise((resolve, reject) => { - uni.request({ - url: "/moment/search_moment", - data: req, - method: "GET", - success(res: UniNamespace.RequestSuccessCallbackResult) { - if (res.statusCode !== 200) { - reject(res); - } - const data = res.data as SearchMomentPreviewsResp; - resolve(data); - } - }); - }); -} - /** * @description * @param req diff --git a/src/apis/post/post.ts b/src/apis/post/post.ts index 5b128ccd..5cd083d6 100644 --- a/src/apis/post/post.ts +++ b/src/apis/post/post.ts @@ -12,12 +12,6 @@ import { PictureStyle } from "@/apis/cos/cos-interface"; export async function getPostPreviews(req: GetPostPreviewsReq) { return await new Promise((resolve, reject) => { - req.page = 2; - if (!req.paginationOption) { - req.paginationOption = { limit: 10 }; - } else if (!req.paginationOption.limit) { - req.paginationOption.limit = 10; - } uni.request({ url: "/post/get_post_previews", method: "POST", @@ -27,19 +21,15 @@ export async function getPostPreviews(req: GetPostPreviewsReq) { reject(res); } const data = res.data as GetPostPreviewsResp; - const newData: GetPostPreviewsResp = { - ...data, - posts: [] - }; data.posts?.forEach((post) => { - if (!post.user) return; if (post.coverUrl) { post.coverUrl += PictureStyle.thumbnail; } - post.user.avatarUrl += PictureStyle.thumbnail; - newData.posts.push(post); + if (post.user?.avatarUrl) { + post.user.avatarUrl += PictureStyle.thumbnail; + } }); - resolve(newData); + resolve(data); } }); }); @@ -90,7 +80,9 @@ export async function getPostDetail(req: GetPostDetailReq) { reject(res); } const data = res.data as GetPostDetailResp; - data.post.user.avatarUrl += PictureStyle.thumbnail; + if (data.post.user?.avatarUrl) { + data.post.user.avatarUrl += PictureStyle.thumbnail; + } resolve(data); } }); diff --git a/src/apis/prefetch.ts b/src/apis/prefetch.ts new file mode 100644 index 00000000..90c36115 --- /dev/null +++ b/src/apis/prefetch.ts @@ -0,0 +1,67 @@ +import { GignInResp } from "@/apis/auth/auth-interfaces"; +import { GetUserInfoResp } from "@/apis/user/user-interfaces"; +import { ListCommunityResp } from "@/apis/community/community-interfaces"; +import { GetPostPreviewsResp } from "@/apis/post/post-interfaces"; +import { GetMomentPreviewsResp } from "@/apis/moment/moment-components"; +import { GetCatPreviewsResp } from "@/apis/collection/collection-interfaces"; +import { GetNewsResp } from "@/apis/notice/notice-interfaces"; + +export interface PrefetchResp { + signInResp?: GignInResp; + getUserInfoResp?: GetUserInfoResp; + listCommunityResp?: ListCommunityResp; + firstPostPreviewsResp?: GetPostPreviewsResp; + firstMomentPreviewsResp?: GetMomentPreviewsResp; + firstCatPreviewsResp?: GetCatPreviewsResp; + getNewsResp?: GetNewsResp; + token?: string; + timestamp: number; +} + +interface Token { + communityId?: string; + userId?: string; + env?: string; +} + +let data: PrefetchResp; + +export async function getPrefetchData(expectToken?: Token) { + if (!data) { + data = await new Promise((resolve, reject) => { + uni.getBackgroundFetchData({ + fetchType: "pre", + success: (res) => { + if (res.fetchedData) { + resolve(JSON.parse(res.fetchedData)); + return; + } + reject("获取预加载数据失败"); + }, + fail: (reason) => { + reject(reason); + } + }); + }); + } + if (!data) { + return Promise.reject("获取预加载数据失败"); + } + const token: Token = JSON.parse(data.token || "{}"); + if (!data.timestamp || new Date().getTime() - data.timestamp > 60000) { + return Promise.reject("预加载数据过期"); + } + if ( + expectToken?.communityId && + expectToken.communityId !== token.communityId + ) { + return Promise.reject("社区id不匹配"); + } + if (expectToken?.userId && expectToken.userId !== token.userId) { + return Promise.reject("用户id不匹配"); + } + if (expectToken?.env && expectToken.env !== token.env) { + return Promise.reject("环境不匹配"); + } + return data; +} diff --git a/src/apis/schemas.ts b/src/apis/schemas.ts index 19103115..e7b5d7e7 100644 --- a/src/apis/schemas.ts +++ b/src/apis/schemas.ts @@ -21,6 +21,7 @@ export interface User { article: number; follower: number; following: number; + enableDebug?: boolean; } export interface Auth { @@ -32,12 +33,13 @@ export interface Auth { export interface Comment { id: string; - likes: number; + likeCount: number; createAt: number; text: string; user: User; - comments: number; - replyName?: string; + comments?: number; + replyUser?: User; + isLiked?: boolean; } // post @@ -52,9 +54,10 @@ export interface Post { tags: Tag[]; likes: number; comments: number; - user: User; + user?: User; status: number; isOfficial: boolean; + isLiked?: boolean; } export interface Tag { @@ -128,24 +131,14 @@ export interface Moment { id: string; createAt: number; title: string; - catId?: string; + cats?: Array; communityId: string; text: string; user: User; photos: Array; -} - -export interface MomentData { - id: string; - createAt: number; - title: string; - catId?: string; - communityId: string; - text: string; - user: User; - photos: Array; - likedNumber: number; - comments: number; + likeCount: number; + commentCount: number; + isLiked: boolean; } export const enum TargetType { diff --git a/src/apis/user/user-interfaces.ts b/src/apis/user/user-interfaces.ts index 05466a26..61131d64 100644 --- a/src/apis/user/user-interfaces.ts +++ b/src/apis/user/user-interfaces.ts @@ -4,7 +4,6 @@ export interface GetUserInfoResp { code: number; msg: string; user: User; - enableDebug: boolean; } export interface GetUserInfoReq { diff --git a/src/apis/user/user.ts b/src/apis/user/user.ts index 785756bf..15786ade 100644 --- a/src/apis/user/user.ts +++ b/src/apis/user/user.ts @@ -5,22 +5,33 @@ import { UpdateUserInfoResp } from "./user-interfaces"; import { PictureStyle } from "@/apis/cos/cos-interface"; +import { getPrefetchData } from "@/apis/prefetch"; export async function getUserInfo(req: GetUserInfoReq) { - return await new Promise((resolve, reject) => { - uni.request({ - url: "/user/get_user_info", - data: req, - method: "GET", - success(res: UniNamespace.RequestSuccessCallbackResult) { - if (res.statusCode !== 200) { - reject(res); + return new Promise((resolve, reject) => { + getPrefetchData({ userId: req.userId }) + .then((res) => { + if (!res.getUserInfoResp?.user) { + return Promise.reject("预拉取数据没有用户信息"); } - const data = res.data as GetUserInfoResp; - data.user.avatarUrl += PictureStyle.thumbnail; - resolve(data); - } - }); + resolve(res.getUserInfoResp); + res.getUserInfoResp = undefined; + }) + .catch(() => { + uni.request({ + url: "/user/get_user_info", + data: req, + method: "GET", + success(res: UniNamespace.RequestSuccessCallbackResult) { + if (res.statusCode !== 200) { + reject(res); + } + const data = res.data as GetUserInfoResp; + data.user.avatarUrl += PictureStyle.thumbnail; + resolve(data); + } + }); + }); }); } diff --git a/src/components/BottomBar/BottomBarContent.vue b/src/components/BottomBar/BottomBarContent.vue index fb67238d..80c8b1a1 100644 --- a/src/components/BottomBar/BottomBarContent.vue +++ b/src/components/BottomBar/BottomBarContent.vue @@ -4,7 +4,7 @@ v-for="item in tabContent" :key="item.id" class="tab" - @click="item.id === 'draft' ? draft(item.url) : tabChange(item.url)" + @click="item.id === 'draft' ? draft() : tabChange(item.url)" > { }; const draft = () => { emits("toggleShowingDraft", true); - // if (props.id === "draft") { - // uni.navigateTo({ - // url: path - // }); - // } else { - // uni.navigateTo({ - // url: momentUrl - // }); - // } }; diff --git a/src/components/DebugPanel.vue b/src/components/DebugPanel.vue index 2c86f9e6..22ba4a94 100644 --- a/src/components/DebugPanel.vue +++ b/src/components/DebugPanel.vue @@ -57,6 +57,8 @@ import { Pages } from "@/utils/url"; import { BackendEnv, StorageKeys } from "@/utils/const"; const reboot = () => { + uni.removeStorageSync(StorageKeys.UserId); + uni.removeStorageSync(StorageKeys.AccessToken); uni.reLaunch({ url: Pages.FirstPage }); diff --git a/src/env.d.ts b/src/env.d.ts index e32e8289..7caaa1f2 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -14,6 +14,7 @@ declare module "*.vue" { interface ImportMetaEnv extends Readonly> { readonly VITE_BASIC_URL: string; readonly VITE_NAME: string; + readonly VITE_ENABLE_DEBUG: boolean; } interface ImportMeta { diff --git a/src/interceptor.ts b/src/interceptor.ts index 91c21627..b7d4a3a5 100644 --- a/src/interceptor.ts +++ b/src/interceptor.ts @@ -1,4 +1,4 @@ -import { StorageKeys } from "@/utils/const"; +import { BackendEnvMap, StorageKeys } from "@/utils/const"; export function createInterceptors() { uni.addInterceptor("request", { @@ -7,20 +7,23 @@ export function createInterceptors() { const env = uni.getStorageSync(StorageKeys.BackendEnv); const lane = uni.getStorageSync(StorageKeys.BackendLane); args.url = import.meta.env.VITE_BASIC_URL + args.url; - // console.log({ - // Authorization: uni.getStorageSync(StorageKeys.AccessToken), - // "X-Xh-Env": env ? env : import.meta.env.VITE_XH_ENV, - // "X-Xh-Lane": lane ? lane : "" - // }); args.header = { - Authorization: uni.getStorageSync(StorageKeys.AccessToken), - // "X-Xh-Env": "", - // "X-Xh-Lane": "" - "X-Xh-Env": env ? env : import.meta.env.VITE_XH_ENV, + Authorization: uni.getStorageSync(StorageKeys.AccessToken).token, + "X-Xh-Env": env + ? env + : BackendEnvMap[uni.getAccountInfoSync().miniProgram.envVersion], "X-Xh-Lane": lane ? lane : "" }; } }, + success(result: any) { + if (result.statusCode >= 400) { + uni.showToast({ + title: "请求失败", + icon: "error" + }); + } + }, fail() { uni.showToast({ title: "网络异常", diff --git a/src/main.ts b/src/main.ts index 3f599850..7b5f8b46 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,12 +2,14 @@ import { createSSRApp } from "vue"; import { createPinia } from "pinia"; import { createInterceptors } from "@/interceptor"; import App from "./App.vue"; +import share from "./utils/share"; createInterceptors(); export function createApp() { const app = createSSRApp(App); const pinia = createPinia(); + app.mixin(share); app.use(pinia); return { app diff --git a/src/pages.json b/src/pages.json index d70d89d9..86172fae 100644 --- a/src/pages.json +++ b/src/pages.json @@ -200,10 +200,10 @@ "text": "社区" }, { - "pagePath": "pages/plan/plan", + "pagePath": "pages/collection/collection", "iconPath": "static/images/collection-grey.png", "selectedIconPath": "static/images/collection-blue.png", - "text": "小鱼干" + "text": "图鉴" }, { "pagePath": "pages/world/world", diff --git a/src/pages/collection/collection.vue b/src/pages/collection/collection.vue index a45d29e2..b9e471f6 100644 --- a/src/pages/collection/collection.vue +++ b/src/pages/collection/collection.vue @@ -15,7 +15,7 @@ > @@ -48,33 +48,22 @@ - @@ -205,6 +175,7 @@ onShow(() => { display: flex; flex-direction: column; width: 100vw; + height: 100vh; } .switch { diff --git a/src/pages/community/CarouselFrame.vue b/src/pages/community/CarouselFrame.vue index fa83c4bf..7b4270db 100644 --- a/src/pages/community/CarouselFrame.vue +++ b/src/pages/community/CarouselFrame.vue @@ -1,23 +1,33 @@ diff --git a/src/pages/community/CarouselTest.vue b/src/pages/community/CarouselTest.vue index 0a1a7f25..61464909 100644 --- a/src/pages/community/CarouselTest.vue +++ b/src/pages/community/CarouselTest.vue @@ -1,5 +1,5 @@ diff --git a/src/pages/community/CollectionEntry.vue b/src/pages/community/CollectionEntry.vue index 9837b2fc..126a836c 100644 --- a/src/pages/community/CollectionEntry.vue +++ b/src/pages/community/CollectionEntry.vue @@ -1,5 +1,5 @@ diff --git a/src/pages/community/Masonry.vue b/src/pages/community/Masonry.vue index a6cf2c1a..880cd024 100644 --- a/src/pages/community/Masonry.vue +++ b/src/pages/community/Masonry.vue @@ -47,14 +47,14 @@ - {{ moment.likedNumber }}位喵友觉得很赞 + {{ moment.likeCount }}位喵友觉得很赞 - {{ moment.comments }}条回复{{ moment.commentCount }}条回复 @@ -70,13 +70,11 @@ diff --git a/src/pages/community/community.vue b/src/pages/community/community.vue index e99d71c9..f513ba43 100644 --- a/src/pages/community/community.vue +++ b/src/pages/community/community.vue @@ -26,7 +26,7 @@ - + @@ -38,7 +38,7 @@