feat: 新增运动节拍训练工具套件与子工具页面

新增运动节拍RepClock全套小程序页面、后端API与数据库服务,新增subhub子工具汇总页面,优化全局主页样式与配置,为web静态资源添加版本缓存参数,补充配套调试脚本
This commit is contained in:
yangxiangyuan
2026-09-09 14:43:06 +08:00
parent db7648eb4d
commit d4bf3627fd
69 changed files with 5759 additions and 297 deletions
+79 -10
View File
@@ -12,13 +12,16 @@ const request = (options) => {
return new Promise((resolve, reject) => {
const { url, method = 'GET', data = {}, header = {}, timeout = 30000 } = options
const fullUrl = url.indexOf('http') === 0 ? url : BASE_URL() + url
const h = Object.assign({
'content-type': 'application/json; charset=utf-8',
Accept: 'application/json; charset=utf-8',
'X-Mp-Timeassistant': 'mp_time_assistant_v1_' + Math.random().toString(36).slice(2, 10),
}, header)
wx.request({
url: fullUrl,
method,
data,
header: Object.assign({
'content-type': 'application/json',
}, header),
header: h,
timeout,
success: (res) => {
const body = res.data || {}
@@ -26,7 +29,12 @@ const request = (options) => {
resolve(body)
} else {
const msg = body && body.error ? body.error : `请求失败 (HTTP ${res.statusCode})`
reject(new Error(msg))
const err = new Error(msg)
err.statusCode = res.statusCode
if (body && typeof body === 'object') {
try { Object.assign(err, body) } catch (_) {}
}
reject(err)
}
},
fail: (err) => {
@@ -45,6 +53,9 @@ const uploadFile = (options) => {
filePath,
name,
formData,
header: {
'X-Mp-Timeassistant': 'mp_time_assistant_v1_' + Math.random().toString(36).slice(2, 10),
},
timeout,
success: (res) => {
try {
@@ -78,37 +89,94 @@ const core = {
const personalCollect = {
list: (keyword = '') => request({
url: '/api/mp_time_assistant/kits/personal_collect/items',
url: '/api/mp_personal_collect/kits/personal_collect/items',
method: 'GET',
data: { keyword: keyword || '' },
}),
get: (id) => request({
url: `/api/mp_time_assistant/kits/personal_collect/items/${encodeURIComponent(id)}`,
url: `/api/mp_personal_collect/kits/personal_collect/items/${encodeURIComponent(id)}`,
method: 'GET',
}),
create: (payload) => request({
url: '/api/mp_time_assistant/kits/personal_collect/items',
url: '/api/mp_personal_collect/kits/personal_collect/items',
method: 'POST',
data: payload,
}),
update: (payload) => request({
url: '/api/mp_time_assistant/kits/personal_collect/items',
url: '/api/mp_personal_collect/kits/personal_collect/items',
method: 'PUT',
data: payload,
}),
remove: (id) => request({
url: '/api/mp_time_assistant/kits/personal_collect/items',
url: '/api/mp_personal_collect/kits/personal_collect/items',
method: 'DELETE',
data: { id },
}),
upload: (filePath, groupId = '') => uploadFile({
url: '/api/mp_time_assistant/kits/personal_collect/upload',
url: '/api/mp_personal_collect/kits/personal_collect/upload',
filePath,
name: 'file',
formData: groupId ? { groupId } : {},
}),
}
const repClock = {
meta: () => request({ url: '/api/mp_rep_clock/meta', method: 'GET' }),
state: () => request({ url: '/api/mp_rep_clock/state', method: 'GET' }),
resetRunning: (sessionId) => request({
url: '/api/mp_rep_clock/kits/rep_clock/state/reset-running',
method: 'POST',
data: { sessionId },
}),
listCards: () => request({ url: '/api/mp_rep_clock/kits/rep_clock/cards', method: 'GET' }),
getCard: (id) => request({ url: `/api/mp_rep_clock/kits/rep_clock/cards/${encodeURIComponent(id)}`, method: 'GET' }),
createCard: (payload) => request({
url: '/api/mp_rep_clock/kits/rep_clock/cards',
method: 'POST',
data: payload,
}),
updateCard: (payload) => request({
url: '/api/mp_rep_clock/kits/rep_clock/cards',
method: 'PUT',
data: payload,
}),
removeCard: (id) => request({
url: '/api/mp_rep_clock/kits/rep_clock/cards',
method: 'DELETE',
data: { id },
}),
history: (limit = 200) => request({
url: '/api/mp_rep_clock/kits/rep_clock/history',
method: 'GET',
data: { limit },
}),
sessionStart: (payload) => request({
url: '/api/mp_rep_clock/kits/rep_clock/sessions/start',
method: 'POST',
data: payload,
}),
sessionSync: (payload) => request({
url: '/api/mp_rep_clock/kits/rep_clock/sessions/sync',
method: 'POST',
data: payload,
}),
sessionFinish: (payload) => request({
url: '/api/mp_rep_clock/kits/rep_clock/sessions/finish',
method: 'POST',
data: payload,
}),
ttsPreview: (text, voice = 'female_01') => request({
url: '/api/mp_rep_clock/kits/rep_clock/tts/preview',
method: 'GET',
data: { text, voice },
}),
ttsBatch: (cardId, card, voice = 'female_01') => request({
url: '/api/mp_rep_clock/kits/rep_clock/tts/batch',
method: 'POST',
data: { cardId, card, voice },
}),
}
const chooseChatAttachments = (count = 9) => {
return new Promise((resolve, reject) => {
try {
@@ -141,5 +209,6 @@ module.exports = {
uploadFile,
core,
personalCollect,
repClock,
chooseChatAttachments,
}