Files
opc-manager/backend/migrations/data_fixes.py
mac e7e93c06f8 fix: 历史费用状态修正为「计入费用」
- data_fixes 新增 migrate_fix_expense_status
- 将 NULL/空/待审批 的费用状态统一修正为「计入费用」
- 服务启动时自动执行,幂等安全
- 版本号 v1.0.0.6
2026-07-07 18:39:11 +08:00

115 lines
3.9 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()