From eb44980484862e6ab15e24c6c629fc613229f01a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=8E=AB=E5=94=90=E5=B0=BC?= Date: Wed, 9 Sep 2026 20:41:00 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=BB=93=E6=9E=84=E4=B8=8E=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BB=86=E8=8A=82=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增首页精选分类配置类型定义与逻辑,支持自定义首页分类展示顺序 2. 移除冗余的qs导入与注释代码,简化请求参数处理 3. 修复瞬间详情页悬浮操作的渲染问题与收藏按钮样式 4. 优化文章卡片的头像处理与分类跳转逻辑 5. 重构数据加载组件,新增尺寸配置与样式优化 6. 为分类文章页添加排序切换功能,支持默认/置顶/最新/最旧排序 7. 优化首页分类模块的加载状态与数据获取逻辑,添加延迟模拟 8. 统一API文件的导入格式与代码风格 --- src/api/halo.ts | 294 +++++++++--------- src/api/types/uni-halo.ts | 6 + .../uh-article-card/uh-article-card.vue | 17 +- .../uh-data-loading/uh-data-loading.vue | 60 ++-- .../uh-home-category/uh-home-category.vue | 90 +++--- src/http/interceptor.ts | 11 + .../category-articles/category-articles.vue | 75 +++-- .../moment-detail/moment-detail.vue | 6 +- 8 files changed, 307 insertions(+), 252 deletions(-) diff --git a/src/api/halo.ts b/src/api/halo.ts index ec90675..74ab70b 100644 --- a/src/api/halo.ts +++ b/src/api/halo.ts @@ -1,41 +1,41 @@ /** * Halo 官方 API 接口定义 */ -import { http } from '@/http/alova' -import { RequestFrom } from '@/http/tools/enum' -import type { IResponse } from '@/http/types' -import { getCache } from '@/utils/storage' -import { getNologinEmail, getOpenid } from '@/utils/auth' +import { http } from '@/http/alova'; +import { RequestFrom } from '@/http/tools/enum'; +import type { IResponse } from '@/http/types'; +import { getCache } from '@/utils/storage'; +import { getNologinEmail, getOpenid } from '@/utils/auth'; import type { - IBlogStats, - ICategory, - ICategoryListReq, - ICategoryListRes, - IComment, - ICommentListReq, - ICommentListRes, - ILink, - ILinkGroup, - ILinkListRes, - IMoment, - IMomentListReq, - IMomentListRes, - IPhotoGroupListReq, - IPhotoGroupListRes, - IPhotoListReq, - IPhotoListRes, - IPost, - IPostListReq, - IPostListRes, - ISearchReq, - ISearchRes, - ITagListRes, - ITrackerCounterReq, - IUpvoteReq, -} from './types/halo' + IBlogStats, + ICategory, + ICategoryListReq, + ICategoryListRes, + IComment, + ICommentListReq, + ICommentListRes, + ILink, + ILinkGroup, + ILinkListRes, + IMoment, + IMomentListReq, + IMomentListRes, + IPhotoGroupListReq, + IPhotoGroupListRes, + IPhotoListReq, + IPhotoListRes, + IPost, + IPostListReq, + IPostListRes, + ISearchReq, + ISearchRes, + ITagListRes, + ITrackerCounterReq, + IUpvoteReq +} from './types/halo'; /** 评论验证码 cookie key */ -const COMMENT_WIDGET_CAPTCHA_COOKIES = 'comment-widget-captcha' +const COMMENT_WIDGET_CAPTCHA_COOKIES = 'comment-widget-captcha'; /* ==================== 文章 ==================== */ @@ -43,76 +43,74 @@ const COMMENT_WIDGET_CAPTCHA_COOKIES = 'comment-widget-captcha' * 文章列表 */ export function getPostList(params: IPostListReq) { - return http.Get>('/apis/api.content.halo.run/v1alpha1/posts', { - query: params, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>('/apis/api.content.halo.run/v1alpha1/posts', { + query: params, + meta: { requestFrom: RequestFrom.Halo } + }); } /** * 文章详情(带访客标识头) */ export function getPostByName(name: string) { - return http.Get>(`/apis/api.content.halo.run/v1alpha1/posts/${name}`, { - headers: { - 'Wechat-Session-Id': getOpenid(), - 'nologin-email': getNologinEmail(), - }, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>(`/apis/api.content.halo.run/v1alpha1/posts/${name}`, { + headers: { + 'Wechat-Session-Id': getOpenid(), + 'nologin-email': getNologinEmail() + }, + meta: { requestFrom: RequestFrom.Halo } + }); } /** * 关键词搜索文章 */ export function getPostListByKeyword(params: ISearchReq) { - return http.Post>('/apis/api.halo.run/v1alpha1/indices/-/search', params, { - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Post>('/apis/api.halo.run/v1alpha1/indices/-/search', params, { + meta: { requestFrom: RequestFrom.Halo } + }); } /* ==================== 分类 / 标签 ==================== */ /** * 分类列表 - * 注:旧代码用 qs.stringify 特殊序列化(arrayFormat:'repeat'、allowDots), - * alova 的 params 对数组默认即 repeat 形式(a=1&a=2),已等价;如遇嵌套对象场景再单独处理 */ export function getCategoryList(params: ICategoryListReq) { - return http.Get>('/apis/api.content.halo.run/v1alpha1/categories', { - params, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>('/apis/api.content.halo.run/v1alpha1/categories', { + params, + meta: { requestFrom: RequestFrom.Halo } + }); } /** * 分类下文章列表 */ export function getCategoryPostList(name: string, params: IPostListReq) { - return http.Get>(`/apis/api.content.halo.run/v1alpha1/categories/${name}/posts`, { - params, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>(`/apis/api.content.halo.run/v1alpha1/categories/${name}/posts`, { + params, + meta: { requestFrom: RequestFrom.Halo } + }); } /** * 标签列表 */ export function getTagList(params: ICategoryListReq) { - return http.Get>('/apis/api.content.halo.run/v1alpha1/tags', { - params, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>('/apis/api.content.halo.run/v1alpha1/tags', { + params, + meta: { requestFrom: RequestFrom.Halo } + }); } /** * 标签下文章列表 */ export function getPostByTagName(tagName: string, params: IPostListReq) { - return http.Get>(`/apis/api.content.halo.run/v1alpha1/tags/${tagName}/posts`, { - params, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>(`/apis/api.content.halo.run/v1alpha1/tags/${tagName}/posts`, { + params, + meta: { requestFrom: RequestFrom.Halo } + }); } /* ==================== 评论(含验证码 cookie 链路) ==================== */ @@ -121,77 +119,73 @@ export function getPostByTagName(tagName: string, params: IPostListReq) { * 评论列表 */ export function getPostCommentList(params: ICommentListReq) { - return http.Get>('/apis/api.halo.run/v1alpha1/comments', { - params, - cacheFor: 0, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>('/apis/api.halo.run/v1alpha1/comments', { + params, + cacheFor: 0, + meta: { requestFrom: RequestFrom.Halo } + }); } /** * 评论回复列表 */ export function getPostCommentReplyList(commentName: string, params: ICommentListReq) { - return http.Get>(`/apis/api.halo.run/v1alpha1/comments/${commentName}/reply`, { - params, - cacheFor: 0, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>(`/apis/api.halo.run/v1alpha1/comments/${commentName}/reply`, { + params, + cacheFor: 0, + meta: { requestFrom: RequestFrom.Halo } + }); } /** 新增评论(带验证码,captchaCode 转入请求头) */ export interface IAddCommentReq { - allowNotification: boolean - raw: string - content?: string - owner?: Record - /** 评论目标引用(subjectRef: group/kind/name/version) */ - subjectRef?: { - group: string - kind: string - name: string - version?: string - } - /** 验证码,提交时转入 X-Captcha-Code 头 */ - captchaCode?: string + allowNotification: boolean; + raw: string; + content?: string; + owner?: Record; + /** 评论目标引用(subjectRef: group/kind/name/version) */ + subjectRef?: { + group: string; + kind: string; + name: string; + version?: string; + }; + /** 验证码,提交时转入 X-Captcha-Code 头 */ + captchaCode?: string; } /** * 新增评论(captchaCode 拆出转 X-Captcha-Code 头 + Cookie) */ export function addPostComment(data: IAddCommentReq) { - const { captchaCode, ...rest } = data - const headers: Record = { - Accept: 'application/json', - } - if (captchaCode) - headers['X-Captcha-Code'] = captchaCode - const cookie = getCache(COMMENT_WIDGET_CAPTCHA_COOKIES) - if (cookie) - headers.Cookie = cookie - return http.Post>('/apis/api.halo.run/v1alpha1/comments', rest, { - headers, - meta: { requestFrom: RequestFrom.Halo }, - }) + const { captchaCode, ...rest } = data; + const headers: Record = { + Accept: 'application/json' + }; + if (captchaCode) headers['X-Captcha-Code'] = captchaCode; + const cookie = getCache(COMMENT_WIDGET_CAPTCHA_COOKIES); + if (cookie) headers.Cookie = cookie; + return http.Post>('/apis/api.halo.run/v1alpha1/comments', rest, { + headers, + meta: { requestFrom: RequestFrom.Halo } + }); } /** * 新增评论回复(同上,验证码逻辑) */ export function addPostCommentReply(commentName: string, data: IAddCommentReq) { - const { captchaCode, ...rest } = data - const headers: Record = { - Accept: 'application/json', - } - if (captchaCode) - headers['X-Captcha-Code'] = captchaCode - const cookie = getCache(COMMENT_WIDGET_CAPTCHA_COOKIES) - if (cookie) - headers.Cookie = cookie - return http.Post>(`/apis/api.halo.run/v1alpha1/comments/${commentName}/reply`, rest, { - headers, - meta: { requestFrom: RequestFrom.Halo }, - }) + const { captchaCode, ...rest } = data; + const headers: Record = { + Accept: 'application/json' + }; + if (captchaCode) headers['X-Captcha-Code'] = captchaCode; + const cookie = getCache(COMMENT_WIDGET_CAPTCHA_COOKIES); + if (cookie) headers.Cookie = cookie; + return http.Post>(`/apis/api.halo.run/v1alpha1/comments/${commentName}/reply`, rest, { + headers, + meta: { requestFrom: RequestFrom.Halo } + }); } /* ==================== 瞬间 ==================== */ @@ -200,19 +194,19 @@ export function addPostCommentReply(commentName: string, data: IAddCommentReq) { * 瞬间列表 */ export function getMomentList(params: IMomentListReq) { - return http.Get>('/apis/api.moment.halo.run/v1alpha1/moments', { - params, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>('/apis/api.moment.halo.run/v1alpha1/moments', { + params, + meta: { requestFrom: RequestFrom.Halo } + }); } /** * 瞬间详情 */ export function getMomentByName(name: string) { - return http.Get>(`/apis/api.moment.halo.run/v1alpha1/moments/${name}`, { - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>(`/apis/api.moment.halo.run/v1alpha1/moments/${name}`, { + meta: { requestFrom: RequestFrom.Halo } + }); } /* ==================== 图库 ==================== */ @@ -221,20 +215,20 @@ export function getMomentByName(name: string) { * 相册分组列表 */ export function getPhotoGroupList(params: IPhotoGroupListReq) { - return http.Get>('/apis/api.photo.halo.run/v1alpha1/photogroups', { - params, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>('/apis/api.photo.halo.run/v1alpha1/photogroups', { + params, + meta: { requestFrom: RequestFrom.Halo } + }); } /** * 照片列表(按相册) */ export function getPhotoListByGroupName(params: IPhotoListReq) { - return http.Get>('/apis/api.photo.halo.run/v1alpha1/photos', { - params, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>('/apis/api.photo.halo.run/v1alpha1/photos', { + params, + meta: { requestFrom: RequestFrom.Halo } + }); } /* ==================== 友链 ==================== */ @@ -243,20 +237,20 @@ export function getPhotoListByGroupName(params: IPhotoListReq) { * 友链分组列表 */ export function getFriendLinkGroupList(params: ICategoryListReq) { - return http.Get>>('/apis/api.link.halo.run/v1alpha1/linkgroups', { - params, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>>('/apis/api.link.halo.run/v1alpha1/linkgroups', { + params, + meta: { requestFrom: RequestFrom.Halo } + }); } /** * 友链列表 */ export function getFriendLinkList(params: ICategoryListReq) { - return http.Get>('/apis/api.link.halo.run/v1alpha1/links', { - params, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>('/apis/api.link.halo.run/v1alpha1/links', { + params, + meta: { requestFrom: RequestFrom.Halo } + }); } /* ==================== 统计 / 埋点 / 插件 ==================== */ @@ -265,38 +259,38 @@ export function getFriendLinkList(params: ICategoryListReq) { * 博客统计信息 */ export function getBlogStatistics() { - return http.Get>('/apis/api.halo.run/v1alpha1/stats/-', { - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>('/apis/api.halo.run/v1alpha1/stats/-', { + meta: { requestFrom: RequestFrom.Halo } + }); } /** * 提交点赞 */ export function submitUpvote(data: IUpvoteReq) { - return http.Post>('/apis/api.halo.run/v1alpha1/trackers/upvote', data, { - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Post>('/apis/api.halo.run/v1alpha1/trackers/upvote', data, { + meta: { requestFrom: RequestFrom.Halo } + }); } /** * 提交计数埋点 */ export function postTrackersCounter(data: ITrackerCounterReq) { - return http.Post>('/apis/api.halo.run/v1alpha1/trackers/counter', data, { - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Post>('/apis/api.halo.run/v1alpha1/trackers/counter', data, { + meta: { requestFrom: RequestFrom.Halo } + }); } /** * 检查插件是否可用 */ export function checkPluginAvailable(name: string) { - return http.Get>(`/apis/api.plugin.halo.run/v1alpha1/plugins/${name}/available`, { - cacheFor: 0, - meta: { requestFrom: RequestFrom.Halo }, - }) + return http.Get>(`/apis/api.plugin.halo.run/v1alpha1/plugins/${name}/available`, { + cacheFor: 0, + meta: { requestFrom: RequestFrom.Halo } + }); } /** 分类资源(供加密分类判断等场景) */ -export type { ICategory, ILink, IMoment, IPost } +export type { ICategory, ILink, IMoment, IPost }; diff --git a/src/api/types/uni-halo.ts b/src/api/types/uni-halo.ts index 71bd88b..c26be20 100644 --- a/src/api/types/uni-halo.ts +++ b/src/api/types/uni-halo.ts @@ -63,6 +63,12 @@ export interface IPageConfig { /** 是否显示快捷导航(首页) */ useQuickNavigation?: boolean bannerConfig?: IBannerConfig + /** 首页精选分类引用(插件端「通用配置 → 页面设置 → 首页」配置,固定最多 3 个, + * 数组顺序 = 展示顺序;未配置/为空时客户端回退默认取数) */ + categories?: Array<{ + name: string + displayName?: string + }> } categoryConfig?: { type?: string } momentConfig?: { useTagRandomColor?: boolean } diff --git a/src/components/uh-article-card/uh-article-card.vue b/src/components/uh-article-card/uh-article-card.vue index a6314d6..7d6d416 100644 --- a/src/components/uh-article-card/uh-article-card.vue +++ b/src/components/uh-article-card/uh-article-card.vue @@ -1,6 +1,6 @@