Commit Graph

39 Commits

Author SHA1 Message Date
v6ole c71a2ac88e perf: Vite 分包优化 — Element Plus / Vue 独立 chunk
build.rollupOptions.manualChunks:
- element-plus → ~923 kB (独立缓存,首次加载后 HIT)
- vue-vendor → ~110 kB (Vue + Router + Pinia)
- index (app code) → ~59 kB (从 ~1 MB 缩减)

首屏加载显著减少,二次访问几乎零加载。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 15:40:07 +08:00
v6ole 861a4cecff feat: 客户查重前端集成
- 新建客户时输入名称失焦后自动调用 /customers/check-duplicate
- 若有同名客户显示黄色警告条(含客户名+经理)
- 编辑模式不触发查重

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 15:37:44 +08:00
v6ole c4e8a3b790 feat: 富消息升级 — 催办用模板卡片 + 公告用 Markdown
scheduler.py:
- 未填报经理 → 模板卡片消息(标题+描述+「去填报」按钮)
- 支局长/领导 → Markdown 每日填报汇总(markdown)
- 文本消息作为降级方案

wecom.py API:
- remind: 模板卡片优先 → 降级文本
- announcement: Markdown 优先 → 降级文本

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 15:34:21 +08:00
v6ole 327637f94c feat: 移动端/桌面端自动适配
- utils/index.ts: 新增 isMobile() 检测 user-agent
- router: beforeEach 守卫中根据设备自动跳转
  - 手机访问 / 桌面路由 → 自动跳 /m
  - 桌面访问 /m 移动路由 → 自动跳 /

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 15:33:09 +08:00
v6ole ab3384d6a5 chore: 企微绑定流程收尾 — 回调日志 + 调试完成
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 15:24:33 +08:00
v6ole 313b25c631 fix: WecomBind.vue — 修复 auth.user 不存在的问题
auth store 暴露的是独立字段 (name/userId/role) 而非 user 对象,
导致 auth.user?.name 始终为 undefined。

修复:
- auth.name 替代 auth.user?.name
- 调用 /users/me 获取 wecom_userid (store 不存储该字段)
- window.location.href 替代 router.push (企微浏览器兼容)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 15:18:36 +08:00
v6ole 9d3a8ae57e fix: 绑定页用 window.location 跳转登录 (企微浏览器兼容)
router.push 在企微内置浏览器可能不触发跳转,
改用 window.location.href 强制整页跳转

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 15:09:31 +08:00
v6ole 19ebb85209 fix: 绑定页面登录态检查 + 登录后返回原页面
Login.vue:
- goCasdoorLogin() 前将 redirect 参数存入 sessionStorage
- 登录成功后检查 sessionStorage 跳回原页面
- wecomLogin 流程同样支持 returnUrl

WecomBind.vue:
- onMounted 检测未登录 → 跳转 /login?redirect=/wecom-bind?token=xxx
- 登录后自动回到绑定页面,auth.user 不再为空

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 13:14:26 +08:00
v6ole 7264184315 feat: 企微绑定重构 — 回调事件 + 支局长手动绑定/解绑
绑定流程改为 rural-optical-rectify 方案:
- 企微菜单「绑定账号」发送 click 事件(而非 OAuth 跳转)
- 回调 POST 接收事件 → 生成绑定 token → 推送绑定链接
- 前端 WecomBind.vue (/wecom-bind) 确认绑定
- 新增 POST /api/wecom/bind-confirm (JWT 保护)

支局长手动管理:
- 新增 PUT /api/users/{id}/wecom 绑定/解绑端点
- UserManage.vue 编辑对话框新增企微 UserID 字段
- 表格操作列新增「解绑」按钮
- 重复绑定检测

