diff --git a/src/api/halo.ts b/src/api/halo.ts index f3a99be..f1a603b 100644 --- a/src/api/halo.ts +++ b/src/api/halo.ts @@ -1,42 +1,42 @@ /** * 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, - ILinkGroupListRes, - ILinkListRes, - IMoment, - IMomentListReq, - IMomentListRes, - IPhotoGroupListReq, - IPhotoGroupListRes, - IPhotoListReq, - IPhotoListRes, - IPluginAvailable, - IPost, - IPostListReq, - IPostListRes, - ISearchReq, - ISearchRes, - ITagListRes, - ITrackerCounterReq, - IUpvoteReq -} from './types/halo'; + IBlogStats, + ICategory, + ICategoryListReq, + ICategoryListRes, + IComment, + ICommentListReq, + ICommentListRes, + ILink, + ILinkGroupListRes, + ILinkListRes, + IMoment, + IMomentListReq, + IMomentListRes, + IPhotoGroupListReq, + IPhotoGroupListRes, + IPhotoListReq, + IPhotoListRes, + IPluginAvailable, + 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' /* ==================== 文章 ==================== */ @@ -44,32 +44,32 @@ 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', { + 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 }, + }) } /* ==================== 分类 / 标签 ==================== */ @@ -80,40 +80,40 @@ export function getPostListByKeyword(params: ISearchReq) { * 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 链路) ==================== */ @@ -122,71 +122,75 @@ export function getPostByTagName(tagName: string, params: IPostListReq) { * 评论列表 */ export function getPostCommentList(params: ICommentListReq) { - return http.Get>('/apis/api.halo.run/v1alpha1/comments', { - params, - meta: { requestFrom: RequestFrom.Halo } - }); + return http.Get>('/apis/api.halo.run/v1alpha1/comments', { + params, + meta: { requestFrom: RequestFrom.Halo }, + }) } /** * 评论回复列表 */ export function getPostCommentReplyList(commentName: string, params: ICommentListReq) { - return http.Get>(`/apis/api.halo.run/v1alpha1/comments/${commentName}/reply`, { - params, - meta: { requestFrom: RequestFrom.Halo } - }); + return http.Get>(`/apis/api.halo.run/v1alpha1/comments/${commentName}/reply`, { + params, + 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 }, + }) } /* ==================== 瞬间 ==================== */ @@ -195,19 +199,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 }, + }) } /* ==================== 图库 ==================== */ @@ -216,20 +220,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 }, + }) } /* ==================== 友链 ==================== */ @@ -238,20 +242,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 }, + }) } /* ==================== 统计 / 埋点 / 插件 ==================== */ @@ -260,37 +264,37 @@ 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`, { - meta: { requestFrom: RequestFrom.Halo } - }); + return http.Get>(`/apis/api.plugin.halo.run/v1alpha1/plugins/${name}/available`, { + 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 20d25d0..80abc45 100644 --- a/src/api/types/uni-halo.ts +++ b/src/api/types/uni-halo.ts @@ -62,6 +62,28 @@ export interface IAuditConfig { } } +/** 审核模式数据(公开接口 GET /audit-data 返回) */ +export interface IAuditDataResult { + /** 审核模式开关(联动设置页 auditModeEnabled) */ + enabled: boolean + /** 选中的引用 name 列表(数组顺序即展示顺序;开关关闭时为空) */ + spec?: { + /** 选中的文章 Post metadata.name 列表 */ + posts?: string[] + /** 选中的分类 Category metadata.name 列表 */ + categories?: string[] + /** 选中的图库分组 PhotoGroup metadata.name 列表 */ + galleryGroups?: string[] + /** 选中的瞬间 Moment metadata.name 列表 */ + moments?: string[] + /** 选中的链接分组 LinkGroup metadata.name 列表 */ + linkGroups?: string[] + /** 备注 */ + description?: string + [key: string]: unknown + } +} + /** 应用基础配置(对应旧 DefaultAppConfigs) */ export interface IAppConfig { basicConfig?: { @@ -90,9 +112,6 @@ export interface IHaloGlobalConfig { [key: string]: unknown } -/** 审计模式模拟数据 */ -export type IMockJson = Record - /* ---------- plugin-uni-halo 二维码 / 检查更新 ---------- */ export interface IQRCodeInfo { @@ -310,4 +329,96 @@ export interface ILoveStoryListReq { [key: string]: unknown } +/* ---------- 小程序链接(plugin-uni-halo mini-program-links) ---------- */ + +/** 小程序链接 spec(对齐插件 MiniProgramLinkSpec) */ +export interface IMiniProgramLinkSpec { + /** 小程序名称 */ + displayName?: string + /** 太阳码(小程序码图片 URL,必填) */ + miniProgramCode?: string + /** 小程序地址(跳转链接) */ + link?: string + /** 作者昵称 */ + authorName?: string + /** 作者头像(图片 URL) */ + avatar?: string + /** 作者网站 */ + website?: string + /** 分组(引用分组 metadata.name;空=未分组) */ + groupName?: string + /** 描述 */ + description?: string + /** 预览图(多图) */ + screenshots?: string[] + /** 可见性(公开接口恒为 true) */ + visible?: boolean + /** 来源:manual 手动 / submitted 申请 */ + source?: string + /** 排序权重 */ + priority?: number + [key: string]: unknown +} + +/** 小程序链接 */ +export interface IMiniProgramLink { + metadata?: { + name?: string + creationTimestamp?: string + [key: string]: unknown + } + spec?: IMiniProgramLinkSpec +} + +export interface IMiniProgramLinkListReq { + page?: number + size?: number + [key: string]: unknown +} + +export type IMiniProgramLinkListRes = IMiniProgramLink[] + +/** grouped=true 分组返回项 */ +export interface IMiniProgramLinkGroupVo { + /** 分组名(空=未分组) */ + groupName?: string + /** 分组显示名 */ + displayName?: string + links: IMiniProgramLink[] +} + +export type IMiniProgramLinkGroupedRes = IMiniProgramLinkGroupVo[] + +/** 分组选项(/types) */ +export interface IMiniProgramLinkGroupOption { + name?: string + displayName?: string +} + +/** 提交申请表单(公开 POST /submissions,body 为 { spec: {...} }) */ +export interface IMiniProgramLinkSubmissionForm { + /** 小程序名称(必填) */ + displayName: string + /** 太阳码图片 URL(必填) */ + miniProgramCode: string + /** 小程序地址 */ + link?: string + /** 作者昵称 */ + authorName?: string + /** 作者头像 */ + avatar?: string + /** 作者网站 */ + website?: string + /** 分组 */ + groupName?: string + /** 描述 */ + description?: string + /** 申请说明 */ + applyRemark?: string + /** 预览图 */ + screenshots?: string[] + /** 申请人邮箱(非必填,填写校验格式) */ + email?: string +} + export type ILoveStoryListRes = ILoveStory[] diff --git a/src/api/uni-halo.ts b/src/api/uni-halo.ts index 97d7d6c..0df460b 100644 --- a/src/api/uni-halo.ts +++ b/src/api/uni-halo.ts @@ -14,6 +14,7 @@ import { getNologinEmail, getOpenid } from '@/utils/auth' import { getPersonalToken } from '@/store/token' import type { IAppConfig, + IAuditDataResult, ICommentWidgetConfig, IDoubanDetail, IHaloGlobalConfig, @@ -27,6 +28,10 @@ import type { ILoveStory, ILoveStoryListReq, ILoveStoryListRes, + IMiniProgramLink, + IMiniProgramLinkGroupedRes, + IMiniProgramLinkGroupOption, + IMiniProgramLinkSubmissionForm, IQRCodeInfo, IRestrictReadCheckReq, IRestrictReadCheckRes, @@ -53,6 +58,15 @@ export function getAppConfigs() { }) } +/** + * 获取审核模式数据(公开接口;auditModeEnabled=true 时返回选中引用列表,否则 {enabled:false}) + */ +export function getAuditData() { + return http.Get>('/apis/api.unihalo.ialley.cn/v1alpha1/plugins/plugin-uni-halo/audit-data', { + meta: { requestFrom: RequestFrom.Halo }, + }) +} + /** * 获取 Halo 全局配置信息 */ @@ -168,6 +182,60 @@ export function getLoveStories(params: ILoveStoryListReq) { }) } +/* ==================== 小程序链接(plugin-uni-halo) ==================== */ + +/** + * 获取小程序链接分组列表(grouped=true,仅可见,按分组聚合返回) + */ +export function getMiniProgramLinkGroupedList() { + return http.Get>( + '/apis/api.unihalo.ialley.cn/v1alpha1/plugins/plugin-uni-halo/mini-program-links', + { + params: { grouped: true }, + meta: { requestFrom: RequestFrom.Halo }, + }, + ) +} + +/** + * 获取小程序链接分组选项(/types,仅可见链接引用的分组) + */ +export function getMiniProgramLinkTypes() { + return http.Get>( + '/apis/api.unihalo.ialley.cn/v1alpha1/plugins/plugin-uni-halo/mini-program-links/types', + { + meta: { requestFrom: RequestFrom.Halo }, + }, + ) +} + +/** + * 获取小程序链接详情(仅可见,不存在返回 404) + */ +export function getMiniProgramLinkDetail(name: string) { + return http.Get>( + `/apis/api.unihalo.ialley.cn/v1alpha1/plugins/plugin-uni-halo/mini-program-links/${name}`, + { + meta: { requestFrom: RequestFrom.Halo }, + }, + ) +} + +/** + * 提交小程序链接申请(公开接口,落库为待审核;受 linkConfig.submissionEnabled 开关控制) + */ +export function submitMiniProgramLinkApplication(data: IMiniProgramLinkSubmissionForm) { + return http.Post>( + '/apis/api.unihalo.ialley.cn/v1alpha1/plugins/plugin-uni-halo/mini-program-links/submissions', + { + spec: data, + }, + { + meta: { requestFrom: RequestFrom.Halo }, + }, + ) +} + /* ==================== 受限阅读(tools.muyin.site) ==================== */ /** @@ -284,8 +352,8 @@ export function getDoubanDetail(url: string) { */ export function getCommentWidgetCaptcha() { return http.Get>('/apis/api.commentwidget.halo.run/v1alpha1/captcha/-/generate', { - cacheFor:0, - meta: { requestFrom: RequestFrom.Halo }, + cacheFor: 0, + meta: { requestFrom: RequestFrom.Halo }, }) } diff --git a/src/components/uh-mini-link-apply/uh-mini-link-apply.vue b/src/components/uh-mini-link-apply/uh-mini-link-apply.vue new file mode 100644 index 0000000..0ed62f9 --- /dev/null +++ b/src/components/uh-mini-link-apply/uh-mini-link-apply.vue @@ -0,0 +1,225 @@ + + +