feat(widget): 新增评论组件核心功能及开发环境配置
新增评论组件核心功能,包括评论列表、分页、回复、表单验证等功能 添加开发环境配置,包括Vite构建配置、样式变量和工具函数 实现管理员验证功能,支持本地存储加密 添加组件基础类及常用组件如加载状态、分页、模态框等 配置文档站点构建流程,支持widget独立构建和集成
This commit is contained in:
123
docs/widget/src/core/api.js
Normal file
123
docs/widget/src/core/api.js
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* API 请求封装
|
||||
*/
|
||||
|
||||
/**
|
||||
* 创建 API 客户端
|
||||
* @param {Object} config - 配置对象
|
||||
* @param {string} config.apiBaseUrl - API 基础地址
|
||||
* @param {string} config.postSlug - 文章标识符
|
||||
* @param {string} config.postTitle - 文章标题(可选)
|
||||
* @param {string} config.postUrl - 文章 URL(可选)
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function createApiClient(config) {
|
||||
const baseUrl = config.apiBaseUrl.replace(/\/$/, '');
|
||||
|
||||
/**
|
||||
* 获取评论列表
|
||||
* @param {number} page - 页码
|
||||
* @param {number} limit - 每页数量
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
async function fetchComments(page = 1, limit = 20) {
|
||||
const params = new URLSearchParams({
|
||||
post_slug: config.postSlug,
|
||||
page: page.toString(),
|
||||
limit: limit.toString(),
|
||||
nested: 'true',
|
||||
});
|
||||
|
||||
if (config.avatarPrefix) {
|
||||
params.set('avatar_prefix', config.avatarPrefix);
|
||||
}
|
||||
|
||||
const response = await fetch(`${baseUrl}/api/comments?${params}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`获取评论失败:${response.status} ${response.statusText}`);
|
||||
}
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交评论
|
||||
* @param {Object} data - 评论数据
|
||||
* @param {string} data.name - 昵称
|
||||
* @param {string} data.email - 邮箱
|
||||
* @param {string} data.url - 网址(可选)
|
||||
* @param {string} data.content - 评论内容
|
||||
* @param {number} data.parentId - 父评论 ID(可选,用于回复)
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
async function submitComment(data) {
|
||||
const response = await fetch(`${baseUrl}/api/comments`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
post_slug: config.postSlug,
|
||||
post_title: config.postTitle,
|
||||
post_url: config.postUrl,
|
||||
name: data.name,
|
||||
email: data.email,
|
||||
url: data.url || undefined,
|
||||
content: data.content,
|
||||
parent_id: data.parentId,
|
||||
adminToken: data.adminToken
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
// Try to parse error message
|
||||
let msg = response.statusText;
|
||||
try {
|
||||
const json = await response.json();
|
||||
if (json.message) msg = json.message;
|
||||
} catch (e) {}
|
||||
throw new Error(msg);
|
||||
}
|
||||
return response.json();
|
||||
}
|
||||
|
||||
async function verifyAdminKey(key) {
|
||||
const response = await fetch(`${baseUrl}/api/verify-admin`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ adminToken: key })
|
||||
});
|
||||
if (!response.ok) {
|
||||
let msg = response.statusText;
|
||||
try {
|
||||
const json = await response.json();
|
||||
if (json.message) msg = json.message;
|
||||
} catch (e) {}
|
||||
throw new Error(msg);
|
||||
}
|
||||
return response.json();
|
||||
}
|
||||
|
||||
async function trackVisit() {
|
||||
try {
|
||||
await fetch(`${baseUrl}/api/analytics/visit`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
postSlug: config.postSlug,
|
||||
postTitle: config.postTitle,
|
||||
postUrl: config.postUrl
|
||||
})
|
||||
});
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
fetchComments,
|
||||
submitComment,
|
||||
verifyAdminKey,
|
||||
trackVisit
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user