# CLAUDE.md — 企迹 (qiji) 政企周报管理系统 ## 项目概述 面向中国电信政企客户经理团队,替代 Excel 的周报管理系统。覆盖每日拜访记录、下周工作计划、小微业务商机跟单、要客拜访计划四大模块。支持 PC 端(支局长/分管领导汇总查看)和移动端(客户经理外勤填报 + 企微入口)。 ## 技术栈 | 层 | 技术 | |---|------| | 后端 | FastAPI + SQLAlchemy 2.0 (async) + Alembic | | 数据库 | PostgreSQL (已有,复用) | | 文件存储 | MinIO (已有,复用) | | 认证 | Casdoor OIDC (已有) + 企业微信 OAuth | | 前端 | Vue 3 + Vite + TypeScript + Element Plus | | 状态管理 | Pinia | | 定时任务 | APScheduler | ## 项目结构 ``` qiji/ ├── docker-compose.yml # PostgreSQL + MinIO + backend ├── 政企周报管理系统-设计文档.md # 完整设计文档 ├── backend/ │ ├── app/ │ │ ├── main.py # FastAPI 入口 + lifespan + 路由挂载 │ │ ├── config.py # pydantic-settings 配置 │ │ ├── database.py # async engine + session │ │ ├── models/ # 8 张表 (见下方数据模型) │ │ ├── schemas/ # Pydantic 请求/响应 schema │ │ ├── api/ # REST 路由 (12 个模块) │ │ ├── services/ # 业务逻辑层 │ │ ├── middleware/auth.py # JWT 鉴权 + 角色权限 │ │ └── utils/security.py # JWT 签发/验证 │ ├── alembic/ # 数据库迁移 │ └── requirements.txt ├── frontend/ │ ├── src/ │ │ ├── router/index.ts # 路由 (mobile + desktop 两套布局) │ │ ├── stores/auth.ts # Pinia 认证 store │ │ ├── api/ # 9 个 Axios API 模块 │ │ ├── views/ │ │ │ ├── mobile/ # 移动端页面 (Home, VisitForm, ...) │ │ │ └── desktop/ # PC 端页面 (Dashboard, WeeklyReport, ...) │ │ └── components/ # MobileLayout + DesktopLayout │ ├── nginx.conf # 生产 nginx 配置 │ └── Dockerfile ``` ## 数据模型 (8 张 PostgreSQL 表) | 表 | 核心字段 | |----|---------| | `users` | id, casdoor_id, name, role(manager/director/leader), wecom_userid | | `customers` | id, name, industry, address, in_use_services, monthly_fee, remarks, created_by | | `customer_contacts` | id, customer_id, name, phone, role_desc | | `customer_assignments` | id, customer_id, manager_id, role(primary/assistant), assigned_by | | `visits` | id, customer_id, visit_date, visit_method, time_range, communication_content, customer_demand, companions(UUID[]), photos(TEXT[]), manager_id | | `work_plans` | id, customer_id, plan_content, plan_date, manager_id, status | | `mini_business` | id, customer_id, product_type, amount, follow_up_detail, status, manager_id | | `key_visits` | id, customer_id, urgency_level, description, progress_status, planned_date, planned_visitor, visit_target, manager_id | ## 当前进度 ### 已完成 ✅ - [x] **Phase 1: 项目骨架** — 完整目录结构,FastAPI + Vue 3 均可启动/构建 - [x] **Phase 2: 数据模型** — 8 个 SQLAlchemy 模型 + Alembic 迁移配置 - [x] **Phase 3: 认证系统** — JWT + Casdoor OIDC + 企微静默登录 + 角色中间件 - [x] **Phase 4: 客户档案** — CRUD 全链路 API + PC 端管理页 + 归属分配/批量转移 - [x] **Phase 5: 拜访记录** — CRUD API + MinIO 预签名直传 + 移动端填报表单 + 移动端首页 - [x] **Phase 6: 计划/商机/要客** — 三个模块的 CRUD API + 移动端表单 - [x] **Phase 7: 仪表盘与汇总** — 四卡统计 + 填报进度 + 四 Tab 周报 + 按人/客户筛选 + 时间轴 - [x] **Phase 8: Excel 导入导出** — 导出四 sheet xlsx + 导入预览→确认→去重 - [x] **Phase 9: 企业微信** — 静默登录 + 催办/公告推送 + 每日 18:00 定时检查 - [x] **Phase 10: 部署** — Dockerfile × 2 + nginx.conf + docker-compose.yml - [x] **Casdoor 对接** — 已配置 Casdoor OIDC,前后端 Client ID 统一,登录/回调正常 - [x] **MinIO 对接** — 已配置预签名上传/下载,bucket 就绪 - [x] **PostgreSQL 对接** — 8 张表自动创建,数据持久化正常 - [x] **用户管理** — 支局长可在 PC 端「用户管理」页面修改任意用户角色 - [x] **客户档案增强** — 详情含客户经理、点击名称查看、备注字段、收支费用(金额+单位)、联系人管理(新增/删除)、多选批量转移 - [x] **客户导入导出** — 导出含全部字段 + 模板下载 + Excel 批量导入(自动去重匹配经理) - [x] **路由修复** — Hash 改 HTML5 History 模式,Casdoor 回调正常 - [x] **网络部署** — 后端监听 0.0.0.0:8002,前端监听 0.0.0.0:5173,防火墙已开放 ### 待完善 - [ ] 实际对接企业微信(需填写 WECOM_CORP_ID/AGENT_ID/SECRET 等) - [ ] 前端移动端/桌面端自动适配(目前路由分两套,user-agent 判断待完善) - [ ] 客户查重前端集成(API 已有 `/customers/check-duplicate/{name}`) - [ ] 缩略图生成策略(MinIO 端配置) - [ ] 企微聊天侧边栏(设计文档标注为"后续扩展,首期不做") ## 验证状态 | 检查项 | 结果 | |--------|------| | `import app.main` | ✅ 成功 | | `vite build` | ✅ 构建成功,输出到 `dist/` | | 后端运行 | ✅ `http://10.10.10.14:8002` | | 前端运行 | ✅ `http://10.10.10.14:5173` | | PostgreSQL | ✅ `10.10.10.14:5432/qiji` | | MinIO | ✅ `10.10.10.13:17051`,bucket `qiji-photos` | | Casdoor | ✅ `10.10.10.14:18000`,登录/回调正常 | | 企微推送 | ⚠️ 待填写有效 Token/AESKey 后测试 | | `docker-compose up` | ⚠️ 需要本地 PostgreSQL + MinIO 实例 | ## 启动命令 ### 第一步:配置环境变量 ```bash # 后端 cd backend cp .env.example .env # 编辑 .env,填入 Casdoor/PostgreSQL/MinIO/企微 的真实连接信息 # 前端(Casdoor 登录用) cd frontend cat > .env << 'EOF' VITE_CASDOOR_ENDPOINT=http://your-casdoor:18000 VITE_CASDOOR_CLIENT_ID=your-client-id EOF ``` 配置项说明: | 配置块 | 说明 | 必须? | |--------|------|--------| | `DATABASE_URL` | PostgreSQL 连接串,已有基础设施填真实地址 | ✅ 必须 | | `CASDOOR_*` | Casdoor OIDC 认证服务的地址、Client ID/Secret | ✅ 登录必须 | | `MINIO_*` | MinIO 对象存储地址和密钥 | ✅ 照片上传必须 | | `WECOM_*` | 企微自建应用的 Corp ID / Agent ID / Secret | ⚠️ 企微功能需要 | | `SECRET_KEY` | JWT 签发密钥,生产环境务必修改 | ✅ 必须 | | `CORS_ORIGINS` | 前端地址白名单 | ✅ 必须 | | `VITE_CASDOOR_*` | 前端登录跳转 Casdoor 所需,必须与后端一致 | ✅ 必须 | ### 第二步:启动 PostgreSQL + MinIO 如果已有可用的 PostgreSQL 和 MinIO 实例,跳过此步。否则用 docker-compose 启动: ```bash # 在项目根目录执行 docker-compose up -d postgres minio ``` ### 第三步:启动后端 ```bash cd backend uvicorn app.main:app --reload --port 8002 --host 0.0.0.0 # 首次启动会自动创建数据库表(lifespan 中执行 Base.metadata.create_all) # API 文档 → http://localhost:8002/docs ``` ### 第四步:启动前端 ```bash cd frontend npm run dev -- --host 0.0.0.0 # 页面 → http://localhost:5173 # vite proxy 自动将 /api/* 请求转发到 localhost:8002 ``` ### 一键启动(生产模式) ```bash # 项目根目录 docker-compose up -d # 后端 :8000 + PostgreSQL :5432 + MinIO :9000 + :9001(console) # 前端需单独部署到 nginx,见 frontend/Dockerfile + nginx.conf ``` ## 关键设计决策 1. **双布局**: `/m/*` 移动端(底部 TabBar),`/*` PC 端(侧边栏菜单) 2. **照片上传**: 前端从 `/api/upload/presigned-url` 拿 PUT URL → 直传 MinIO → 表单只传 object key 3. **同访人员**: 选同访人后,后端自动创建一条内容为空的状态副本 4. **权限**: JWT payload 含 `role`,`RoleChecker` 做接口级鉴权,前端 Pinia store 做 UI 级控制 5. **企微静默登录**: wecom code → userid → 查 users 表 → 找到签 JWT / 未找到引导 Casdoor 绑定 6. **前后端分离开发**: `vite.config.ts` proxy 转发 `/api` → `localhost:8000`