feat: sync latest ARR implementation

This commit is contained in:
Wyndham ARR
2026-07-31 15:11:42 +08:00
parent d6f8a747fa
commit bf7939dd1a
185 changed files with 17527 additions and 2260 deletions

View File

@@ -13,12 +13,12 @@
<header class="masthead">
<div class="shell masthead-inner">
<a class="brand" href="#daily" aria-label="ARR Report 首页">
<span class="brand-mark" aria-hidden="true"><i></i><i></i><i></i></span>
<span><b>ARR</b><small>REPORT</small></span>
<span class="brand-name">ARR Report</span>
</a>
<div class="header-meta">
<span class="system-status" id="system-status"><i></i><span>正在连接数据服务</span></span>
<a class="h5-link" href="/h5">手机看板</a>
<button class="task-log-trigger" id="task-log-trigger" type="button" aria-haspopup="dialog" aria-controls="task-log-dialog">任务日志</button>
<button class="logout-button" id="logout-button" type="button" disabled hidden>退出登录</button>
</div>
</div>
</header>
@@ -26,7 +26,7 @@
<nav class="tab-bar" aria-label="主要模块">
<div class="shell tabs" role="tablist">
<button class="tab is-active" type="button" role="tab" aria-selected="true" aria-controls="panel-daily" data-tab="daily">日报处理</button>
<button class="tab" type="button" role="tab" aria-selected="false" aria-controls="panel-monthly" data-tab="monthly">标准月报</button>
<button class="tab" type="button" role="tab" aria-selected="false" aria-controls="panel-monthly" data-tab="monthly">月报</button>
<button class="tab" type="button" role="tab" aria-selected="false" aria-controls="panel-bi" data-tab="bi">渠道BI</button>
<button class="tab" type="button" role="tab" aria-selected="false" aria-controls="panel-usage" data-tab="usage">公司渠道明细</button>
</div>
@@ -34,22 +34,12 @@
<main class="shell page" id="main-content">
<section class="tabpanel is-active" id="panel-daily" role="tabpanel" data-panel="daily">
<div class="section-heading">
<div>
<p class="eyebrow">DAILY ARRIVAL</p>
<h1>日报处理</h1>
<p>上传 Opera ARR.XML处理结果验收通过后写入业务数据库。</p>
</div>
</div>
<div class="daily-layout">
<section class="daily-overview" aria-label="日报处理概览">
<section class="panel upload-panel" aria-labelledby="upload-title">
<div class="panel-heading">
<div class="panel-heading upload-heading">
<div>
<span class="step-label">01 / UPLOAD</span>
<h2 id="upload-title">上传 ARR.XML</h2>
</div>
<span class="retention-note">本月留痕</span>
</div>
<label class="dropzone" id="dropzone" for="xml-file">
<input id="xml-file" type="file" accept=".xml,text/xml,application/xml" />
@@ -60,34 +50,21 @@
<span>或点击选择文件,单个文件最大 25 MB</span>
<em id="selected-file">尚未选择文件</em>
</label>
<button class="primary-button" id="upload-button" type="button" disabled>开始处理</button>
<p class="service-hint" id="upload-hint" role="status"></p>
</section>
<section class="panel process-panel" aria-labelledby="process-title">
<div class="panel-heading">
<div>
<span class="step-label">02 / STATUS</span>
<h2 id="process-title">处理状态</h2>
<div class="upload-progress" id="upload-progress" hidden aria-live="polite">
<div class="upload-progress-meta">
<span id="upload-progress-label">等待开始</span>
<strong id="upload-progress-percent">0%</strong>
</div>
<div class="upload-progress-track" id="upload-progress-track" role="progressbar" aria-label="ARR.XML 处理进度" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" aria-valuetext="等待开始 0%">
<span id="upload-progress-bar"></span>
</div>
</div>
<div class="process-state" id="process-state">
<div class="process-orbit" aria-hidden="true"><i></i></div>
<div>
<strong id="process-copy">等待上传 ARR.XML</strong>
<p id="process-detail">完成后将自动刷新日报记录。</p>
</div>
<div class="upload-footer">
<p class="service-hint" id="upload-hint" role="status"></p>
<button class="primary-button" id="upload-button" type="button" disabled>开始处理</button>
</div>
<ol class="pipeline" aria-label="处理流程">
<li><i>1</i><span>安全上传<small>私有对象存储</small></span></li>
<li><i>2</i><span>远端处理<small>确定性日报规则</small></span></li>
<li><i>3</i><span>结果验收<small>文件与数据复核</small></span></li>
<li><i>4</i><span>数据入库<small>原子提交</small></span></li>
</ol>
</section>
</div>
<section class="metric-grid daily-metrics" aria-label="最近一次处理结果">
<article class="metric-card">
<span>ARRIVAL DATE</span>
<strong id="metric-arrival"></strong>
@@ -108,8 +85,7 @@
<section class="panel table-panel" aria-labelledby="daily-history-title">
<div class="panel-heading table-heading">
<div>
<span class="step-label">THIS MONTH</span>
<h2 id="daily-history-title">日报处理记录</h2>
<h2 id="daily-history-title">Daily Report</h2>
</div>
<button class="text-button" id="refresh-jobs" type="button">刷新</button>
</div>
@@ -119,37 +95,37 @@
<tbody id="jobs-body"><tr><td class="empty-cell" colspan="7">正在读取本月记录…</td></tr></tbody>
</table>
</div>
<nav class="pagination-bar" aria-label="Daily Report 分页">
<span class="pagination-summary" id="jobs-pagination-summary">共 0 条</span>
<div class="pagination-actions">
<button class="pagination-button" id="jobs-prev" type="button" disabled>上一页</button>
<span class="pagination-page" id="jobs-page-label">第 1 / 1 页</span>
<button class="pagination-button" id="jobs-next" type="button" disabled>下一页</button>
</div>
</nav>
</section>
</section>
<section class="tabpanel" id="panel-monthly" role="tabpanel" data-panel="monthly" hidden>
<div class="section-heading split-heading">
<div>
<p class="eyebrow">DATABASE REPORT</p>
<h1>标准月报</h1>
<p>按数据库中已验收的日报事实生成月报,版本与文件月内持续留痕。</p>
</div>
<div class="report-controls" aria-label="月报生成参数">
<label><span>月份</span><input id="monthly-month" type="month" /></label>
<label><span>更新至</span><input id="monthly-as-of" type="date" /></label>
<button class="primary-button compact" id="generate-monthly" type="button">生成标准月报</button>
</div>
</div>
<section class="panel table-panel" aria-labelledby="monthly-history-title">
<div class="panel-heading table-heading">
<div>
<span class="step-label">VERSION HISTORY</span>
<h2 id="monthly-history-title">标准月报版本记录</h2>
</div>
<button class="text-button" id="refresh-monthly" type="button">刷新</button>
<section class="tabpanel monthly-page" id="panel-monthly" role="tabpanel" data-panel="monthly" hidden>
<section class="panel table-panel monthly-history-panel" aria-labelledby="monthly-processing-title">
<div class="monthly-panel-toolbar">
<h2 class="monthly-panel-title" id="monthly-processing-title">月报处理</h2>
<span class="trace-live-state is-live" id="monthly-live-state" role="status" aria-live="polite">自动更新 · 4 秒</span>
</div>
<div class="table-scroll">
<table>
<thead><tr><th>版本</th><th>更新至</th><th>状态</th><th>数据行</th><th>公司数</th><th>生成时间</th><th>月报</th></tr></thead>
<tbody id="monthly-body"><tr><td class="empty-cell" colspan="7">正在读取月报记录…</td></tr></tbody>
<table class="monthly-table">
<thead><tr><th>更新至</th><th>状态</th><th>数据行</th><th>公司数</th><th>生成时间</th><th>月报</th></tr></thead>
<tbody id="monthly-body"><tr><td class="empty-cell" colspan="6">正在读取月报记录…</td></tr></tbody>
</table>
</div>
<nav class="pagination-bar" aria-label="月报记录分页">
<span class="pagination-summary" id="monthly-pagination-summary">共 0 条</span>
<div class="pagination-actions">
<button class="pagination-button" id="monthly-prev" type="button" disabled>上一页</button>
<span class="pagination-page" id="monthly-page-label">第 1 / 1 页</span>
<button class="pagination-button" id="monthly-next" type="button" disabled>下一页</button>
</div>
</nav>
</section>
</section>
@@ -191,7 +167,6 @@
<section class="panel table-panel matrix-panel" aria-labelledby="matrix-title">
<div class="panel-heading table-heading">
<div>
<span class="step-label">ROOMS SOLD</span>
<h2 id="matrix-title">渠道 × 房型售出房数</h2>
</div>
</div>
@@ -201,12 +176,11 @@
<section class="tabpanel usage-panel" id="panel-usage" role="tabpanel" data-panel="usage" hidden aria-label="公司渠道明细">
<div class="section-heading company-page-heading">
<div>
<p class="eyebrow">COMPANY DETAIL REPORTS</p>
<div class="company-page-title">
<h1>公司渠道明细</h1>
<p>基于 finance 已校验数据,按 C/O离店日所属期间生成五家公司 Excel。</p>
<p class="company-fixed-companies">固定生成LianTai、QBD、DY-AI-Easy-KB、FengRun、HanaTour</p>
</div>
<button class="text-button company-refresh" id="refresh-company-reports" type="button">刷新任务</button>
<button class="text-button company-refresh" id="refresh-company-reports" type="button" title="重新读取服务状态、Excel 来源和生成记录">刷新任务</button>
</div>
<div class="company-service-banner" id="company-report-unavailable" role="status" hidden>
@@ -214,62 +188,111 @@
<span>请检查本机数据库和 Excel 生成服务后刷新。</span>
</div>
<section class="panel company-report-setup" aria-labelledby="company-report-setup-title">
<div class="panel-heading">
<div>
<span class="step-label">FINANCE DATA</span>
<h2 id="company-report-setup-title">选择月份和本月生成期间</h2>
<p>点击任一期间后,一次固定生成 LianTai、QBD、DY-AI-Easy-KB、FengRun、HanaTour 五份工作簿。</p>
</div>
</div>
<div class="company-generator-grid">
<section class="panel company-report-setup" aria-label="公司渠道明细处理">
<div class="company-setup-heading">
<h2>生成报表</h2>
<label class="company-month-field" for="company-report-month">
<span>报表月份</span>
<input id="company-report-month" type="month" min="2020-01" max="2099-12" autocomplete="off" />
<small>支持已开放期间重跑和历史月份补录。</small>
<span class="sr-only">报表月份</span>
<input id="company-report-month" type="month" min="2020-01" max="2099-12" autocomplete="off" aria-label="报表月份" title="选择 C/O 所属报表月份,并筛选下方生成记录" />
</label>
<div class="company-timezone" aria-label="业务时区:泰国曼谷 UTC+7">
<span>页面与期间时区</span>
<div class="company-timezone-value">
<i aria-hidden="true">BKK</i>
<span><strong>泰国曼谷</strong><small>UTC+7 · Asia/Bangkok</small></span>
</div>
</div>
<div class="company-scope" aria-label="固定生成公司">
<span>固定生成公司</span>
<div class="company-chip-list">
<span>LianTai</span><span>QBD</span><span>DY-AI-Easy-KB</span><span>FengRun</span><span>HanaTour</span>
</div>
</div>
</div>
<fieldset class="company-period-fieldset">
<legend>本月生成期间(一次生成五家公司)</legend>
<div class="company-period-actions">
<button class="company-period-button" type="button" data-company-period="01-10" aria-describedby="company-period-availability" disabled>
<span class="company-period-topline"><span class="company-period-index">第一期</span><span class="company-period-state" data-company-period-state>核对中</span></span>
<strong class="company-period-range" data-company-period-range>0110</strong>
<small class="company-period-detail"><span>C/O0110</span><span data-company-period-release>当月 11 日 00:00 开放</span></small>
<span class="company-period-cta"><span>生成截至 10 日</span><b aria-hidden="true"></b></span>
</button>
<button class="company-period-button" type="button" data-company-period="11-20" aria-describedby="company-period-availability" disabled>
<span class="company-period-topline"><span class="company-period-index">第二期</span><span class="company-period-state" data-company-period-state>核对中</span></span>
<strong class="company-period-range" data-company-period-range>1120</strong>
<small class="company-period-detail"><span>C/O1120</span><span data-company-period-release>当月 21 日 00:00 开放</span></small>
<span class="company-period-cta"><span>生成截至 20 日</span><b aria-hidden="true"></b></span>
</button>
<button class="company-period-button" type="button" data-company-period="21-month-end" aria-describedby="company-period-availability" disabled>
<span class="company-period-topline"><span class="company-period-index">第三期</span><span class="company-period-state" data-company-period-state>核对中</span></span>
<strong class="company-period-range" data-company-period-range>21月末</strong>
<small class="company-period-detail"><span data-company-period-co>C/O21月末</span><span data-company-period-release>次月 1 日 00:00 开放</span></small>
<span class="company-period-cta"><span>生成截至月末</span><b aria-hidden="true"></b></span>
</button>
</div>
<p class="company-period-availability" id="company-period-availability" aria-live="polite">正在核对期间开放日期…</p>
</fieldset>
<div class="company-report-card-row">
<section class="company-source-card" aria-labelledby="company-source-title">
<div class="company-card-heading">
<h3 id="company-source-title">上传 Excel 报表</h3>
</div>
<div class="company-source-action">
<label class="company-excel-dropzone" id="company-excel-dropzone" for="company-excel-file">
<input id="company-excel-file" type="file" accept=".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
<span class="company-upload-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" focusable="false"><path d="M12 15V4m0 0L7.8 8.2M12 4l4.2 4.2M5 14.5v3.3A2.2 2.2 0 0 0 7.2 20h9.6a2.2 2.2 0 0 0 2.2-2.2v-3.3"/></svg>
</span>
<span class="company-upload-copy">
<strong>选择或拖放 Excel 文件</strong>
<span>.xlsx 格式,单个文件最大 25 MB</span>
<em id="company-selected-file">尚未选择文件</em>
</span>
</label>
<button class="company-upload-button" id="company-upload-button" type="button" disabled>
<span>提取并核对</span><b aria-hidden="true"></b>
</button>
</div>
<p class="company-source-error" id="company-source-error" role="alert" hidden></p>
</section>
<button class="company-period-button" type="button" data-company-period="01-10" disabled>
<span class="company-period-topline"><span class="company-period-state" data-company-period-state>核对中</span></span>
<strong class="company-period-range" data-company-period-range>C/O:01-10</strong>
<small class="company-period-detail"><span data-company-period-release>周期结束:当月 11 日 00:00曼谷</span></small>
<span class="company-period-cta"><span>生成</span><b aria-hidden="true"></b></span>
</button>
<button class="company-period-button" type="button" data-company-period="11-20" disabled>
<span class="company-period-topline"><span class="company-period-state" data-company-period-state>核对中</span></span>
<strong class="company-period-range" data-company-period-range>C/O:11-20</strong>
<small class="company-period-detail"><span data-company-period-release>周期结束:当月 21 日 00:00曼谷</span></small>
<span class="company-period-cta"><span>生成</span><b aria-hidden="true"></b></span>
</button>
<button class="company-period-button" type="button" data-company-period="21-month-end" disabled>
<span class="company-period-topline"><span class="company-period-state" data-company-period-state>核对中</span></span>
<strong class="company-period-range" data-company-period-range>C/O:21-30</strong>
<small class="company-period-detail"><span data-company-period-release>周期结束:次月 1 日 00:00曼谷</span></small>
<span class="company-period-cta"><span>生成</span><b aria-hidden="true"></b></span>
</button>
</div>
<section class="company-review-panel" id="company-review-panel" aria-labelledby="company-review-title" hidden>
<header class="company-review-header">
<div class="company-review-title-block">
<h3 id="company-review-title">Booking记录提取</h3>
<p class="company-review-file">
<span>提取文件</span>
<strong id="company-review-filename"></strong>
</p>
</div>
<dl class="company-review-metrics" aria-label="提取统计">
<div><dt>已确认</dt><dd id="company-review-confirmed">0</dd></div>
<div class="is-pending"><dt>待人工</dt><dd id="company-review-pending">0</dd></div>
<div><dt>已删除</dt><dd id="company-review-deleted">0</dd></div>
</dl>
</header>
<div class="company-review-toolbar">
<div class="company-review-selection">
<span id="company-review-selection-count" role="status" aria-live="polite">已选 0 条</span>
<button class="company-review-delete-selected" id="company-review-delete-selected" type="button" disabled>删除所选</button>
</div>
<div class="company-review-actions">
<button class="company-review-discard" id="company-review-discard" type="button">放弃本次提取</button>
<button class="company-review-activate" id="company-review-activate" type="button" disabled>确认并启用</button>
</div>
</div>
<div class="company-review-scroll" role="region" aria-label="提取房型记录" tabindex="0">
<table class="company-review-table">
<thead>
<tr>
<th class="company-review-select-column" scope="col"><input class="company-review-checkbox" id="company-review-select-page" type="checkbox" aria-label="选择本页全部记录" /></th>
<th scope="col">Tour Code</th>
<th scope="col">原始标识</th>
<th scope="col">房型</th>
<th scope="col">数量</th>
<th scope="col">状态</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody id="company-review-body"></tbody>
</table>
</div>
<p class="company-review-empty" id="company-review-empty" hidden>没有可显示的提取记录。</p>
<nav class="company-review-pagination" aria-label="提取记录分页">
<span id="company-review-page-summary">共 0 条</span>
<div>
<button id="company-review-prev" type="button" disabled>上一页</button>
<strong id="company-review-page-label">第 1 / 1 页</strong>
<button id="company-review-next" type="button" disabled>下一页</button>
</div>
</nav>
</section>
<p class="company-report-error" id="company-report-error" role="alert" hidden></p>
<p class="company-generation-note">同月重跑会生成新的正式版本并保留历史归档;浏览器只提交月份和期间,不提交公司名单、数据库参数或文件路径。</p>
</section>
<section class="panel company-job-panel" id="company-report-job-panel" aria-labelledby="company-report-job-title" hidden>
@@ -282,7 +305,6 @@
<div class="company-job-summary">
<span class="status-chip running" id="company-report-job-state">已排队</span>
<strong id="company-report-success-count">0 / 5</strong>
<small>公司已生成</small>
</div>
</div>
<div class="company-progress-wrap">
@@ -290,15 +312,15 @@
<div class="company-progress-track" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" id="company-report-progress-track"><span id="company-report-progress-bar"></span></div>
</div>
<dl class="company-job-meta">
<div><dt>报表月份</dt><dd id="company-report-job-month"></dd></div>
<div><dt>截止日期</dt><dd id="company-report-job-as-of"></dd></div>
<div><dt>任务耗时</dt><dd id="company-report-job-duration"></dd></div>
<div><dt>报表月份</dt><dd id="company-report-job-month">暂无</dd></div>
<div><dt>截止日期</dt><dd id="company-report-job-as-of">暂无</dd></div>
<div><dt>任务耗时</dt><dd id="company-report-job-duration">暂无</dd></div>
<div><dt>需复核</dt><dd id="company-report-warning-count">0 项</dd></div>
</dl>
<div class="table-scroll company-result-scroll">
<table class="company-result-table">
<caption class="sr-only">本次任务中五家公司的生成结果</caption>
<thead><tr><th>公司</th><th class="company-period-column">0110</th><th class="company-period-column">1120</th><th class="company-period-column" id="company-result-month-end-header">21月末</th><th>合计</th><th>状态</th><th>复核 / 异常</th><th>版本</th><th>Excel</th></tr></thead>
<thead><tr><th>公司</th><th class="company-period-column">01-10</th><th class="company-period-column">11-20</th><th class="company-period-column" id="company-result-month-end-header">21-月末</th><th>合计</th><th>状态</th><th>复核 / 异常</th><th>生成时间</th><th>Excel</th></tr></thead>
<tbody id="company-report-result-rows"></tbody>
</table>
</div>
@@ -307,10 +329,9 @@
<section class="panel table-panel company-history-panel" aria-labelledby="company-history-title">
<div class="panel-heading table-heading">
<div>
<span class="step-label">TASK HISTORY</span>
<h2 id="company-history-title">公司渠道明细生成记录</h2>
<h2 id="company-history-title">生成记录</h2>
</div>
<span class="company-history-count" id="company-history-count">0 条记录</span>
<span class="company-history-count">每页 50 条</span>
</div>
<div class="table-scroll">
<table class="company-history-table">
@@ -318,11 +339,75 @@
<tbody id="company-history-rows"><tr><td class="empty-cell" colspan="7">正在读取公司渠道明细任务…</td></tr></tbody>
</table>
</div>
<nav class="pagination-bar" aria-label="生成记录分页">
<span class="pagination-summary" id="company-pagination-summary">共 0 条</span>
<div class="pagination-actions">
<button class="pagination-button" id="company-prev" type="button" disabled>上一页</button>
<span class="pagination-page" id="company-page-label">第 1 / 1 页</span>
<button class="pagination-button" id="company-next" type="button" disabled>下一页</button>
</div>
</nav>
</section>
</section>
</main>
<dialog class="task-log-dialog" id="task-log-dialog" aria-labelledby="process-title" aria-describedby="task-log-description">
<section class="panel process-panel task-log-panel">
<p class="sr-only" id="task-log-description">显示当前选中的日报处理任务从上传到下游通知的处理日志。</p>
<div class="panel-heading trace-heading">
<div>
<span class="step-label">DAILY JOB / LOG</span>
<h2 id="process-title">任务日志</h2>
</div>
<div class="trace-terminal-actions">
<span class="trace-live-state" id="trace-live-state">未选择任务</span>
<button class="trace-refresh-button" id="refresh-trace" type="button" disabled>刷新日志</button>
<button class="trace-refresh-button" id="copy-trace" type="button" disabled>复制全部日志</button>
<button class="trace-refresh-button" id="close-task-log" type="button">关闭</button>
</div>
</div>
<div class="trace-log-frame">
<div class="trace-log-heading">
<span>arr-task.log</span>
<span id="trace-log-count">0 lines</span>
</div>
<pre class="trace-log" id="process-log" role="log" aria-live="polite" aria-label="任务原始日志">$ arr trace
# 请上传文件,或从 Daily Report 中选择一个任务。</pre>
</div>
</section>
</dialog>
<dialog class="company-review-confirm-dialog" id="company-review-confirm-dialog" aria-labelledby="company-review-confirm-title" aria-describedby="company-review-confirm-description company-review-confirm-note">
<div class="company-review-confirm-card">
<div class="company-review-confirm-copy">
<h2 id="company-review-confirm-title">删除房型记录</h2>
<p id="company-review-confirm-description">确认删除所选房型记录?</p>
<p class="company-review-confirm-note" id="company-review-confirm-note">此操作只影响本次提取结果,确认启用前原数据源不会改变。</p>
<p class="company-review-confirm-error" id="company-review-confirm-error" role="alert" hidden></p>
</div>
<div class="company-review-confirm-actions">
<button class="company-review-confirm-cancel" id="company-review-confirm-cancel" type="button">取消</button>
<button class="company-review-confirm-submit" id="company-review-confirm-submit" type="button">确认删除</button>
</div>
</div>
</dialog>
<dialog class="company-report-confirm-dialog" id="company-report-confirm-dialog" aria-labelledby="company-report-confirm-title" aria-describedby="company-report-confirm-description company-report-confirm-note">
<div class="company-report-confirm-card">
<div class="company-report-confirm-copy">
<h2 id="company-report-confirm-title">确认生成</h2>
<p class="company-report-confirm-description" id="company-report-confirm-description">2026年07月01-10</p>
<p class="company-report-confirm-note" id="company-report-confirm-note">将一次生成五家公司的正式 Excel。</p>
<p class="company-report-confirm-error" id="company-report-confirm-error" role="alert" hidden></p>
</div>
<div class="company-report-confirm-actions">
<button class="company-report-confirm-cancel" id="company-report-confirm-cancel" type="button">取消</button>
<button class="company-report-confirm-submit" id="company-report-confirm-submit" type="button">确认生成</button>
</div>
</div>
</dialog>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<footer class="page-footer"><span>页面日期时间统一按泰国曼谷UTC+7显示。</span><span>公司渠道明细按 C/O离店日所属期间分页。</span></footer>
<footer class="page-footer"><span>页面日期时间统一按泰国曼谷UTC+7显示。</span></footer>
</body>
</html>