wecom.py 新增:
- in-memory bind token store (TTL 600s)
- send_text_card() 卡片消息方法
- access_token 属性暴露

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 12:10:38 +08:00
v6ole 1d2dacc3ab feat: 企微 API 代理 + 菜单部署修复
config.py:
- 新增 WECOM_API_BASE 环境变量 (默认 https://qyapi.weixin.qq.com)

wecom.py:
- 所有 API 调用改用 settings.WECOM_API_BASE (支持代理)
- 修复 _post_with_retry URL 拼接 bug (? vs &)
- 菜单名去掉 emoji (企微限制 16 字符)

api/wecom.py:
- setup-menu 端点菜单名修正

.env.example:
- 新增 WECOM_API_BASE 说明

当前 .env 配置: WECOM_API_BASE=https://api.v6ole.top
已验证: 通过代理获取 token , 菜单创建 

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 11:58:12 +08:00
v6ole da1f24c710 feat: 企微菜单管理 — create_menu / get_menu / delete_menu
wecom.py 新增:
- create_menu(buttons) — 创建/替换应用自定义菜单
- get_menu() — 获取当前菜单配置
- delete_menu() — 删除菜单

API 新增:
- POST /api/wecom/setup-menu — 一键部署标准菜单(开始填报 + 绑定账号)
- GET /api/wecom/menu — 查看当前菜单

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 11:36:16 +08:00
v6ole 5006642354 feat: 企微绑定入口 — BindWechat.vue + 路由
新增 /bind-wechat 公开路由:
- 页面加载后自动重定向到企微 OAuth 授权页
- scope=snsapi_base (静默授权,无需用户确认)
- 回调到 /login?wecom_code=xxx → 自动绑定

用法: 企微工作台应用主页设为 https://qj.dhdx.fun/bind-wechat

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 11:30:06 +08:00
v6ole ad0c894f93 feat: 企微测试消息端点 + 调度器 msgfmt 优化
- 新增 POST /api/wecom/test-message 测试端点(需 director)
- 调度器仅推已绑定 wecom_userid 的经理
- wecom.py 已支持 markdown/模板卡片消息

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 09:49:33 +08:00
v6ole eae7fdafb8 fix: 企微回调验证 — 返回纯文本而非 JSON
企微后台保存时要求响应为原始解密明文(Content-Type: text/plain),
FastAPI 默认 JSON 序列化会加引号导致验证失败。
改用 PlainTextResponse 返回纯文本。

验证: 本地 + 生产域名均返回 text/plain, 解密内容正确

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 09:46:19 +08:00
v6ole 36ba9338f1 feat: 企业微信 Phase 1 — token 续期 + 回调验证 + 调度器注册
wecom.py:
- Token 自动续期 (7200s 过期 + 60s 提前量 + 42001 重试)
- POST 请求自动重试 (最多 3 次,含速率限制退避)
- 新增 send_markdown_message() / send_template_card() 富消息方法

wecom.py API:
- GET /api/wecom/callback: 企微回调 URL 验证 (SHA1 签名 + AES 解密)
- POST /api/wecom/callback: 事件接收占位

scheduler.py:
- 仅推送给已绑定 wecom_userid 的经理
- 消息内容优化 (已填报/未填报人数统计)

main.py:
- APScheduler 注册每日 17:30 自动检查填报

已验证: WECOM_TOKEN 获取成功

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 09:37:13 +08:00
v6ole 72fb7524f3 docs: CLAUDE.md — 更新部署架构 + 工作页客户经理列
- 新增完成项: 工作页客户经理列+汇总栏, 云端部署
- 新增部署架构章节 (FRP 隧道/前端容器/OpenResty/端口表)
- 新增设计决策 #22 (云端部署)
- 更新验证状态表 (生产 URL/FRP/容器)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 09:21:41 +08:00
v6ole e71fa6e3ed chore: 生产部署适配 — nginx.conf 精简 + .gitignore 更新
- nginx.conf: 移除 /api/ 代理(改由 OpenResty 边缘路由),仅保留 SPA fallback
- .gitignore: 排除所有 .env.* (保留 .env.example),防止 .env.production 误提交

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 09:02:46 +08:00
v6ole c2a62c29cd feat: 工作计划/商机/要客页面新增客户经理列与汇总栏
- 表格新增「客户经理」列,暖灰色哈希标签,每人唯一颜色
- 页面顶部新增汇总栏,按经理分组显示各有多少条记录
- 汇总栏仅在有数据时显示,与亮灯表配色体系一致

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 08:30:19 +08:00
v6ole b3d355179f chore: 部署文档不纳入版本管理
- 从 git 移除 qiji部署交接文档.md 和 通用部署文档.md
- 更新 .gitignore 忽略所有 *部署文档.md/*部署交接文档.md
- 部署文档含敏感信息(服务器IP/端口/密码),应本地保存

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 08:30:06 +08:00
v6ole 8867e2f5fe docs: 通用部署文档 — FRP + OpenResty + Docker 平台化部署模板
包含:
- 完整端口规划表 (基础设施/项目后端/项目前端 三区间)
- 当前端口占用清单 (所有已用端口一目了然)
- 本机端口分配方案 (8000/8002/8004...)
- 新项目 7 步部署流程 (端口分配→FRP→后端→前端→OpenResty→DNS→验证)
- 前端 Dockerfile + nginx.conf 模板
- 日常运维速查 (FRP/容器/OpenResty/后端)
- 故障排查表
- 已有项目索引

特点:所有项目特定值均用 {PLACEHOLDER} 标记,复制即用

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 08:29:05 +08:00
v6ole 4ae8c69193 docs: qiji 部署交接文档 — FRP + OpenResty + Docker 部署方案
基于 H3ConuMS2 部署模式,适配 qiji 项目:
- 新增 qiji-backend FRP 隧道 (8002→18061)
- 前端容器化部署 (qiji-frontend:18063)
- OpenResty 站点配置 (qj.dhdx.fun)
- 复用已有 Casdoor / PostgreSQL / MinIO
- 含部署检查清单和故障排查指南
- 所有敏感凭据已替换为占位符

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 08:27:31 +08:00
v6ole ce94c6b2ba refine: 缓存的 AI 摘要默认折叠,点击展开
- aiExpanded ref: 缓存加载=false, 新生成=true
- 标题栏可点击切换折叠/展开
- 折叠态显示 ▶ + '点击展开' 提示
- 展开态显示 ▼ + 复制按钮
- 卡片边框折叠时降为 warm-border
2026-06-25 12:05:33 +08:00
v6ole 5b38246801 feat: AI 摘要持久化 — DB 缓存 + 自动加载
后端:
- 新增 ai_summaries 表 (week_start/week_end/generated_by/summary)
- get_cached_summary(): 按周+用户查缓存
- delete_cached_summary(): 生成前清理旧缓存
- generate_summary(): 自动保存到 DB
- API: GET /ai/summary(加载) POST(生成) DELETE(清除)

前端:
- onMounted 自动 GET 缓存摘要, 有则直接展示
- 按钮: 无缓存→'AI 生成摘要', 有缓存→'重新生成'
- 标题栏显示生成时间戳
2026-06-25 11:45:04 +08:00
v6ole e681beba24 chore: 更新 CLAUDE.md — 亮灯表+AI摘要 v0.2
- 亮灯表: 几何圆形图标、权限控制、周报联动
- AI 摘要: DeepSeek V4 配置、亮灯表数据注入、复制兼容
- 新增关键设计决策 #20 #21
2026-06-24 19:45:04 +08:00
v6ole 5b50e7ec27 fix: AI 摘要复制失败 — HTTP 环境 Clipboard API 不可用
navigator.clipboard 需要安全上下文(HTTPS/localhost),
内网 HTTP 部署时自动降级为 textarea + execCommand('copy')
2026-06-24 19:39:28 +08:00
v6ole 24c7aff093 fix: 恢复 AI_MODEL 为 deepseek-v4-flash
DeepSeek API 当前模型:
- deepseek-v4-flash / deepseek-v4-pro (2026-04-24 发布)
- deepseek-chat / deepseek-reasoner 是旧别名, 2026-07-24 废弃

.env.example 同步添加 DeepSeek 配置注释
2026-06-24 19:33:06 +08:00
v6ole d07311d5a5 fix: AI 摘要 DeepSeek 配置修复
1. generate_summary 调用 get_light_board 补传 user_id/role
   (否则亮灯表数据为空, 摘要缺少覆盖分析)
2. AI_API_URL: /anthropic → /v1/chat/completions
   (原先 URL 不是 DeepSeek 标准 OpenAI 兼容端点)
3. AI_MODEL: deepseek-v4-flash → deepseek-chat
   (原模型名不是已知的 DeepSeek 模型)
2026-06-24 19:19:57 +08:00
v6ole dd69e902ec feat: 亮灯表点击客户 → 周报自动按客户筛选
- WeeklyReport onMounted 新增 customer_id 路由参数处理
- 筛选栏新增「按客户筛选」下拉框(filterable搜索)
- 加载客户列表供下拉选项
2026-06-24 19:07:28 +08:00
v6ole 1d0f412e4a fix: 亮灯表权限控制 — 客户经理只看自己
get_light_board 新增 user_id/role 参数:
- director/leader: 看全部经理 + 未分配客户
- manager: 只看自己, 不显示未分配客户
- API 层从 current_user 提取身份信息透传
2026-06-24 17:22:05 +08:00
v6ole a8ed71fbff refine: 亮灯表视觉优化
- 用几何圆形图标代替文字'亮/临/灭':
  ● 实心圆(已拜访) / ◐ 半圆(临期) / ○ 空心圆(未拜访) / ◌ 虚线圆(未分配)
- 客户名称全量显示, 允许换行, card 拓宽至 220px
- 仪表盘标签从 '🟢 亮灯' 改为 '已拜访/临期/未拜访/未分配'
2026-06-24 16:07:15 +08:00
v6ole 305ee5df09 feat: 客户亮灯表 + AI 周报摘要 — v0.2
亮灯表:
- 四色覆盖矩阵: 绿亮灯/黄临期/红灭灯/灰未分配
- 按客户经理折叠卡片流, 覆盖率进度条, 团队总览统计
- 红灯客户显示连续未拜访月份, 未分配客户专区
- 后端: light_board.py service + GET /api/dashboard/light-board
- 前端: LightBoard.vue + 路由 /light-board + 汇总侧边栏

AI 周报摘要:
- 接入 OpenAI 兼容大模型, 注入拜访数据+亮灯表覆盖数据
- 四段式结构化输出: 概况/需求/覆盖分析/建议
- 一键生成+Markdown渲染+复制纯文本
- 支局长/分管领导专用, 支持配置内部模型
- 后端: ai_summary.py service + POST /api/ai/summary
- 前端: WeeklyReport 集成按钮+结果面板
- 新增配置: AI_API_URL / AI_API_KEY / AI_MODEL

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-24 12:03:00 +08:00
v6ole b79a5296c4 chore: 添加 README.md,.gitignore 忽略 CLAUDE.md 和 .claude/
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-24 08:56:17 +08:00
v6ole d52725990d chore: 完善 .gitignore,忽略 node_modules 等 2026-06-24 08:54:12 +08:00
v6ole bf67e0575f feat: 信息架构重组 + 变更追踪 + 图片预览增强
- 信息架构重组: 周报精简为拜访+纪要两个Tab,工作计划/商机/要客独立为侧边栏「工作」分组下的独立页面
- 侧边栏分组: 汇总/工作/管理三层分组,仪表盘四卡可点击跳转
- 变更追踪(edit_log): 5张表新增JSONB edit_log列,POST创建/PUT diff自动记录,编辑弹窗变更时间轴,表格🕐编辑标记
- 图片预览增强: ImagePreview统一组件,支持适应页面/缩放/拖拽平移/滚轮缩放/键盘快捷键
- 修复客户导入500错误(errors变量未初始化)
- 移除工作计划/商机/要客页面冗余编辑按钮

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-24 08:30:12 +08:00
v6ole aa3fbca710 feat: 历史周报+图片预览+照片管理+导入优化+用户合并
新增:
- 历史周报: Dashboard/周报详情支持周选择器翻看往周,归档只读
- 图片预览: 全屏大图(移动端+PC端),点击遮罩关闭
- PC端照片管理: 编辑时可上传/删除照片
- 客户导入改为更新模式: 重名自动更新信息,显示操作明细
- 导入跳过原因: 旧周报导入也显示每条跳过原因

优化:
- 填报进度权限: 经理只看到自己,支局长/领导看全员
- 客户经理暖灰色hash标签列
- 用户去重合并(4组),数据完整迁移
- CLAUDE.md 更新到最新状态

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-24 08:30:12 +08:00
v6ole 8926475b20 docs: 更新 CLAUDE.md — 9张表+新增功能+设计决策 2026-06-24 08:30:12 +08:00
v6ole e7af0e15ab feat: 完整功能迭代 — 移动端+PC端全面优化
新增:
- 今日纪要 (6分类+彩色标签+时间选择器)
- 客户经理PC端工作台 (我的数据,5模块CRUD)
- 用户管理页 (支局长修改角色)
- 客户备注/收支费用(金额+单位)/联系人管理
- 拜访人姓名+电话字段
- 客户导入导出/旧周报导入模板下载
- 序号列+分页(25/50/100)

修复/优化:
- Hash路由→HTML5 History, Casdoor回调正常
- 时区统一为Asia/Shanghai (today_cst)
- 数据库懒加载→selectinload预加载
- 日期解析兼容ISO datetime字符串
- 文件上传定位修复 (position:relative)
- 表单button type='button'防止误提交
- 分管领导权限(只读客户档案,不可编辑)
- 侧边栏折叠+SVG图标
- 拜访方式/紧急度统一chip风格
- 时间范围统一为el-time-picker(is-range)
- 全局CSS设计变量+box-sizing修复滚动条

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-24 08:30:12 +08:00
v6ole a1886074dd 企迹(qiji) 政企周报管理系统 — v0.1
后端: FastAPI + SQLAlchemy 2.0 (async) + Alembic + MinIO + Casdoor + 企微
前端: Vue 3 + Vite + TypeScript + Element Plus + Pinia

功能清单:
- 8 张数据表自动建表 / Casdoor OIDC 登录 / 企微静默登录
- 双布局: 移动端(填报) + PC端(汇总管理)
- 拜访记录 CRUD + MinIO 照片直传 + 缩略图预览 + 同访人草稿
- 今日纪要 (6 分类) / 工作计划 / 小微商机 / 要客拜访 CRUD
- 客户档案: 备注/收支费用/联系人/归属分配/批量转移
- 客户导入导出 + 模板下载 + 搜索/分页/筛选
- 仪表盘: 四卡统计 + 填报进度 (拜访+纪要双维度)
- 周报详情: 五 Tab + 按人/客户筛选 + 时间轴
- 用户管理 / 客户经理 PC 端工作台
- 企微: 催办/公告/定时提醒 / 时区修正
- Docker 部署配置

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-24 08:30:12 +08:00
v6ole 2a8225c31f Initial commit 2026-06-23 11:47:54 +08:00