cangku/backend/src/services/taobaoDetailPlusDataService.js

90 lines
1.8 KiB
JavaScript

const planningDatabase = require('./planningDatabase');
const TABLE_NAME = 'taobao_detail_plus_data';
const JSON_COLUMNS = [
'item_imgs_json',
'skus_json',
'attribute_json',
'specs_json',
'props_json',
'main_item_info_json',
'raw_data_json',
'raw_response_json',
];
function normalizeItemId(value) {
return String(value || '').trim();
}
function parseJsonColumn(value) {
if (value === null || value === undefined || value === '') {
return null;
}
if (typeof value !== 'string') {
return value;
}
try {
return JSON.parse(value);
} catch (_error) {
return value;
}
}
function normalizeRow(row) {
if (!row) {
return null;
}
const data = { ...row };
for (const column of JSON_COLUMNS) {
if (Object.prototype.hasOwnProperty.call(data, column)) {
data[column] = parseJsonColumn(data[column]);
}
}
return data;
}
function validateItemId(itemId) {
if (!itemId) {
return '请提供商品 id';
}
if (itemId.length > 64) {
return '商品 id 长度不能超过 64 个字符';
}
if (!/^[0-9A-Za-z_-]+$/.test(itemId)) {
return '商品 id 只能包含数字、字母、下划线或短横线';
}
return '';
}
async function getTaobaoDetailPlusByItemId(rawItemId) {
const itemId = normalizeItemId(rawItemId);
const validationError = validateItemId(itemId);
if (validationError) {
const error = new Error(validationError);
error.statusCode = 400;
throw error;
}
const rows = await planningDatabase.query(
`SELECT *
FROM ${TABLE_NAME}
WHERE requested_item_id = ?
OR item_id = ?
ORDER BY fetched_at DESC, id DESC
LIMIT 1`,
[itemId, itemId]
);
return normalizeRow(rows[0]);
}
module.exports = {
getTaobaoDetailPlusByItemId,
};