林海 1 день назад
Родитель
Сommit
25d3cec716
1 измененных файлов с 338 добавлено и 35 удалено
  1. 338 35
      README.md

+ 338 - 35
README.md

@@ -1,65 +1,368 @@
-# 家谱管理系统 (Genealogy Management System)
+# 留氏族谱信息管理系统
 
-本项目实现了家谱管理功能,包括用户登录、文件上传(图片/扫描件)、上传到 OSS、OCR 自动解析页码以及数据库存储
+家谱管理后台,用于留氏族谱数字化管理:扫描件/PDF 上传、OSS 存储、AI 识别人名、成员录入与关系维护、世系树可视化、聚落地图、微信小程序 API 等
 
-## 功能特性
+**生产地址:** `https://familial.yunzhixue.cn/manager/`  
+**本地开发:** `http://127.0.0.1:5001/manager/`
 
-1. **登录管理**:基于数据库 `users` 表的身份验证。
-2. **家谱管理**:支持上传扫描件或图片。
-3. **OSS 上传**:通过指定的 `https://crmapi.dcjxb.yunzhixue.cn/file/upload` 接口实现。
-4. **OCR 页码解析**:自动解析图片中的页码并记录。
-5. **数据库存储**:在 MySQL 数据库中存储记录。
+---
 
-## 目录结构
+## 一、技术栈
 
-- `app.py`: Flask 应用主入口。
-- `oss_utils.py`: OSS 上传工具类。
-- `ocr_utils.py`: OCR 页码解析工具类。
-- `init_db.py`: 数据库初始化脚本(创建表和添加测试用户)。
-- `templates/`: HTML 模板文件。
-- `requirements.txt`: Python 依赖项。
+| 类别 | 技术 |
+|------|------|
+| Web 框架 | Flask 2.0.1(单文件主应用 `app.py`,约 7400+ 行) |
+| 数据库 | MySQL(阿里云 RDS),PyMySQL + dbutils 连接池 |
+| 文件存储 | 春笋 OSS 上传代理(`crmapi.dcjxb.yunzhixue.cn`) |
+| AI 识别 | 火山引擎豆包 `doubao-seed-1-8-251228`(扫描件识别人名、族谱原文生成) |
+| OCR | Tesseract(页码识别,需系统安装 `tesseract-ocr` + 中文语言包) |
+| PDF 处理 | PyMuPDF (`fitz`),按页拆分为 PNG |
+| 图片处理 | Pillow(压缩、水印) |
+| 前端 | Jinja2 模板 + Bootstrap 5 + D3.js(世系树) |
+| 微信 | 小程序登录(`jscode2session` + 手机号解密) |
 
-## 快速开始
+**补充依赖(未写入 requirements.txt,部署时需手动安装):**
+
+```bash
+pip install pymupdf cryptography
+```
+
+---
+
+## 二、目录结构
+
+```
+genealogy_app/
+├── app.py                  # 主应用:路由、业务逻辑、AI、微信 API、内联数据库迁移
+├── oss_utils.py            # OSS 文件上传
+├── ocr_utils.py            # Tesseract 页码识别
+├── requirements.txt        # Python 依赖
+├── init_db.py              # 数据库初始化(genealogy_records 表 + 测试账号)
+│
+├── templates/              # Jinja2 页面模板(16 个)
+├── static/                 # 静态资源(/manager/static/ 访问)
+│   ├── css/                # bootstrap.min.css、bootstrap-icons
+│   ├── js/                 # bootstrap.bundle.min.js、d3.min.js
+│   ├── fonts/              # 水印字体、首页定制字体
+│   └── images/home/        # 首页设计切图
+├── uploads/                # 本地上传临时目录(gitignore,启动时自动创建)
+│
+├── migrate_*.py            # 一次性数据库迁移脚本
+├── update_*.py / db_update.py
+├── add_*.py                # 字段增补、超级管理员等
+├── check_*.py              # 数据库/数据检查脚本
+├── clean_*.py              # 疑似错误数据清理
+├── fill_missing_fields.py  # 从族谱原文批量补全字辈、曾用名等
+└── test_*.py               # API / AI 测试脚本
+```
+
+> **架构说明:** 业务逻辑高度集中在 `app.py`,无模块化分包。接手后建议用 `grep "@app.route"` 快速定位路由。
+
+---
+
+## 三、快速启动
 
 ### 1. 安装依赖
 
 ```bash
 pip install -r requirements.txt
-```
-
-*注意:OCR 功能需要系统安装 `tesseract-ocr` 引擎。*
+pip install pymupdf cryptography
 
