You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
9.1 KiB

5 days ago
-- ============================================================
-- 测试环境 crm 库 schema 补齐(opportunity / opportunity_customer)
-- 背景 20260901:导表后两表为残缺混合结构(缺 party_a_clear 等列,
-- 实体映射全列 SELECT/INSERT → SQLSyntaxErrorException → 50001)。
-- 用法:Navicat 整段执行 / mysql -uroot -p crm < opp-schema-migration.sql
-- 幂等:列已存在自动跳过(information_schema 判存 + 动态 SQL,MySQL 8 无 ADD COLUMN IF NOT EXISTS)。
-- 对齐实体:Opportunity.java(L40-230)+ OpportunityCustomer.java + BaseEntity.java。
-- 更省事的替代:重启 crm-app 容器即可,jpa.hibernate.ddl-auto=update 会自动补齐全部缺列。
-- ============================================================
DELIMITER $$
DROP PROCEDURE IF EXISTS crm_add_column $$
CREATE PROCEDURE crm_add_column(
IN p_table VARCHAR(64), IN p_column VARCHAR(64), IN p_ddl TEXT)
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = p_table AND COLUMN_NAME = p_column
) THEN
SET @s = CONCAT('ALTER TABLE `', p_table, '` ADD COLUMN `', p_column, '` ', p_ddl);
PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;
SELECT CONCAT('ADD ', p_table, '.', p_column) AS applied;
END IF;
END $$
DELIMITER ;
-- ---------- opportunity 主表 ----------
CALL crm_add_column('opportunity','opp_name', "varchar(200) NOT NULL COMMENT '商机名称'");
CALL crm_add_column('opportunity','opp_source', "varchar(64) NOT NULL COMMENT '商机来源字典code'");
CALL crm_add_column('opportunity','opp_type', "varchar(64) NOT NULL COMMENT '商机类型字典code'");
CALL crm_add_column('opportunity','industry_code', "varchar(64) NOT NULL COMMENT '行业字典code'");
CALL crm_add_column('opportunity','bid_form', "varchar(64) NOT NULL COMMENT '招标形式字典code'");
CALL crm_add_column('opportunity','locality_type', "varchar(64) NOT NULL COMMENT '项目属地字典code'");
CALL crm_add_column('opportunity','party_a_clear', "tinyint NOT NULL DEFAULT 0 COMMENT '甲方是否明确'");
CALL crm_add_column('opportunity','party_a', "varchar(200) NULL COMMENT '甲方名称'");
CALL crm_add_column('opportunity','province_code', "varchar(12) NOT NULL COMMENT '省份国标code'");
CALL crm_add_column('opportunity','city_code', "varchar(12) NOT NULL COMMENT '市/区国标code'");
CALL crm_add_column('opportunity','remark', "text NULL COMMENT '备注'");
CALL crm_add_column('opportunity','project_amount', "decimal(14,2) NULL COMMENT '项目金额'");
CALL crm_add_column('opportunity','address', "varchar(255) NULL COMMENT '项目详细地址'");
CALL crm_add_column('opportunity','owner_user_id', "bigint NULL COMMENT '领取人ID'");
CALL crm_add_column('opportunity','owner_name_snapshot', "varchar(64) NULL COMMENT '领取人姓名快照'");
CALL crm_add_column('opportunity','owner_dept_id', "bigint NULL COMMENT '领取人部门快照'");
CALL crm_add_column('opportunity','origin_dept_id', "bigint NULL COMMENT '原始血缘部门'");
CALL crm_add_column('opportunity','pool_reason', "varchar(32) NULL COMMENT '进入公海原因'");
CALL crm_add_column('opportunity','creator_user_id', "bigint NOT NULL COMMENT '创建人ID'");
CALL crm_add_column('opportunity','opp_status', "tinyint NOT NULL COMMENT '商机状态'");
CALL crm_add_column('opportunity','current_stage_id', "bigint NOT NULL COMMENT '当前阶段节点ID'");
CALL crm_add_column('opportunity','stage_template_id', "bigint NOT NULL COMMENT '阶段模板版本行ID'");
CALL crm_add_column('opportunity','stage_template_version', "varchar(20) NOT NULL COMMENT '阶段模板版本号冗余'");
CALL crm_add_column('opportunity','source_lead_id', "bigint NULL COMMENT '来源线索ID'");
CALL crm_add_column('opportunity','source_lead_name', "varchar(200) NULL COMMENT '线索名快照'");
CALL crm_add_column('opportunity','source_phone', "varchar(32) NULL COMMENT '联系电话快照'");
CALL crm_add_column('opportunity','source_product_code', "varchar(64) NULL COMMENT '需求产品码快照'");
CALL crm_add_column('opportunity','claim_time', "datetime NULL COMMENT '领取时刻'");
CALL crm_add_column('opportunity','last_valid_follow_time', "datetime NULL COMMENT '最近有效跟进时间'");
CALL crm_add_column('opportunity','primary_customer_id', "bigint NULL COMMENT '主要意向客户ID'");
CALL crm_add_column('opportunity','primary_customer_name_snapshot', "varchar(200) NULL COMMENT '主客户名快照'");
CALL crm_add_column('opportunity','key_contact_id', "bigint NULL COMMENT '商机关键联系人ID'");
CALL crm_add_column('opportunity','key_contact_name_snapshot', "varchar(200) NULL COMMENT '商机关键联系人姓名快照'");
CALL crm_add_column('opportunity','key_contact_company_snapshot', "varchar(200) NULL COMMENT '关键人所在公司快照'");
CALL crm_add_column('opportunity','scheme_budget', "decimal(18,2) NULL COMMENT '方案卡预算快照'");
CALL crm_add_column('opportunity','scheme_card_status', "int NULL COMMENT '方案卡状态快照'");
CALL crm_add_column('opportunity','pause_time', "datetime NULL COMMENT '暂缓开始时刻'");
CALL crm_add_column('opportunity','pause_reason', "varchar(32) NULL COMMENT '暂缓原因'");
CALL crm_add_column('opportunity','pause_expected_restart_date', "date NULL COMMENT '预计重启日期'");
CALL crm_add_column('opportunity','pause_remark', "varchar(500) NULL COMMENT '暂缓补充说明'");
CALL crm_add_column('opportunity','version', "int NOT NULL DEFAULT 0 COMMENT '乐观锁版本号'");
-- BaseEntity 公共列(通常都在,幂等兜底)
CALL crm_add_column('opportunity','creator_id', "varchar(50) NULL COMMENT '创建用户id'");
CALL crm_add_column('opportunity','updater_id', "varchar(50) NULL COMMENT '更新用户id'");
CALL crm_add_column('opportunity','create_time', "datetime NULL COMMENT '创建时间'");
CALL crm_add_column('opportunity','update_time', "datetime NULL COMMENT '更新时间'");
CALL crm_add_column('opportunity','delete_key', "tinyint NOT NULL DEFAULT 0 COMMENT '逻辑删除位'");
-- ---------- opportunity_customer 关联客户表 ----------
CALL crm_add_column('opportunity_customer','opportunity_id', "bigint NOT NULL COMMENT '所属商机ID'");
CALL crm_add_column('opportunity_customer','customer_id', "bigint NOT NULL COMMENT '客户ID'");
CALL crm_add_column('opportunity_customer','customer_name_snapshot', "varchar(200) NOT NULL COMMENT '客户名快照'");
CALL crm_add_column('opportunity_customer','customer_role', "varchar(32) NULL COMMENT '客户角色字典code'");
CALL crm_add_column('opportunity_customer','is_primary_intended', "tinyint NOT NULL DEFAULT 0 COMMENT '是否主要意向客户'");
CALL crm_add_column('opportunity_customer','delete_key', "bigint NOT NULL DEFAULT 0 COMMENT '软删除复用键'");
CALL crm_add_column('opportunity_customer','creator_id', "varchar(50) NULL COMMENT '创建用户id'");
CALL crm_add_column('opportunity_customer','updater_id', "varchar(50) NULL COMMENT '更新用户id'");
CALL crm_add_column('opportunity_customer','create_time', "datetime NULL COMMENT '创建时间'");
CALL crm_add_column('opportunity_customer','update_time', "datetime NULL COMMENT '更新时间'");
-- ---------- 索引/约束补齐(不阻塞运行,建议顺手执行) ----------
SET @ix := (SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'opportunity' AND INDEX_NAME = 'idx_source_lead');
SET @sql := IF(@ix = 0,
'ALTER TABLE `opportunity` ADD UNIQUE INDEX `idx_source_lead` (`source_lead_id`)',
'SELECT 1');
PREPARE st FROM @sql; EXECUTE st; DEALLOCATE PREPARE st;
SET @ix := (SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'opportunity' AND INDEX_NAME = 'idx_owner_status');
SET @sql := IF(@ix = 0,
'ALTER TABLE `opportunity` ADD INDEX `idx_owner_status` (`owner_user_id`, `opp_status`)',
'SELECT 1');
PREPARE st FROM @sql; EXECUTE st; DEALLOCATE PREPARE st;
SET @ix := (SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'opportunity' AND INDEX_NAME = 'idx_owner_dept_status');
SET @sql := IF(@ix = 0,
'ALTER TABLE `opportunity` ADD INDEX `idx_owner_dept_status` (`owner_dept_id`, `opp_status`)',
'SELECT 1');
PREPARE st FROM @sql; EXECUTE st; DEALLOCATE PREPARE st;
DROP PROCEDURE crm_add_column;
-- 执行完核对(应全部返回 0 行 = 缺列已补齐):
-- SELECT TABLE_NAME, COLUMN_NAME FROM information_schema.COLUMNS
-- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME IN ('opportunity','opportunity_customer')
-- AND COLUMN_NAME IN ('party_a_clear','project_amount','address','key_contact_id',
-- 'key_contact_name_snapshot','key_contact_company_snapshot',
-- 'customer_role','is_primary_intended');