SNAPSHOT W7 已部署稳定态 — 凯迪ERP+OA一体化平台 (MET 73.3%)

恢复点(restore point)。别人改崩后可 git reset --hard 回到此提交。

== 此快照内容 ==
- 后端 oa-backend: 734 控制器 / 711 实体 (Spring Boot 3.2.5 + SQLite, 端口8091)
- 前端 modern-ui/app: Vue3+Vite, 约700页 (构建产物已在 oa-backend/src/main/resources/static)
- 数据库 oa-backend/data/oa.db: 含全部演示数据 (强制入库, 6.6MB)
- 交接文档 go.md + go-code-reference/endpoints/entities/database.md
- 多代理建设脚本 .claude/wf-*.js

== 状态 ==
- 对 凯迪科技ERP_20260507.xlsx 合规 MET ~73.3% (PARTIAL 75: 34可建+6种子/bug+35外部硬天花板)
- 安全: 5轮红队+5轮复检, default-deny分级鉴权, 连续零可利用
- W3~W7 累计补完436缺口; W8末轮(40缺口)为半成品(源码树可编译但未集成)
- 运行: cd oa-backend; java -jar build/libs/oa-backend-0.1.0.jar --server.port=8091; admin/123456

== 排除(gitignore, 可再生) ==
node_modules / oa-backend/build / .jdks / *.log / Backup-ERP-* / 弃用的OFBiz核心(只保留modern-ui)
完整文件夹备份见同目录 Backup-ERP-20260615-191517/ (含上述全部, 仅缺 node_modules)

