This commit is contained in:
张成
2026-03-18 16:16:04 +08:00
parent 3d3b9b5dfa
commit a62018a062
8 changed files with 38 additions and 17 deletions

12
.vscode/launch.json vendored
View File

@@ -9,10 +9,22 @@
"type": "node",
"request": "launch",
"name": "同步数据库",
"cwd": "${workspaceFolder}\\server",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}\\server\\scripts\\db_sync.js"
},
{
"type": "node",
"request": "launch",
"name": "启动服务",
"skipFiles": [
"<node_internals>/**"
],
// 工作区根目录
"cwd": "${workspaceFolder}\\server",
"program": "${workspaceFolder}\\server\\app.js"
}
]
}

4
1.md
View File

@@ -38,3 +38,7 @@
- 可视化看板: 每天自动推送一份“户外品类异动日报”。
- 爆款预警: 当监测到“防水包”类目下某新品 3 天内排名上升超过 50% 时,系统触发钉钉/邮件预警。
- 决策支持: 提供该款产品的“避坑指南”(基于竞品售后差评分析)。
"C:\Program Files\Google\Chrome\Application\chrome.exe" --disable-features=ExtensionManifestV2Unsupported,ExtensionManifestV2Disabled

View File

@@ -20,7 +20,7 @@ const cfg = get_app_config();
const port = cfg.server.port;
await sequelize.authenticate();
await sequelize.sync();
// await sequelize.sync();
start_all_cron_tasks();
app.listen(port);

View File

@@ -55,7 +55,8 @@ export function get_app_config() {
crx_src_path: must_get('CRX_SRC_PATH'),
action_timeout_ms: get_int('ACTION_TIMEOUT_MS', 300000),
puppeteer_headless: get_bool('PUPPETEER_HEADLESS', false),
chrome_executable_path: (get_env('CHROME_EXECUTABLE_PATH') || '').trim() || path.resolve(__dirname, '../../chrome-win/chrome.exe')
chrome_executable_path: (get_env('CHROME_EXECUTABLE_PATH') || '').trim() || path.resolve(__dirname, '../../chrome-win/chrome.exe'),
log_invoke_action: get_bool('LOG_INVOKE_ACTION', true)
}
};

View File

@@ -5,10 +5,10 @@
export const cron_task_list = [
// 示例:每 6 小时跑一次列表抓取
// {
// name: 'amazon_search_list_every_6h',
// cron_expression: '0 */6 * * *',
// action_name: 'amazon_search_list',
// action_payload: { keyword: '午餐包', limit: 100 }
// }
{
name: 'amazon_search_list_every_6h',
cron_expression: '0 */1 * * *',
action_name: 'amazon_search_list',
action_payload: { keyword: '野餐包', limit: 100 }
}
];

View File

@@ -2,6 +2,7 @@ import { get_app_config } from './app_config.js';
export function get_sequelize_options() {
const cfg = get_app_config();
console.log( 'get_sequelize_options', cfg.mysql );
return {
host: cfg.mysql.host,

View File

@@ -4,9 +4,9 @@ import { execute_action_and_record } from './task_executor.js';
const cron_jobs = [];
export function start_all_cron_tasks() {
export async function start_all_cron_tasks() {
for (const task of cron_task_list) {
const job = cron.schedule(task.cron_expression, async () => {
// const job = cron.schedule(task.cron_expression, async () => {
try {
await execute_action_and_record({
action_name: task.action_name,
@@ -16,9 +16,9 @@ export function start_all_cron_tasks() {
} catch (err) {
// 失败会在 crawl_run_record 落库
}
});
// });
cron_jobs.push(job);
// cron_jobs.push(job);
}
}

View File

@@ -13,15 +13,18 @@ export async function execute_action_and_record(params) {
let error_message = null;
try {
const result = await invoke_extension_action(action_name, action_payload || {});
console.log( 'invoke_extension_action-start', action_name, action_payload );
const res_invoke = await invoke_extension_action(action_name, action_payload || {});
console.log( 'invoke_extension_action-end', action_name, result );
ok = true;
result_payload = safe_json_stringify(result);
result_payload = safe_json_stringify(res_invoke);
// 按 stage 自动入库(不影响原始 run_record 记录)
await persist_amazon_result(result);
await persist_amazon_result(res_invoke.result);
return result;
return res_invoke;
} catch (err) {
ok = false;
error_message = (err && err.message) || String(err);