221 lines
8.1 KiB
Python
221 lines
8.1 KiB
Python
|
|
"""迁移 015: PPT/海报功能扩展 — 扩展现有表 + 创建新表。
|
|||
|
|
|
|||
|
|
覆盖:
|
|||
|
|
- 扩展 insurance_ppt_companies(+3 字段)
|
|||
|
|
- 扩展 insurance_ppt_products(+16 字段)
|
|||
|
|
- 扩展 insurance_ppt_templates(+6 字段)
|
|||
|
|
- 创建 insurance_ppt_history
|
|||
|
|
- 创建 poster_case_uploads
|
|||
|
|
- 创建 poster_templates
|
|||
|
|
- 创建 poster_copy_templates
|
|||
|
|
- 创建 poster_records
|
|||
|
|
- 创建 system_settings + 种子数据
|
|||
|
|
"""
|
|||
|
|
import logging
|
|||
|
|
|
|||
|
|
logger = logging.getLogger(__name__)
|
|||
|
|
|
|||
|
|
|
|||
|
|
def _add_column(table, column_def, db):
|
|||
|
|
"""安全添加列(已存在则跳过)。"""
|
|||
|
|
from sqlalchemy import text
|
|||
|
|
try:
|
|||
|
|
db.session.execute(text(f"ALTER TABLE {table} ADD COLUMN {column_def}"))
|
|||
|
|
except Exception as e:
|
|||
|
|
# 仅忽略"列已存在"错误,其他错误记录日志
|
|||
|
|
err_msg = str(e).lower()
|
|||
|
|
if "already exists" not in err_msg and "duplicate column" not in err_msg:
|
|||
|
|
logger.warning(f"添加列 {table}.{column_def} 失败: {e}")
|
|||
|
|
|
|||
|
|
|
|||
|
|
def migrate():
|
|||
|
|
"""迁移入口。"""
|
|||
|
|
from insurance.db.compat import db
|
|||
|
|
from sqlalchemy import text
|
|||
|
|
|
|||
|
|
# ========== 1. 扩展 insurance_ppt_companies ==========
|
|||
|
|
logger.info("[migrate_015] 扩展 insurance_ppt_companies ...")
|
|||
|
|
for col in [
|
|||
|
|
"logo_url VARCHAR(500)",
|
|||
|
|
"status SMALLINT DEFAULT 1",
|
|||
|
|
"sort_order INTEGER DEFAULT 0",
|
|||
|
|
]:
|
|||
|
|
_add_column("insurance_ppt_companies", col, db)
|
|||
|
|
db.session.execute(text(
|
|||
|
|
"UPDATE insurance_ppt_companies SET status = 1 WHERE status IS NULL"
|
|||
|
|
))
|
|||
|
|
db.session.commit()
|
|||
|
|
logger.info("[migrate_015] insurance_ppt_companies 扩展完成")
|
|||
|
|
|
|||
|
|
# ========== 2. 扩展 insurance_ppt_products ==========
|
|||
|
|
logger.info("[migrate_015] 扩展 insurance_ppt_products ...")
|
|||
|
|
for col in [
|
|||
|
|
"product_code VARCHAR(50)",
|
|||
|
|
"product_type VARCHAR(20)",
|
|||
|
|
"coverage_period VARCHAR(50)",
|
|||
|
|
"payment_period VARCHAR(50)",
|
|||
|
|
"insured_age_range VARCHAR(50)",
|
|||
|
|
"waiting_period VARCHAR(50)",
|
|||
|
|
"highlights TEXT",
|
|||
|
|
"extra_fields TEXT",
|
|||
|
|
"status SMALLINT DEFAULT 1",
|
|||
|
|
"sort_order INTEGER DEFAULT 0",
|
|||
|
|
"updated_at TIMESTAMP DEFAULT NOW()",
|
|||
|
|
"manual_file_url VARCHAR(500)",
|
|||
|
|
"manual_parse_status VARCHAR(20) DEFAULT 'none'",
|
|||
|
|
"manual_parsed_rules TEXT",
|
|||
|
|
"manual_reviewed_by VARCHAR(50)",
|
|||
|
|
"manual_reviewed_at TIMESTAMP",
|
|||
|
|
]:
|
|||
|
|
_add_column("insurance_ppt_products", col, db)
|
|||
|
|
db.session.execute(text(
|
|||
|
|
"UPDATE insurance_ppt_products SET status = 1 WHERE status IS NULL"
|
|||
|
|
))
|
|||
|
|
db.session.commit()
|
|||
|
|
logger.info("[migrate_015] insurance_ppt_products 扩展完成")
|
|||
|
|
|
|||
|
|
# ========== 3. 扩展 insurance_ppt_templates ==========
|
|||
|
|
logger.info("[migrate_015] 扩展 insurance_ppt_templates ...")
|
|||
|
|
for col in [
|
|||
|
|
"name VARCHAR(100)",
|
|||
|
|
"scenario_tag VARCHAR(50)",
|
|||
|
|
"preview_image VARCHAR(500)",
|
|||
|
|
"applicable_company_ids TEXT",
|
|||
|
|
"applicable_product_ids TEXT",
|
|||
|
|
"status SMALLINT DEFAULT 1",
|
|||
|
|
]:
|
|||
|
|
_add_column("insurance_ppt_templates", col, db)
|
|||
|
|
db.session.commit()
|
|||
|
|
logger.info("[migrate_015] insurance_ppt_templates 扩展完成")
|
|||
|
|
|
|||
|
|
# ========== 4. 创建 insurance_ppt_history ==========
|
|||
|
|
logger.info("[migrate_015] 创建 insurance_ppt_history ...")
|
|||
|
|
db.session.execute(text("""
|
|||
|
|
CREATE TABLE IF NOT EXISTS insurance_ppt_history (
|
|||
|
|
id BIGSERIAL PRIMARY KEY,
|
|||
|
|
user_id VARCHAR(50) NOT NULL,
|
|||
|
|
session_id VARCHAR(50),
|
|||
|
|
action_type VARCHAR(20) NOT NULL,
|
|||
|
|
company_id VARCHAR(50),
|
|||
|
|
product_id VARCHAR(50),
|
|||
|
|
template_id VARCHAR(50),
|
|||
|
|
content_snapshot TEXT,
|
|||
|
|
file_url VARCHAR(500),
|
|||
|
|
ip VARCHAR(50),
|
|||
|
|
user_agent VARCHAR(500),
|
|||
|
|
created_at TIMESTAMP DEFAULT NOW()
|
|||
|
|
)
|
|||
|
|
"""))
|
|||
|
|
db.session.execute(text(
|
|||
|
|
"CREATE INDEX IF NOT EXISTS idx_ppt_history_user ON insurance_ppt_history(user_id, created_at DESC)"
|
|||
|
|
))
|
|||
|
|
db.session.commit()
|
|||
|
|
logger.info("[migrate_015] insurance_ppt_history 创建完成")
|
|||
|
|
|
|||
|
|
# ========== 5. 创建 poster_case_uploads ==========
|
|||
|
|
logger.info("[migrate_015] 创建 poster_case_uploads ...")
|
|||
|
|
db.session.execute(text("""
|
|||
|
|
CREATE TABLE IF NOT EXISTS poster_case_uploads (
|
|||
|
|
id BIGSERIAL PRIMARY KEY,
|
|||
|
|
user_id VARCHAR(50) NOT NULL,
|
|||
|
|
product_id VARCHAR(50) NOT NULL,
|
|||
|
|
source_file_url VARCHAR(500) NOT NULL,
|
|||
|
|
parse_status VARCHAR(20) DEFAULT 'pending',
|
|||
|
|
parsed_data TEXT,
|
|||
|
|
confirmed_data TEXT,
|
|||
|
|
confirmed_by VARCHAR(50),
|
|||
|
|
confirmed_at TIMESTAMP,
|
|||
|
|
created_at TIMESTAMP DEFAULT NOW()
|
|||
|
|
)
|
|||
|
|
"""))
|
|||
|
|
db.session.commit()
|
|||
|
|
logger.info("[migrate_015] poster_case_uploads 创建完成")
|
|||
|
|
|
|||
|
|
# ========== 6. 创建 poster_templates ==========
|
|||
|
|
logger.info("[migrate_015] 创建 poster_templates ...")
|
|||
|
|
db.session.execute(text("""
|
|||
|
|
CREATE TABLE IF NOT EXISTS poster_templates (
|
|||
|
|
id BIGSERIAL PRIMARY KEY,
|
|||
|
|
name VARCHAR(100) NOT NULL,
|
|||
|
|
scenario_tag VARCHAR(50),
|
|||
|
|
style_description TEXT NOT NULL,
|
|||
|
|
color_scheme TEXT,
|
|||
|
|
reference_image VARCHAR(500),
|
|||
|
|
preview_image VARCHAR(500),
|
|||
|
|
status SMALLINT DEFAULT 1,
|
|||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|||
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|||
|
|
)
|
|||
|
|
"""))
|
|||
|
|
db.session.commit()
|
|||
|
|
logger.info("[migrate_015] poster_templates 创建完成")
|
|||
|
|
|
|||
|
|
# ========== 7. 创建 poster_copy_templates ==========
|
|||
|
|
logger.info("[migrate_015] 创建 poster_copy_templates ...")
|
|||
|
|
db.session.execute(text("""
|
|||
|
|
CREATE TABLE IF NOT EXISTS poster_copy_templates (
|
|||
|
|
id BIGSERIAL PRIMARY KEY,
|
|||
|
|
name VARCHAR(100) NOT NULL,
|
|||
|
|
scenario_tag VARCHAR(50),
|
|||
|
|
content TEXT NOT NULL,
|
|||
|
|
variables TEXT,
|
|||
|
|
status SMALLINT DEFAULT 1,
|
|||
|
|
created_at TIMESTAMP DEFAULT NOW()
|
|||
|
|
)
|
|||
|
|
"""))
|
|||
|
|
db.session.commit()
|
|||
|
|
logger.info("[migrate_015] poster_copy_templates 创建完成")
|
|||
|
|
|
|||
|
|
# ========== 8. 创建 poster_records ==========
|
|||
|
|
logger.info("[migrate_015] 创建 poster_records ...")
|
|||
|
|
db.session.execute(text("""
|
|||
|
|
CREATE TABLE IF NOT EXISTS poster_records (
|
|||
|
|
id BIGSERIAL PRIMARY KEY,
|
|||
|
|
user_id VARCHAR(50) NOT NULL,
|
|||
|
|
product_id VARCHAR(50),
|
|||
|
|
case_upload_id BIGINT,
|
|||
|
|
template_id BIGINT,
|
|||
|
|
copy_mode VARCHAR(20),
|
|||
|
|
copy_content TEXT,
|
|||
|
|
ai_raw_content TEXT,
|
|||
|
|
export_url VARCHAR(500),
|
|||
|
|
export_format VARCHAR(10),
|
|||
|
|
export_size VARCHAR(20),
|
|||
|
|
reference_image_used VARCHAR(500),
|
|||
|
|
prompt_used TEXT,
|
|||
|
|
created_at TIMESTAMP DEFAULT NOW()
|
|||
|
|
)
|
|||
|
|
"""))
|
|||
|
|
db.session.execute(text(
|
|||
|
|
"CREATE INDEX IF NOT EXISTS idx_poster_records_user ON poster_records(user_id, created_at DESC)"
|
|||
|
|
))
|
|||
|
|
db.session.commit()
|
|||
|
|
logger.info("[migrate_015] poster_records 创建完成")
|
|||
|
|
|
|||
|
|
# ========== 9. 创建 system_settings + 种子数据 ==========
|
|||
|
|
logger.info("[migrate_015] 创建 system_settings ...")
|
|||
|
|
db.session.execute(text("""
|
|||
|
|
CREATE TABLE IF NOT EXISTS system_settings (
|
|||
|
|
id BIGSERIAL PRIMARY KEY,
|
|||
|
|
key VARCHAR(100) UNIQUE NOT NULL,
|
|||
|
|
value TEXT NOT NULL,
|
|||
|
|
description VARCHAR(500),
|
|||
|
|
updated_by VARCHAR(50),
|
|||
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|||
|
|
)
|
|||
|
|
"""))
|
|||
|
|
# 种子数据(幂等:已存在则跳过)
|
|||
|
|
for key, value, desc in [
|
|||
|
|
("ppt_history_retention_days", "365", "PPT 历史记录保留天数(0=永久保留)"),
|
|||
|
|
("poster_history_retention_days", "365", "海报历史记录保留天数(0=永久保留)"),
|
|||
|
|
]:
|
|||
|
|
db.session.execute(text(
|
|||
|
|
"INSERT INTO system_settings (key, value, description) "
|
|||
|
|
"SELECT :key, :value, :desc "
|
|||
|
|
"WHERE NOT EXISTS (SELECT 1 FROM system_settings WHERE key = :key)"
|
|||
|
|
), {"key": key, "value": value, "desc": desc})
|
|||
|
|
db.session.commit()
|
|||
|
|
logger.info("[migrate_015] system_settings 创建完成")
|
|||
|
|
|
|||
|
|
logger.info("[migrate_015] 全部迁移完成")
|