-### 2. 初始化数据库
+# macOS 安装 Tesseract(页码 OCR)
+brew install tesseract tesseract-lang
+```
 
-运行初始化脚本以创建必要的表并添加默认管理员账号:
+### 2. 数据库初始化(首次部署)
 
 ```bash
 python3 init_db.py
 ```
 
-- 默认账号:`admin`
-- 默认密码:`admin123`
+会创建 `genealogy_records` 表,并添加测试账号 `genealogy_admin` / `admin123`。  
+**注意:** 核心业务表(`users`、`family_member_info`、`family_relation_info` 等)在 RDS 中已存在,本脚本不会重建。
 
-### 3. 运行应用
+### 3. 启动服务
 
 ```bash
 python3 app.py
+# 监听 0.0.0.0:5001,debug=False
+```
+
+### 4. 服务器部署
+
+```bash
+git pull
+ls static/images/home/    # 确认首页切图存在
+ls static/fonts/home/     # 确认字体存在
+# 重启应用进程(gunicorn / systemd 等,以实际部署方式为准)
+```
+
+静态资源通过 `/manager/static/` 访问。`app.py` 使用**绝对路径**加载 `static/` 目录,避免工作目录不同导致资源 404。
+
+---
+
+## 四、配置说明
+
+当前**未使用环境变量**,配置硬编码在源码中(交接后建议迁移到 `.env`):
+
+| 配置项 | 位置 | 说明 |
+|--------|------|------|
+| 数据库连接 | `app.py` → `DB_CONFIG` | 主机、账号、库名 `csqz-client` |
+| Flask Session 密钥 | `app.py` → `app.secret_key` | 当前为固定字符串 |
+| 微信小程序 | `app.py` → `WECHAT_APP_ID/SECRET` | 小程序登录 |
+| 豆包 AI API Key | `app.py` 内 `call_doubao_*` 函数 | Bearer Token |
+| OSS 上传地址 | `oss_utils.py` | `POST https://crmapi.dcjxb.yunzhixue.cn/file/upload` |
+
+> ⚠️ `init_db.py` 中数据库主机名与 `app.py` 略有差异(`...u2.mysql` vs `...u2wo.mysql`),以 `app.py` 的 `DB_CONFIG` 为准。
+
+---
+
+## 五、功能模块与路由
+
+所有后台路由前缀为 **`/manager/`**,共约 72 个路由。
+
+### 5.1 登录与首页
+
+| 路由 | 说明 |
+|------|------|
+| `GET/POST /manager/login` | 用户登录(`users` 表,明文密码比对) |
+| `GET /manager/logout` | 退出 |
+| `GET /manager/home` | 系统首页(统计数据 + 快速导航) |
+
+### 5.2 扫描件管理(`genealogy_records`)
+
+| 路由 | 说明 |
+|------|------|
+| `GET /manager/` | 扫描件列表(支持版本、来源、上传人筛选) |
+| `GET/POST /manager/upload` | 多文件上传(图片/PDF),后台线程压缩 → OSS → AI 识别 |
+| `POST /manager/save_upload` | 手动保存扫描记录 |
+| `POST /manager/delete_upload/<id>` | 删除扫描记录 |
+| `POST /manager/api/start_analysis/<id>` | 单条触发 AI 识别 |
+| `GET /manager/batch_ai_parse` | 批量 AI 识别(`ai_status=0` 的记录,5 线程并发) |
+| `GET /manager/image/wm` | 带水印的图片代理(需登录) |
+
+**AI 状态码(`ai_status`):** 0=未开始,1=处理中,2=成功,3=失败
+
+### 5.3 家谱 PDF 管理(超级管理员)
+
+| 路由 | 说明 |
+|------|------|
+| `GET /manager/pdf_management` | PDF 列表与预览 |
+| `GET/POST /manager/upload_pdf` | 上传 PDF(含版本元数据) |
+| `POST /manager/parse_pdf/<id>` | 拆分 PDF 为单页 PNG → OSS → 写入扫描记录 |
+| `POST /manager/delete_pdf/<id>` | 删除 PDF |
+
+### 5.4 成员管理(`family_member_info`)
+
+| 路由 | 说明 |
+|------|------|
+| `GET /manager/members` | 成员列表(支持姓名/字辈搜索) |
+| `GET/POST /manager/add_member` | 新增成员(支持关系、佐证材料、AI 预填) |
+| `GET/POST /manager/edit_member/<id>` | 编辑成员 |
+| `GET /manager/member_detail/<id>` | 成员详情 |
+| `POST /manager/delete_member/<id>` | 删除成员 |
+| `GET /manager/suspected_errors` | 疑似错误汇总 |
+| `GET /manager/api/check_name` | 重名检查 |
+
+### 5.5 批量族谱原文生成
+
+| 路由 | 说明 |
+|------|------|
+| `GET /manager/batch_genealogy` | 批量处理界面 |
+| `GET /manager/api/members/empty_genealogy` | 获取缺族谱原文的成员 |
+| `POST /manager/api/members/batch_process_genealogy` | 同步批量生成 |
+| `POST /manager/api/members/batch_process_genealogy_async` | 异步批量任务 |
+| `GET /manager/api/members/batch_task_status/<task_id>` | 查询任务进度 |
+
+### 5.6 世系树与查询
+
+| 路由 | 说明 |
+|------|------|
+| `GET /manager/tree` | 交互式世系树(D3.js) |
+| `GET /manager/tree_gen` | 世代分层树 |
+| `GET /manager/tree_classic` | 传统吊线图导出 |
+| `GET /manager/lineage_query` | 世系查询 |
+| `GET /manager/api/tree_data` | 全量成员 + 关系 JSON |
+| `POST /manager/api/search_member` | 树节点搜索 |
+| `GET /manager/api/get_lineage/<id>` | 获取某成员完整世系 |
+
+### 5.7 聚落地图(`family_settlements`)
+
+| 路由 | 说明 |
+|------|------|
+| `GET /manager/settlements` | 聚落地图界面 |
+| `GET/POST /manager/api/settlements` | 列表 / 新增 |
+| `GET/PUT/DELETE /manager/api/settlements/<id>` | 查看 / 修改 / 删除(写操作需超级管理员) |
+
+### 5.8 数据质量
+
+| 路由 | 说明 |
+|------|------|
+| `GET /manager/generation_check` | 代数连续性核查页面 |
+| `GET /manager/api/generation_check` | 核查 API(父子代数是否连续) |
+
+### 5.9 微信小程序 API
+
+**正式接口(`mp_users` 表 + Bearer Token):**
+
+| 路由 | 说明 |
+|------|------|
+| `POST /manager/api/wechat/login` | 微信登录,返回 token |
+| `GET /manager/api/members/search` | 成员搜索 |
+| `POST /manager/api/members/add` | 新增成员 |
+| `GET /manager/api/members/my` | 当前用户绑定成员 |
+| `GET /manager/api/lineage/<id>` | 世系查询 |
+
+**Mock 接口(开发用,`family_member_bind` 表 + `X-MP-Openid` 头):**
+
+| 路由 | 说明 |
+|------|------|
+| `POST /manager/api/mp/wx/auth/login` | 模拟登录 |
+| `GET /manager/api/mp/wx/family/member/selfCard` | 绑定成员卡片 |
+| `POST /manager/api/mp/wx/family/member/bind` | 绑定 openid → 成员 |
+
+---
+
+## 六、数据库核心表
+
+数据库:`csqz-client`(阿里云 RDS MySQL)
+
+| 表名 | 用途 |
+|------|------|
+| `users` | 后台管理员账号(`is_super_admin=1` 为超级管理员) |
+| `family_member_info` | 家族成员主表(姓名、字辈、生卒、联系方式、族谱原文等) |
+| `family_relation_info` | 成员关系(父子/母子/夫妻/兄弟姐妹,`sub_relation_type` 区分亲生/养父母) |
+| `genealogy_records` | 扫描件记录(OSS 地址、页码、AI 识别结果 `ai_content`) |
+| `genealogy_pdfs` | PDF 源文件及拆页状态 |
+| `family_settlements` | 聚落地理信息(经纬度、代表人) |
+| `batch_genealogy_task` | 异步批量族谱原文生成任务 |
+| `mp_users` | 微信小程序用户(openid、token) |
+| `family_member_bind` | 小程序用户与成员绑定(Mock API) |
+
+**关系类型(`relation_type`):** 1=父子,2=母子,10=夫妻,11=兄弟,12=姐妹  
+**子关系类型(`sub_relation_type`):** 0=正常,2=生父母,3=养父母/入继
+
+应用启动时会自动执行部分内联迁移(`child_order`、`reference_*` 字段、`batch_genealogy_task` 表等),日志前缀 `[DB Migrate]`。
+
+---
+
+## 七、权限模型
+
+### 后台登录(Flask Session)
+
+- 登录后 session 写入:`user_id`、`username`、`is_super_admin`
+- 大部分页面检查 `user_id`,未登录跳转 `/manager/login`
+- **超级管理员**(`is_super_admin=1`)额外权限:家谱 PDF 管理、聚落增删改
+- 密码当前为 `users.password` 字段**明文比对**(未做哈希)
+
+### 图片水印
+
+- 登录用户浏览 OSS 图片时,通过 `/manager/image/wm?u=<编码后的OSS地址>` 代理
+- 图片叠加用户名 + 时间戳水印,防止未授权传播
+- 水印缓存目录:`/tmp/wm_cache/`(7 天 TTL)
+
+---
+
+## 八、页面模板说明
+
+| 模板 | 说明 | 基模板 |
+|------|------|--------|
+| `home.html` | 系统首页(定制 UI,设计稿还原) | 独立页面 |
+| `layout.html` | 侧边栏导航基模板 | — |
+| `login.html` | 登录页 | 独立 |
+| `index.html` | 扫描件列表 | layout |
+| `upload.html` | 扫描件上传 | layout |
+| `upload_pdf.html` | PDF 上传 | layout |
+| `pdf_management.html` | 家谱 PDF 管理 | layout |
+| `members.html` | 成员列表 | layout |
+| `add_member.html` | 新增/编辑成员(左右分栏:表单 + 扫描件) | layout |
+| `member_detail.html` | 成员详情 | layout |
+| `batch_genealogy.html` | 批量族谱原文处理 | layout |
+| `suspected_errors.html` | 疑似错误汇总 | layout |
+| `tree.html` | 交互式世系树 | layout |
+| `tree_gen.html` | 世代分层树 | layout |
+| `tree_classic.html` | 传统吊线图 | 独立(CDN Bootstrap) |
+| `lineage_query.html` | 世系查询 | layout |
+| `settlements.html` | 聚落地图 | layout |
+| `generation_check.html` | 代数核查 | layout |
+
+---
+
+## 九、核心业务流程
+
+### 流程 A:扫描件 → AI 识别 → 录入成员
+
+```
+上传图片 → 压缩 → OSS → 写入 genealogy_records(ai_status=1)
+    → 后台 AI 线程识别人名 → ai_content JSON(ai_status=2)
+    → 管理员在扫描件列表点击「录入」→ add_member 页面预填
+    → 保存成员 → 标记 AI 结果中该人为已导入
 ```
 
