Files
opc-manager/backend/migrations/data_fixes.py
mac c0fb382d78 feat: 大版本更新-工作台改版+总报完善+UI优化
工作台改版:
- 学会→学术, 总工作台→总览(数据库迁移+session清理)
- 侧边栏工作台从下拉菜单改为竖向平铺+独立图标
- 5个工作台去除部门模块, 只有总览显示
- 工作台顺序: 总览→学术→MCN→科普→医患→科研

经营月报+季度月报:
- 月度/季度总览改名(月度总览→经营月报, 季度总览→季度月报)
- 财务概览增加回款/项目现金流行(7行)
- 新增业务线经营情况卡片(毛利/平台费用/利润)
- 新增业务线现金流卡片(项目现金流/平台费用已付/业务线现金流)
- 季度月报完善为三卡片结构, 与经营月报一致
- 计划模块总览独立数据源(computePlanMonthly)

UI优化:
- 汇总卡片单行显示+5x2网格+去外层卡片
- 项目表格行高压缩(py-px+line-height:0.95)
- 表头不压缩, 只压缩tbody
- 加权/项目类型内联下拉去原生箭头+自定义箭头
- 加权/项目类型表头去除排序箭头
- 实际模块已付→支出, 已回款→回款, 成本→成本(不含平台费用)
- 现金流注释(回款-支出)
- 卡片间距/筛选区/tip高度压缩
- 实际模块增加执行提示tip

修复:
- routes.py planFinances client_name列去重
- plan_expense.js savePlanExpense改用api()+load()
- plan.js createPlanFinance拆分try-catch
- 版本号 v1.0.0.35
2026-07-08 20:39:44 +08:00

160 lines
5.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""migrations/data_fixes.py — 数据修正迁移(修复脏数据、变更枚举值)"""
def migrate_fix_task_status():
"""修正 project_tasks 中非法的 status 值"""
from db import db, _exec, mysql, logger
conn = db()
try:
fixes = [
"UPDATE project_tasks SET status='未开始' WHERE status='' OR status IS NULL",
"UPDATE project_tasks SET status='已结束' WHERE status='done'",
"UPDATE project_tasks SET status='进行中' WHERE status='验收中'",
]
for sql in fixes:
try:
cur = _exec(conn, sql)
affected = cur.rowcount
cur.close()
if affected:
print(f"[migrate] 修正 {affected} 条任务状态")
except mysql.connector.Error as e:
logger.warning(f"task status fix skipped: {e}")
conn.commit()
finally:
conn.close()
def migrate_rename_tenant():
"""工作台重命名:无界·无界 → 学会·无界"""
from db import db, _exec, mysql
conn = db()
try:
tables = ["user_tenants", "sales_leads", "follow_up_records", "business_proposals",
"operation_projects", "product_versions", "finance_records", "project_tasks",
"project_finances"]
for table in tables:
try:
cur = _exec(conn, f"UPDATE {table} SET tenant='学会·无界' WHERE tenant='无界·无界'")
affected = cur.rowcount
cur.close()
if affected:
print(f"[migrate] {table}: {affected} 条记录 tenant 改为 '学会·无界'")
except mysql.connector.Error:
pass
conn.commit()
finally:
conn.close()
def migrate_drop_product_fields():
"""删除 product_versions 表的 owner / platform / feature_list 字段"""
from db import db, mysql
conn = db()
try:
for col in ["owner", "platform", "feature_list"]:
cur = conn.cursor(dictionary=True)
cur.execute("SHOW COLUMNS FROM product_versions LIKE %s", (col,))
exists = cur.fetchone()
cur.close()
if exists:
try:
cur = conn.cursor()
cur.execute(f"ALTER TABLE product_versions DROP COLUMN {col}")
cur.close()
conn.commit()
print(f"[migrate] product_versions.{col} 列已删除")
except mysql.connector.Error as e:
print(f"[migrate] 删除 {col} 失败: {e}")
finally:
conn.close()
def migrate_fix_service_fee_standard():
"""修正 project_finances.service_fee_standard 旧数据为默认值 55%"""
from db import db
conn = db()
try:
cur = conn.cursor()
cur.execute(
"UPDATE project_finances SET service_fee_standard = 5 "
"WHERE service_fee_standard = 0 OR service_fee_standard IS NULL "
"OR service_fee_standard NOT IN (5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)"
)
affected = cur.rowcount
cur.close()
if affected:
conn.commit()
print(f"[migrate] project_finances: {affected} 条记录 service_fee_standard 修正为 5")
finally:
conn.close()
def migrate_fix_expense_status():
"""修正 expense_records 中空的 status 为默认值「计入费用」"""
from db import db
conn = db()
try:
cur = conn.cursor()
cur.execute(
"UPDATE expense_records SET status='计入费用' "
"WHERE status IS NULL OR status='' OR status='待审批'"
)
affected = cur.rowcount
cur.close()
if affected:
conn.commit()
print(f"[migrate] expense_records: {affected} 条记录 status 修正为 '计入费用'")
finally:
conn.close()
def migrate_rename_xuehui_to_xueshu():
"""工作台重命名:学会·无界 → 学术·无界"""
from db import db, _exec, mysql
conn = db()
try:
tables = ["project_finances", "plan_finances", "expense_records", "plan_expense_records",
"sales_leads", "business_proposals", "product_versions", "operation_projects",
"follow_up_records", "project_tasks", "finance_records", "users", "user_tenants"]
for table in tables:
try:
cur = _exec(conn, f"UPDATE {table} SET tenant='学术·无界' WHERE tenant='学会·无界'")
affected = cur.rowcount
cur.close()
if affected:
conn.commit()
print(f"[migrate] {table}: {affected} 条记录 tenant 改为 '学术·无界'")
except mysql.connector.Error:
pass
finally:
conn.close()
def migrate_rename_zong_to_overview():
"""工作台重命名:总工作台 → 总览"""
from db import db, _exec, mysql
conn = db()
try:
tables = ["project_finances", "plan_finances", "expense_records", "plan_expense_records",
"sales_leads", "business_proposals", "product_versions", "operation_projects",
"follow_up_records", "project_tasks", "finance_records", "users", "user_tenants"]
for table in tables:
try:
cur = _exec(conn, f"UPDATE {table} SET tenant='总览' WHERE tenant='总工作台'")
affected = cur.rowcount
cur.close()
if affected:
conn.commit()
print(f"[migrate] {table}: {affected} 条记录 tenant 改为 '总览'")
except mysql.connector.Error:
pass
finally:
conn.close()