时间戳: 20260615-191517

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Qiufeng
2026-06-15 19:19:15 +08:00
co-authored by Claude Opus 4.8
commit 5e51dc3f56
10584 changed files with 2501339 additions and 0 deletions
+78
View File
@@ -0,0 +1,78 @@
export const meta = {
name: 'erp-p2-build',
description: 'P2重要能力:跨模块自动取数/报表看板/AI服务层/移动可服务部分 4工作流并行(全新建文件+回传共享片段)',
phases: [{ title: 'P2并行建设' }],
}
const COMMON = `黄金模板:控制器 web/FinancingController.java、聚合只读 web/FundPoolController.java(无实体、跨表聚合走ApiResp)、前端 oa/pages/payment/financing.vue(MasterDataPage)与 repayment.vue(自定义页)。
硬约束:①金额BigDecimal+com.kaidi.oa.common.Money(无裸double算钱);②控制器@RestController @RequestMapping("/api/oa/<资源>"),返回ApiResp.ok(),record请求体,NotFoundException/ApiException(400,中文);③仓库extends JpaRepository;④前端真实页接真后端(import { http },http.get/post已解包ApiResp.data,token键oa.token),列表套MasterDataPage,看板/聚合用el-table/el-card自定义;⑤无emoji(@element-plus/icons-vue)、无渐变(纯色蓝主调)、排版承载形态慎重;⑥类名表名加域前缀,grep确认不撞名(现有~110控制器)。
**关键纪律**:①**只新建文件**,凡需改共享文件(config/AuthInterceptor.java、data/oaModules.ts)一律不自改,放进 sharedFileSnippets(file+anchor原文+change改法+why)由主代理串行合并;②**不运行gradle/npm**(并行争用),逐文件自审语法。`
const RESULT = {
type: 'object', additionalProperties: false,
properties: {
workstream: { type: 'string' },
backendFiles: { type: 'array', items: { type: 'string' } },
frontendFiles: { type: 'array', items: { type: 'string' } },
authFinancePrefixes: { type: 'array', items: { type: 'string' } },
authSensitiveRead: { type: 'array', items: { type: 'string' } },
navEntries: { type: 'array', items: {
type: 'object', additionalProperties: false,
properties: { moduleId: { type: 'string' }, items: { type: 'array', items: {
type: 'object', additionalProperties: false,
properties: { key: { type: 'string' }, label: { type: 'string' }, kind: { type: 'string' }, path: { type: 'string' } },
required: ['key', 'label', 'kind', 'path'] } } },
required: ['moduleId', 'items'] } },
sharedFileSnippets: { type: 'array', items: {
type: 'object', additionalProperties: false,
properties: { file: { type: 'string' }, anchor: { type: 'string' }, change: { type: 'string' }, why: { type: 'string' } },
required: ['file', 'anchor', 'change', 'why'] } },
endpoints: { type: 'array', items: { type: 'string' } },
externalDeps: { type: 'string', description: '需外部资源才能完全生效的部分(如API Key/设备能力),据实说明' },
summary: { type: 'string' },
},
required: ['workstream', 'backendFiles', 'frontendFiles', 'authFinancePrefixes', 'authSensitiveRead', 'navEntries', 'sharedFileSnippets', 'endpoints', 'externalDeps', 'summary'],
}
const WS = [
{
key: 'autofetch', label: '跨模块自动取数',
prompt: `工作流【跨模块自动取数】(审计:数据中心"统一数据库/流程驱动自动取数"大面积缺,申报条件自查/研发费用归集证据链不自动)。全新建:
①web/EligibilityCheckController.java + service/EligibilityCheckService.java:申报条件自查自动取数——给定申报类型(如高企),自动从 财务(RdExpenseRepository研发费用)、HR(PersonnelCertRepository人员证书/科技人员)、知识产权(PatentRepository专利软著)、项目(ProjectRepository已完成项目) 各仓库读数,按规则(研发费用占比/知识产权数量/科技人员占比)生成"达标/不达标"清单(每项:要求值/实际值/是否达标/差距/数据来源),不再人工录入。
②web/RdExpenseTraceController.java:研发费用归集证据链——按 rdProjectId 聚合 RdExpense,列出每笔费用+来源单据引用,形成证据链汇总(项目/费用类型/金额合计/笔数)。
均为只读聚合(参考 FundPoolController 跨表聚合不建实体)。前端挂 datacenter 模块(申报条件自查/研发费用证据链 看板页,接真后端)。`,
},
{
key: 'dashboard', label: '报表看板',
prompt: `工作流【报表看板】(审计:运营KPI/后勤成本/QHSE/财务多维看板缺)。全新建只读聚合控制器+前端看板页(参考FundPoolController聚合、el-card+el-table展示):
①web/OpsKpiController.java:运营KPI看板——聚合 WaterQualityRecord(达标率)、WorkOrder(产量/完成率)、相关运营数据,出KPI卡片+趋势。
②web/QhseDashboardController.java:QHSE指标看板——聚合 SafetyCheck/QmsRecord(隐患数/整改率/质量记录),出QHSE指标。
③web/FinanceDashboardController.java:财务多维看板——聚合 Contract(合同额/已付/已开票)、Payment(付款)、Voucher、ArApItem(应收应付),出资金/往来/合同多维汇总。
前端挂 report 或 datacenter 模块(运营KPI/QHSE/财务看板 页)。只读聚合不建实体。`,
},
{
key: 'ai', label: 'AI服务层',
prompt: `工作流【AI服务层】(审计:市场/行政/法务/财务多处点名AI,无统一LLM层)。全新建AI能力框架(可配置,无Key时优雅降级):
web/AiController.java + service/AiService.java + 配置类:统一AI服务层,提供 POST /api/oa/ai/complete(body{scenario,prompt,context}) 调 LLM 返回文本;封装场景端点 /ai/draft(文案/话术起草)、/ai/classify(舆情情感分类)、/ai/summarize(摘要)、/ai/risk(风险提示)。
实现:AiService 用 Spring 的 org.springframework.web.client.RestClient/RestTemplate(或 java.net.http.HttpClient) POST 到 Anthropic Messages API: https://api.anthropic.com/v1/messages, headers: x-api-key:<key>、anthropic-version:2023-06-01、content-type:application/json, body:{model, max_tokens:1024, messages:[{role:user,content:prompt}]}。model 从配置读,默认 "claude-haiku-4-5-20251001"(高性价比)。API Key 从 application.yml 的 oa.ai.api-key 或环境变量 ANTHROPIC_API_KEY 读;**未配置 Key 时不报错,返回 ApiResp.ok 一个降级结果{configured:false, text:"AI 服务未配置 API Key,请在 application.yml 配置 oa.ai.api-key 后启用", scenario}**,保证活体不崩。配置项写到 application.yml(oa.ai.api-key: "" 占位 + 注释)。前端挂 appdev 或 intel 模块一个"AI 助手"页(选场景+输入→调/ai/complete→显示结果,未配置Key时友好提示)。
externalDeps 据实写明:需配置 Anthropic API Key 才能真正产出AI结果,否则降级提示。`,
},
{
key: 'mobile', label: '移动端可服务部分',
prompt: `工作流【移动端可服务部分】(审计:GPS打卡/扫码/离线/专项审批移动场景缺;其中GPS定位/扫码/离线属设备/前端能力,后端先把可服务的数据接口与审批队列建好)。全新建:
①web/MobileCheckinController.java + domain/MobileCheckin.java(外勤打卡:用户/打卡类型 上班/外勤/拜访/经纬度lat/lng/地址/时间/备注)+仓库:打卡记录CRUD+按用户按日查询。经纬度由前端定位回填(设备能力),后端存储+台账。
②web/MobileApprovalController.java:移动审批队列聚合——复用现有审批(读 FormInstance 当前办理人为当前用户的待办),输出精简的移动待办列表(标题/类型/发起人/金额/时间),供移动端专项审批。只读聚合。
前端挂 mobile 模块(外勤打卡/移动审批 页,接真后端;打卡页用 navigator.geolocation 取经纬度,取不到则手填,优雅降级)。
externalDeps 写明:GPS定位依赖浏览器/设备 geolocation、扫码依赖摄像头,属前端设备能力;离线依赖PWA/缓存,本期先做在线数据接口与审批队列。`,
},
]
phase('P2并行建设')
const results = await parallel(WS.map((w) => () =>
agent(
`你是资深全栈工程师,为凯迪 ERP 平台做 P2 重要能力补建。${w.prompt}\n\n${COMMON}\n\n返回结构化结果(含 externalDeps 据实说明)。`,
{ label: `P2:${w.key}`, phase: 'P2并行建设', schema: RESULT }
)
)).then((a) => a.filter(Boolean))
return { built: results.length, results }