- 积分规则: 添加 update/delete service + handler + 路由 - 兑换商品: 添加 update/delete service + handler + 路由 - 文章标签: 添加 update service + handler + 路由 - Web 管理端: 规则/商品列表页支持编辑/删除/启用切换 - Web 管理端: 标签管理页支持编辑、删除传 version
271 lines
6.0 KiB
TypeScript
271 lines
6.0 KiB
TypeScript
import client from '../client';
|
|
import type { PaginatedResponse } from '../types';
|
|
|
|
// --- Article Types ---
|
|
|
|
export type ArticleStatus = 'draft' | 'pending_review' | 'published' | 'rejected';
|
|
export type ArticleContentType = 'rich_text' | 'markdown';
|
|
|
|
export interface ArticleListItem {
|
|
id: string;
|
|
title: string;
|
|
summary?: string;
|
|
cover_image?: string;
|
|
content_type: ArticleContentType;
|
|
status: ArticleStatus;
|
|
slug?: string;
|
|
category_id?: string;
|
|
category_name?: string;
|
|
tags?: ArticleTagItem[];
|
|
author?: string;
|
|
reviewed_by?: string;
|
|
reviewed_at?: string;
|
|
review_note?: string;
|
|
view_count: number;
|
|
sort_order: number;
|
|
published_at?: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
version: number;
|
|
}
|
|
|
|
export interface Article extends ArticleListItem {
|
|
content?: string;
|
|
}
|
|
|
|
export interface CreateArticleReq {
|
|
title: string;
|
|
summary?: string;
|
|
content?: string;
|
|
content_type?: ArticleContentType;
|
|
cover_image?: string;
|
|
slug?: string;
|
|
category_id?: string;
|
|
tag_ids?: string[];
|
|
sort_order?: number;
|
|
}
|
|
|
|
export interface UpdateArticleReq {
|
|
title?: string;
|
|
summary?: string;
|
|
content?: string;
|
|
content_type?: ArticleContentType;
|
|
cover_image?: string;
|
|
slug?: string;
|
|
category_id?: string;
|
|
tag_ids?: string[];
|
|
sort_order?: number;
|
|
version: number;
|
|
}
|
|
|
|
export interface ArticleListParams {
|
|
page?: number;
|
|
page_size?: number;
|
|
status?: ArticleStatus;
|
|
category_id?: string;
|
|
tag_id?: string;
|
|
keyword?: string;
|
|
}
|
|
|
|
// --- Category Types ---
|
|
|
|
export interface ArticleCategory {
|
|
id: string;
|
|
name: string;
|
|
slug?: string;
|
|
parent_id?: string;
|
|
parent_name?: string;
|
|
sort_order: number;
|
|
description?: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
export interface CreateCategoryReq {
|
|
name: string;
|
|
slug?: string;
|
|
parent_id?: string;
|
|
sort_order?: number;
|
|
description?: string;
|
|
}
|
|
|
|
export interface UpdateCategoryReq {
|
|
name?: string;
|
|
slug?: string;
|
|
parent_id?: string;
|
|
sort_order?: number;
|
|
description?: string;
|
|
}
|
|
|
|
// --- Tag Types ---
|
|
|
|
export interface ArticleTagItem {
|
|
id: string;
|
|
name: string;
|
|
slug?: string;
|
|
color?: string;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface CreateTagReq {
|
|
name: string;
|
|
slug?: string;
|
|
color?: string;
|
|
}
|
|
|
|
// --- Article API ---
|
|
|
|
export const articleApi = {
|
|
list: async (params: ArticleListParams) => {
|
|
const { data } = await client.get<{
|
|
success: boolean;
|
|
data: PaginatedResponse<ArticleListItem>;
|
|
}>('/health/articles', { params });
|
|
return data.data;
|
|
},
|
|
|
|
get: async (id: string) => {
|
|
const { data } = await client.get<{
|
|
success: boolean;
|
|
data: Article;
|
|
}>(`/health/articles/${id}`);
|
|
return data.data;
|
|
},
|
|
|
|
create: async (req: CreateArticleReq) => {
|
|
const { data } = await client.post<{
|
|
success: boolean;
|
|
data: Article;
|
|
}>('/health/articles', req);
|
|
return data.data;
|
|
},
|
|
|
|
update: async (id: string, req: UpdateArticleReq) => {
|
|
const { data } = await client.put<{
|
|
success: boolean;
|
|
data: Article;
|
|
}>(`/health/articles/${id}`, req);
|
|
return data.data;
|
|
},
|
|
|
|
delete: async (id: string) => {
|
|
const { data } = await client.delete<{
|
|
success: boolean;
|
|
data: null;
|
|
}>(`/health/articles/${id}`);
|
|
return data.data;
|
|
},
|
|
|
|
submit: async (id: string, version: number) => {
|
|
const { data } = await client.post<{
|
|
success: boolean;
|
|
data: Article;
|
|
}>(`/health/articles/${id}/submit`, { version });
|
|
return data.data;
|
|
},
|
|
|
|
approve: async (id: string, version: number) => {
|
|
const { data } = await client.post<{
|
|
success: boolean;
|
|
data: Article;
|
|
}>(`/health/articles/${id}/approve`, { version });
|
|
return data.data;
|
|
},
|
|
|
|
reject: async (id: string, version: number, review_note: string) => {
|
|
const { data } = await client.post<{
|
|
success: boolean;
|
|
data: Article;
|
|
}>(`/health/articles/${id}/reject`, { version, review_note });
|
|
return data.data;
|
|
},
|
|
|
|
unpublish: async (id: string, version: number) => {
|
|
const { data } = await client.post<{
|
|
success: boolean;
|
|
data: Article;
|
|
}>(`/health/articles/${id}/unpublish`, { version });
|
|
return data.data;
|
|
},
|
|
|
|
view: async (id: string) => {
|
|
const { data } = await client.post<{
|
|
success: boolean;
|
|
data: Article;
|
|
}>(`/health/articles/${id}/view`);
|
|
return data.data;
|
|
},
|
|
};
|
|
|
|
// --- Category API ---
|
|
|
|
export const articleCategoryApi = {
|
|
list: async () => {
|
|
const { data } = await client.get<{
|
|
success: boolean;
|
|
data: ArticleCategory[];
|
|
}>('/health/article-categories');
|
|
return data.data;
|
|
},
|
|
|
|
create: async (req: CreateCategoryReq) => {
|
|
const { data } = await client.post<{
|
|
success: boolean;
|
|
data: ArticleCategory;
|
|
}>('/health/article-categories', req);
|
|
return data.data;
|
|
},
|
|
|
|
update: async (id: string, req: UpdateCategoryReq) => {
|
|
const { data } = await client.put<{
|
|
success: boolean;
|
|
data: ArticleCategory;
|
|
}>(`/health/article-categories/${id}`, req);
|
|
return data.data;
|
|
},
|
|
|
|
delete: async (id: string) => {
|
|
const { data } = await client.delete<{
|
|
success: boolean;
|
|
data: null;
|
|
}>(`/health/article-categories/${id}`);
|
|
return data.data;
|
|
},
|
|
};
|
|
|
|
// --- Tag API ---
|
|
|
|
export const articleTagApi = {
|
|
list: async () => {
|
|
const { data } = await client.get<{
|
|
success: boolean;
|
|
data: ArticleTagItem[];
|
|
}>('/health/article-tags');
|
|
return data.data;
|
|
},
|
|
|
|
create: async (req: CreateTagReq) => {
|
|
const { data } = await client.post<{
|
|
success: boolean;
|
|
data: ArticleTagItem;
|
|
}>('/health/article-tags', req);
|
|
return data.data;
|
|
},
|
|
|
|
update: async (id: string, req: { name: string; version: number }) => {
|
|
const { data } = await client.put<{
|
|
success: boolean;
|
|
data: ArticleTagItem;
|
|
}>(`/health/article-tags/${id}`, req);
|
|
return data.data;
|
|
},
|
|
|
|
delete: async (id: string, version: number) => {
|
|
const { data } = await client.delete<{
|
|
success: boolean;
|
|
data: null;
|
|
}>(`/health/article-tags/${id}`, { data: { version } });
|
|
return data.data;
|
|
},
|
|
};
|