feat: 历史周报+图片预览+照片管理+导入优化+用户合并

新增:
- 历史周报: Dashboard/周报详情支持周选择器翻看往周,归档只读
- 图片预览: 全屏大图(移动端+PC端),点击遮罩关闭
- PC端照片管理: 编辑时可上传/删除照片
- 客户导入改为更新模式: 重名自动更新信息,显示操作明细
- 导入跳过原因: 旧周报导入也显示每条跳过原因

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-06-23 16:59:31 +08:00
parent 8926475b20
commit aa3fbca710
15 changed files with 323 additions and 74 deletions
+3 -1
View File
@@ -15,7 +15,7 @@ from app.models.user import User
async def import_from_excel(db: AsyncSession, file_bytes: bytes, manager_id: uuid.UUID) -> dict:
"""Parse old weekly report Excel and import data. Returns summary stats."""
wb = openpyxl.load_workbook(io.BytesIO(file_bytes), data_only=True)
stats = {"visits": 0, "work_plans": 0, "mini_business": 0, "key_visits": 0, "skipped": 0}
stats = {"visits": 0, "work_plans": 0, "mini_business": 0, "key_visits": 0, "skipped": 0, "skip_reasons": []}
# Resolve customer name -> id cache
customers_result = await db.execute(select(Customer.id, Customer.name))
@@ -38,6 +38,7 @@ async def import_from_excel(db: AsyncSession, file_bytes: bytes, manager_id: uui
customer_id = customer_map.get(cust_name)
if not customer_id:
stats["skipped"] += 1
stats["skip_reasons"].append(f"客户「{cust_name}」不存在,跳过")
continue
try:
@@ -54,6 +55,7 @@ async def import_from_excel(db: AsyncSession, file_bytes: bytes, manager_id: uui
)
if existing.scalar_one_or_none():
stats["skipped"] += 1
stats["skip_reasons"].append(f"重复:{cust_name} {visit_date} 已存在")
continue
visit = Visit(