modex/index.vue 分割

This commit is contained in:
eafonyang
2026-07-01 16:53:38 +08:00
parent cacee5f294
commit e2577ff661
10 changed files with 1999 additions and 1157 deletions
+93 -3
View File
@@ -13,6 +13,7 @@ const { authMiddleware } = require('../middleware/auth');
const { fetchAndValidateCurve } = require('../services/curveClient');
const { uploadMeasurementToS3, getMeasurementFromS3 } = require('../services/measurementStorage');
const { getEqCacheKeys, getEqCacheField } = require('../services/eqCacheStorage');
const { fetchFromSquigLink, downloadTxtFile } = require('../services/squiglink');
/**
* 将 TXT 频响文件内容转换为 CSV 格式
@@ -303,6 +304,70 @@ router.get('/api/models/:model_id', async (req, res) => {
}
});
// POST /api/models/squiglink-fetch — 从 squig.link share URL 抓取频响数据
router.post('/api/models/squiglink-fetch', async (req, res) => {
try {
const { share_url, selected_file } = req.body;
if (!share_url) {
return res.json(ApiResponse.error('缺少 share_url 参数'));
}
logger.info(`SquigLink fetch: ${share_url}${selected_file ? ' (selected=' + selected_file + ')' : ''}`);
// 如果用户从候选列表中选择了特定文件,直接下载
if (selected_file) {
const { parseShareUrl, detectFormFromUrl } = require('../services/squiglink');
const { baseUrl } = parseShareUrl(share_url);
const [downloadResult, detectedForm] = await Promise.all([
downloadTxtFile(baseUrl, selected_file),
detectFormFromUrl(baseUrl),
]);
const csvContent = convertTxtToCsv(downloadResult.buffer);
// 从 file 名解析品牌和型号
const parts = selected_file.split(' ');
const brandName = parts.length > 1 ? parts[0] : '';
const modelName = parts.length > 1 ? parts.slice(1).join(' ') : selected_file;
return res.json(ApiResponse.success({
brand_name: brandName,
model_name: modelName,
form: detectedForm || null,
csv_content: csvContent,
data_url: downloadResult.url,
matches: [],
}));
}
// 自动抓取
const result = await fetchFromSquigLink(share_url);
// 多个候选,返回给前端选择
if (result.matches.length > 1) {
return res.json(ApiResponse.success({
brand_name: '',
model_name: '',
form: result.form || null,
csv_content: null,
data_url: null,
matches: result.matches,
}));
}
// 单个匹配,返回 CSV 内容
const csvContent = convertTxtToCsv(result.buffer);
return res.json(ApiResponse.success({
brand_name: result.brandName,
model_name: result.modelName,
form: result.form || null,
csv_content: csvContent,
data_url: result.dataUrl,
matches: [],
}));
} catch (e) {
logger.error(`SquigLink fetch error: ${e.message}`);
return res.json(ApiResponse.error(e.message || '抓取失败'));
}
});
// POST /api/models/ (multipart/form-data)
router.post('/api/models/', upload.single('measurement_file'), async (req, res) => {
try {
@@ -316,8 +381,19 @@ router.post('/api/models/', upload.single('measurement_file'), async (req, res)
return res.json(ApiResponse.error('该品牌下型号名称已存在'));
}
// 处理文件上传
if (req.file && req.file.originalname) {
// 处理文件上传(优先 squiglink_csv,其次文件上传)
const { squiglink_csv } = req.body;
if (squiglink_csv) {
// 从 squig.link 抓取的 CSV 内容直接上传 S3
const csvBuffer = Buffer.from(squiglink_csv, 'utf-8');
const s3Key = await uploadMeasurementToS3(csvBuffer, {
source: source || 'Eafonyoung',
form: form || 'in-ear',
brandName: brand_name,
modelName: name,
});
logger.info(`SquigLink CSV uploaded to S3: ${s3Key}`);
} else if (req.file && req.file.originalname) {
const fileExt = path.extname(req.file.originalname).toLowerCase();
if (!ALLOWED_EXTENSIONS.includes(fileExt)) {
logger.error(`Unsupported file format: ${fileExt}`);
@@ -390,7 +466,21 @@ router.put('/api/models/:model_id', upload.single('measurement_file'), async (re
const effSource = source === undefined || source === 'null' ? dbModel.source : source;
const effForm = form === undefined || form === 'null' ? dbModel.form : form;
if (req.file && req.file.originalname) {
// 处理频响文件(优先 squiglink_csv,其次文件上传)
const { squiglink_csv } = req.body;
if (squiglink_csv) {
if (!effSource || !effForm) {
return res.json(ApiResponse.error('上传频响文件需要来源与形式字段'));
}
const csvBuffer = Buffer.from(squiglink_csv, 'utf-8');
const s3Key = await uploadMeasurementToS3(csvBuffer, {
source: effSource,
form: effForm,
brandName: newBrandName,
modelName: newName,
});
logger.info(`SquigLink CSV uploaded to S3: ${s3Key}`);
} else if (req.file && req.file.originalname) {
const fileExt = path.extname(req.file.originalname).toLowerCase();
if (!ALLOWED_EXTENSIONS.includes(fileExt)) {
logger.error(`Unsupported file format: ${fileExt}`);