From 592937db4efed0dd2cc943331c2e8bf1fab89cdb Mon Sep 17 00:00:00 2001
From: kangwenjing <1138819403@qq.com>
Date: Fri, 3 Apr 2026 17:46:58 +0800
Subject: [PATCH] =?UTF-8?q?=E6=89=8B=E5=86=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.DS_Store | Bin 10244 -> 10244 bytes
docs/business-schema-design.md | 526 ------------
docs/crm.md | 641 +++++++++++++++
docs/crm操作手册.pdf | Bin 0 -> 2665536 bytes
docs/deployment-guide.md | 103 ---
docs/scripts/capture-manual-screenshots.mjs | 758 ++++++++++++++++++
docs/scripts/render-formal-pdfs.mjs | 691 ++++++++++++++++
docs/ziguang-huizhi-crm-icon-logo.svg | 46 --
docs/ziguang-huizhi-crm-icon-minimal.svg | 37 -
docs/ziguang-huizhi-crm-icon-premium-glow.svg | 86 --
docs/ziguang-huizhi-crm-icon-system.svg | 86 --
docs/ziguang-huizhi-crm-icon.svg | 76 --
docs/ziguang-huizhi-sales-crm-icon.svg | 94 ---
docs/数据结构.md | 658 +++++++++++++++
14 files changed, 2748 insertions(+), 1054 deletions(-)
delete mode 100644 docs/business-schema-design.md
create mode 100644 docs/crm.md
create mode 100644 docs/crm操作手册.pdf
delete mode 100644 docs/deployment-guide.md
create mode 100644 docs/scripts/capture-manual-screenshots.mjs
create mode 100644 docs/scripts/render-formal-pdfs.mjs
delete mode 100644 docs/ziguang-huizhi-crm-icon-logo.svg
delete mode 100644 docs/ziguang-huizhi-crm-icon-minimal.svg
delete mode 100644 docs/ziguang-huizhi-crm-icon-premium-glow.svg
delete mode 100644 docs/ziguang-huizhi-crm-icon-system.svg
delete mode 100644 docs/ziguang-huizhi-crm-icon.svg
delete mode 100644 docs/ziguang-huizhi-sales-crm-icon.svg
create mode 100644 docs/数据结构.md
diff --git a/.DS_Store b/.DS_Store
index a2f3500c5f11681e02af34fc741506e877541c20..4c6310ab68bc06e46ec25974fe8409c50a9f67b8 100644
GIT binary patch
delta 30
kcmZn(XbITRBE-lrxmD;8BjaQb;VD2iqln1nkHW$t0GJC1`v3p{
delta 30
kcmZn(XbITRBE-lzxmD;8Bg145;VD2iqln1nkHW$t0GJyH`~Uy|
diff --git a/docs/business-schema-design.md b/docs/business-schema-design.md
deleted file mode 100644
index 8b1e5b43..00000000
--- a/docs/business-schema-design.md
+++ /dev/null
@@ -1,526 +0,0 @@
-# CRM业务表设计
-
-## 1. 设计依据
-
-本设计根据当前前端页面反推业务模型,涉及页面如下:
-
-- `src/pages/Opportunities.tsx`:商机储备、商机详情、跟进记录
-- `src/pages/Expansion.tsx`:销售人员拓展、渠道拓展、跟进记录
-- `src/pages/Work.tsx`:外勤打卡、日报、历史记录、主管点评
-- `src/pages/Profile.tsx`:个人资料、统计信息
-- `src/pages/Dashboard.tsx`:首页统计、待办、动态
-
-当前前端是展示型页面,未接入真实接口,因此以下设计属于“按现有前端信息推导出的第一版业务库设计”。
-
----
-
-## 2. 业务模块拆分
-
-建议按以下模块建表:
-
-1. 组织与人员
-2. 客户与商机
-3. 拓展管理
-4. 工作管理
-5. 待办与动态(可选增强)
-
----
-
-## 3. 核心实体关系
-
-```text
-部门 department
- └─< 用户 user
-
-客户 customer
- └─< 商机 opportunity
- └─< 商机跟进记录 opportunity_followup
-
-用户 user
- └─< 销售拓展 sales_expansion
- └─< 拓展跟进记录 expansion_followup
-
-用户 user
- └─< 渠道拓展 channel_expansion
- └─< 拓展跟进记录 expansion_followup
-
-用户 user
- └─< 外勤打卡 work_checkin
- └─< 打卡附件 work_checkin_attachment
-
-用户 user
- └─< 日报 work_daily_report
- └─< 日报点评 work_daily_report_comment
-```
-
----
-
-## 4. 表设计
-
-## 4.1 `sys_department` 部门表
-
-用于承接“华东大区、华北大区”等组织信息。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| dept_code | varchar(50) | 部门编码 |
-| dept_name | varchar(100) | 部门名称 |
-| parent_id | bigint | 上级部门ID |
-| manager_user_id | bigint | 部门负责人 |
-| status | tinyint | 1启用 0停用 |
-| created_at | datetime | 创建时间 |
-| updated_at | datetime | 更新时间 |
-
----
-
-## 4.2 `sys_user` 用户表
-
-承接“张三、李四、王五”等销售人员,以及个人页中的员工资料。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| user_code | varchar(50) | 工号/员工编号 |
-| username | varchar(50) | 登录账号 |
-| real_name | varchar(50) | 姓名 |
-| mobile | varchar(20) | 手机号 |
-| email | varchar(100) | 邮箱 |
-| dept_id | bigint | 所属部门 |
-| job_title | varchar(100) | 职位,如高级销售 |
-| status | tinyint | 1在职 0离职 |
-| hire_date | date | 入职日期 |
-| avatar_url | varchar(255) | 头像地址 |
-| password_hash | varchar(255) | 登录密码摘要 |
-| created_at | datetime | 创建时间 |
-| updated_at | datetime | 更新时间 |
-
-索引建议:
-
-- `idx_user_dept_id(dept_id)`
-- `uk_user_username(username)`
-- `uk_user_mobile(mobile)`
-
----
-
-## 4.3 `crm_customer` 客户表
-
-来源于商机页面中的“客户名称”,如医院、学校、集团。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| customer_code | varchar(50) | 客户编码 |
-| customer_name | varchar(200) | 客户名称 |
-| customer_type | varchar(50) | 客户类型,如医院/高校/企业 |
-| industry | varchar(50) | 行业 |
-| province | varchar(50) | 省份 |
-| city | varchar(50) | 城市 |
-| address | varchar(255) | 地址 |
-| owner_user_id | bigint | 当前负责人 |
-| source | varchar(50) | 来源,如渠道推荐/市场活动 |
-| status | varchar(30) | 潜在/跟进中/成交/流失 |
-| remark | text | 备注 |
-| created_at | datetime | 创建时间 |
-| updated_at | datetime | 更新时间 |
-
-索引建议:
-
-- `idx_customer_owner(owner_user_id)`
-- `idx_customer_name(customer_name)`
-
----
-
-## 4.4 `crm_opportunity` 商机表
-
-这是前端最核心业务表,对应“商机储备”页面。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| opportunity_code | varchar(50) | 商机编号,如 `HD-20231024-001` |
-| opportunity_name | varchar(200) | 商机名称 |
-| customer_id | bigint | 关联客户 |
-| owner_user_id | bigint | 商机负责人 |
-| amount | decimal(18,2) | 商机金额 |
-| expected_close_date | date | 预计结单日期 |
-| confidence_pct | tinyint | 把握度,0-100 |
-| stage | varchar(50) | 阶段,如初步沟通/方案交流/招投标/商务谈判/已成交 |
-| opportunity_type | varchar(50) | 类型,如新建/扩容 |
-| product_type | varchar(100) | 产品类别,如VDI/VOI/IDV云桌面 |
-| source | varchar(50) | 商机来源 |
-| pushed_to_oms | tinyint | 是否已推送 OMS |
-| oms_push_time | datetime | 推送 OMS 时间 |
-| description | text | 商机说明/备注 |
-| status | varchar(30) | 正常/赢单/输单/关闭 |
-| created_at | datetime | 创建时间 |
-| updated_at | datetime | 更新时间 |
-
-索引建议:
-
-- `uk_opportunity_code(opportunity_code)`
-- `idx_opportunity_customer(customer_id)`
-- `idx_opportunity_owner(owner_user_id)`
-- `idx_opportunity_stage(stage)`
-- `idx_opportunity_expected_close(expected_close_date)`
-
----
-
-## 4.5 `crm_opportunity_followup` 商机跟进记录表
-
-对应商机详情里的“跟进记录”时间线。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| opportunity_id | bigint | 商机ID |
-| followup_time | datetime | 跟进时间 |
-| followup_type | varchar(50) | 跟进方式,如电话沟通/现场拜访/微信沟通 |
-| content | text | 跟进内容 |
-| next_action | varchar(255) | 下一步动作 |
-| followup_user_id | bigint | 跟进人 |
-| created_at | datetime | 创建时间 |
-| updated_at | datetime | 更新时间 |
-
-索引建议:
-
-- `idx_opp_followup_opportunity(opportunity_id, followup_time desc)`
-- `idx_opp_followup_user(followup_user_id)`
-
----
-
-## 4.6 `crm_sales_expansion` 销售拓展表
-
-对应“销售人员拓展”。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| candidate_name | varchar(50) | 候选人姓名 |
-| mobile | varchar(20) | 手机号 |
-| email | varchar(100) | 邮箱 |
-| target_dept_id | bigint | 目标归属部门 |
-| industry | varchar(50) | 擅长行业 |
-| title | varchar(100) | 当前或目标职位 |
-| intent_level | varchar(20) | 意向度,高/中/低 |
-| stage | varchar(50) | 阶段,如初步沟通/方案交流 |
-| has_desktop_exp | tinyint | 是否有云桌面经验 |
-| in_progress | tinyint | 是否持续跟进中 |
-| employment_status | varchar(20) | 在职/离职/已入职/已放弃 |
-| expected_join_date | date | 预计入职日期,可为空 |
-| owner_user_id | bigint | 负责人 |
-| remark | text | 备注 |
-| created_at | datetime | 创建时间 |
-| updated_at | datetime | 更新时间 |
-
-索引建议:
-
-- `idx_sales_expansion_owner(owner_user_id)`
-- `idx_sales_expansion_stage(stage)`
-- `idx_sales_expansion_mobile(mobile)`
-
----
-
-## 4.7 `crm_channel_expansion` 渠道拓展表
-
-对应“渠道拓展”。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| channel_name | varchar(200) | 渠道名称 |
-| province | varchar(50) | 所在省份 |
-| industry | varchar(50) | 主要行业 |
-| annual_revenue | decimal(18,2) | 年营收规模 |
-| staff_size | int | 公司人数 |
-| contact_name | varchar(50) | 联系人 |
-| contact_title | varchar(100) | 联系人职务 |
-| contact_mobile | varchar(20) | 联系电话 |
-| stage | varchar(50) | 阶段,如初步接触/合作洽谈 |
-| landed_flag | tinyint | 是否已落地 |
-| expected_sign_date | date | 预计签约日期 |
-| owner_user_id | bigint | 负责人 |
-| remark | text | 备注 |
-| created_at | datetime | 创建时间 |
-| updated_at | datetime | 更新时间 |
-
-索引建议:
-
-- `idx_channel_expansion_owner(owner_user_id)`
-- `idx_channel_expansion_stage(stage)`
-- `idx_channel_expansion_name(channel_name)`
-
----
-
-## 4.8 `crm_expansion_followup` 拓展跟进记录表
-
-销售拓展和渠道拓展都存在“跟进记录”,建议共用一张表,通过对象类型区分。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| biz_type | varchar(20) | `sales` / `channel` |
-| biz_id | bigint | 对应拓展对象ID |
-| followup_time | datetime | 跟进时间 |
-| followup_type | varchar(50) | 电话/微信/面谈等 |
-| content | text | 跟进内容 |
-| next_action | varchar(255) | 下一步动作 |
-| followup_user_id | bigint | 跟进人 |
-| created_at | datetime | 创建时间 |
-| updated_at | datetime | 更新时间 |
-
-索引建议:
-
-- `idx_exp_followup_biz(biz_type, biz_id, followup_time desc)`
-- `idx_exp_followup_user(followup_user_id)`
-
----
-
-## 4.9 `work_checkin` 外勤打卡表
-
-对应工作台里的“外勤打卡”。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| user_id | bigint | 打卡人 |
-| checkin_date | date | 打卡日期 |
-| checkin_time | datetime | 打卡时间 |
-| longitude | decimal(10,6) | 经度 |
-| latitude | decimal(10,6) | 纬度 |
-| location_text | varchar(255) | 地址文本 |
-| remark | varchar(500) | 备注说明 |
-| status | varchar(30) | 正常/异常/补卡 |
-| created_at | datetime | 创建时间 |
-| updated_at | datetime | 更新时间 |
-
-索引建议:
-
-- `idx_checkin_user_date(user_id, checkin_date desc)`
-
----
-
-## 4.10 `work_checkin_attachment` 打卡附件表
-
-前端要求“现场照片必填”,建议单独拆附件表。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| checkin_id | bigint | 打卡ID |
-| file_url | varchar(255) | 文件地址 |
-| file_type | varchar(30) | image/audio/video |
-| file_name | varchar(255) | 原始文件名 |
-| file_size | bigint | 文件大小 |
-| created_at | datetime | 创建时间 |
-
-索引建议:
-
-- `idx_checkin_attachment_checkin(checkin_id)`
-
----
-
-## 4.11 `work_daily_report` 日报表
-
-对应“每日表”和右侧历史日报。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| user_id | bigint | 提交人 |
-| report_date | date | 日报日期 |
-| work_content | text | 今日工作内容 |
-| tomorrow_plan | text | 明日工作计划 |
-| source_type | varchar(30) | manual/voice |
-| submit_time | datetime | 提交时间 |
-| status | varchar(30) | 待提交/已提交/已阅/已点评 |
-| score | int | 评分 |
-| created_at | datetime | 创建时间 |
-| updated_at | datetime | 更新时间 |
-
-索引建议:
-
-- `idx_daily_report_user_date(user_id, report_date desc)`
-- `idx_daily_report_status(status)`
-- `uk_daily_report_user_date(user_id, report_date)`
-
----
-
-## 4.12 `work_daily_report_comment` 日报点评表
-
-对应历史记录中的“主管点评”。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| report_id | bigint | 日报ID |
-| reviewer_user_id | bigint | 点评人 |
-| score | int | 评分 |
-| comment_content | text | 点评内容 |
-| reviewed_at | datetime | 点评时间 |
-| created_at | datetime | 创建时间 |
-
-索引建议:
-
-- `idx_report_comment_report(report_id)`
-
----
-
-## 4.13 `work_todo` 待办表(建议补充)
-
-首页有“待办事项”,虽然现在是静态数据,但真实业务通常需要。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| user_id | bigint | 所属用户 |
-| title | varchar(200) | 待办标题 |
-| biz_type | varchar(30) | opportunity / expansion / report / other |
-| biz_id | bigint | 业务对象ID |
-| due_date | datetime | 截止时间 |
-| status | varchar(20) | todo / done / canceled |
-| priority | varchar(20) | high / medium / low |
-| created_at | datetime | 创建时间 |
-| updated_at | datetime | 更新时间 |
-
----
-
-## 4.14 `sys_activity_log` 动态日志表(建议补充)
-
-首页“最新动态”适合由统一动态表驱动。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| id | bigint PK | 主键 |
-| biz_type | varchar(30) | 业务类型 |
-| biz_id | bigint | 业务ID |
-| action_type | varchar(50) | 如商机阶段更新/日报点评/新增渠道 |
-| title | varchar(200) | 动态标题 |
-| content | varchar(500) | 动态描述 |
-| operator_user_id | bigint | 操作人 |
-| created_at | datetime | 创建时间 |
-
-索引建议:
-
-- `idx_activity_created(created_at desc)`
-- `idx_activity_biz(biz_type, biz_id)`
-
----
-
-## 5. 推荐枚举值
-
-为了避免硬编码中文状态,建议状态字段统一使用编码值,前端再做字典映射。
-
-### 商机阶段 `opportunity.stage`
-
-- `initial_contact` 初步沟通
-- `solution_discussion` 方案交流
-- `bidding` 招投标
-- `business_negotiation` 商务谈判
-- `won` 已成交
-- `lost` 已丢单
-
-### 商机状态 `opportunity.status`
-
-- `active`
-- `won`
-- `lost`
-- `closed`
-
-### 销售拓展意向 `sales_expansion.intent_level`
-
-- `high`
-- `medium`
-- `low`
-
-### 外勤打卡状态 `work_checkin.status`
-
-- `normal`
-- `abnormal`
-- `reissue`
-
-### 日报状态 `work_daily_report.status`
-
-- `draft`
-- `submitted`
-- `read`
-- `reviewed`
-
----
-
-## 6. 第一版最小可落地表
-
-如果先做 MVP,建议优先落以下 8 张:
-
-1. `sys_department`
-2. `sys_user`
-3. `crm_customer`
-4. `crm_opportunity`
-5. `crm_opportunity_followup`
-6. `crm_channel_expansion`
-7. `work_checkin`
-8. `work_daily_report`
-
-这 8 张就能支撑目前前端大部分核心展示。
-
-如果要把“拓展管理”做完整,再补:
-
-1. `crm_sales_expansion`
-2. `crm_expansion_followup`
-3. `work_checkin_attachment`
-4. `work_daily_report_comment`
-
----
-
-## 7. 建表原则建议
-
-1. 所有业务表统一保留 `created_at`、`updated_at`。
-2. 负责人、创建人、点评人等人员字段统一关联 `sys_user.id`。
-3. 跟进记录建议独立建表,不要直接塞进主表。
-4. 金额统一用 `decimal(18,2)`,不要用字符串。
-5. 时间类字段区分清楚 `date` 和 `datetime`。
-6. 中文状态不要直接写死在数据库,建议存编码值。
-7. 如果后续要对接 OMS,商机表中保留 `pushed_to_oms` 和外部系统单号字段会更稳妥。
-
----
-
-## 8. 与前端页面的映射关系
-
-### 商机页
-
-- 列表:`crm_opportunity`
-- 客户名称:`crm_customer`
-- 详情跟进:`crm_opportunity_followup`
-
-### 拓展页
-
-- 销售拓展:`crm_sales_expansion`
-- 渠道拓展:`crm_channel_expansion`
-- 跟进记录:`crm_expansion_followup`
-
-### 工作页
-
-- 外勤打卡:`work_checkin`
-- 打卡照片:`work_checkin_attachment`
-- 日报:`work_daily_report`
-- 主管点评:`work_daily_report_comment`
-
-### 首页/我的
-
-- 统计看板:由商机、拓展、打卡、日报聚合生成
-- 待办事项:`work_todo`
-- 最新动态:`sys_activity_log`
-- 个人信息:`sys_user` + `sys_department`
-
----
-
-## 9. 下一步建议
-
-如果要继续往后端落地,建议按以下顺序推进:
-
-1. 先定字段字典和状态流转
-2. 再输出 MySQL DDL
-3. 再补接口文档
-4. 最后和前端页面一一对齐新增/编辑/详情接口
-
-如果需要,我下一步可以直接继续帮你补一版 MySQL 建表 SQL。
diff --git a/docs/crm.md b/docs/crm.md
new file mode 100644
index 00000000..84f7c754
--- /dev/null
+++ b/docs/crm.md
@@ -0,0 +1,641 @@
+# 紫光汇智 CRM 技术系统规划与技术文档
+
+## 1. 文档定位
+
+本文档面向研发、架构、测试、运维与交付团队,说明紫光汇智 CRM 系统的技术现状、目标架构、模块规划、关键设计原则、实施路线与交付边界。
+
+文档目标如下:
+
+- 为当前系统提供统一的技术说明基线
+- 为后续迭代提供可落地的技术规划
+- 为环境部署、模块扩展、接口治理和性能治理提供参考
+- 为研发协作、测试设计和运维交接提供统一口径
+
+本文档基于当前仓库代码、SQL 初始化脚本与现有项目文档整理,整理日期为 `2026-04-03`。
+
+## 2. 系统概述
+
+紫光汇智 CRM 是一个围绕销售过程管理建设的轻量 CRM 系统,当前主要覆盖以下业务域:
+
+- 首页工作台聚合
+- 销售拓展与渠道拓展
+- 商机储备与推进
+- 外勤打卡
+- 销售日报
+- 个人资料与账号安全
+
+系统当前采用前后端分离模式:
+
+- 前端:`frontend/`,基于 `Vite + React + TypeScript`
+- 后端:`backend/`,基于 `Spring Boot + MyBatis Plus + PostgreSQL + Redis`
+- 数据:通过 `sql/init_full_pg17.sql` 初始化业务表
+
+## 3. 当前技术现状
+
+### 3.1 前端现状
+
+前端目录位于 `frontend/src/`,核心结构如下:
+
+```text
+frontend/src/
+├── App.tsx
+├── components/
+├── hooks/
+├── lib/
+└── pages/
+```
+
+当前页面模块包括:
+
+- `Login.tsx`:登录页
+- `Dashboard.tsx`:首页工作台
+- `Expansion.tsx`:销售拓展、渠道拓展
+- `Opportunities.tsx`:商机管理
+- `Work.tsx`:打卡、日报、历史记录
+- `Profile.tsx`:个人中心
+
+当前前端特点:
+
+- 使用 `react-router-dom` 管理路由
+- 通过 `lib/auth.ts` 封装统一 API 调用
+- 已适配 PC 与移动端
+- 页面交互完整,具备较强的可交付性
+- 复杂页面采用单文件实现,后续存在进一步拆分空间
+
+### 3.2 后端现状
+
+后端目录位于 `backend/src/main/java/com/unis/crm/`,当前结构包括:
+
+```text
+backend/src/main/java/com/unis/crm/
+├── common/
+├── config/
+├── controller/
+├── dto/
+├── mapper/
+├── service/
+└── service/impl/
+```
+
+当前已实现的控制器包括:
+
+- `DashboardController`
+- `ExpansionController`
+- `OpportunityController`
+- `WorkController`
+- `ProfileController`
+- `OpportunityIntegrationController`
+- `WecomSsoController`
+
+当前后端特点:
+
+- 采用 Spring Boot 单体模式
+- 基于 MyBatis Plus 组织数据访问
+- DTO 分包清晰,按业务域拆分
+- 已具备基础异常处理、统一响应和安全配置
+- 业务仍集中在服务实现层,后续可继续增强领域边界和可测试性
+
+### 3.3 数据层现状
+
+当前项目已将业务初始化入口收敛为:
+
+- `sql/init_full_pg17.sql`
+
+脚本中已覆盖以下核心表:
+
+- `crm_customer`
+- `crm_opportunity`
+- `crm_opportunity_followup`
+- `crm_sales_expansion`
+- `crm_channel_expansion`
+- `crm_channel_expansion_contact`
+- `crm_expansion_followup`
+- `work_checkin`
+- `work_daily_report`
+- `work_daily_report_comment`
+- `work_todo`
+- `sys_activity_log`
+
+当前数据层特点:
+
+- 业务主表与过程表已较完整
+- 初始化脚本已能作为统一部署入口
+- 仍依赖基础平台表与基础数据
+- 后续需继续收敛索引策略、归档策略和审计策略
+
+## 4. 技术建设目标
+
+未来技术建设建议围绕以下五个目标推进:
+
+1. 稳定性目标:保证主链路功能可持续发布与回归验证。
+2. 可维护性目标:降低单文件复杂度,提升模块边界清晰度。
+3. 可扩展性目标:为后续客户管理、审批流、分析报表等能力预留扩展空间。
+4. 可运维性目标:完善日志、监控、配置治理和部署标准。
+5. 安全性目标:提升鉴权、配置、上传、接口访问和数据变更可控性。
+
+## 5. 总体技术架构规划
+
+建议系统继续保持“前后端分离 + 单体业务后端”的建设模式,在当前阶段不急于拆分微服务,以降低复杂度与运维成本。
+
+推荐总体架构如下:
+
+```mermaid
+flowchart TD
+ U["用户端
PC / Mobile"] --> FE["前端应用
React + Vite"]
+ FE --> GW["应用接入层
Nginx / HTTPS"]
+ GW --> BE["CRM 后端单体服务
Spring Boot"]
+ BE --> PG["PostgreSQL"]
+ BE --> RD["Redis"]
+ BE --> BASE["基础平台能力
用户/组织/参数/鉴权"]
+ BE --> OMS["外部系统集成
OMS / 其他业务系统"]
+ BE --> FILE["文件存储目录
上传附件 / 打卡照片"]
+```
+
+规划原则:
+
+- 业务复杂度未达到微服务拆分必要性前,优先优化单体结构
+- 前端优先按业务域拆分组件和状态
+- 后端优先按业务模块做清晰分层,而不是过早做技术拆分
+- 数据库优先保障一致性与查询性能
+- 接口治理、日志治理、异常治理要优先于功能外延扩张
+
+## 6. 模块规划
+
+### 6.1 首页工作台模块
+
+职责:
+
+- 聚合展示欢迎语、统计指标、待办事项、最新动态
+- 提供工作入口跳转
+
+技术规划:
+
+- 统计接口与待办接口继续保留聚合型接口风格
+- 增加缓存策略,减少重复统计计算
+- 动态与待办建议做统一事件源或统一日志源治理
+
+### 6.2 拓展管理模块
+
+职责:
+
+- 管理销售拓展与渠道拓展主数据
+- 支撑后续商机关联、日报关联和项目推进
+
+技术规划:
+
+- 拓展列表查询支持分页、筛选、导出、关键词搜索
+- 跟进记录数据结构统一化
+- 重复校验规则集中到服务层或领域规则层
+- 前端表单组件逐步抽象,降低 `Expansion.tsx` 单文件复杂度
+
+### 6.3 商机管理模块
+
+职责:
+
+- 管理商机主数据、推进阶段、竞争态势、售前协同和系统推送
+
+技术规划:
+
+- 商机状态机建议标准化
+- 推送外部系统逻辑与本地业务保存逻辑解耦
+- 推送记录、失败原因、重试机制单独建模
+- 回写字段、自动跟进字段需进一步规范来源
+
+### 6.4 工作管理模块
+
+职责:
+
+- 支撑打卡、日报、历史记录和过程数据留痕
+
+技术规划:
+
+- 打卡上传、定位、逆地理解析可进一步隔离为基础服务组件
+- 日报行项目结构建议形成稳定 DTO 契约
+- 历史记录建议增加分页游标和时间维度索引优化
+- 主管点评能力后续可进一步显式建模为评审子域
+
+### 6.5 个人中心模块
+
+职责:
+
+- 查看与修改个人资料
+- 密码修改
+- 展示个人月度工作概览
+
+技术规划:
+
+- 用户资料更新与基础平台用户数据同步策略需要明确
+- 密码修改链路需与统一安全策略对齐
+
+## 7. 分层设计规划
+
+建议后端逐步收敛为以下分层:
+
+### 7.1 Controller 层
+
+职责:
+
+- 接收 HTTP 请求
+- 做基础参数校验
+- 调用应用服务
+- 返回统一响应体
+
+约束:
+
+- 不直接承载复杂业务规则
+- 不直接拼接复杂数据库逻辑
+
+### 7.2 Application Service 层
+
+职责:
+
+- 编排业务流程
+- 协调多个领域对象、外部系统、事务边界
+- 对接 Mapper/Repository
+
+建议:
+
+- 当前 `service/impl` 可逐步向“应用服务 + 领域服务”演进
+
+### 7.3 Domain Rule 层
+
+职责:
+
+- 放置核心业务规则
+- 例如:重复校验、状态切换、编辑权限判定、推送条件判断
+
+建议:
+
+- 先从复杂模块开始,例如商机推送、日报回写、拓展重复校验
+
+### 7.4 Repository / Mapper 层
+
+职责:
+
+- 承接数据库查询和持久化
+- 隔离 SQL 与业务逻辑
+
+建议:
+
+- 查询 SQL 与写入 SQL 适当拆分
+- 对复杂列表查询建立专门 Mapper 方法,不在服务层拼装
+
+## 8. 前端技术规划
+
+### 8.1 路由与页面拆分
+
+建议维持当前路由结构,但将复杂页面拆成子模块:
+
+- `Expansion.tsx` 拆为列表区、表单区、详情区、导出逻辑
+- `Opportunities.tsx` 拆为列表、详情、推送弹窗、编辑弹窗
+- `Work.tsx` 拆为打卡面板、日报面板、历史面板、对象选择器
+
+### 8.2 API 层治理
+
+建议继续以 `lib/auth.ts` 作为 API 网关入口,但逐步按域拆文件:
+
+- `api/dashboard.ts`
+- `api/expansion.ts`
+- `api/opportunity.ts`
+- `api/work.ts`
+- `api/profile.ts`
+
+收益:
+
+- 便于维护
+- 更清晰的类型边界
+- 更方便单元测试和 mock
+
+### 8.3 组件规划
+
+建议将高复用部分抽出:
+
+- 弹窗容器
+- 列表卡片
+- 表单字段组件
+- 状态标签组件
+- 导出按钮组件
+- 历史记录详情组件
+
+### 8.4 前端质量治理
+
+建议补齐以下内容:
+
+- ESLint 与 Prettier 统一规范
+- 类型检查纳入 CI
+- 关键页面冒烟测试
+- API mock 机制沉淀为正式脚本
+
+## 9. 后端技术规划
+
+### 9.1 单体后端演进路线
+
+当前推荐继续使用单体服务,建议按模块增强而不是拆服务。
+
+演进方向:
+
+- 强化模块边界
+- 减少跨模块直接访问
+- 将外部系统集成收敛到独立适配层
+- 增加服务层测试与接口测试
+
+### 9.2 DTO 与接口契约
+
+当前 DTO 已按业务域拆包,建议继续坚持:
+
+- 输入 DTO 与输出 DTO 分离
+- 复杂聚合返回专门建模
+- 避免前端直接依赖数据库字段命名
+
+### 9.3 事务与一致性
+
+重点关注场景:
+
+- 商机保存与外部系统推送
+- 日报提交与商机回写
+- 拓展编辑与关联信息刷新
+- 打卡上传文件与数据库记录保存
+
+建议:
+
+- 本地事务和外部调用解耦
+- 外部系统调用失败时保留本地状态与失败日志
+- 对推送行为增加状态记录表或审计表
+
+## 10. 数据库规划
+
+### 10.1 设计原则
+
+- 主表负责业务主状态
+- 过程表负责轨迹沉淀
+- 审计字段默认标准化
+- 删除操作优先逻辑删除或状态化
+- 高频查询字段提前建索引
+
+### 10.2 索引规划建议
+
+建议重点优化以下查询:
+
+- 首页待办查询
+- 首页动态查询
+- 商机列表按负责人、阶段、归档状态查询
+- 拓展列表按负责人、姓名、渠道名查询
+- 打卡/日报历史按用户、日期倒序查询
+
+### 10.3 归档与清理规划
+
+建议对以下数据建立归档策略:
+
+- 已归档商机
+- 早期历史动态日志
+- 历史打卡照片
+- 大体量日报附件或冗余快照
+
+## 11. 接口治理规划
+
+### 11.1 接口规范
+
+建议保持统一 API 风格:
+
+- URL 使用业务域前缀
+- GET 用于查询
+- POST 用于新增或业务动作
+- PUT 用于更新
+- 统一返回结构 `code / msg / data`
+
+### 11.2 错误处理
+
+建议错误分层:
+
+- 参数错误
+- 业务规则错误
+- 鉴权错误
+- 外部系统错误
+- 系统内部错误
+
+并在日志中保留:
+
+- traceId
+- userId
+- requestPath
+- requestParams
+- errorCode
+- rootCause
+
+### 11.3 版本治理
+
+当前系统体量不大,可暂不引入 `/v1` 路径版本。
+
+但建议提前约定:
+
+- 外部开放接口预留版本化策略
+- 集成接口变更必须同步更新文档
+- 高风险字段变更必须保持向后兼容
+
+## 12. 安全规划
+
+### 12.1 鉴权
+
+当前系统基于 JWT 鉴权,建议继续强化:
+
+- Access Token 有效期控制
+- Refresh Token 生命周期管理
+- 登录失败次数控制
+- 敏感操作二次确认
+
+### 12.2 数据权限
+
+建议明确至少三类权限边界:
+
+- 仅本人可编辑
+- 本部门可查看
+- 管理员可全局查看
+
+### 12.3 配置安全
+
+建议将敏感配置从默认配置文件中进一步外置:
+
+- 数据库密码
+- Redis 密码
+- JWT Secret
+- 内部系统 Secret
+- 外部系统 API Key
+
+### 12.4 上传安全
+
+打卡照片上传需重点关注:
+
+- 文件类型限制
+- 文件大小限制
+- 文件名安全
+- 存储目录隔离
+- 访问权限控制
+
+## 13. 日志、监控与可观测性规划
+
+建议建立以下可观测能力:
+
+### 13.1 日志
+
+- 应用日志
+- 接口访问日志
+- 外部系统调用日志
+- 业务动作日志
+- 失败日志
+
+### 13.2 监控指标
+
+- 接口响应时间
+- 错误率
+- 慢 SQL
+- PostgreSQL 连接数
+- Redis 可用性
+- 文件上传失败率
+- 外部系统推送成功率
+
+### 13.3 告警建议
+
+- 登录异常激增
+- 商机推送失败率异常
+- 文件上传失败率异常
+- 数据库连接异常
+- 首页聚合接口超时
+
+## 14. 测试规划
+
+建议建立三层测试体系:
+
+### 14.1 单元测试
+
+覆盖重点:
+
+- 业务规则判断
+- 状态切换
+- 参数转换
+- 重复校验
+
+### 14.2 接口测试
+
+覆盖重点:
+
+- 登录
+- 首页接口
+- 拓展新增/编辑
+- 商机新增/编辑/推送
+- 打卡与日报提交流程
+
+### 14.3 前端冒烟测试
+
+覆盖重点:
+
+- 登录页
+- 首页
+- 拓展页
+- 商机页
+- 打卡页
+- 日报页
+- 个人中心页
+
+## 15. 部署与环境规划
+
+### 15.1 环境分层建议
+
+建议至少分为:
+
+- 本地开发环境
+- 测试环境
+- 预发布环境
+- 生产环境
+
+### 15.2 部署建议
+
+前端建议:
+
+- 使用 Nginx 托管静态资源
+- 区分环境配置
+- 启用 gzip 与缓存策略
+
+后端建议:
+
+- 使用独立配置文件或环境变量
+- 使用进程守护或容器部署
+- 按环境区分日志目录、上传目录和外部地址
+
+数据库建议:
+
+- 定期备份
+- 版本化执行 SQL
+- 升级前回滚预案
+
+## 16. 迭代路线建议
+
+### 第一阶段:稳态交付
+
+目标:
+
+- 完成现有主链路稳定交付
+- 收敛环境配置
+- 完成基础测试清单
+
+建议事项:
+
+- 修正高复杂度页面拆分
+- 完善日志与异常信息
+- 固化部署手册与回归手册
+
+### 第二阶段:治理增强
+
+目标:
+
+- 增强可维护性与可观测性
+
+建议事项:
+
+- 引入 CI 检查
+- 完成 API 分层拆分
+- 增加推送日志和审计机制
+- 增强权限模型
+
+### 第三阶段:业务扩展
+
+目标:
+
+- 支撑更大规模的 CRM 业务演进
+
+建议事项:
+
+- 引入客户主档视图
+- 引入审批/流程节点
+- 引入经营分析与管理报表
+- 引入更标准的数据字典中心
+
+## 17. 当前主要技术风险
+
+建议重点关注以下风险:
+
+1. 前端复杂页面单文件过大,维护成本上升。
+2. 外部系统集成失败场景的状态闭环仍需增强。
+3. 当前配置文件中存在敏感参数,生产治理需加强。
+4. 数据权限与角色权限模型还需要形成正式方案。
+5. 自动化测试和持续集成能力仍有较大提升空间。
+
+## 18. 技术文档交付建议
+
+建议后续完整技术文档体系至少包括:
+
+- 技术系统规划与技术文档
+- 部署手册
+- 数据库设计说明
+- 接口文档
+- 测试方案与回归清单
+- 运维巡检与故障处理手册
+
+## 19. 相关文件
+
+- `docs/system-construction.md`
+- `docs/business-schema-design.md`
+- `docs/deployment-guide.md`
+- `docs/opportunity-integration-api.md`
+- `backend/README.md`
+- `frontend/README.md`
+
diff --git a/docs/crm操作手册.pdf b/docs/crm操作手册.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..c6d2b38e7cb6b5ded7267b2c65ed410c797b69c6
GIT binary patch
literal 2665536
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