(function () {
'use strict';
const state = {
accounts: [],
settlementPage: 1,
settlementPageSize: 50,
settlementPages: 1,
summary: { settlementId: 0, page: 1, pageSize: 100, pages: 1 },
detail: { id: 0, number: '', account: '', page: 1, pageSize: 100 },
kingdeeFields: [],
walmartFieldRows: []
};
const escHtml = value => typeof esc === 'function' ? esc(value == null ? '' : value) : String(value == null ? '' : value);
const moneyText = value => Number(value || 0).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const statusText = value => ({ pending: '待推送', success: '推送成功', failed: '推送失败', error: '推送失败' })[value] || value || '待推送';
const statusClass = value => value === 'success' ? 'success' : (value === 'failed' || value === 'error') ? 'failed' : 'pending';
function help(text) {
return '
' + escHtml(text) + '
';
}
function installStyle() {
const style = document.createElement('style');
style.textContent = `
.wm-toolbar{display:flex;justify-content:flex-end;gap:8px;align-items:center;flex-wrap:wrap}
#navWalmartSettlement .wm-nav-icon{display:inline-flex;width:18px;justify-content:center;margin-right:5px;font-size:14px;vertical-align:-1px}
.wm-message{display:block;max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:copy}
.wm-actions{display:flex;gap:6px;white-space:nowrap}
.wm-actions button{padding:6px 10px}
.wm-map-table input,.wm-map-table select{min-width:120px;padding:7px 9px}
.wm-map-table input[type=checkbox]{min-width:0;width:16px}
#walmart-settlement-details .table-wrap{max-height:calc(100vh - 330px)}
.wm-summary-shell{max-width:780px;margin:0 auto;padding:2px 18px 24px;background:#fff}
.wm-summary-meta{font-size:13px;color:#64748b;margin-top:4px}
.wm-summary-section{padding:20px 6px 22px;border-bottom:1px solid #e5e7eb}
.wm-summary-section:last-child{border-bottom:0}
.wm-summary-section h3{margin:0 0 10px;color:#111827;font-size:15px;font-weight:700}
.wm-summary-line,.wm-summary-total{display:grid;grid-template-columns:minmax(0,1fr) 150px;gap:18px;align-items:center;min-height:32px;color:#111827}
.wm-summary-line button{appearance:none;border:0;background:transparent;padding:0;text-align:left;color:#111827;font-weight:400;cursor:pointer}
.wm-summary-line button:hover{color:#1d4ed8;text-decoration:underline}
.wm-summary-amount{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.wm-summary-total{margin-top:4px;padding-top:7px;border-top:1px solid #f1f5f9;font-weight:700}
.wm-summary-total.negative .wm-summary-amount{color:#dc2626}
.wm-summary-action{display:flex;justify-content:flex-end;margin-top:9px}
.wm-view-details{background:#fff!important;color:#111827!important;border:1px solid #111827!important;border-radius:18px!important;padding:6px 16px!important;font-size:12px!important}
.wm-view-details:hover{background:#f8fafc!important;color:#1d4ed8!important;border-color:#1d4ed8!important}
.wm-detail-toolbar{display:grid;grid-template-columns:minmax(240px,1fr) 170px 170px auto;gap:10px;align-items:end;padding:12px 14px;background:#fff;border:1px solid #dbe3ef}
.wm-detail-toolbar label{color:#475569}
.wm-detail-status{display:inline-flex;padding:3px 10px;border-radius:3px;background:#fff7e6;color:#9a6700;font-size:12px}
.wm-mapping-status{display:inline-flex;margin-left:8px;padding:2px 7px;border-radius:3px;font-size:11px;vertical-align:1px}
.wm-mapping-status.ok{background:#ecfdf3;color:#087443}
.wm-mapping-status.missing{background:#fff1f2;color:#be123c}
@media(max-width:900px){.wm-summary-shell{padding:0 10px}.wm-detail-toolbar{grid-template-columns:1fr 1fr}.wm-summary-line,.wm-summary-total{grid-template-columns:minmax(0,1fr) 110px}}
`;
document.head.appendChild(style);
}
function installNavigation() {
if (document.getElementById('navWalmartSettlement')) return;
const anchor = document.getElementById('navFit') || document.getElementById('navSystem');
const parent = anchor ? anchor.parentNode : document.querySelector('.side');
const group = document.createElement('div');
group.className = 'navgroup';
group.id = 'navWalmartSettlement';
group.innerHTML = '🛒沃尔玛平台▸';
group.onclick = window.toggleWalmartSettlementNav;
const sub = document.createElement('div');
sub.className = 'navsub';
sub.id = 'navWalmartSettlementSub';
[
['walmart-api-config', 'API接口配置'],
['walmart-settlements', '结算单'],
['walmart-settlement-summary', '结算单汇总'],
['walmart-settlement-details', '结算明细'],
['walmart-fee-mapping', '费用项映射'],
['walmart-field-mapping', '金蝶单据字段映射'],
['walmart-schedule', '定时拉取']
].forEach(([id, label]) => {
const item = document.createElement('div');
item.className = 'nav navchild';
item.dataset.s = id;
item.textContent = label;
item.onclick = () => openWalmartPage(id);
sub.appendChild(item);
});
parent.insertBefore(group, anchor || null);
parent.insertBefore(sub, anchor || null);
}
window.toggleWalmartSettlementNav = function () {
document.getElementById('navWalmartSettlement')?.classList.toggle('open');
document.getElementById('navWalmartSettlementSub')?.classList.toggle('open');
};
function installPages() {
const main = document.querySelector('main');
if (!main || document.getElementById('walmart-api-config')) return;
main.insertAdjacentHTML('beforeend', `
${help('维护 Walmart Marketplace OAuth 账号。金蝶登录信息复用结算单 API 配置;FormId 和分录 Key 按沃尔玛账号独立保存。')}
沃尔玛 API接口配置
保存账号后点击“检查报告日期”,确认 Walmart 官方当前是否已生成可下载的结算报告。
| 账号编码 | 账号名称 | 市场 | Client ID | Client Secret | FormId | 状态 | 操作 |
|---|
${help('从沃尔玛官方可用结算报告日期中发现新报告并下载。普通同步自动跳过已存在报告;覆盖同步不会覆盖已关联金蝶单据的记录。')}
${help('结算单汇总:先选择一张结算单,再点击业务类型或费用项目查看对应明细。业务类型、原因和费用明细保留沃尔玛原始英文。')}
${help('结算明细:可按明细 ID、交易主键、订单号、PO、SKU、交易类型或金额类型查询。业务类型、原因和费用明细保留英文。')}
${help('费用项映射由全部沃尔玛账号共享。普通类型按汇总大类 + 汇总项目映射;Services fees 按查看明细中的 Fee Detail 映射。推送金蝶前必须完成费用编码和金额字段配置,旧的原始类型映射会保留并兼容。')}
| 汇总大类 | 汇总项目 / Fee Detail | 映射层级 | 金蝶费用项编码 | 费用项字段 | 金蝶金额字段 | 启用 |
|---|
${help('金蝶字段映射按沃尔玛账号保存,可从一个沃尔玛账号复制到另一个账号。复制只覆盖目标账号,不改变源账号或独立站映射。')}
沃尔玛金蝶单据字段映射
| 金蝶字段 | 名称 | 范围 | 取值方式 | 来源字段/固定值 | 基础资料 | 分录 Key | 父分录 Key | 启用 |
|---|
请选择账号并读取金蝶字段 |
${help('定时任务只发现和下载尚未入库的结算报告,不重复下载已有报告。建议保持至少两小时一次。')}
`);
}
function loadWalmartPageData(id) {
const loaders = {
'walmart-api-config': loadWalmartAccounts,
'walmart-settlements': () => loadWalmartSettlements(false),
'walmart-settlement-summary': () => loadWalmartSummary(false),
'walmart-settlement-details': () => state.detail.id ? loadWalmartDetails(false) : null,
'walmart-fee-mapping': loadWalmartFeeMappings,
'walmart-field-mapping': loadWalmartFieldMappings,
'walmart-schedule': loadWalmartSchedule
};
if (loaders[id]) loaders[id]();
}
window.loadWalmartPageData = loadWalmartPageData;
function openWalmartPage(id) {
if (typeof showSection === 'function') showSection(id);
if (typeof window.activateWorkspacePage !== 'function') loadWalmartPageData(id);
}
window.openWalmartPage = openWalmartPage;
async function loadWalmartAccounts() {
try {
const data = await apiGet('/api/walmart-settlement/accounts');
state.accounts = data.rows || [];
const tb = document.getElementById('wmAccountTb');
if (tb) tb.innerHTML = state.accounts.map(item => `| ${escHtml(item.code)} | ${escHtml(item.name)} | ${escHtml(item.marketplace)} | ${escHtml(item.client_id)} | ${escHtml(item.client_secret)} | ${escHtml(item.form_id)} | ${item.enabled ? '启用' : '停用'} | |
`).join('') || '暂无沃尔玛账号 |
';
refreshAccountSelects();
if (document.getElementById('walmart-api-config')?.classList.contains('active') && state.accounts.length && !wmAccountCode.value.trim()) editWalmartAccount(state.accounts[0].code);
return data;
} catch (error) { toast('加载沃尔玛账号失败:' + error.message); }
}
window.loadWalmartAccounts = loadWalmartAccounts;
function refreshAccountSelects() {
['wmSettlementAccount', 'wmSummaryAccount', 'wmFieldAccount', 'wmFieldCopySource'].forEach(id => {
const select = document.getElementById(id); if (!select) return;
const current = select.value;
const all = (id === 'wmSettlementAccount' || id === 'wmSummaryAccount') ? '' : '';
select.innerHTML = all + state.accounts.map(item => ``).join('');
if (Array.from(select.options).some(option => option.value === current)) select.value = current;
});
}
window.resetWalmartAccountForm = function () {
['wmAccountCode','wmAccountName','wmClientId','wmClientSecret','wmFormId','wmChannelType'].forEach(id => document.getElementById(id).value = '');
wmMarketplace.value = 'US'; wmAccountEnabled.value = '1'; wmEntryKey.value = 'FEntity'; wmServiceName.value = 'Walmart Marketplace'; wmAccountCode.readOnly = false;
};
window.editWalmartAccount = function (code) {
const item = state.accounts.find(row => row.code === code); if (!item) return;
wmAccountCode.value = item.code; wmAccountCode.readOnly = true; wmAccountName.value = item.name; wmClientId.value = item.client_id;
wmClientSecret.value = item.client_secret; wmMarketplace.value = item.marketplace || 'US'; wmAccountEnabled.value = String(item.enabled);
wmFormId.value = item.form_id || ''; wmEntryKey.value = item.entry_key || 'FEntity'; wmServiceName.value = item.service_name || 'Walmart Marketplace'; wmChannelType.value = item.channel_type || '';
};
function accountPayload() { return { code: wmAccountCode.value.trim(), name: wmAccountName.value.trim(), client_id: wmClientId.value.trim(), client_secret: wmClientSecret.value.trim(), marketplace: wmMarketplace.value, enabled: Number(wmAccountEnabled.value), form_id: wmFormId.value.trim(), entry_key: wmEntryKey.value.trim(), service_name: wmServiceName.value.trim(), channel_type: wmChannelType.value.trim() }; }
window.saveWalmartAccount = async function () { try { await apiPost('/api/walmart-settlement/accounts', accountPayload()); toast('沃尔玛账号已保存'); await loadWalmartAccounts(); } catch (error) { toast('保存失败:' + error.message); } };
window.testWalmartAccount = async function () { const code = wmAccountCode.value.trim(); if (!code) return toast('请先填写并保存账号编码'); try { showLoading('正在连接沃尔玛...'); const result = await apiPost('/api/walmart-settlement/accounts/' + encodeURIComponent(code) + '/test'); const dates=(result.available_dates||[]).join('、'); toast(result.message + (dates ? ':' + dates : ';当前没有可用报告日期')); } catch (error) { toast('连接失败:' + error.message); } finally { hideLoading(); } };
window.checkWalmartAvailableReports = async function () { const code = wmAccountCode.value.trim(); if (!code) return toast('请先填写并保存账号编码'); try { showLoading('正在查询官方报告日期...'); const result = await apiGet('/api/walmart-settlement/accounts/' + encodeURIComponent(code) + '/available-reports'); const dates=result.dates||[]; wmAvailableReports.textContent = dates.length ? 'Recon 可下载报告日期(共 ' + dates.length + ' 个):' + dates.join('、') : result.statement_date && result.payment_status==='paid' ? 'Payment Statement 已到付款确认时间,结算日期:' + result.statement_date + '。点击“立即同步”即可入库。' : result.statement_date ? '当前周期结算日期:' + result.statement_date + ',尚未确认付款;系统将在 ' + result.paid_after + ' 后允许拉取。' : '连接成功,但 Recon 和 Payment Statement 都没有返回结算日期。'; toast(result.message); } catch (error) { wmAvailableReports.textContent = '查询失败:' + error.message; toast('查询失败:' + error.message); } finally { hideLoading(); } };
window.deleteWalmartAccount = async function (code) { if (!confirm('确认删除沃尔玛账号 ' + code + ' 的 API 配置?\n删除后不可恢复;如果账号已有结算数据,系统会阻止删除。')) return; if (!confirm('请再次确认:确实要删除该客户的沃尔玛 API 配置?')) return; try { await apiDelete('/api/walmart-settlement/accounts/' + encodeURIComponent(code)); toast('API 配置已删除'); resetWalmartAccountForm(); loadWalmartAccounts(); } catch (error) { toast('删除失败:' + error.message); } };
function settlementQuery() {
const query = new URLSearchParams({ page: state.settlementPage, page_size: state.settlementPageSize });
[['account_code','wmSettlementAccount'],['date_min','wmSettlementDateMin'],['date_max','wmSettlementDateMax'],['settlement_number','wmSettlementNumber'],['push_status','wmSettlementPushStatus']].forEach(([key,id]) => { const value = document.getElementById(id)?.value.trim(); if (value) query.set(key, value); });
return query;
}
const walmartSettlementSelectAll = () => document.getElementById('wmSettlementSelectAll');
window.loadWalmartSettlements = async function (reset) {
if (reset) state.settlementPage = 1;
if (!state.accounts.length) await loadWalmartAccounts();
try {
const data = await apiGet('/api/walmart-settlement/settlements?' + settlementQuery());
state.settlementPages = Math.max(1, Math.ceil(data.total / data.page_size));
wmSettlementTb.innerHTML = (data.rows || []).map(row => ` | ${escHtml(row.account_name || row.account_code)} | ${escHtml(row.settlement_number)} | ${escHtml(row.settlement_date || row.report_date)} | ${moneyText(row.total_amount)} | ${escHtml(row.currency)} | ${row.detail_count} | ${statusText(row.push_status)} | ${escHtml(row.kingdee_bill_no || '')} | ${escHtml(row.push_message || '')} | ${row.push_status === 'success' ? `` : ``} |
`).join('') || '暂无结算单,请点击“立即同步” |
';
const selectAll = walmartSettlementSelectAll();
if (selectAll) selectAll.checked = false;
if (selectAll) selectAll.indeterminate = false;
wmSettlementPageInfo.textContent = `第 ${data.page} / ${state.settlementPages} 页,共 ${data.total} 条`;
} catch (error) { toast('加载结算单失败:' + error.message); }
};
window.changeWalmartSettlementPage = function (delta) { state.settlementPage = Math.min(state.settlementPages, Math.max(1, state.settlementPage + delta)); loadWalmartSettlements(false); };
window.changeWalmartSettlementPageSize = function () { state.settlementPageSize = Number(wmSettlementPageSize.value); state.settlementPage = 1; loadWalmartSettlements(false); };
window.toggleWalmartSettlementAll = function (checked) { document.querySelectorAll('[data-wm-settlement-id]').forEach(item => { item.checked = checked; }); const selectAll = walmartSettlementSelectAll(); if (selectAll) selectAll.indeterminate = false; };
window.syncWalmartSettlementSelectAll = function () { const items = Array.from(document.querySelectorAll('[data-wm-settlement-id]')); const selected = items.filter(item => item.checked).length; const selectAll = walmartSettlementSelectAll(); if (selectAll) { selectAll.checked = items.length > 0 && selected === items.length; selectAll.indeterminate = selected > 0 && selected < items.length; } };
function includeWalmartSyncedDates(result) {
const dates = (result.results || []).flatMap(account => account.results || []).filter(item => item.status==='saved' || item.status==='skipped').map(item => item.report_date).filter(Boolean).sort();
if (!dates.length) return;
const first = dates[0], last = dates[dates.length - 1];
if (!wmSettlementDateMin.value || wmSettlementDateMin.value > first) wmSettlementDateMin.value = first;
if (!wmSettlementDateMax.value || wmSettlementDateMax.value < last) wmSettlementDateMax.value = last;
state.settlementPage = 1;
}
window.syncWalmartSettlements = async function (replace) {
const account = wmSettlementAccount.value;
const dateMin = wmSettlementDateMin.value || null;
const dateMax = wmSettlementDateMax.value || null;
if (replace && !account) return toast('覆盖同步必须先选择一个沃尔玛账号');
const reportDate = dateMin && dateMin === dateMax ? dateMin : '';
if (replace && !reportDate) return toast('覆盖同步必须把开始和结束日期设为同一天');
if (replace && !confirm('确认覆盖该账号指定日期的沃尔玛结算报告?已关联金蝶单据的记录不会被覆盖。')) return;
try {
showLoading('正在读取沃尔玛结算报告...');
const result = await apiPost('/api/walmart-settlement/settlements/sync', {
account_codes: account ? [account] : null,
report_date: reportDate || null,
date_min: dateMin,
date_max: dateMax,
replace: !!replace
});
if (result.duplicate) { toast(result.message); return; }
includeWalmartSyncedDates(result);
const failures = (result.failed || []).map(item => (item.account_code || '账号') + ':' + (item.message || '未知错误'));
const usedStatement = (result.results || []).some(item => item.source === 'payment_statement');
let message;
if (failures.length) message = '同步失败:' + failures.join(';');
else if (!result.accounts) message = '没有已启用的沃尔玛账号,请先到 API接口配置保存并启用账号。';
else if (result.unpaid) message = '发现 ' + result.unpaid + ' 个进行中或待付款周期,按规则未拉取;已存在的未推送待付款记录已清理。';
else if (!result.available && result.filtered) message = 'Walmart 返回了报告日期,但所选范围内没有可拉取的历史结算单。';
else if (!result.available) message = '已扫描 ' + result.accounts + ' 个账号,但 Walmart 官方没有返回可用结算数据。';
else message = '扫描 ' + result.accounts + ' 个账号,' + (usedStatement ? 'Payment Statement' : 'Recon 报告') + ' ' + result.available + ' 个,新增 ' + (result.saved || 0) + ' 份,已存在 ' + (result.skipped || 0) + ' 份。';
toast(message);
loadWalmartSettlements(false);
} catch (error) {
toast('同步失败:' + error.message);
} finally {
hideLoading();
}
};
window.clearWalmartFailedMessages = async function () { const ids = Array.from(document.querySelectorAll('[data-wm-settlement-id]:checked')).map(item => Number(item.dataset.wmSettlementId)); if (!ids.length) return loadWalmartSettlements(false); try { const result = await apiPost('/api/walmart-settlement/settlements/clear-failed-messages', { ids }); toast('已清除 ' + result.cleared + ' 条失败信息'); loadWalmartSettlements(false); } catch (error) { toast('刷新失败:' + error.message); } };
window.pushSelectedWalmartKingdee = async function () {
const selected = Array.from(document.querySelectorAll('[data-wm-settlement-id]:checked')).map(input => ({ id: Number(input.dataset.wmSettlementId), account: input.dataset.wmSettlementAccount, status: input.dataset.wmSettlementStatus }));
if (!selected.length) return toast('请先勾选要推送的结算单');
const targets = selected.filter(item => item.status !== 'success');
if (!targets.length) return toast('所选结算单均已推送,请先检查金蝶单据');
if (!confirm('确认推送选中的 ' + targets.length + ' 张结算单到金蝶?')) return;
let success = 0, failed = 0, skipped = selected.length - targets.length;
showLoading('正在推送选中的结算单...');
try {
for (const item of targets) {
try {
const result = await apiPost('/api/walmart-settlement/settlements/push', { settlement_id: item.id, account_code: item.account });
if (result.ok) success += 1; else if (result.status === 'skipped') skipped += 1; else failed += 1;
} catch (error) { failed += 1; }
}
toast('推送完成:成功 ' + success + ' 张,跳过 ' + skipped + ' 张,失败 ' + failed + ' 张');
loadWalmartSettlements(false);
} finally { hideLoading(); }
};
window.pushWalmartKingdee = async function (id, account) { if (!confirm('确认将这张沃尔玛结算单推送到金蝶?')) return; try { showLoading('正在推送金蝶...'); const result = await apiPost('/api/walmart-settlement/settlements/push', { settlement_id: id, account_code: account }); toast(result.message || (result.ok ? '推送成功' : '推送失败')); loadWalmartSettlements(false); } catch (error) { toast('推送失败:' + error.message); } finally { hideLoading(); } };
window.checkWalmartKingdee = async function (id, account) { try { showLoading('正在检查金蝶单据...'); const result = await apiPost('/api/walmart-settlement/settlements/' + id + '/check?account_code=' + encodeURIComponent(account)); toast(result.message); loadWalmartSettlements(false); } catch (error) { toast('检查失败:' + error.message); } finally { hideLoading(); } };
function walmartMoney(value, currency) {
const amount = Number(value || 0);
const symbol = currency === 'USD' ? '$' : (currency || '');
return `${amount < 0 ? '-' : ''}${symbol} ${moneyText(Math.abs(amount))}`.trim();
}
function walmartDetailTitle(groupLabel, itemLabel) {
if (itemLabel) return itemLabel;
if (groupLabel === 'Services fees') return 'Services Fees';
return groupLabel || '结算明细';
}
function walmartFeeDetail(row) {
const raw = String(row.description || row.amount_field || '').trim();
const key = raw.toLowerCase().replace(/[^a-z0-9]+/g, '');
const labels = {
wfsfulfillmentfee: 'WFS Fulfillment Fee',
wfsreturnprocessingfee: 'Return Processing Fee',
wfsreturneditemdisposalfee: 'Returned Item Disposal Fee',
wfslostinventory: 'Found Inventory',
wfsstoragefee: Number(row.amount || 0) > 0 ? 'Discounts - Storage Fee' : 'Storage Fee',
wfslongtermstoragefee: 'Long Term Storage Fee',
wfsinboundtransportationfee: 'Inbound Transportation Fee'
};
if (labels[key]) return labels[key];
return raw.replace(/^WFS\s*/i, '').replace(/([a-z])([A-Z])/g, '$1 $2') || row.amount_field || '-';
}
function mergeWalmartServiceDetails(rows) {
const merged = new Map();
rows.forEach(row => {
const feeDetail = walmartFeeDetail(row);
const current = merged.get(feeDetail) || { ...row, amount: 0, detail_count: 0 };
current.amount += Number(row.amount || 0);
current.detail_count += 1;
if (!current.transaction_date && row.transaction_date) current.transaction_date = row.transaction_date;
merged.set(feeDetail, current);
});
return Array.from(merged.values());
}
function renderWalmartDetailHeader(isServices) {
wmDetailHead.innerHTML = isServices
? '| 服务 | 费用明细 | 扣费日期 | 金额 | 状态 |
'
: '| 服务 | 费用明细 | 扣费日期 | 订单号 | 采购订单号 | SKU | 金额 | 状态 | 交易类型 |
';
}
function walmartEnglishDate(value) {
const text = String(value || '').slice(0, 10);
const parts = text.split('-').map(Number);
if (parts.length !== 3 || !parts[0]) return text || '-';
return new Date(parts[0], parts[1] - 1, parts[2]).toLocaleDateString('en-US', {
month: 'short', day: 'numeric', year: 'numeric'
});
}
window.loadWalmartSummary = async function () {
const query = new URLSearchParams({ page: 1, page_size: 10 });
if (state.summary.settlementId) query.set('settlement_id', state.summary.settlementId);
try {
const data = await apiGet('/api/walmart-settlement/settlements/summary?' + query);
if (!data.settlement) {
wmSummaryMeta.textContent = '未找到结算单。';
wmSummarySections.innerHTML = '请先从结算单列表选择一张结算单。
';
return;
}
const settlement = data.settlement;
state.summary.settlementId = settlement.id;
state.summary.settlement = settlement;
const period = [settlement.period_start, settlement.period_end].filter(Boolean).join(' - ') || settlement.report_date || '-';
wmSummaryMeta.textContent = `结算单编号:${settlement.settlement_number} · 周期:${period} · 结算金额:${walmartMoney(data.official_total, settlement.currency)}`;
wmSummarySections.innerHTML = (data.groups || []).map(group => {
const items = (group.items || []).filter(item => item.item_key !== 'total');
const itemRows = items.map(item => `${walmartMoney(item.amount, settlement.currency)}
`).join('');
const negative = Number(group.amount || 0) < 0 ? ' negative' : '';
return `${escHtml(group.group_label)}
${itemRows}Total:${walmartMoney(group.amount, settlement.currency)}
`;
}).join('');
} catch (error) {
toast('Unable to load settlement summary: ' + error.message);
}
};
window.showWalmartSettlementSummary = function (id, number, account) {
state.summary = { settlementId: id, number: number || '', account: account || '', settlement: null };
openWalmartPage('walmart-settlement-summary');
};
window.openWalmartSummaryDetails = function (groupKey, itemKey, groupLabel, itemLabel) {
const settlement = state.summary.settlement || {};
state.detail = {
id: state.summary.settlementId,
number: settlement.settlement_number || state.summary.number || '',
account: settlement.account_code || state.summary.account || '',
groupKey: groupKey || '', itemKey: itemKey || '',
groupLabel: groupLabel || '', itemLabel: itemLabel || '',
paymentStatus: settlement.payment_status || '', page: 1, pageSize: 100, pages: 1
};
wmDetailKeyword.value = '';
wmDetailDateMin.value = '';
wmDetailDateMax.value = '';
openWalmartPage('walmart-settlement-details');
};
window.showWalmartSettlementDetail = function (id, number, account) {
state.summary = { settlementId: id, number: number || '', account: account || '', settlement: null };
openWalmartSummaryDetails('', '', '全部明细', '');
};
window.backToWalmartSummary = function () {
openWalmartPage('walmart-settlement-summary');
};
window.loadWalmartDetails = async function (reset) {
if (!state.detail.id) return;
if (reset) state.detail.page = 1;
const query = new URLSearchParams({
settlement_id: state.detail.id, page: state.detail.page, page_size: state.detail.groupKey === 'services_fees' ? 500 : state.detail.pageSize
});
if (state.detail.groupKey) query.set('group_key', state.detail.groupKey);
if (state.detail.itemKey) query.set('item_key', state.detail.itemKey);
if (wmDetailKeyword.value.trim()) query.set('keyword', wmDetailKeyword.value.trim());
if (wmDetailDateMin.value) query.set('date_min', wmDetailDateMin.value);
if (wmDetailDateMax.value) query.set('date_max', wmDetailDateMax.value);
try {
const data = await apiGet('/api/walmart-settlement/settlements/summary?' + query);
const settlement = data.settlement || {};
state.detail.paymentStatus = settlement.payment_status || state.detail.paymentStatus;
wmDetailTitle.textContent = walmartDetailTitle(state.detail.groupLabel, state.detail.itemLabel);
const isServices = state.detail.groupKey === 'services_fees';
wmDetailSubtitle.textContent = isServices
? '查看 Walmart fulfillment services 的费用明细。'
: `结算单编号:${settlement.settlement_number || state.detail.number || ''} · ${state.detail.groupLabel || '全部明细'}`;
const status = String(state.detail.paymentStatus || '').toLowerCase() === 'paid' ? 'Paid' : 'Pending';
const displayRows = isServices ? mergeWalmartServiceDetails(data.details || []) : (data.details || []);
renderWalmartDetailHeader(isServices);
wmDetailTb.innerHTML = displayRows.map(row => {
const service = row.item_key === 'walmart_fulfillment_services' ? 'WFS'
: row.item_key === 'sem_marketing' ? 'SEM'
: row.item_key === 'walmart_product_advertising' ? 'Advertising'
: row.item_key === 'review_accelerator' ? 'Review'
: (row.group_label || row.transaction_type || '-');
const base = `${escHtml(service)} | ${escHtml(walmartFeeDetail(row))} | ${escHtml(walmartEnglishDate(row.transaction_date))} | `;
if (isServices) return `${base}| ${walmartMoney(row.amount, row.currency || settlement.currency)} | ${status} |
`;
return `${base}| ${escHtml(row.order_number || '-')} | ${escHtml(row.purchase_order_id || '-')} | ${escHtml(row.sku || '-')} | ${walmartMoney(row.amount, row.currency || settlement.currency)} | ${status} | ${escHtml(row.transaction_type || '-')} |
`;
}).join('') || `暂无匹配明细。 |
`;
const detailTotal = isServices ? displayRows.length : data.detail_total;
state.detail.pages = Math.max(1, Math.ceil(detailTotal / data.page_size));
wmDetailPageInfo.textContent = `第 ${data.page} / ${state.detail.pages} 页,共 ${detailTotal} 条`;
} catch (error) {
toast('加载结算明细失败:' + error.message);
}
};
window.changeWalmartDetailPage = function (delta) { state.detail.page = Math.min(state.detail.pages || 1, Math.max(1, state.detail.page + delta)); loadWalmartDetails(false); };
async function downloadWithAuth(url, filename) { const response = await fetch(url, { headers: authHeaders() }); if (!response.ok) throw new Error('导出失败:' + response.status); const blob = await response.blob(); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = filename; document.body.appendChild(link); link.click(); setTimeout(() => { URL.revokeObjectURL(link.href); link.remove(); }, 1000); }
window.exportWalmartSummary = async function (format) { if (!state.summary.settlementId) return toast('请先打开一张结算单'); const suffix = format === 'pdf' ? 'pdf' : 'xlsx'; const number = (state.summary.settlement && state.summary.settlement.settlement_number) || state.summary.number || state.summary.settlementId; try { await downloadWithAuth(`/api/walmart-settlement/settlements/${state.summary.settlementId}/summary-export?format=${suffix}`, `walmart_settlement_summary_${number}.${suffix}`); toast('汇总导出成功'); } catch (error) { toast(error.message); } };
window.exportWalmartDetails = async function () { if (!state.detail.id) return toast('请先打开一张结算单'); try { await downloadWithAuth(`/api/walmart-settlement/settlements/${state.detail.id}/export`, state.detail.number + '.xlsx'); toast('导出成功'); } catch (error) { toast(error.message); } };
window.loadWalmartFeeMappings = async function () { try { const [types, saved] = await Promise.all([apiGet('/api/walmart-settlement/types'), apiGet('/api/walmart-settlement/fee-mappings')]); const map = new Map((saved.rows || []).map(item => [item.transaction_type + '\u0000' + item.amount_field, item])); wmFeeMappingTb.innerHTML = (types.rows || []).map(type => { const savedItem = map.get(type.transaction_type + '\u0000' + type.amount_field) || {}; const item = Object.keys(savedItem).length ? savedItem : (type.mapping || {}); const scope = type.mapping_scope === 'fee_detail' ? 'Fee Detail' : '汇总项目'; return `| ${escHtml(type.transaction_type)} | ${escHtml(type.amount_field)} | ${scope} | | | | |
`; }).join('') || '同步到有金额的结算明细后,这里会自动出现待映射项 |
'; } catch (error) { toast('加载费用项映射失败:' + error.message); } };
window.saveWalmartFeeMappings = async function () { const rows = Array.from(wmFeeMappingTb.querySelectorAll('tr[data-type]')).map(tr => ({ transaction_type: tr.dataset.type, amount_field: tr.dataset.field, fee_item: tr.querySelector('[data-key=fee_item]').value.trim(), fee_item_field: tr.querySelector('[data-key=fee_item_field]').value.trim(), amount_target_field: tr.querySelector('[data-key=amount_target_field]').value.trim(), enabled: tr.querySelector('[data-key=enabled]').checked ? 1 : 0 })); try { const result = await apiPost('/api/walmart-settlement/fee-mappings', { rows }); toast('已保存 ' + result.saved + ' 条费用项映射'); } catch (error) { toast('保存失败:' + error.message); } };
const sourceOptions = ['结算单编号','结算日期','账号编码','交易类型','金额字段','金额','币种','订单号','交易开始日期','交易结束日期'];
function renderFieldMappings(fields, saved) { const savedMap = new Map((saved || []).map(item => [item.target_key + '\u0000' + item.field_scope + '\u0000' + (item.entry_key || ''), item])); wmFieldMappingTb.innerHTML = (fields || []).map(field => { const item = savedMap.get(field.key + '\u0000' + field.scope + '\u0000' + (field.entry_key || '')) || {}; const source = item.source_col || ''; return `| ${escHtml(field.key)} | ${escHtml(field.name || '')} | ${field.scope === 'head' ? '单据头' : '明细'} | | | | ${escHtml(field.entry_key || '')} | ${escHtml(field.parent_entry_key || '')} | |
`; }).join('') + ``; }
window.loadWalmartKingdeeFields = async function () { const account = wmFieldAccount.value; if (!account) return toast('请选择当前账号'); try { showLoading('正在读取金蝶字段...'); const [fields, saved] = await Promise.all([apiGet('/api/walmart-settlement/kingdee-fields?account_code=' + encodeURIComponent(account)), apiGet('/api/walmart-settlement/field-mappings?account_code=' + encodeURIComponent(account))]); if (!fields.ok) throw new Error(fields.message); state.kingdeeFields = fields.fields || []; renderFieldMappings(state.kingdeeFields, saved.rows || []); } catch (error) { toast('读取失败:' + error.message); } finally { hideLoading(); } };
window.loadWalmartFieldMappings = async function () { if (!state.accounts.length) await loadWalmartAccounts(); const account = wmFieldAccount.value; if (!account) return; try { const saved = await apiGet('/api/walmart-settlement/field-mappings?account_code=' + encodeURIComponent(account)); if (state.kingdeeFields.length) renderFieldMappings(state.kingdeeFields, saved.rows || []); else if ((saved.rows || []).length) renderFieldMappings(saved.rows.map(item => ({ key: item.target_key, name: item.target_name, scope: item.field_scope, entry_key: item.entry_key, parent_entry_key: item.parent_entry_key })), saved.rows); } catch (error) { toast('加载字段映射失败:' + error.message); } };
window.saveWalmartFieldMappings = async function () { const account = wmFieldAccount.value; if (!account) return toast('请选择当前账号'); const mappings = Array.from(wmFieldMappingTb.querySelectorAll('tr[data-target]')).map((tr, index) => { const type = tr.querySelector('[data-key=value_type]').value; const value = tr.querySelector('[data-key=source]').value.trim(); return { target_key: tr.dataset.target, target_name: tr.dataset.name, field_scope: tr.dataset.scope, value_type: type, source_col: type === 'source' ? value : '', const_value: type === 'const' ? value : '', is_base: tr.querySelector('[data-key=is_base]').checked ? 1 : 0, entry_key: tr.dataset.entry, parent_entry_key: tr.dataset.parent, enabled: tr.querySelector('[data-key=enabled]').checked ? 1 : 0, sort_order: index }; }); try { const result = await apiPost('/api/walmart-settlement/field-mappings', { account_code: account, mappings }); toast('已保存 ' + result.saved + ' 条字段映射'); } catch (error) { toast('保存失败:' + error.message); } };
window.copyWalmartFieldMappings = async function () { const source = wmFieldCopySource.value, target = wmFieldAccount.value; if (!source || !target) return toast('请选择复制来源账号和当前目标账号'); if (!confirm('确认用 ' + source + ' 的映射替换 ' + target + ' 当前映射?')) return; try { const result = await apiPost('/api/walmart-settlement/field-mappings/copy', { source_account_code: source, target_account_code: target }); toast('已复制 ' + result.copied + ' 条映射'); loadWalmartFieldMappings(); } catch (error) { toast('复制失败:' + error.message); } };
window.loadWalmartSchedule = async function () { try { const data = await apiGet('/api/walmart-settlement/schedule'); wmScheduleEnabled.value = String(data.enabled || 0); wmScheduleCron.value = data.cron || '0 */2 * * *'; wmScheduleNext.value = data.next_run_at || '未安排'; wmScheduleStatus.textContent = `上次执行:${data.last_run_at || '无'};状态:${data.last_run_status || '未执行'};${data.last_run_message || ''}`; } catch (error) { toast('加载定时配置失败:' + error.message); } };
window.saveWalmartSchedule = async function () { try { const data = await apiPost('/api/walmart-settlement/schedule', { enabled: Number(wmScheduleEnabled.value), cron: wmScheduleCron.value.trim() }); toast('定时拉取配置已保存'); wmScheduleNext.value = data.next_run_at || '未安排'; } catch (error) { toast('保存失败:' + error.message); } };
window.runWalmartScheduleNow = async function () { try { showLoading('正在发现沃尔玛结算报告...'); const result = await apiPost('/api/walmart-settlement/schedule/run', {}); toast('执行完成:新增 ' + (result.saved || 0) + ' 份报告'); loadWalmartSchedule(); } catch (error) { toast('执行失败:' + error.message); } finally { hideLoading(); } };
function walmartFieldValueOptions(current) {
const values = sourceOptions.slice();
if (current && !values.includes(current)) values.unshift(current);
return '' + values.map(value => ``).join('');
}
function syncWalmartFieldMappings() {
state.walmartFieldRows = Array.from(wmFieldMappingTb.querySelectorAll('tr[data-wm-field-row]')).map(tr => {
const read = key => tr.querySelector(`[data-key="${key}"]`);
const type = read('value_type')?.value || 'source';
const value = read('source')?.value || '';
return { target_key: read('target_key')?.value.trim() || '', target_name: read('target_name')?.value.trim() || '', field_scope: read('field_scope')?.value || 'entry', value_type: type, source_col: type === 'source' ? value : '', const_value: type === 'const' ? value : '', is_base: read('is_base')?.checked ? 1 : 0, entry_key: read('entry_key')?.value.trim() || 'FEntity', parent_entry_key: read('parent_entry_key')?.value.trim() || '', enabled: read('enabled')?.checked ? 1 : 0 };
});
return state.walmartFieldRows;
}
window.onWalmartFieldValueTypeChange = function () { syncWalmartFieldMappings(); renderFieldMappings([], state.walmartFieldRows); };
function renderFieldMappings(fields, saved) {
const savedRows = saved || [];
const rows = (fields || []).map(field => {
const item = savedRows.find(row => row.target_key === field.key && (row.entry_key || '') === (field.entry_key || '')) || savedRows.find(row => row.target_key === field.key) || {};
return { target_key: item.target_key || field.key || '', target_name: item.target_name || field.name || '', field_scope: item.field_scope || field.scope || 'entry', value_type: item.value_type || 'source', source_col: item.source_col || '', const_value: item.const_value || '', is_base: item.is_base ? 1 : 0, entry_key: item.entry_key || field.entry_key || 'FEntity', parent_entry_key: item.parent_entry_key || field.parent_entry_key || '', enabled: item.enabled === 0 ? 0 : 1 };
});
if (!fields || !fields.length) rows.push(...savedRows.filter(item => !rows.some(row => row.target_key === item.target_key)));
state.walmartFieldRows = rows;
wmFieldMappingTb.innerHTML = rows.map((row, index) => {
const value = row.value_type === 'const' ? row.const_value : row.source_col;
const sourceCell = row.value_type === 'auto' ? '' : row.value_type === 'source' ? `` : ``;
return ` | | | | ${sourceCell} | | | | | |
`;
}).join('') || '暂无字段,请先从金蝶拉取字段 |
';
}
window.deleteWalmartFieldMappingRow = function (index) { syncWalmartFieldMappings(); state.walmartFieldRows.splice(index, 1); renderFieldMappings([], state.walmartFieldRows); };
window.addWalmartFieldMappingRow = function () { syncWalmartFieldMappings(); state.walmartFieldRows.push({ target_key: '', target_name: '', field_scope: 'entry', value_type: 'source', source_col: '', const_value: '', is_base: 0, entry_key: 'FEntity', parent_entry_key: '', enabled: 1 }); renderFieldMappings([], state.walmartFieldRows); };
window.saveWalmartFieldMappings = async function () { const account = wmFieldAccount.value; if (!account) return toast('请选择当前账号'); const mappings = syncWalmartFieldMappings().filter(row => row.target_key); try { const result = await apiPost('/api/walmart-settlement/field-mappings', { account_code: account, mappings }); toast('已保存 ' + result.saved + ' 条字段映射'); } catch (error) { toast('保存失败:' + error.message); } };
window.loadWalmartKingdeeFields = async function () { const account = wmFieldAccount.value; if (!account) return toast('请选择当前账号'); try { showLoading('正在读取金蝶字段...'); const [fields, saved] = await Promise.all([apiGet('/api/walmart-settlement/kingdee-fields?account_code=' + encodeURIComponent(account)), apiGet('/api/walmart-settlement/field-mappings?account_code=' + encodeURIComponent(account))]); if (!fields.ok) throw new Error(fields.message); state.kingdeeFields = fields.fields || []; renderFieldMappings(state.kingdeeFields, saved.rows || []); toast('已按结算单字段映射规则读取 ' + state.kingdeeFields.length + ' 个字段'); } catch (error) { toast('读取失败:' + error.message); } finally { hideLoading(); } };
function installWalmartFieldMappingParity() {
const table = document.querySelector('#walmart-field-mapping table');
const head = table?.querySelector('thead tr');
if (head) head.innerHTML = '金蝶字段标识 | 金蝶名称 | 字段层级 | 取值方式 | 取值(来源列 / 固定值) | 分录Key | 父分录Key | 基础资料 | 启用 | 操作 | ';
const card = document.querySelector('#walmart-field-mapping .card');
if (card && !document.getElementById('wmAddFieldMapping')) card.insertAdjacentHTML('beforeend', '');
}
function walmartMappingBadge(status) {
if (!status) return '';
const missing = status === '未配置';
return `${status}`;
}
function mergeWalmartServiceDetails(rows) {
const merged = new Map();
rows.forEach(row => {
const feeDetail = walmartFeeDetail(row);
const current = merged.get(feeDetail) || { ...row, amount: 0, detail_count: 0, mapping_status: '已配置' };
current.amount += Number(row.amount || 0);
current.detail_count += 1;
if (row.mapping_status === '未配置') current.mapping_status = '未配置';
if (!current.transaction_date && row.transaction_date) current.transaction_date = row.transaction_date;
merged.set(feeDetail, current);
});
return Array.from(merged.values());
}
function renderWalmartDetailHeader(isServices) {
wmDetailHead.innerHTML = isServices
? '| 鏈嶅姟 | 璐圭敤鏄庣粏 | 鏄惁鏄犲皠 | 鎵h垂鏃ユ湡 | 閲戦 | 鐘舵€?/th> |
'
: '| 鏈嶅姟 | 璐圭敤鏄庣粏 | 鏄惁鏄犲皠 | 鎵h垂鏃ユ湡 | 璁㈠崟鍙?/th> | 閲囪喘璁㈠崟鍙?/th> | SKU | 閲戦 | 鐘舵€?/th> | 浜ゆ槗绫诲瀷 |
';
}
window.loadWalmartSummary = async function () {
const query = new URLSearchParams({ page: 1, page_size: 10 });
if (state.summary.settlementId) query.set('settlement_id', state.summary.settlementId);
try {
const data = await apiGet('/api/walmart-settlement/settlements/summary?' + query);
if (!data.settlement) { wmSummarySections.innerHTML = '请先从结算单列表选择一张结算单。
'; return; }
const settlement = data.settlement;
state.summary.settlementId = settlement.id;
state.summary.settlement = settlement;
const period = [settlement.period_start, settlement.period_end].filter(Boolean).join(' - ') || settlement.report_date || '-';
wmSummaryMeta.textContent = `结算单编号:${settlement.settlement_number} · 周期:${period} · 结算金额:${walmartMoney(data.official_total, settlement.currency)}`;
wmSummarySections.innerHTML = (data.groups || []).map(group => {
const items = (group.items || []).filter(item => item.item_key !== 'total');
const itemRows = items.map(item => `${walmartMoney(item.amount, settlement.currency)}
`).join('');
const negative = Number(group.amount || 0) < 0 ? ' negative' : '';
return `${escHtml(group.group_label)}${walmartMappingBadge(group.mapping_status)}
${itemRows}Total:${walmartMappingBadge(group.mapping_status)}${walmartMoney(group.amount, settlement.currency)}
`;
}).join('');
} catch (error) { toast('Unable to load settlement summary: ' + error.message); }
};
window.loadWalmartDetails = async function (reset) {
if (!state.detail.id) return;
if (reset) state.detail.page = 1;
const query = new URLSearchParams({ settlement_id: state.detail.id, page: state.detail.page, page_size: state.detail.groupKey === 'services_fees' ? 500 : state.detail.pageSize });
if (state.detail.groupKey) query.set('group_key', state.detail.groupKey);
if (state.detail.itemKey) query.set('item_key', state.detail.itemKey);
if (wmDetailKeyword.value.trim()) query.set('keyword', wmDetailKeyword.value.trim());
if (wmDetailDateMin.value) query.set('date_min', wmDetailDateMin.value);
if (wmDetailDateMax.value) query.set('date_max', wmDetailDateMax.value);
try {
const data = await apiGet('/api/walmart-settlement/settlements/summary?' + query);
const settlement = data.settlement || {};
state.detail.paymentStatus = settlement.payment_status || state.detail.paymentStatus;
wmDetailTitle.textContent = walmartDetailTitle(state.detail.groupLabel, state.detail.itemLabel);
const isServices = state.detail.groupKey === 'services_fees';
wmDetailSubtitle.textContent = isServices ? '鏌ョ湅 Walmart fulfillment services 鐨勮垂鐢ㄦ槑缁嗐€?' : `缁撶畻鍗曠紪鍙凤細${settlement.settlement_number || state.detail.number || ''}`;
const status = String(state.detail.paymentStatus || '').toLowerCase() === 'paid' ? 'Paid' : 'Pending';
const displayRows = isServices ? mergeWalmartServiceDetails(data.details || []) : (data.details || []);
renderWalmartDetailHeader(isServices);
wmDetailTb.innerHTML = displayRows.map(row => {
const service = row.item_key === 'walmart_fulfillment_services' ? 'WFS' : row.item_key === 'sem_marketing' ? 'SEM' : row.item_key === 'walmart_product_advertising' ? 'Advertising' : row.item_key === 'review_accelerator' ? 'Review' : (row.group_label || row.transaction_type || '-');
const base = `${escHtml(service)} | ${escHtml(walmartFeeDetail(row))} | ${walmartMappingBadge(row.mapping_status) || '未配置'} | ${escHtml(walmartEnglishDate(row.transaction_date))} | `;
if (isServices) return `${base}| ${walmartMoney(row.amount, row.currency || settlement.currency)} | ${status} |
`;
return `${base}| ${escHtml(row.order_number || '-')} | ${escHtml(row.purchase_order_id || '-')} | ${escHtml(row.sku || '-')} | ${walmartMoney(row.amount, row.currency || settlement.currency)} | ${status} | ${escHtml(row.transaction_type || '-')} |
`;
}).join('') || `鏆傛棤鍖归厤鏄庣粏銆?/div> |
`;
const detailTotal = isServices ? displayRows.length : data.detail_total;
state.detail.pages = Math.max(1, Math.ceil(detailTotal / data.page_size));
wmDetailPageInfo.textContent = 'Page ' + data.page + ' / ' + state.detail.pages + ', total ' + detailTotal;
} catch (error) { toast('加载结算明细失败:' + error.message); }
};
function installPermissions() {
const original = window.applyNavPermissions;
window.applyNavPermissions = function () {
if (original) original();
const map = { 'walmart-api-config':'walmart_settlement.api_config', 'walmart-settlements':'walmart_settlement.settlements', 'walmart-settlement-summary':'walmart_settlement.summary', 'walmart-settlement-details':'walmart_settlement.details', 'walmart-fee-mapping':'walmart_settlement.fee_mapping', 'walmart-field-mapping':'walmart_settlement.field_mapping', 'walmart-schedule':'walmart_settlement.schedule' };
let visible = false;
document.querySelectorAll('#navWalmartSettlementSub [data-s]').forEach(item => { const allowed = typeof hasResource !== 'function' || hasResource(map[item.dataset.s]) || (item.dataset.s === 'walmart-settlement-summary' && hasResource('walmart_settlement.details')); item.style.display = allowed ? '' : 'none'; if (allowed) visible = true; });
document.getElementById('navWalmartSettlement').style.display = visible ? '' : 'none';
};
}
function hideLegacyWalmartKingdeeAccountFields() {
['wmFormId', 'wmEntryKey'].forEach(id => {
const input = document.getElementById(id);
if (input && input.parentElement) input.parentElement.style.display = 'none';
});
const table = document.querySelector('#walmart-api-config table');
if (table) {
table.querySelectorAll('th:nth-child(6), td:nth-child(6)').forEach(cell => { cell.style.display = 'none'; });
}
const mappingTable = document.getElementById('wmFeeMappingTb');
if (mappingTable && !mappingTable.dataset.multiFieldHints) {
mappingTable.dataset.multiFieldHints = '1';
const applyHints = () => {
mappingTable.querySelectorAll('[data-key="fee_item_field"]').forEach(input => {
input.placeholder = 'F_PAEZ_FYX,F_PAEZ_Base';
input.title = '多个字段用逗号、分号或换行分隔,会同时写入同一行';
});
mappingTable.querySelectorAll('[data-key="amount_target_field"]').forEach(input => {
input.placeholder = 'FAMOUNT,F_PAEZ_Amount';
input.title = '多个字段用逗号、分号或换行分隔,会同时写入同一行';
});
};
new MutationObserver(applyHints).observe(mappingTable, { childList: true, subtree: true });
applyHints();
}
}
installStyle();
installNavigation();
installPages();
hideLegacyWalmartKingdeeAccountFields();
installWalmartFieldMappingParity();
installPermissions();
if (window.currentUser && window.applyNavPermissions) window.applyNavPermissions();
})();