# AGENTS.md ## 项目定位 本项目是**银城员工端 APP**,按“陪练 → 大喇叭+知识学习平台 → 北森对接”三阶段推进。正式验收主线仍是阶段一试点;提前发布的阶段二/三单项能力不等于整体验收。`position` 沿用现有值,MVP 资料已归档;结论必须区分生产部署、正式账号/真机验证和严格试点。 ## 工程边界 - `backend/` 是 `dromara/RuoYi-Vue-Plus` 的 `5.X` 分支检出。 - `frontend/` 是 `CrazyLionCat/plus-ui` 的 `5.X` 分支检出,只承载管理端。 - `mobile-uni/` 是当前用户侧工程,承载员工端、候选人端、主管端,使用 uni-app Vue3 H5 + App-Plus;原生资源、隐私/签名和真机门禁见 `docs/MOBILE_APP_PACKAGING.md`,旧 `mobile/` 仅保留为 MVP 演示兜底,不再承载新增功能。 - 本项目自己的本地编排放在根目录:`docker-compose.dev.yml`、`scripts/`;运行说明在 `docs/DEV_SETUP.md`。 - 除非确实要接业务模块,不要改上游框架默认配置;本地端口和开关优先放根目录脚本里覆盖。 ## 本地运行 - MySQL:`127.0.0.1:13306`,库 `ry-vue`,账号 `root/root`。 - Redis:`127.0.0.1:16379`,密码 `ruoyi123`。 - MinIO:API `127.0.0.1:9000`,Console `127.0.0.1:9001`,账号 `ruoyi / ruoyi123`,bucket `ruoyi`。 - Qdrant:REST `127.0.0.1:6333`,默认 collection `aihr_knowledge`;可用 `AIHR_QDRANT_URL`、`AIHR_QDRANT_COLLECTION`、`AIHR_QDRANT_API_KEY` 覆盖。 - 资料导入根目录:默认 `./.data/import`,由 `scripts/dev-backend.sh` 传入 `aihr.import.root`;也可用 `AIHR_IMPORT_ROOT` 覆盖。 - 本地私密配置:根目录 `.env.local` 已被 `.gitignore` 忽略,`scripts/dev-backend.sh` 会自动加载;阿里云短信密钥只放这里或外部环境变量,不写入 `application-*.yml`。 - 后端:默认通过 portless 启动,入口 `https://wygj-api.localhost/`;命令为 `portless run --name wygj-api ./scripts/dev-backend.sh` 或根目录 `./scripts/dev.sh`,显式 `PORTLESS=0` 时才回退端口 `8080`。管理端 Vite 代理目标由 `frontend/.env.development` 的 `VITE_APP_PROXY_TARGET` 指向该入口。 - 管理端前端:`./scripts/dev-frontend.sh`,默认走 portless,入口 `https://wygj-admin.localhost/`;显式 `PORTLESS=0` 时回退端口 `5173`。 - 当前用户侧前端:`portless` 启动 `mobile-uni`,入口 `https://wygj-mobile-uni.localhost/h5/`。 - 旧移动端兜底:`./scripts/dev-mobile.sh`,端口 `5174`,只用于回看 MVP 演示壳。 - 重置数据:`./scripts/reset-dev-db.sh`,会删除并重建本地 `ry-vue`。 导入 SQL 必须带 `--default-character-set=utf8mb4`,否则中文昵称可能按错误字符集导入并触发字段长度问题。 ## 验证口径 - 前端首页:`https://wygj-admin.localhost/` - 用户侧首页:`https://wygj-mobile-uni.localhost/h5/` - 后端接口:`https://wygj-api.localhost/` - 租户接口:`https://wygj-admin.localhost/dev-api/auth/tenant/list` - 验证码接口:`https://wygj-admin.localhost/dev-api/auth/code` - 默认登录:租户 `000000`,管理员 `admin / admin123`。 ## 发布口径 - 线上管理端:`https://peilian.njzhmj.top/`,Caddy 服务 `/opt/wygj/www`;该目录包含移动端 `/h5`,发布管理端时先备份整个目录,再 `rsync -az frontend/dist/ YCWY:/opt/wygj/www/`,**不得**对根目录使用 `--delete`。纯管理端静态修复不需要重启后端。 - 线上移动端 H5:`https://peilian.njzhmj.top/h5/`,Caddy 服务 `/opt/wygj/www/h5`。 - 只发布移动端静态资源时,用 `npm --prefix mobile-uni run build:h5` 后备份远端 `/opt/wygj/www/h5`,再 `rsync -az --delete mobile-uni/dist/build/h5/ YCWY:/opt/wygj/www/h5/`;前端静态修复不需要重启后端。 - 原生 App 不复用 H5 静态发布流程;`npm --prefix mobile-uni run build:app` 仅生成 HBuilderX 出包资源,未提供法务 HTTPS 链接、签名或真机验收前不得称为已出包或上架。 ## 当前业务边界 - 管理端业务路由集中在 `frontend/src/router/index.ts`,覆盖首页、AI 面试、训练运营、问题榜、案例、知识空间、SOP、资料处理、系统配置、组织权限和成长激励;侧栏过滤在 `frontend/src/layout/components/Sidebar/index.vue`,不要恢复若依默认全量菜单。 - 用户侧只改 `mobile-uni/src/pages/*`;员工、候选人、主管首页分别为 `/pages/user/today/index`、`/pages/candidate/index/index`、`/pages/supervisor/index/index`,旧 `/h5/user|candidate|supervisor|employee|admin` 只做兼容重定向。底栏固定「今日/练/问/我」;问师傅文字和现场附件查询复用 `/api/knowledge/query`、`/api/knowledge/query-media`,内部登录端可带 `conversationId/contextVersion` 使用 30 分钟、最近 6 轮的短期会话,原文件/视频只通过 `/api/knowledge/resources/{attachmentId}/content` 重新鉴权交付;总结卡复用 `/api/knowledge/summary-card`,失败不兜假数据。显式“记一下/帮我记/保存一下”复用同一 query 返回确认卡,确认后按 `PRIVATE/COMPANY` 写 `aihr_assistant_capture`;COMPANY 只表示 `PENDING` 待流转,不得冒充已派单或已送达。外部知识 API 保持无状态。 - 术语和数据边界:工作助手承载日常事实与确认式记忆;现有 `/pages/user/report/index`、`/api/aihr/work-report/**` 和 `aihr_work_report` 只承载 CASE/VIDEO/SOP/KNOWLEDGE 四类投稿审核,产品名为“成果投稿”;“今日工作成果”按员工 + 项目 + 自然日从已确认记录确定性聚合,员工页为 `/pages/user/work-results/index`,主管页为 `/pages/supervisor/work-results/index`,默认当日但允许查看历史日期且不得选择未来日期。不要把三条链路合表或自动互写。多项目交互只让用户按项目名称选择,内部项目编码必须由服务端按当前身份复核,不让用户输入编码。 - 不要把三端概括成全模态:员工对练/每日题和问师傅支持文字/语音,问师傅图片/视频只用于本次分析,案例传音频;候选面试支持文字/语音,资料可传文档/图片但图片不参与评分;主管写文字复盘/指派并回听录音。员工对练图像/视频情境、服务录像回放和方言正式验收仍未完成;语音继续复用 `services/speech.ts` 与 `/api/ai/asr`。 - 问题榜奖励只记积分/学习学分,不得擅自增加现金、提现、预算或税务语义;选最佳答案和考试提交必须保持请求幂等。 - 全网 AI 与企业问师傅必须分入口、分来源和分免责声明;提供方仅允许公网 HTTPS,修改地址/密钥后必须连接测试成功才能启用,未配置时明确不可用且不生成假答案。 - 多租户知识平台的有效范围是“租户 + 调用应用绑定 + 主体授权”的交集;不信任客户端传入身份,API_TOKEN 不得进入浏览器或小程序包。生产排序规则以 `aihr_knowledge_info.tenant_id` 为基准,新表最后执行 `aihr_20260718_release_collation_compat_mysql8.sql`。 - 移动端首页接口:`GET /api/aihr/mobile/home/{role}`,当前 `@SaIgnore` 公开只读 seed,用于 H5 首屏 API 优先 + 本地 fallback;后续确定小程序登录后再接移动端 token,不复用管理后台登录态。 - 移动端手机号登录:验证码发送走 `GET /resource/sms/code?phonenumber=...`,登录走 `POST /auth/mobile/sms-login`;短信发送复用 `sms.blends.config1` 阿里云配置。手机号不存在时自动注册 `app_user`,备注为“移动端短信自动注册”。模板 ID 用 `AIHR_SMS_LOGIN_TEMPLATE_ID`,AccessKey/Secret/签名用 `ALIYUN_SMS_ACCESS_KEY_ID`、`ALIYUN_SMS_ACCESS_KEY_SECRET`、`ALIYUN_SMS_SIGN_NAME`,本地放 `.env.local`。`aihr.sms.dev-fixed-code` 非空则验证码固定(dev 默认 `123456`)、不真发短信;prod 默认关闭,试点期必须同时显式设置 `AIHR_SMS_DEV_FIXED_CODE` 与 `AIHR_SMS_PROD_FIXED_CODE_ENABLED=true`,停用时删除固定码并关闭生产开关。 - 移动端员工训练闭环:员工端首页“开始训练”复用 `POST /api/train/practice/start`、`/turn`、`/finish`,请求必须带移动端登录返回的 `Authorization` 与 `clientid`;`mode=mobile` 完成后写入 `aihr_practice_session`,并更新主管端首页完训率、“待复盘对练”、员工训练历史和能力画像。主管端复盘详情查 `GET /api/aihr/mobile/practice/reviews/{id}`,标记复盘用 `POST /api/aihr/mobile/practice/reviews/{id}/reviewed`。 - 正式试点 CSV 走 `GET /api/train/practice/export?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD`,起止日必填;训练、校准和 SOP 评审必须按同一窗口、唯一在职组织身份统计,完训定义为每人至少 10 次。CSV 应保留原始校准命中/SOP 可用计数,严格预检用 `AIHR_PILOT_START_DATE`、`AIHR_PILOT_END_DATE` 与 `AIHR_PILOT_STRICT=true ./scripts/demo-check.sh`;不允许用历史 seed、开发身份或四舍五入比率伪造正式试点通过。 - 移动端候选人闭环:候选人端“开始面试/面试练习”复用 `POST /api/recruit/interview/start`、`/answer`、`/finish`;“补充资料”走认证接口 `POST /api/aihr/mobile/candidate/materials`(multipart `file` + `candidateId/candidateName/materialType`)和 `GET /api/aihr/mobile/candidate/materials`,文件先写 `sys_oss`/MinIO,再写 `aihr_candidate_material` 状态 `待审核`。HR 审核复用管理端 `/recruit/interview` 页,接口为 `GET /api/aihr/hr/candidate/materials` 和 `POST /api/aihr/hr/candidate/materials/{id}/review`,状态只用 `待审核/已通过/已驳回`。上传接口不要放进 class-level `@SaIgnore` 的 `AihrMobileController`。 - 后端 API 对接先看 `docs/API_INTEGRATION.md`。三角色对练 `/turn`/`/finish` 使用 `AihrPracticeLlmService`,必须保留“未配置/失败回退 seed”的降级链。 - 对练语音走 `POST /api/ai/asr`(≤5MB multipart)和 `POST /api/ai/tts`(文本≤300字,返回 base64 dataURL);TTS 保留旧 `voice` 字符串,并支持 `voiceProfile={role,voice?,speed?,emotion?}`,当前老师傅/业主/面试官分音色,业主按对练情绪分调整语气与语速。模型走 `aihr_model_config` 的 `asr`/`tts` 类目(`category` 全集:chat/vector/rerank/asr/tts/vision)。移动端 `getUserMedia/MediaRecorder` 不可用或麦克风权限失败时,用隐藏 `audio/*` file input 选择/录制音频后继续走同一 ASR 接口,不要退回只有文字输入。multipart 头部的 filename/contentType 已做 CRLF 清洗,新增外发 HTTP 时同样注意。 - 后端业务代码不要塞进上游 `ruoyi-demo`;自有 API 放在 `backend/ruoyi-modules/ruoyi-aihr`,再接入 `ruoyi-admin`。 - AI 面试页、三角色对练页、案例沉淀页、SOP 知识库页和移动端三端首页已是 API 优先 + 本地 fallback;SOP 知识库优先查 `aihr_knowledge_fragment` 的 MySQL Fulltext,vector 模型和 Qdrant 可用时混合召回,`category=rerank` 模型启用时融合后语义重排(失败保持 RRF 顺序);支持 `.txt/.md/.markdown/.pdf/.doc/.docx/.xls/.xlsx/.ppt/.pptx`、图片 `.jpg/.jpeg/.png/.gif/.webp/.bmp` 及视频 `.mp4/.mov/.avi/.mkv/.webm/.m4v` 上传解析入库。 - 浏览器批量上传走异步队列 `POST /api/knowledge/doc/upload-async`(暂存目录 `aihr.upload.staging` 默认 `./.data/staging`,队列表 `aihr_knowledge_upload_item`,单文件重试);同步接口 `POST /api/knowledge/doc/upload` 只留给 SOP 页单文件即时预览,**不要把重加工逻辑加回同步请求线程**。视频(≤500MB/≤60分钟)只走异步队列,依赖服务器安装 ffmpeg/ffprobe。 - SOP 上传接口是 `POST /api/knowledge/doc/upload`,表单字段为 `file` 和 `category`;当前限制 100MB 内,支持 txt/md/PDF/Word/Excel/PPT 及图片,先写 MinIO/`sys_oss` 再绑定 `aihr_knowledge_attach.oss_id`,同一知识库同名文件会替换旧 fragment。若数据库启用 `category=vector` 的模型配置,会同步调用 OpenAI-compatible `/embeddings`,写入 `embedding_json` 并尽力 upsert 到 Qdrant;配置缺失或外部 embedding 失败才用 `local-hash-v1` 兜底,Qdrant 不可用时保留 MySQL Fulltext/seed fallback。管理端 `uploadKnowledgeDoc` 单接口 timeout 是 180s;遇到约 50s `Broken pipe` 先查浏览器客户端超时,不要改全局 axios。 - 图片视觉 OCR:上传图片时经 `visionRuntime()` 找启用模型(优先 `aihr_model_config.category='vision'`,无则回退 `category='chat'`),把图片编码成 base64 data URL 调 OpenAI-compatible `/chat/completions` 提取文字再切分入库;无可用视觉模型或 OCR 无结果时按「待处理」落库(0 片段),不算失败。视频关键帧用带画面描述的 FRAME_PROMPT(文字+一句场景描述),改 prompt 时别退回纯 OCR。不依赖 Tesseract。 - 向量库状态接口是 `GET /api/knowledge/doc/vector-index-status`,重建接口是 `POST /api/knowledge/doc/rebuild-vector-index`;外部 embedding 成功但 Qdrant collection 维度不一致时不要静默降级,走状态提示和重建。 - 资料处理接口是 `GET /api/knowledge/processing/overview`,直接聚合 `aihr_knowledge_attach`、`aihr_knowledge_fragment` 和 `sys_oss.ext1`;页面只保留“批量导入”,走 `POST /api/knowledge/doc/upload-async`,不要恢复“选择目录”“服务端导入”或目录导入任务面板。`POST /api/knowledge/doc/import-local`、`POST /api/knowledge/doc/import-local-task`、`GET /api/knowledge/doc/import-tasks` 和 `POST /api/knowledge/doc/import-tasks/{id}/cancel` 仅保留为后端运维/调试接口;目录只能是 `aihr.import.root` 下的相对路径。 - `ruoyi-ai` 只按 `docs/RUOYI_AI_INCREMENTAL_MIGRATION.md` 分片迁移到 `ruoyi-aihr`,不要整包搬 `ruoyi-chat`;已落地页面保持真实接口/模型优先与 seed fallback,不能退回静态壳。 - 本项目 AI 表前缀用 `aihr_*`:知识库是 `aihr_knowledge_info/attach/fragment`,问师傅短期会话是 `aihr_knowledge_conversation`,确认式采集是 `aihr_memory_candidate` / `aihr_assistant_capture`(旧项目记录兼容 `aihr_service_memory/version`),上传队列是 `aihr_knowledge_upload_item`,导入任务是 `aihr_knowledge_import_task`,模型配置是 `aihr_model_provider/config`,移动端训练记录是 `aihr_practice_session`,候选人补充资料是 `aihr_candidate_material`,组织人员快照是 `aihr_org_snapshot`(本地 reset 有 Demo seed;生产/试点从 `docs/open-org-sync-api-design-v1.md` 对应开放组织系统同步,入口 `POST /api/aihr/org/sync`)。 ## 业务文档 - 总入口:`README.md` - 文档索引:`docs/README.md` - Figma 实现与逐页视觉验收以 `docs/FIGMA_DESIGN_INVENTORY.md` 为准;复用既有变量/组件并人工查看当次截图,结构、视觉、功能、发布和生产验证分别记录。 - MVP 演示与验收:`docs/DEMO_ACCEPTANCE.md` - 阶段交付归档:`docs/archive/2026-07-mvp-delivery/` - 分阶段总纲:`docs/银城员工端APP分阶段实施总纲.md` - AI 陪练二期推进(阶段一执行):`docs/AI陪练二期开发推进计划.md` - 数字师傅产品定案(2026-07-08 学练问报/问题榜/学分):`docs/20260708/数字师傅学练问报整合方案.md` - 工作助手后续施工顺序:`docs/工作助手与今日工作成果迭代计划-20260721.md` - 产品功能优先级与本轮增量:`docs/银城帮道产品功能优先级与实施计划-20260721.md` - AI 陪练缺口修订:`docs/AI陪练功能优化与缺口分析(修订).md` - 后端 API 对接:`docs/API_INTEGRATION.md` - 对外会议版口径:`docs/AI人力资源系统项目规划方案与AI接口说明.md` - 业务需求:`docs/物业AI人力资源系统业务需求文档BRD.md` - 开发规格:`docs/物业AI人力资源系统开发规格TechSpec.md`