Initial commit: Memind H5 portal with MindSpace, Plaza, and agent jobs.

Track application source and tests; exclude local env, user workspaces, and runtime data via .gitignore.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
John
2026-06-15 15:04:43 -07:00
commit 2e14873f2d
272 changed files with 64133 additions and 0 deletions
+66
View File
@@ -0,0 +1,66 @@
import express from 'express';
import { fetch } from 'undici';
const ASR_TARGET = process.env.H5_ASR_TARGET ?? 'https://asr.tkmind.cn';
const ASR_MAX_BYTES = Number(process.env.H5_ASR_MAX_BYTES ?? 5 * 1024 * 1024);
const ASR_TIMEOUT_MS = Number(process.env.H5_ASR_TIMEOUT_MS ?? 45_000);
export function attachAsrRoutes(api, deps) {
const multipartRaw = express.raw({
type: (req) => (req.headers['content-type'] ?? '').includes('multipart/form-data'),
limit: ASR_MAX_BYTES,
});
// 登录校验由 api 全局中间件负责(req.currentUser
api.post('/asr/oneshot', multipartRaw, async (req, res) => {
const contentType = req.headers['content-type'] ?? '';
if (!contentType.includes('multipart/form-data')) {
return deps.sendError(res, req, 400, 'invalid_request', 'Content-Type 必须为 multipart/form-data');
}
if (!req.body?.length) {
return deps.sendError(res, req, 400, 'invalid_request', '音频内容为空');
}
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), ASR_TIMEOUT_MS);
try {
const upstream = await fetch(`${ASR_TARGET}/asr/oneshot`, {
method: 'POST',
headers: { 'content-type': contentType },
body: req.body,
signal: controller.signal,
});
const text = await upstream.text();
let payload = null;
try {
payload = JSON.parse(text);
} catch {
payload = null;
}
if (!upstream.ok) {
return deps.sendError(
res,
req,
upstream.status,
'asr_failed',
payload?.message ?? text ?? 'ASR 请求失败',
);
}
if (payload?.code !== 200) {
return deps.sendError(res, req, 502, 'asr_failed', payload?.message ?? '识别失败');
}
return deps.sendData(res, req, { text: payload?.data?.text ?? '' });
} catch (err) {
const message =
err instanceof Error && err.name === 'AbortError'
? '识别超时,请重试'
: err instanceof Error
? err.message
: 'ASR 请求失败';
return deps.sendError(res, req, 502, 'asr_failed', message);
} finally {
clearTimeout(timer);
}
});
}