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
This commit is contained in:
@@ -17,7 +17,7 @@ def run_migrations():
|
||||
"""
|
||||
from migrations.tables import migrate_create_tables
|
||||
from migrations.columns import migrate_add_columns
|
||||
from migrations.data_fixes import migrate_fix_task_status, migrate_rename_tenant, migrate_drop_product_fields, migrate_fix_service_fee_standard, migrate_fix_expense_status
|
||||
from migrations.data_fixes import migrate_fix_task_status, migrate_rename_tenant, migrate_drop_product_fields, migrate_fix_service_fee_standard, migrate_fix_expense_status, migrate_rename_xuehui_to_xueshu, migrate_rename_zong_to_overview
|
||||
from migrations.data_split import migrate_data_split
|
||||
from migrations.seed import migrate_seed_users, migrate_seed_demo_data
|
||||
|
||||
@@ -28,6 +28,8 @@ def run_migrations():
|
||||
migrate_drop_product_fields()
|
||||
migrate_fix_service_fee_standard()
|
||||
migrate_fix_expense_status()
|
||||
migrate_rename_xuehui_to_xueshu()
|
||||
migrate_rename_zong_to_overview()
|
||||
migrate_data_split()
|
||||
migrate_seed_users()
|
||||
migrate_seed_demo_data()
|
||||
|
||||
@@ -114,3 +114,46 @@ def migrate_fix_expense_status():
|
||||
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()
|
||||
|
||||
@@ -28,7 +28,7 @@ def migrate_seed_users():
|
||||
# 绑定工作台
|
||||
tenant_map = [
|
||||
("kepu", "科普·无界"), ("keyan", "科研·无界"), ("yihuan", "医患·无界"),
|
||||
("mcn", "MCN·无界"), ("wuji", "学会·无界"),
|
||||
("mcn", "MCN·无界"), ("wuji", "学术·无界"),
|
||||
]
|
||||
for uname, tenant in tenant_map:
|
||||
u = one(conn, "SELECT id FROM users WHERE username=?", (uname,))
|
||||
|
||||
@@ -8,7 +8,7 @@ random.seed(42)
|
||||
from datetime import date
|
||||
from db import db, _exec, one
|
||||
|
||||
TENANTS = ["科普·无界", "科研·无界", "医患·无界", "MCN·无界", "学会·无界"]
|
||||
TENANTS = ["科普·无界", "科研·无界", "医患·无界", "MCN·无界", "学术·无界"]
|
||||
|
||||
# 每个工作台的差异化客户和项目模板
|
||||
TENANT_CUSTOMERS = {
|
||||
@@ -40,7 +40,7 @@ TENANT_CUSTOMERS = {
|
||||
("B站知识区", ["深度科普纪录片", "医学动画制作"]),
|
||||
("微信视频号", ["医生科普直播运营", "企业微信科普推送"]),
|
||||
],
|
||||
"学会·无界": [
|
||||
"学术·无界": [
|
||||
("中华医学会", ["学术年会数字化平台", "继续教育学分系统", "基层医生培训"]),
|
||||
("中国医师协会", ["医师定考管理系统", "专科医师培训平台"]),
|
||||
("中国抗癌协会", ["肿瘤科普万里行", "CACA指南推广"]),
|
||||
|
||||
@@ -14,7 +14,7 @@ from helpers import add_file_index, attach_common, monthly_finance
|
||||
|
||||
bp = Blueprint("api", __name__)
|
||||
|
||||
ALL_TENANTS = ["总工作台", "科普·无界", "科研·无界", "医患·无界", "MCN·无界", "学会·无界"]
|
||||
ALL_TENANTS = ["总览", "科普·无界", "科研·无界", "医患·无界", "MCN·无界", "学术·无界"]
|
||||
|
||||
TABLES = {
|
||||
"sales": ("sales_leads", ["target_customer", "priority", "status", "tenant"]),
|
||||
@@ -75,10 +75,13 @@ def auth_login():
|
||||
session["display_name"] = user["display_name"]
|
||||
session["role"] = user["role"]
|
||||
if user["role"] == "admin":
|
||||
session["tenants"] = ["总工作台", "科普·无界", "科研·无界", "医患·无界", "MCN·无界", "学会·无界"]
|
||||
session["tenants"] = ["总览", "科普·无界", "科研·无界", "医患·无界", "MCN·无界", "学术·无界"]
|
||||
else:
|
||||
ut = rows(conn, "SELECT tenant FROM user_tenants WHERE user_id=?", (user["id"],))
|
||||
session["tenants"] = [x["tenant"] for x in ut]
|
||||
# 清理旧名称
|
||||
session["tenants"] = [t if t != "总工作台" else "总览" for t in session["tenants"]]
|
||||
session["tenants"] = [t if t != "学会·无界" else "学术·无界" for t in session["tenants"]]
|
||||
return jsonify({
|
||||
"ok": True,
|
||||
"user": {"id": user["id"], "username": user["username"], "display_name": user["display_name"], "role": user["role"]},
|
||||
@@ -123,8 +126,10 @@ def auth_me():
|
||||
if "user_id" not in session:
|
||||
return jsonify({"logged_in": False})
|
||||
tenants = session.get("tenants", [])
|
||||
if "总工作台" not in tenants:
|
||||
tenants = ["总工作台"] + tenants
|
||||
tenants = [t if t != "总工作台" else "总览" for t in tenants]
|
||||
tenants = [t if t != "学会·无界" else "学术·无界" for t in tenants]
|
||||
if "总览" not in tenants:
|
||||
tenants = ["总览"] + tenants
|
||||
return jsonify({
|
||||
"logged_in": True,
|
||||
"user": {"id": session["user_id"], "username": session["username"], "display_name": session["display_name"], "role": session["role"]},
|
||||
@@ -257,15 +262,17 @@ def bootstrap():
|
||||
_year = date.today().year
|
||||
tenant = request.args.get("tenant", session.get("tenants", ["科普·无界"])[0])
|
||||
allowed = session.get("tenants", [])
|
||||
if "总工作台" not in allowed:
|
||||
allowed = ["总工作台"] + allowed
|
||||
allowed = [t if t != "总工作台" else "总览" for t in allowed]
|
||||
allowed = [t if t != "学会·无界" else "学术·无界" for t in allowed]
|
||||
if "总览" not in allowed:
|
||||
allowed = ["总览"] + allowed
|
||||
if tenant not in allowed:
|
||||
tenant = allowed[0]
|
||||
conn = db()
|
||||
try:
|
||||
# 总工作台:聚合所有工作台的首页数据
|
||||
if tenant == "总工作台":
|
||||
real_tenants = [t for t in allowed if t != "总工作台"]
|
||||
if tenant == "总览":
|
||||
real_tenants = [t for t in allowed if t != "总览"]
|
||||
all_metrics = []
|
||||
all_monthly = []
|
||||
all_recent = []
|
||||
@@ -423,7 +430,7 @@ def bootstrap():
|
||||
m[field] = sum(tl[i][field] if i < len(tl) else 0 for tl in all_monthly)
|
||||
merged_monthly.append(m)
|
||||
summary = {
|
||||
"project_name": "总工作台",
|
||||
"project_name": "总览",
|
||||
"metrics": agg,
|
||||
"recent": sorted(all_recent, key=lambda x: x.get("id", 0), reverse=True)[:8],
|
||||
"risks": [],
|
||||
|
||||
Reference in New Issue
Block a user