refactor: 项目架构重构 - 目录标准化 + 清理冗余

- 目录重命名: backend/wdkj-server/ → server/, frontend/ai-dimension/ → client/
- 删除 20+ 冗余文件(WDKJ 旧脚本、Windows 脚本、过时文档、设计稿)
- 更新 package.json 元数据(移除 wdkj 命名)
- 完善三级 .gitignore(根 + server + client)
- 重写 README.md 和 CHANGELOG.md
- 工具脚本移至 scripts/
This commit is contained in:
Yuzhiran Dev
2026-07-11 12:45:37 +08:00
parent 66ac576082
commit c1d6dd3b29
106 changed files with 17436 additions and 2311 deletions
+202
View File
@@ -0,0 +1,202 @@
/**
* 宇之然AI维度 — API 工具
* 后端地址:wdkj.yuzhiran.com.cn (生产) / 127.0.0.1:3001 (开发)
*/
const BASE_URL = 'https://wdkj.yuzhiran.com.cn'
const DEV_URL = 'http://127.0.0.1:3001'
// 生产环境使用域名(SSL 已续期)
const API_BASE = 'https://wdkj.yuzhiran.com.cn'
/**
* 通用请求封装
*/
async function request(method, path, data = null, token = null) {
const url = `${API_BASE}${path}`
const headers = {
'Content-Type': 'application/json'
}
if (token) {
headers['Authorization'] = `Bearer ${token}`
}
try {
const res = await uni.request({
url,
method,
data,
header: headers,
timeout: 15000
})
const body = res.data
if (body.success) {
return body.data
}
throw new Error(body.error || '请求失败')
} catch (err) {
console.error(`[API] ${method} ${path} failed:`, err)
throw err
}
}
/**
* 认证相关
*/
export const authApi = {
/** 微信小程序登录 */
login: (code, userInfo) =>
request('POST', '/api/auth/login', { code, userInfo }),
/** H5 密码登录 */
h5Login: (username, password) =>
request('POST', '/api/auth/user/login', { username, password }),
/** H5 注册 */
register: (username, password, nickName) =>
request('POST', '/api/auth/user/register', { username, password, nickName }),
/** 获取当前用户 */
me: (token) =>
request('GET', '/api/auth/me', null, token),
}
/**
* 知识库
*/
export const knowledgeApi = {
/** 获取知识列表 */
list: (params = {}) => {
const query = Object.entries(params)
.filter(([_, v]) => v !== undefined && v !== null)
.map(([k, v]) => `${k}=${v}`)
.join('&')
return request('GET', `/api/knowledge${query ? '?' + query : ''}`)
},
/** 获取知识详情 */
detail: (id) =>
request('GET', `/api/knowledge/${id}`),
/** 收藏知识 */
collect: (id, token) =>
request('POST', `/api/knowledge/${id}/collect`, null, token),
/** 取消收藏 */
uncollect: (id, token) =>
request('DELETE', `/api/knowledge/collect/${id}`, null, token),
/** 获取收藏列表 */
collected: (token) =>
request('GET', '/api/knowledge/collected', null, token),
/** 获取维度问答 */
questions: (dim) =>
request('GET', `/api/knowledge/${dim}/questions`),
/** 搜索知识 */
search: (q, options = {}) => {
const params = { q, ...options }
const query = Object.entries(params)
.filter(([_, v]) => v !== undefined && v !== null)
.map(([k, v]) => `${k}=${encodeURIComponent(v)}`)
.join('&')
return request('GET', `/api/knowledge/search${query ? '?' + query : ''}`)
},
}
/**
* AI 问答
*/
export const aiChatApi = {
/** 获取配额 */
quota: (token) =>
request('GET', '/api/ai-chat/quota', null, token),
/** 提问 */
ask: (question, dimension = 'general', token) =>
request('POST', '/api/ai-chat/ask', { question, dimension }, token),
/** 分享获得次数 */
shareGain: (token) =>
request('POST', '/api/ai-chat/share-gain', null, token),
}
/**
* 用户相关
*/
export const userApi = {
/** 获取用户进度 */
progress: (token) =>
request('GET', '/api/user/progress', null, token),
/** 保存进度 */
saveProgress: (data, token) =>
request('POST', '/api/user/progress', data, token),
/** 排行榜 */
leaderboard: (dim = null) =>
request('GET', `/api/user/leaderboard${dim ? '?dim=' + dim : ''}`),
/** 获取成就 */
achievements: (token) =>
request('GET', '/api/user/achievements', null, token),
/** 用户统计 */
stats: (token) =>
request('GET', '/api/user/stats', null, token),
}
/**
* 支付相关
*/
export const paymentApi = {
/** 获取商品列表 */
products: () =>
request('GET', '/api/payment/products'),
/** 创建订单 */
createOrder: (productId, token) =>
request('POST', '/api/payment/create-order', { productId }, token),
}
/**
* 趋势资讯
*/
export const trendApi = {
/** 获取趋势列表 */
list: (params = {}) => {
const query = Object.entries(params)
.filter(([_, v]) => v !== undefined && v !== null)
.map(([k, v]) => `${k}=${v}`)
.join('&')
return request('GET', `/api/trend${query ? '?' + query : ''}`)
},
/** 获取趋势详情 */
detail: (id) =>
request('GET', `/api/trend/${id}`),
}
/**
* 意见反馈
*/
export const feedbackApi = {
/** 提交反馈 */
create: (data, token) =>
request('POST', '/api/feedback', data, token),
/** 我的反馈列表 */
my: (token) =>
request('GET', '/api/feedback/my', null, token),
}
export default {
auth: authApi,
knowledge: knowledgeApi,
aiChat: aiChatApi,
user: userApi,
payment: paymentApi,
trend: trendApi,
feedback: feedbackApi
}
+88
View File
@@ -0,0 +1,88 @@
/**
* 维度配置 — 5 个 AI 维度的元数据
* 修改这里可以调整维度名称、颜色、图标等
*/
export const DIMENSIONS = [
{
id: 1,
key: 'origin',
name: 'AI 起源',
icon: '🌅',
desc: '人工智能的诞生——从图灵测试到第一代探索者',
color: 'var(--dim1-color)',
bg: 'var(--dim1-bg)',
iconBg: 'var(--dim1-icon-bg)',
border: 'var(--dim1-border)',
glow: 'var(--dim1-glow)',
articleCount: 12,
quizCount: 4
},
{
id: 2,
key: 'development',
name: 'AI 发展',
icon: '📈',
desc: '技术跃迁之路——深度学习、Transformer 和前沿突破',
color: 'var(--dim2-color)',
bg: 'var(--dim2-bg)',
iconBg: 'var(--dim2-icon-bg)',
border: 'var(--dim2-border)',
glow: 'var(--dim2-glow)',
articleCount: 18,
quizCount: 6
},
{
id: 3,
key: 'current',
name: 'AI 当前',
icon: '🌐',
desc: '2026 年 AI 世界——大模型、Agent、人形机器人',
color: 'var(--dim3-color)',
bg: 'var(--dim3-bg)',
iconBg: 'var(--dim3-icon-bg)',
border: 'var(--dim3-border)',
glow: 'var(--dim3-glow)',
articleCount: 15,
quizCount: 5
},
{
id: 4,
key: 'learning',
name: 'AI 学习',
icon: '🛠',
desc: '动手学 AI——提示词、微调、RAG 和实用工具',
color: 'var(--dim4-color)',
bg: 'var(--dim4-bg)',
iconBg: 'var(--dim4-icon-bg)',
border: 'var(--dim4-border)',
glow: 'var(--dim4-glow)',
articleCount: 20,
quizCount: 8
},
{
id: 5,
key: 'trend',
name: 'AI 趋势',
icon: '🔥',
desc: '前沿动态——每日 AI 新闻、产品和趋势洞察',
color: 'var(--dim5-color)',
bg: 'var(--dim5-bg)',
iconBg: 'var(--dim5-icon-bg)',
border: 'var(--dim5-border)',
glow: 'var(--dim5-glow)',
articleCount: 0,
quizCount: 0,
isFull: true // 跨列
}
]
/** 按维度 ID 查找 */
export function getDimension(id) {
return DIMENSIONS.find(d => d.id === id)
}
/** 按维度 key 查找 */
export function getDimensionByKey(key) {
return DIMENSIONS.find(d => d.key === key)
}
+64
View File
@@ -0,0 +1,64 @@
/**
* 全局错误处理
* 在 main.js 中调用 initErrorHandler()
*/
export function initErrorHandler() {
// 捕获未处理的 Promise rejection
uni.onUnhandledRejection((res) => {
console.error('[Global Error]', res.reason)
uni.showToast({ title: '操作失败,请重试', icon: 'none' })
})
}
/**
* 网络请求拦截器
* 增强版 request 函数,带全局错误处理
*/
async function request(method, path, data = null, token = null, options = {}) {
const BASE_URL = 'https://wdkj.yuzhiran.com.cn'
const DEV_URL = 'http://127.0.0.1:3001'
const isDev = import.meta.env.DEV
const API_BASE = isDev ? DEV_URL : BASE_URL
const url = `${API_BASE}${path}`
const headers = {
'Content-Type': 'application/json'
}
if (token) {
headers['Authorization'] = `Bearer ${token}`
}
try {
const res = await uni.request({
url,
method,
data,
header: headers,
timeout: options.timeout || 15000
})
// 统一错误处理
if (res.statusCode >= 400) {
throw new Error(res.data?.error || `请求失败 (${res.statusCode})`)
}
const body = res.data
if (body && body.success) {
return body.data
}
throw new Error(body?.error || '请求失败')
} catch (err) {
// 网络错误
if (err.errMsg && err.errMsg.includes('timeout')) {
throw new Error('网络超时,请检查网络')
}
if (err.errMsg && err.errMsg.includes('fail')) {
throw new Error('网络连接失败')
}
console.error(`[API Error] ${method} ${path}:`, err)
throw err
}
}
export default request