-访问 `http://127.0.0.1:5001` 即可开始使用。
+### 流程 B:PDF 批量导入
+
+```
+超级管理员上传 PDF → genealogy_pdfs
+    → 点击「拆页」→ 每页转 PNG → OSS → genealogy_records
+    → 可选:/manager/batch_ai_parse 批量 AI 识别
+```
+
+### 流程 C:成员维护
+
+```
+成员列表搜索 → 新增/编辑(支持多关系:父/母/配偶/兄弟姐妹)
+    → 年龄校验(子女出生日期须晚于父母)
+    → 可上传佐证材料到 OSS
+    → suspected_error 字段标记数据疑点 → 疑似错误汇总页审核
+```
+
+### 流程 D:批量族谱原文
+
+```
+batch_genealogy 页面 → 列出缺族谱原文的成员
+    → AI 根据成员信息 + 关系生成繁/简族谱原文
+    → 异步任务记录在 batch_genealogy_task 表
+```
+
+---
+
+## 十、运维脚本
+
+| 脚本 | 用途 |
+|------|------|
+| `check_schema.py` / `check_columns.py` | 检查表结构 |
+| `check_suspected_errors.py` | 检查疑似错误数据 |
+| `clean_suspected_errors.py` | 清理空疑似错误 |
+| `fill_missing_fields.py` | 从族谱原文推断字辈、曾用名、乳名 |
+| `add_super_admin.py` | 设置超级管理员 |
+| `migrate_ai_fields.py` | AI 相关字段迁移 |
+| `migrate_reference_document.py` | 佐证材料字段迁移 |
+
+---
+
+## 十一、交接注意事项
 
