费用模块: - 字段精简为5个:费用类型(下拉6选)、月份(3年36月下拉)、金额、已发生金额、费用说明(textarea) - 三视图切换(总/季度/月度),按expense_month筛选,汇总卡片实时更新 - 类型筛选功能,Toolbar+汇总+表格三段式布局 - 删除按钮移至关闭按钮左侧,间距8px - 费用记录删除合计行,列宽固定200px,居中 项目模块: - 卡片网格6→7列(14卡片7×2满排),配置驱动 METRIC_CARDS - 新增费用/利润字段,利润=毛利-费用 - 表格行添加费用、利润列,比率列text-xs→text-sm - 项目流水tab费用与已付列对调,汇总卡片6→1×6 - 修复月度/季度切换时汇总卡片不更新 - 筛选区统一为卡片,去除'筛选:'前缀 数据库: - expense_records新增expense_type/expense_month/incurred_amount列 - migrations/columns.py幂等迁移,启动时自动执行
113 lines
6.8 KiB
Python
113 lines
6.8 KiB
Python
"""migrations/columns.py — 加列迁移(老表补字段,幂等)"""
|
|
|
|
|
|
def _add_column_if_missing(conn, table, column, ddl):
|
|
"""检查列是否存在,不存在才加(幂等)"""
|
|
from db import _exec, mysql, logger
|
|
|
|
cur = conn.cursor(dictionary=True)
|
|
cur.execute(f"SHOW COLUMNS FROM {table} LIKE %s", (column,))
|
|
exists = cur.fetchone()
|
|
cur.close()
|
|
if not exists:
|
|
try:
|
|
_exec(conn, ddl)
|
|
print(f"[migrate] {table}.{column} 列已添加")
|
|
except mysql.connector.Error as e:
|
|
logger.debug(f"add column {table}.{column} skipped: {e}")
|
|
|
|
|
|
def migrate_add_columns():
|
|
"""为老表补齐后续新增的字段"""
|
|
from db import db
|
|
|
|
conn = db()
|
|
try:
|
|
# tenant 字段(多工作台支持)
|
|
for table in ["sales_leads", "follow_up_records", "business_proposals",
|
|
"operation_projects", "product_versions", "finance_records",
|
|
"project_tasks"]:
|
|
_add_column_if_missing(conn, table, "tenant",
|
|
f"ALTER TABLE {table} ADD COLUMN tenant VARCHAR(100) NOT NULL DEFAULT '科普·无界'")
|
|
|
|
# business_proposals 扩展字段
|
|
_add_column_if_missing(conn, "business_proposals", "proposal_type",
|
|
"ALTER TABLE business_proposals ADD COLUMN proposal_type VARCHAR(100) NOT NULL DEFAULT '业务方案'")
|
|
_add_column_if_missing(conn, "business_proposals", "notes",
|
|
"ALTER TABLE business_proposals ADD COLUMN notes VARCHAR(2000) NOT NULL DEFAULT ''")
|
|
|
|
# product_versions 扩展字段
|
|
_add_column_if_missing(conn, "product_versions", "priority",
|
|
"ALTER TABLE product_versions ADD COLUMN priority VARCHAR(10) NOT NULL DEFAULT 'P2'")
|
|
_add_column_if_missing(conn, "product_versions", "start_date",
|
|
"ALTER TABLE product_versions ADD COLUMN start_date VARCHAR(30) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "product_versions", "plan_date",
|
|
"ALTER TABLE product_versions ADD COLUMN plan_date VARCHAR(30) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "product_versions", "dev_done_date",
|
|
"ALTER TABLE product_versions ADD COLUMN dev_done_date VARCHAR(30) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "product_versions", "test_date",
|
|
"ALTER TABLE product_versions ADD COLUMN test_date VARCHAR(30) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "product_versions", "devs",
|
|
"ALTER TABLE product_versions ADD COLUMN devs VARCHAR(500) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "product_versions", "testers",
|
|
"ALTER TABLE product_versions ADD COLUMN testers VARCHAR(500) NOT NULL DEFAULT ''")
|
|
|
|
# project_tasks 扩展字段
|
|
_add_column_if_missing(conn, "project_tasks", "status",
|
|
"ALTER TABLE project_tasks ADD COLUMN status VARCHAR(50) NOT NULL DEFAULT '未开始'")
|
|
_add_column_if_missing(conn, "project_tasks", "sort_order",
|
|
"ALTER TABLE project_tasks ADD COLUMN sort_order INT NOT NULL DEFAULT 0")
|
|
_add_column_if_missing(conn, "project_tasks", "priority",
|
|
"ALTER TABLE project_tasks ADD COLUMN priority VARCHAR(10) NOT NULL DEFAULT 'P2'")
|
|
|
|
# project_finances 12 个月度预算字段(确收/毛利/回款/费用)
|
|
for m in ["01","02","03","04","05","06","07","08","09","10","11","12"]:
|
|
for field in ["rev", "gross", "payment", "cost"]:
|
|
col = f"{field}_2026_{m}"
|
|
_add_column_if_missing(conn, "project_finances", col,
|
|
f"ALTER TABLE project_finances ADD COLUMN {col} DOUBLE NOT NULL DEFAULT 0")
|
|
|
|
# project_finances 总视图字段:已回款 / 应付 / 已付
|
|
_add_column_if_missing(conn, "project_finances", "total_payment",
|
|
"ALTER TABLE project_finances ADD COLUMN total_payment DOUBLE NOT NULL DEFAULT 0")
|
|
_add_column_if_missing(conn, "project_finances", "total_cost",
|
|
"ALTER TABLE project_finances ADD COLUMN total_cost DOUBLE NOT NULL DEFAULT 0")
|
|
_add_column_if_missing(conn, "project_finances", "total_paid",
|
|
"ALTER TABLE project_finances ADD COLUMN total_paid DOUBLE NOT NULL DEFAULT 0")
|
|
|
|
# project_finances 项目基本信息扩展字段
|
|
_add_column_if_missing(conn, "project_finances", "project_code",
|
|
"ALTER TABLE project_finances ADD COLUMN project_code VARCHAR(50) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "project_finances", "start_date",
|
|
"ALTER TABLE project_finances ADD COLUMN start_date VARCHAR(30) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "project_finances", "end_date",
|
|
"ALTER TABLE project_finances ADD COLUMN end_date VARCHAR(30) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "project_finances", "task_type",
|
|
"ALTER TABLE project_finances ADD COLUMN task_type VARCHAR(100) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "project_finances", "task_count",
|
|
"ALTER TABLE project_finances ADD COLUMN task_count DOUBLE NOT NULL DEFAULT 0")
|
|
_add_column_if_missing(conn, "project_finances", "service_fee_standard",
|
|
"ALTER TABLE project_finances ADD COLUMN service_fee_standard DOUBLE NOT NULL DEFAULT 0")
|
|
_add_column_if_missing(conn, "project_finances", "project_manager",
|
|
"ALTER TABLE project_finances ADD COLUMN project_manager VARCHAR(100) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "project_finances", "task_data",
|
|
"ALTER TABLE project_finances ADD COLUMN task_data TEXT")
|
|
_add_column_if_missing(conn, "project_finances", "contact_name",
|
|
"ALTER TABLE project_finances ADD COLUMN contact_name VARCHAR(100) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "project_finances", "contact_phone",
|
|
"ALTER TABLE project_finances ADD COLUMN contact_phone VARCHAR(50) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "project_finances", "other_info",
|
|
"ALTER TABLE project_finances ADD COLUMN other_info VARCHAR(500) NOT NULL DEFAULT ''")
|
|
# expense_records 字段迁移(重构为费用类型+月份+金额+已发生金额+费用说明)
|
|
_add_column_if_missing(conn, "expense_records", "expense_type",
|
|
"ALTER TABLE expense_records ADD COLUMN expense_type VARCHAR(100) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "expense_records", "expense_month",
|
|
"ALTER TABLE expense_records ADD COLUMN expense_month VARCHAR(20) NOT NULL DEFAULT ''")
|
|
_add_column_if_missing(conn, "expense_records", "incurred_amount",
|
|
"ALTER TABLE expense_records ADD COLUMN incurred_amount DOUBLE NOT NULL DEFAULT 0")
|
|
|
|
conn.commit()
|
|
print("[migrate] 加列迁移完成")
|
|
finally:
|
|
conn.close()
|