OAFRONT5 收口PC剩余P2展示问题

这个提交包含在:
2026-05-25 10:04:34 +08:00
父节点 ef24010d4a
当前提交 373301da32
共修改 4 个文件,包含 48 行新增和 32 行删除
+26 -24
查看文件
@@ -41,6 +41,7 @@ import { isApiError } from "../api/types";
import { useAuth } from "../auth/AuthContext";
import { hasPermission } from "../auth/permissions";
import { ConfirmDialog } from "../components/common/ConfirmDialog";
import { DateTextInput } from "../components/common/DateTextInput";
import { ListWorkspace, WorkspaceHeader } from "../components/patterns/ListWorkspace";
import { Button } from "../components/ui/button";
import {
@@ -62,6 +63,7 @@ import {
} from "../components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../components/ui/tabs";
import { downloadBlob } from "../lib/download";
import { formatDisplayDate, formatDisplayDateTime } from "../lib/displayFormat";
type OperationsTab = "ledger" | "pending" | "failed" | "risk" | "reconciliation";
type RiskActionType = "resolve" | "dismiss";
@@ -91,20 +93,24 @@ function resolveErrorMessage(error: unknown, fallback = "操作失败") {
}
function formatDateTime(value: string | null) {
if (!value) {
return "-";
}
const date = new Date(value);
if (Number.isNaN(date.getTime())) {
return value;
}
return date.toLocaleString("zh-CN", {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
});
return formatDisplayDateTime(value);
}
function formatDate(value: string | null | undefined) {
return formatDisplayDate(value);
}
function displayPersonName(value: string | null | undefined, fallback = "-") {
const name = value?.trim();
if (!name) return fallback;
const smokeNameLabels: Record<string, string> = {
Employee: "测试员工",
Manager: "测试主管",
Admin: "测试管理员",
Finance: "测试财务",
"Finance Manager": "测试财务负责人",
};
return smokeNameLabels[name] ?? name;
}
function statusBadgeClass(status: string) {
@@ -737,8 +743,7 @@ export function ApOperationsPage() {
</div>
<div className="space-y-2">
<div className="text-sm font-medium text-zinc-700">报销日期从</div>
<Input
type="date"
<DateTextInput
value={ledgerDateFrom}
onChange={(event) => {
setLedgerDateFrom(event.target.value);
@@ -748,8 +753,7 @@ export function ApOperationsPage() {
</div>
<div className="space-y-2">
<div className="text-sm font-medium text-zinc-700">报销日期至</div>
<Input
type="date"
<DateTextInput
value={ledgerDateTo}
onChange={(event) => {
setLedgerDateTo(event.target.value);
@@ -811,7 +815,7 @@ export function ApOperationsPage() {
<div className="text-xs text-zinc-500">{item.description || "无说明"}</div>
</TableCell>
<TableCell>
<div className="font-medium text-zinc-900">{item.owner?.name ?? item.submitter?.name ?? "-"}</div>
<div className="font-medium text-zinc-900">{displayPersonName(item.owner?.name ?? item.submitter?.name)}</div>
<div className="text-xs text-zinc-500">{item.department?.name ?? "-"}</div>
</TableCell>
<TableCell>
@@ -830,7 +834,7 @@ export function ApOperationsPage() {
{paymentStatusLabel(item.payment.status)}
</span>
<div className="text-xs text-zinc-500">
{item.payment.paymentDate ?? "-"} · {item.payment.paidBy?.name ?? "未记录操作人"}
{formatDate(item.payment.paymentDate)} · {displayPersonName(item.payment.paidBy?.name, "未记录操作人")}
</div>
<div className="text-xs text-zinc-500">
凭证:{item.payment.paymentVoucherNo ?? "-"}
@@ -912,16 +916,14 @@ export function ApOperationsPage() {
</div>
<div className="space-y-2">
<div className="text-sm font-medium text-zinc-700">创建时间从</div>
<Input
type="date"
<DateTextInput
value={pendingCreatedAtFrom}
onChange={(event) => setPendingCreatedAtFrom(event.target.value)}
/>
</div>
<div className="space-y-2">
<div className="text-sm font-medium text-zinc-700">创建时间至</div>
<Input
type="date"
<DateTextInput
value={pendingCreatedAtTo}
onChange={(event) => setPendingCreatedAtTo(event.target.value)}
/>
+16 -2
查看文件
@@ -113,6 +113,20 @@ function assetTypeLabel(value: AssetType | string | null | undefined) {
return assetTypeOptions().find((item) => item.value === value)?.label ?? "未知类型";
}
function assetStatusLabel(value: AssetStatus | string | null | undefined) {
return assetStatusOptions().find((item) => item.value === value)?.label ?? "未知状态";
}
function assetErpChangeTypeLabel(value: string | null | undefined) {
const labels: Record<string, string> = {
created: "新建资产卡",
updated: "资产信息更新",
retired: "资产退役",
archived: "资产归档",
};
return value ? labels[value] ?? "资产变更" : "-";
}
function sensitivityOptions(): Array<{ value: AssetSensitivityLevel | ""; label: string }> {
return [
{ value: "", label: "全部敏感级别" },
@@ -1335,9 +1349,9 @@ export function AssetRegistryPage() {
<div className="grid gap-2 rounded-lg bg-zinc-50 px-3 py-2 text-xs text-zinc-600 md:grid-cols-2">
<div>资产编号:{assetErpTrack?.asset.assetNo ?? currentAsset?.assetNo ?? "-"}</div>
<div>最近 changeType:{assetErpStage.preview.changeType ?? "-"}</div>
<div>最近变更:{assetErpChangeTypeLabel(assetErpStage.preview.changeType)}</div>
<div>分类:{assetErpStage.preview.categoryCode ?? "-"}</div>
<div>资产状态:{assetErpStage.preview.status ?? assetErpTrack?.asset.status ?? "-"}</div>
<div>资产状态:{assetStatusLabel(assetErpStage.preview.status ?? assetErpTrack?.asset.status)}</div>
<div>法体:{assetErpStage.preview.legalEntityCode ?? "-"}</div>
<div>成本中心:{assetErpStage.preview.costCenterCode ?? "-"}</div>
</div>
+3 -4
查看文件
@@ -28,6 +28,7 @@ import { useAuth } from "../auth/AuthContext";
import { hasPermission } from "../auth/permissions";
import { EmployeeAvatar } from "../components/common/EmployeeAvatar";
import { ConfirmDialog } from "../components/common/ConfirmDialog";
import { DateTextInput } from "../components/common/DateTextInput";
import { PageHeader } from "../components/common/PageHeader";
import { Button } from "../components/ui/button";
import {
@@ -566,13 +567,11 @@ export function PeoplePage() {
</option>
))}
</select>
<Input
type="date"
<DateTextInput
value={hireDateFrom}
onChange={(event) => setHireDateFrom(event.target.value)}
/>
<Input
type="date"
<DateTextInput
value={hireDateTo}
onChange={(event) => setHireDateTo(event.target.value)}
/>
@@ -2,10 +2,11 @@
"OAFRONT5-0","建立 OAFRONT4 部署后 PC 体验收口合同","承接 OAFRONT4 已完成的本地 PC 清理,规划部署后只读回归、剩余 PC 体验硬化和 OALAUNCH1 对齐;本合同只作为待审执行合同,不代表批准部署或继续改代码。","CSV 校验通过;明确 OAFRONT5 必须先部署并复跑只读矩阵,之后按 finding 决定是否修 AP/报销/HR/后台日期与密度问题;不得绕过用户采纳门禁。","受影响流程:OAFRONT4 本地完成 -> 公网部署 -> 只读视觉矩阵 -> OAFRONT5 采纳决策;验证步骤:validate_issues_csv.py 本 CSV;check-process-contract general;git diff --check。","python3|node|git|manual","DONE","DONE","DONE","issues/2026-05-25_09-17-51-oa-pc-post-deploy-ui-hardening-v1.csv","[]","MAGI 审视:OAFRONT4 已可部署但未公网验证;执行:先做部署前门禁,不再盲改旧现网截图;提升:把后续分成部署回归、财务/AP、报销高频、HR/后台后置和 OALAUNCH1 对齐。"
"OAFRONT5-1","部署 OAFRONT4 并复跑公网只读回归","在用户明确批准后,部署当前 OAFRONT4 提交到公网 OA,并立即执行健康检查、OAOPS1 只读巡检和 PC 只读视觉矩阵。","部署使用 SYNC_ENV=0,不覆盖远端 .env;/ready 通过;OAOPS1 只读巡检通过或 finding 可解释;OAFRONT3 PC 只读矩阵生成新 summary;不创建业务数据、不执行真实付款。","受影响流程:部署 -> /ready -> live smoke readiness -> OAOPS1 daily -> PC 视觉矩阵;验证步骤:SYNC_ENV=0 bash deploy/trialrun/deploy.sh;curl -fsS https://oa.hyinda.com/ready;LIVE_SMOKE_BASE_URL=https://oa.hyinda.com bash scripts/qa/run-oa-real-use-daily.sh;bash scripts/qa/run-oafront3-pc-readonly-visual.sh。","bash|curl|playwright","TODO","TODO","TODO","deploy/trialrun/deploy.sh;scripts/qa/run-oa-real-use-daily.sh;scripts/qa/run-oafront3-pc-readonly-visual.sh;artifacts/qa-flow","[""OAFRONT5-0""]","需要人工确认才执行部署。回滚路径:按 trialrun runbook 回滚到上一稳定镜像;视觉矩阵只读,不写业务数据。"
"OAFRONT5-2","关闭 OAFRONT4 Regression 并回填证据","部署后根据新公网矩阵回填 OAFRONT4-2..8 的 Regression_Status;若 P1 清零且 P2 可解释,关闭 OAFRONT4;若仍有 P1,转入 OAFRONT5 修复。","OAFRONT4 的 Regression 不再依赖旧现网 baseline;所有关闭项都有新 summary 路径;未清零的 finding 必须分类为 blocker、follow-up 或 accepted-risk。","受影响流程:PC 只读矩阵 -> finding 分类 -> OAFRONT4 状态回填 -> 后续修复决策;验证步骤:检查新 artifacts/qa-flow/oafront3-pc-readonly-visual-*/summary.json;validate OAFRONT4 CSV;git diff --check。","python3|node|git|manual","TODO","TODO","TODO","issues/2026-05-25_00-55-14-oa-pc-launch-ui-cleanup-v1.csv;artifacts/qa-flow/oafront3-pc-readonly-visual-*","[""OAFRONT5-1""]","不得用部署前旧矩阵关闭回归;报告不得包含密码、token、Secret、完整账号、票据原图、合同正文或银行流水。回滚/清理:若回填分类有误,仅回滚 Issue CSV 状态提交;只读矩阵报告保留为审计证据。"
"OAFRONT5-3","财务/AP 页面 PC 日期与密度二次收口","若部署后矩阵仍显示 AP/财务运营页日期英文占位、表单密度或状态展示问题,则优先处理 ApOperationsPage;不改变 AP、付款、导出或银行回单业务语义。","AP 账期、到期日、回单日期等高频字段改用统一中文日期输入/展示;财务列表主展示保持业务编号、供应商/对象、金额、状态和下一步;不新增真实支付或 ERP 能力。","受影响流程:财务登录 -> AP 运营 -> 查看账期/到期/回单 -> 导出/对账;验证步骤:client typecheck/build;check-ui-design-rules;finance 角色 PC 只读截图;OAOPS1 daily 通过。","typescript|playwright|node","TODO","TODO","TODO","client/src/pages/ApOperationsPage.tsx;client/src/components/common/DateTextInput.tsx;client/src/lib/displayFormat.ts","[""OAFRONT5-2""]","优先级取决于部署后 finding;回滚路径:还原 AP 前端展示提交,不触碰后端付款状态。"
"OAFRONT5-3","财务/AP 页面 PC 日期与密度二次收口","若部署后矩阵仍显示 AP/财务运营页日期英文占位、表单密度或状态展示问题,则优先处理 ApOperationsPage;不改变 AP、付款、导出或银行回单业务语义。","AP 账期、到期日、回单日期等高频字段改用统一中文日期输入/展示;财务列表主展示保持业务编号、供应商/对象、金额、状态和下一步;不新增真实支付或 ERP 能力。","受影响流程:财务登录 -> AP 运营 -> 查看账期/到期/回单 -> 导出/对账;验证步骤:client typecheck/build;check-ui-design-rules;finance 角色 PC 只读截图;OAOPS1 daily 通过。","typescript|playwright|node","DONE","DONE","TODO","client/src/pages/ApOperationsPage.tsx;client/src/components/common/DateTextInput.tsx;client/src/lib/displayFormat.ts","[""OAFRONT5-2""]","本地已修:AP 报销日期/创建时间筛选改用 DateTextInput,付款日期展示统一中文日期,通用 smoke 英文姓名改为中文测试名;typecheck/build、check-ui-design-rules 通过。Regression 待部署后 PC 矩阵确认 AP P2 清零。回滚路径:还原 AP 前端展示提交,不触碰后端付款状态。"
"OAFRONT5-4","报销高频页日期输入统一化","如果部署后或真实使用反馈仍认为报销筛选、明细发生日期、付款动作日期有英文原生日期控件风险,则把报销高频页面改用 DateTextInput;保持 PDF OCR、审批、付款语义不变。","报销列表筛选、报销明细日期、付款日期等员工/财务高频路径不再出现英文原生日期占位;已有数据保存格式仍为 YYYY-MM-DD;不改变报销 API。","受影响流程:员工编辑报销明细 -> 提交审批;财务筛选报销 -> 标记付款;验证步骤:client typecheck/build;报销详情和列表 Playwright/视觉截图;回归提交草稿和编辑明细。","typescript|playwright|manual","TODO","TODO","TODO","client/src/pages/ReimbursementDashboardPage.tsx;client/src/pages/reimbursement-detail/ReimbursementItemEditor.tsx;client/src/pages/reimbursement-detail/ReimbursementActions.tsx","[""OAFRONT5-2""]","优先级 P1/P2;真实业务路径优先于后台配置页;回滚路径:还原前端输入组件变更。"
"OAFRONT5-5","HR/考勤/后台配置日期控件后置清单","把 EmployeeProfile、People、Attendance、TeamPresence、Leave、Performance、Budgets、Travel 等页面残留 type=date 分类为 HR/配置/冻结域后置,不在 launch 前大面积改。","后置清单清楚说明哪些页面属于 C 类后台或冻结域;除非真实使用出现 blocker,否则不抢 OALAUNCH1 主线。","受影响流程:HR/管理员维护员工资料、团队状态、考勤镜像和预算/差旅冻结页;验证步骤:rg -n 'type=""date""' client/src/pages client/src/components;人工按 A/B/C 页面分层确认。","rg|manual","TODO","TODO","TODO","client/src/pages/EmployeeProfilePage.tsx;client/src/pages/PeoplePage.tsx;client/src/pages/AttendancePage.tsx;client/src/pages/TeamPresencePage.tsx;client/src/pages/LeaveRequestPage.tsx;client/src/pages/BudgetsPage.tsx;client/src/pages/TravelRequestsPage.tsx","[""OAFRONT5-2""]","企微 HR/考勤仍由企微主办;OA 页面多为镜像、后台或应急边界,不应在启用前扩大为 HR 主办 UI 改造。"
"OAFRONT5-5","HR/考勤/后台配置日期控件后置清单","把 EmployeeProfile、People、Attendance、TeamPresence、Leave、Performance、Budgets、Travel 等页面残留 type=date 分类为 HR/配置/冻结域后置,不在 launch 前大面积改。","后置清单清楚说明哪些页面属于 C 类后台或冻结域;除非真实使用出现 blocker,否则不抢 OALAUNCH1 主线。","受影响流程:HR/管理员维护员工资料、团队状态、考勤镜像和预算/差旅冻结页;验证步骤:rg -n 'type=""date""' client/src/pages client/src/components;人工按 A/B/C 页面分层确认。","rg|manual","DONE","DONE","TODO","client/src/pages/EmployeeProfilePage.tsx;client/src/pages/PeoplePage.tsx;client/src/pages/AttendancePage.tsx;client/src/pages/TeamPresencePage.tsx;client/src/pages/LeaveRequestPage.tsx;client/src/pages/BudgetsPage.tsx;client/src/pages/TravelRequestsPage.tsx","[""OAFRONT5-2""]","本地已修 PC 矩阵命中的 HR People 入职日期筛选,改用 DateTextInput;其他 HR/考勤/预算/差旅冻结域日期控件继续后置,不抢 OALAUNCH1 主线;typecheck/build、check-ui-design-rules 通过。Regression 待部署后矩阵确认 hr /people P2 清零。回滚路径:还原 PeoplePage 日期输入组件改动;不修改员工数据、企微 HR/考勤主办边界或真实人员状态。"
"OAFRONT5-6","Portal 首屏工作台化继续观察","OAFRONT4 已完成 Portal 命名本地化;首屏 hero 是否继续收敛,等部署后截图和真实 7 天反馈,不凭主观审美立即重排。","如果真实用户反馈首屏找不到待办/常用/财务入口,再做小步重排;否则保留现布局,只记录 P2 视觉优化建议。","受影响流程:PC 登录 -> 工作台 -> 找待办/草稿/财务/合同/资产入口;验证步骤:部署后 PC 截图;7 天真实反馈;不得复制竞品文案或做营销式 hero。","playwright|manual","TODO","TODO","TODO","client/src/pages/PortalHomePage.tsx;docs/trialrun/人工试运行报告.md","[""OAFRONT5-1""]","优先级 P2;不作为部署 blocker。回滚路径:如后续采纳并修改 Portal 后反馈变差,回滚对应前端提交;本观察项本身只记录证据,无需清理公网数据。"
"OAFRONT5-7","OALAUNCH1 启用门禁对齐","把部署后 UI 回归结果接入 OALAUNCH1:前端可用性只是启动条件之一,最终启用仍取决于真实业务闭环、权限矩阵、备份恢复、7 天稳定化和 Go/No-Go。","OALAUNCH1 汇总能引用最新 OAFRONT4/OAFRONT5 视觉回归结论;不因 UI 自动通过而跳过真实报销、采购、合同、资产、备份和人工 Go/No-Go。","受影响流程:前端回归 -> OALAUNCH1 汇总 -> Day 7 决策;验证步骤:LIVE_SMOKE_BASE_URL=https://oa.hyinda.com bash scripts/qa/run-oa-real-use-daily.sh;OALAUNCH_STABILIZATION_START_DATE=<date> bash scripts/qa/run-oa-final-launch-readiness.sh。","bash|manual","TODO","TODO","TODO","issues/2026-05-23_16-49-39-oa-final-launch-readiness-v1.csv;scripts/qa/run-oa-final-launch-readiness.sh","[""OAFRONT5-2""]","仍需人工/运维:真实业务样本、备份恢复演练、Day 7 Go/No-Go;自动化只能证明入口和只读巡检。回滚/清理:若 OALAUNCH1 引用错误,仅回滚 Issue CSV/报告引用;不修改公网业务数据。"
"OAFRONT5-8","用户采纳门禁","用户审查 OAFRONT5 后决定是否先部署 OAFRONT4,是否采纳 AP/报销日期收口,是否继续后置 HR/Portal。","用户至少给出 A/B/C:A=先部署并复跑矩阵;B=不部署,先继续本地修 AP/报销;C=暂停前端,回到 OALAUNCH1 人工业务闭环。未采纳前不得执行部署或新增代码修复。","受影响流程:OAFRONT5 合同 -> 用户决策 -> 部署/修复/暂停;验证步骤:人工回填选择并 validate CSV。","manual|python3","DONE","DONE","DONE","issues/2026-05-25_09-17-51-oa-pc-post-deploy-ui-hardening-v1.csv","[""OAFRONT5-0""]","用户已批准按推荐继续部署和修复;2026-05-25 已执行首次部署和只读矩阵,发现付款批次复核人 UUID P1 后转入 OAFRONT5-9。"
"OAFRONT5-9","付款批次复核人内部 ID 展示修复","部署后 PC 视觉矩阵发现付款批次详情的复核人字段仍展示内部 UUID,导致 finance/finance_mgr 页面各 1 个 P1 finding;修复展示层,不改付款流程。","首轮复核人、二次复核人等复核字段不再向用户展示 UUID;若后端只返回内部 ID,前端显示“已记录”;付款批次状态、复核、执行、取消和回单逻辑不变。","受影响流程:财务登录 -> 付款批次 -> 查看详情 -> 复核要求;验证步骤:client typecheck/build;check-ui-design-rules;部署后复跑 PC 只读视觉矩阵,finance/finance_mgr /payment-batches UUID P1 清零。","typescript|playwright|node","DONE","DONE","TODO","client/src/pages/PaymentBatchesPage.tsx;issues/2026-05-25_09-17-51-oa-pc-post-deploy-ui-hardening-v1.csv","[""OAFRONT5-2""]","本地证据:client typecheck/build 通过且无 Circular chunk warning;check-ui-design-rules findings=0;check-process-contract baseline/general 通过;audit-docs errors=0;quick_validate 通过;git diff --check 通过;bash scripts/check-minimal.sh 通过。公网回归待部署后复跑 PC 只读视觉矩阵。回滚路径:还原前端展示 helper;不触碰后端付款状态、审批/复核数据或真实付款记录。"
"OAFRONT5-10","资产 ERP 摘要内部码值中文化","部署后 PC 矩阵仍发现资产台账 ERP 摘要暴露 changeType/created 等内部码值;修复展示层,不改 ASSET1 资产模型、ERP 开关或资产台账数据。","资产 ERP 摘要使用中文字段名和中文变更/状态标签;资产编号、分类、法体、成本中心等业务元数据保留;不保存或展示密码、token、Secret、源码包或完整路径。","受影响流程:管理员登录 -> 资产台账 -> 选中资产 -> ERP 同步状态;验证步骤:client typecheck/build;check-ui-design-rules;部署后 PC 只读矩阵 admin /assets raw status P2 清零或仅剩可解释测试数据。","typescript|playwright|node","DONE","DONE","TODO","client/src/pages/AssetRegistryPage.tsx;issues/2026-05-25_09-17-51-oa-pc-post-deploy-ui-hardening-v1.csv","[""OAFRONT5-2""]","本地已修:ERP 摘要最近 changeType 改为最近变更,created/updated/retired/archived 映射为中文;资产状态使用资产状态标签。typecheck/build、check-ui-design-rules 通过。Regression 待部署后矩阵确认。回滚路径:还原资产 ERP 摘要展示 helper,不触碰资产数据或 ERP 同步开关。"
1 ID Title Description Acceptance Test_Method Tools Dev_Status Review1_Status Regression_Status Files Dependencies Notes
2 OAFRONT5-0 建立 OAFRONT4 部署后 PC 体验收口合同 承接 OAFRONT4 已完成的本地 PC 清理,规划部署后只读回归、剩余 PC 体验硬化和 OALAUNCH1 对齐;本合同只作为待审执行合同,不代表批准部署或继续改代码。 CSV 校验通过;明确 OAFRONT5 必须先部署并复跑只读矩阵,之后按 finding 决定是否修 AP/报销/HR/后台日期与密度问题;不得绕过用户采纳门禁。 受影响流程:OAFRONT4 本地完成 -> 公网部署 -> 只读视觉矩阵 -> OAFRONT5 采纳决策;验证步骤:validate_issues_csv.py 本 CSV;check-process-contract general;git diff --check。 python3|node|git|manual DONE DONE DONE issues/2026-05-25_09-17-51-oa-pc-post-deploy-ui-hardening-v1.csv [] MAGI 审视:OAFRONT4 已可部署但未公网验证;执行:先做部署前门禁,不再盲改旧现网截图;提升:把后续分成部署回归、财务/AP、报销高频、HR/后台后置和 OALAUNCH1 对齐。
3 OAFRONT5-1 部署 OAFRONT4 并复跑公网只读回归 在用户明确批准后,部署当前 OAFRONT4 提交到公网 OA,并立即执行健康检查、OAOPS1 只读巡检和 PC 只读视觉矩阵。 部署使用 SYNC_ENV=0,不覆盖远端 .env;/ready 通过;OAOPS1 只读巡检通过或 finding 可解释;OAFRONT3 PC 只读矩阵生成新 summary;不创建业务数据、不执行真实付款。 受影响流程:部署 -> /ready -> live smoke readiness -> OAOPS1 daily -> PC 视觉矩阵;验证步骤:SYNC_ENV=0 bash deploy/trialrun/deploy.sh;curl -fsS https://oa.hyinda.com/ready;LIVE_SMOKE_BASE_URL=https://oa.hyinda.com bash scripts/qa/run-oa-real-use-daily.sh;bash scripts/qa/run-oafront3-pc-readonly-visual.sh。 bash|curl|playwright TODO TODO TODO deploy/trialrun/deploy.sh;scripts/qa/run-oa-real-use-daily.sh;scripts/qa/run-oafront3-pc-readonly-visual.sh;artifacts/qa-flow ["OAFRONT5-0"] 需要人工确认才执行部署。回滚路径:按 trialrun runbook 回滚到上一稳定镜像;视觉矩阵只读,不写业务数据。
4 OAFRONT5-2 关闭 OAFRONT4 Regression 并回填证据 部署后根据新公网矩阵回填 OAFRONT4-2..8 的 Regression_Status;若 P1 清零且 P2 可解释,关闭 OAFRONT4;若仍有 P1,转入 OAFRONT5 修复。 OAFRONT4 的 Regression 不再依赖旧现网 baseline;所有关闭项都有新 summary 路径;未清零的 finding 必须分类为 blocker、follow-up 或 accepted-risk。 受影响流程:PC 只读矩阵 -> finding 分类 -> OAFRONT4 状态回填 -> 后续修复决策;验证步骤:检查新 artifacts/qa-flow/oafront3-pc-readonly-visual-*/summary.json;validate OAFRONT4 CSV;git diff --check。 python3|node|git|manual TODO TODO TODO issues/2026-05-25_00-55-14-oa-pc-launch-ui-cleanup-v1.csv;artifacts/qa-flow/oafront3-pc-readonly-visual-* ["OAFRONT5-1"] 不得用部署前旧矩阵关闭回归;报告不得包含密码、token、Secret、完整账号、票据原图、合同正文或银行流水。回滚/清理:若回填分类有误,仅回滚 Issue CSV 状态提交;只读矩阵报告保留为审计证据。
5 OAFRONT5-3 财务/AP 页面 PC 日期与密度二次收口 若部署后矩阵仍显示 AP/财务运营页日期英文占位、表单密度或状态展示问题,则优先处理 ApOperationsPage;不改变 AP、付款、导出或银行回单业务语义。 AP 账期、到期日、回单日期等高频字段改用统一中文日期输入/展示;财务列表主展示保持业务编号、供应商/对象、金额、状态和下一步;不新增真实支付或 ERP 能力。 受影响流程:财务登录 -> AP 运营 -> 查看账期/到期/回单 -> 导出/对账;验证步骤:client typecheck/build;check-ui-design-rules;finance 角色 PC 只读截图;OAOPS1 daily 通过。 typescript|playwright|node TODO DONE TODO DONE TODO client/src/pages/ApOperationsPage.tsx;client/src/components/common/DateTextInput.tsx;client/src/lib/displayFormat.ts ["OAFRONT5-2"] 优先级取决于部署后 finding;回滚路径:还原 AP 前端展示提交,不触碰后端付款状态。 本地已修:AP 报销日期/创建时间筛选改用 DateTextInput,付款日期展示统一中文日期,通用 smoke 英文姓名改为中文测试名;typecheck/build、check-ui-design-rules 通过。Regression 待部署后 PC 矩阵确认 AP P2 清零。回滚路径:还原 AP 前端展示提交,不触碰后端付款状态。
6 OAFRONT5-4 报销高频页日期输入统一化 如果部署后或真实使用反馈仍认为报销筛选、明细发生日期、付款动作日期有英文原生日期控件风险,则把报销高频页面改用 DateTextInput;保持 PDF OCR、审批、付款语义不变。 报销列表筛选、报销明细日期、付款日期等员工/财务高频路径不再出现英文原生日期占位;已有数据保存格式仍为 YYYY-MM-DD;不改变报销 API。 受影响流程:员工编辑报销明细 -> 提交审批;财务筛选报销 -> 标记付款;验证步骤:client typecheck/build;报销详情和列表 Playwright/视觉截图;回归提交草稿和编辑明细。 typescript|playwright|manual TODO TODO TODO client/src/pages/ReimbursementDashboardPage.tsx;client/src/pages/reimbursement-detail/ReimbursementItemEditor.tsx;client/src/pages/reimbursement-detail/ReimbursementActions.tsx ["OAFRONT5-2"] 优先级 P1/P2;真实业务路径优先于后台配置页;回滚路径:还原前端输入组件变更。
7 OAFRONT5-5 HR/考勤/后台配置日期控件后置清单 把 EmployeeProfile、People、Attendance、TeamPresence、Leave、Performance、Budgets、Travel 等页面残留 type=date 分类为 HR/配置/冻结域后置,不在 launch 前大面积改。 后置清单清楚说明哪些页面属于 C 类后台或冻结域;除非真实使用出现 blocker,否则不抢 OALAUNCH1 主线。 受影响流程:HR/管理员维护员工资料、团队状态、考勤镜像和预算/差旅冻结页;验证步骤:rg -n 'type="date"' client/src/pages client/src/components;人工按 A/B/C 页面分层确认。 rg|manual TODO DONE TODO DONE TODO client/src/pages/EmployeeProfilePage.tsx;client/src/pages/PeoplePage.tsx;client/src/pages/AttendancePage.tsx;client/src/pages/TeamPresencePage.tsx;client/src/pages/LeaveRequestPage.tsx;client/src/pages/BudgetsPage.tsx;client/src/pages/TravelRequestsPage.tsx ["OAFRONT5-2"] 企微 HR/考勤仍由企微主办;OA 页面多为镜像、后台或应急边界,不应在启用前扩大为 HR 主办 UI 改造。 本地已修 PC 矩阵命中的 HR People 入职日期筛选,改用 DateTextInput;其他 HR/考勤/预算/差旅冻结域日期控件继续后置,不抢 OALAUNCH1 主线;typecheck/build、check-ui-design-rules 通过。Regression 待部署后矩阵确认 hr /people P2 清零。回滚路径:还原 PeoplePage 日期输入组件改动;不修改员工数据、企微 HR/考勤主办边界或真实人员状态。
8 OAFRONT5-6 Portal 首屏工作台化继续观察 OAFRONT4 已完成 Portal 命名本地化;首屏 hero 是否继续收敛,等部署后截图和真实 7 天反馈,不凭主观审美立即重排。 如果真实用户反馈首屏找不到待办/常用/财务入口,再做小步重排;否则保留现布局,只记录 P2 视觉优化建议。 受影响流程:PC 登录 -> 工作台 -> 找待办/草稿/财务/合同/资产入口;验证步骤:部署后 PC 截图;7 天真实反馈;不得复制竞品文案或做营销式 hero。 playwright|manual TODO TODO TODO client/src/pages/PortalHomePage.tsx;docs/trialrun/人工试运行报告.md ["OAFRONT5-1"] 优先级 P2;不作为部署 blocker。回滚路径:如后续采纳并修改 Portal 后反馈变差,回滚对应前端提交;本观察项本身只记录证据,无需清理公网数据。
9 OAFRONT5-7 OALAUNCH1 启用门禁对齐 把部署后 UI 回归结果接入 OALAUNCH1:前端可用性只是启动条件之一,最终启用仍取决于真实业务闭环、权限矩阵、备份恢复、7 天稳定化和 Go/No-Go。 OALAUNCH1 汇总能引用最新 OAFRONT4/OAFRONT5 视觉回归结论;不因 UI 自动通过而跳过真实报销、采购、合同、资产、备份和人工 Go/No-Go。 受影响流程:前端回归 -> OALAUNCH1 汇总 -> Day 7 决策;验证步骤:LIVE_SMOKE_BASE_URL=https://oa.hyinda.com bash scripts/qa/run-oa-real-use-daily.sh;OALAUNCH_STABILIZATION_START_DATE=<date> bash scripts/qa/run-oa-final-launch-readiness.sh。 bash|manual TODO TODO TODO issues/2026-05-23_16-49-39-oa-final-launch-readiness-v1.csv;scripts/qa/run-oa-final-launch-readiness.sh ["OAFRONT5-2"] 仍需人工/运维:真实业务样本、备份恢复演练、Day 7 Go/No-Go;自动化只能证明入口和只读巡检。回滚/清理:若 OALAUNCH1 引用错误,仅回滚 Issue CSV/报告引用;不修改公网业务数据。
10 OAFRONT5-8 用户采纳门禁 用户审查 OAFRONT5 后决定是否先部署 OAFRONT4,是否采纳 AP/报销日期收口,是否继续后置 HR/Portal。 用户至少给出 A/B/C:A=先部署并复跑矩阵;B=不部署,先继续本地修 AP/报销;C=暂停前端,回到 OALAUNCH1 人工业务闭环。未采纳前不得执行部署或新增代码修复。 受影响流程:OAFRONT5 合同 -> 用户决策 -> 部署/修复/暂停;验证步骤:人工回填选择并 validate CSV。 manual|python3 DONE DONE DONE issues/2026-05-25_09-17-51-oa-pc-post-deploy-ui-hardening-v1.csv ["OAFRONT5-0"] 用户已批准按推荐继续部署和修复;2026-05-25 已执行首次部署和只读矩阵,发现付款批次复核人 UUID P1 后转入 OAFRONT5-9。
11 OAFRONT5-9 付款批次复核人内部 ID 展示修复 部署后 PC 视觉矩阵发现付款批次详情的复核人字段仍展示内部 UUID,导致 finance/finance_mgr 页面各 1 个 P1 finding;修复展示层,不改付款流程。 首轮复核人、二次复核人等复核字段不再向用户展示 UUID;若后端只返回内部 ID,前端显示“已记录”;付款批次状态、复核、执行、取消和回单逻辑不变。 受影响流程:财务登录 -> 付款批次 -> 查看详情 -> 复核要求;验证步骤:client typecheck/build;check-ui-design-rules;部署后复跑 PC 只读视觉矩阵,finance/finance_mgr /payment-batches UUID P1 清零。 typescript|playwright|node DONE DONE TODO client/src/pages/PaymentBatchesPage.tsx;issues/2026-05-25_09-17-51-oa-pc-post-deploy-ui-hardening-v1.csv ["OAFRONT5-2"] 本地证据:client typecheck/build 通过且无 Circular chunk warning;check-ui-design-rules findings=0;check-process-contract baseline/general 通过;audit-docs errors=0;quick_validate 通过;git diff --check 通过;bash scripts/check-minimal.sh 通过。公网回归待部署后复跑 PC 只读视觉矩阵。回滚路径:还原前端展示 helper;不触碰后端付款状态、审批/复核数据或真实付款记录。
12 OAFRONT5-10 资产 ERP 摘要内部码值中文化 部署后 PC 矩阵仍发现资产台账 ERP 摘要暴露 changeType/created 等内部码值;修复展示层,不改 ASSET1 资产模型、ERP 开关或资产台账数据。 资产 ERP 摘要使用中文字段名和中文变更/状态标签;资产编号、分类、法体、成本中心等业务元数据保留;不保存或展示密码、token、Secret、源码包或完整路径。 受影响流程:管理员登录 -> 资产台账 -> 选中资产 -> ERP 同步状态;验证步骤:client typecheck/build;check-ui-design-rules;部署后 PC 只读矩阵 admin /assets raw status P2 清零或仅剩可解释测试数据。 typescript|playwright|node DONE DONE TODO client/src/pages/AssetRegistryPage.tsx;issues/2026-05-25_09-17-51-oa-pc-post-deploy-ui-hardening-v1.csv ["OAFRONT5-2"] 本地已修:ERP 摘要最近 changeType 改为最近变更,created/updated/retired/archived 映射为中文;资产状态使用资产状态标签。typecheck/build、check-ui-design-rules 通过。Regression 待部署后矩阵确认。回滚路径:还原资产 ERP 摘要展示 helper,不触碰资产数据或 ERP 同步开关。