Files
LWLT-AI/archive/handoff/2026-07-12/legacy-erp-handoff/scripts/query_parent_plans.js
2026-07-13 19:57:46 +08:00

109 lines
3.9 KiB
JavaScript

// Query ERP parent plan table for two group numbers.
// Read-only — no clicks, no modifications, no exports.
const { chromium } = require('playwright-core');
const PROFILE = 'C:\\Users\\wxy\\AppData\\Local\\LTJT-ERP-Hermes-Chrome';
const CHROME = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe';
const PLAN_URL = 'https://ltjt.yunzhi.run/System/Business/plan.asp';
const TARGETS = ['LW-260806A-A', 'LW-260623A-A'];
async function main() {
const context = await chromium.launchPersistentContext(PROFILE, {
executablePath: CHROME,
headless: false,
viewport: { width: 1440, height: 900 },
});
const page = context.pages()[0] || await context.newPage();
try {
await page.goto(PLAN_URL, { waitUntil: 'domcontentloaded', timeout: 60000 });
await page.waitForTimeout(5000);
// Check for login
const loginInput = await page.$('input[name="UserName"]');
if (loginInput) {
console.log(JSON.stringify({ status: 'login_required', message: 'ERP session expired' }));
return;
}
// Search by departure date 2026-08-06
// Set date range: S_chufariqi and S_chufarizhi
await page.locator('input[name="riqi"][value="chufari"]').check().catch(() => {});
await page.waitForTimeout(800);
await page.locator('#S_chufariqi').fill('2026-8-6');
await page.locator('#S_chufarizhi').fill('2026-8-6');
await page.waitForTimeout(300);
await page.locator('#SearchButton').click();
await page.waitForTimeout(8000);
// Extract all rows from the plan table
const rows = await page.evaluate(() => {
return Array.from(document.querySelectorAll('tr')).map((tr, idx) => {
const text = tr.innerText.replace(/\s+/g, ' ').trim();
const links = Array.from(tr.querySelectorAll('a')).map(a => ({
text: a.innerText.trim(),
href: a.getAttribute('href') || '',
onclick: a.getAttribute('onclick') || '',
}));
return { idx, text, links };
});
});
const results = [];
for (const target of TARGETS) {
// Find rows containing this group number
const candidateRows = rows.filter(r => r.text.includes(target));
if (candidateRows.length === 0) {
results.push({
groupNo: target,
found: false,
message: '未在计划表中找到该团号',
});
continue;
}
for (const row of candidateRows) {
// Check for 拼单 link
const pinDanLink = row.links.find(l => l.text === '拼单');
const chaZhangLink = row.links.find(l => l.text === '查账');
const deleteLink = row.links.find(l => l.text === '删除');
const modifyLink = row.links.find(l => l.text === '修改');
// Extract product name and planned guests from row text
// Row format: [idx] [status] [groupNo] [op] [type.] [product] [date] [duration] [returnDate] [plannedGuests] ...
const text = row.text;
const idxMatch = text.match(/^(\d+)/);
const statusMatch = text.match(/(收客中|已停止|已取消)/);
const productMatch = text.match(/常规团\.\s*(.+?)\s+\d{4}-\d{1,2}-\d{1,2}/);
const plannedMatch = text.match(/计划(\d+)/);
results.push({
groupNo: target,
found: true,
rowIdx: idxMatch ? idxMatch[1] : null,
status: statusMatch ? statusMatch[1] : null,
product: productMatch ? productMatch[1] : null,
plannedGuests: plannedMatch ? parseInt(plannedMatch[1]) : null,
hasPinDan: !!pinDanLink,
hasChaZhang: !!chaZhangLink,
hasDelete: !!deleteLink,
hasModify: !!modifyLink,
allLinks: row.links.map(l => l.text).filter(Boolean),
preview: text.slice(0, 400),
});
}
}
console.log(JSON.stringify({ status: 'ok', results }, null, 2));
} catch (err) {
console.log(JSON.stringify({ status: 'error', message: err.message }));
} finally {
await context.close();
}
}
main();