-## 数据库配置
+1. **单体架构:** 几乎所有逻辑在 `app.py`,修改前先 `grep` 定位,避免误改。
+2. **两套微信 API:** 正式(Bearer Token + `mp_users`)和 Mock(`X-MP-Openid` + `family_member_bind`),不要混用。
+3. **密码安全:** 后台登录为明文密码比对,生产环境建议改为哈希并轮换密钥。
+4. **密钥管理:** 数据库密码、AI Key、微信 Secret 均在源码中,交接后应迁移至环境变量。
+5. **静态资源:** 首页切图在 `static/images/home/`,字体在 `static/fonts/home/`,部署后确认文件存在且可通过 `/manager/static/images/home/logo.png` 访问。
+6. **内联迁移:** 应用启动时自动 ALTER TABLE,关注启动日志中的 `[DB Migrate]` 输出。
+7. **入继关系:** `sub_relation_type=3` 的养父母关系在世系树中有独立展示逻辑(血系/继系切换)。
+8. **设计切图源文件:** 首页 UI 切图原始文件在本地路径 `春笋团队管理/族谱项目/psd/网站/`,工程内已复制到 `static/images/home/`。
 
-- 主机: `rm-f8ze60yirdj8786u2wo.mysql.rds.aliyuncs.com`
-- 用户: `root`
-- 数据库: `csqz-client`
+---
 
-## 接口说明
+## 十二、外部服务依赖
 
-- OSS 上传接口:`POST https://crmapi.dcjxb.yunzhixue.cn/file/upload`
-- 参数:`file` (form-data)
+| 服务 | 地址 | 用途 |
+|------|------|------|
+| OSS 上传 | `https://crmapi.dcjxb.yunzhixue.cn/file/upload` | 文件存储 |
+| OSS CDN | `file.chunsunqiuzhu.com` | 图片访问域名 |
+| 豆包 AI | `https://ark.cn-beijing.volces.com/api/v3/responses` | 扫描识别、族谱原文生成 |
+| 微信 API | `api.weixin.qq.com` | 小程序登录、手机号 |
+| MySQL | 阿里云 RDS | 数据持久化 |
 
-## AI能力
+---
 
-- 模型:`doubao-seed-1-8-251228`
-- 接口地址:`https://ark.cn-beijing.volces.com/api/v3/responses`
+*最后更新:2026-07-07*