284 lines
15 KiB
PL/PgSQL
284 lines
15 KiB
PL/PgSQL
-- =====================================================================
|
||
-- 2026-08-27 CRM 升级 - PostgreSQL 17
|
||
-- =====================================================================
|
||
-- 背景:
|
||
-- 1) 旧版库(archive/init_pg17.sql + 各增量升级脚本)中以下三个表的
|
||
-- biz_type CHECK 约束缺少 'crm' 值,而 CRM 拓展功能会写入
|
||
-- biz_type = 'crm'(日报反写 CRM 拜访记录、CRM 拓展新增拜访记录、
|
||
-- 外勤打卡关联 CRM 拓展、日报消息关联 CRM 拓展),会被旧约束拒绝。
|
||
-- 2) CRM 拓展主表 crm_crm_expansion 与多联系人子表
|
||
-- crm_crm_expansion_contact 的建表脚本在项目 SQL 中缺失,本次补齐,
|
||
-- 结构以当前库实际定义为准(含主键、外键、索引,无触发器/注释,
|
||
-- 子表无外键约束,与现有库保持一致)。
|
||
-- 3) 新增 crm_oms_dict_mapping:CRM 与 OMS 字典码值映射表,用于商机
|
||
-- 推送 OMS / OMS 导入回传时的字典码值转换。
|
||
-- 说明:init_full_pg17.sql(全新初始化)已包含正确约束;本脚本用于
|
||
-- 旧库增量升级。对新库执行同样安全(幂等:create if not exists、
|
||
-- drop constraint if exists)。
|
||
|
||
begin;
|
||
|
||
set search_path to public;
|
||
|
||
-- 1) crm_expansion_followup:跟进/拜访记录表,需支持 sales/channel/crm
|
||
alter table crm_expansion_followup
|
||
drop constraint if exists crm_expansion_followup_biz_type_check;
|
||
alter table crm_expansion_followup
|
||
add constraint crm_expansion_followup_biz_type_check
|
||
check (biz_type in ('sales', 'channel', 'crm'));
|
||
|
||
-- 2) work_checkin:外勤打卡,可关联 sales/channel/opportunity/crm
|
||
alter table work_checkin
|
||
drop constraint if exists work_checkin_biz_type_check;
|
||
alter table work_checkin
|
||
add constraint work_checkin_biz_type_check
|
||
check (biz_type is null or biz_type in ('sales', 'channel', 'opportunity', 'crm'));
|
||
|
||
-- 3) work_report_message:日报消息,可关联 sales/channel/opportunity/crm
|
||
alter table work_report_message
|
||
drop constraint if exists work_report_message_biz_type_check;
|
||
alter table work_report_message
|
||
add constraint work_report_message_biz_type_check
|
||
check (biz_type is null or biz_type in ('sales', 'channel', 'opportunity', 'crm'));
|
||
|
||
-- 4) CRM 拓展主表(结构与当前库实际定义一致)
|
||
create table if not exists crm_crm_expansion (
|
||
id bigint generated by default as identity primary key,
|
||
end_user varchar(200) not null,
|
||
office_name varchar(200) not null,
|
||
industry_attr varchar(200),
|
||
extension_type varchar(50) not null,
|
||
purchase_date date,
|
||
warranty_expiry date,
|
||
online_status varchar(50) not null,
|
||
contact_name varchar(100),
|
||
contact_phone varchar(50),
|
||
contact_title varchar(100),
|
||
supplier_id bigint,
|
||
h3c_contact_id bigint,
|
||
has_expansion_opportunity varchar(10),
|
||
owner_user_id bigint not null,
|
||
remark text,
|
||
created_at timestamptz not null default now(),
|
||
updated_at timestamptz not null default now(),
|
||
constraint fk_crm_crm_expansion_supplier
|
||
foreign key (supplier_id) references crm_channel_expansion(id),
|
||
constraint fk_crm_crm_expansion_h3c_contact
|
||
foreign key (h3c_contact_id) references crm_sales_expansion(id)
|
||
);
|
||
|
||
create index if not exists idx_crm_crm_expansion_owner
|
||
on crm_crm_expansion (owner_user_id);
|
||
|
||
create index if not exists idx_crm_crm_expansion_supplier
|
||
on crm_crm_expansion (supplier_id);
|
||
|
||
-- 5) CRM 拓展多联系人子表(结构与当前库实际定义一致)
|
||
create table if not exists crm_crm_expansion_contact (
|
||
id bigint generated by default as identity primary key,
|
||
crm_expansion_id bigint not null,
|
||
contact_name varchar(255),
|
||
contact_mobile varchar(64),
|
||
contact_title varchar(128),
|
||
sort_order integer not null default 0,
|
||
created_at timestamptz not null default now(),
|
||
updated_at timestamptz not null default now()
|
||
);
|
||
|
||
create index if not exists idx_crm_expansion_contact_expansion
|
||
on crm_crm_expansion_contact (crm_expansion_id);
|
||
|
||
-- 5.5) CRM 拓展主表新增字段:软件点数 / 扩容时间 / 扩容规模
|
||
-- 软件点数:整数;扩容时间:日期(与采购时间/过保时间一致用 date);
|
||
-- 扩容规模:文本。
|
||
alter table crm_crm_expansion
|
||
add column if not exists software_points int;
|
||
|
||
alter table crm_crm_expansion
|
||
add column if not exists expansion_time date;
|
||
|
||
alter table crm_crm_expansion
|
||
add column if not exists expansion_scale varchar(100);
|
||
|
||
comment on column crm_crm_expansion.software_points is '软件点数';
|
||
comment on column crm_crm_expansion.expansion_time is '扩容时间';
|
||
comment on column crm_crm_expansion.expansion_scale is '扩容规模';
|
||
|
||
-- 5.6) CRM 拓展主表新增字段:进货商名称 / 新华三对接人名称
|
||
-- 需求:进货商、新华三对接人在下拉里没有想选的人时,可直接手动输入文字保存。
|
||
-- 因此除保留 supplier_id / h3c_contact_id 关联外,新增名称冗余字段:
|
||
-- - 下拉选中时:存 id,并冗余存名称(supplier_name / h3c_contact_name)
|
||
-- - 手动输入时:supplier_id / h3c_contact_id 置空,名称存文本
|
||
-- 列表/详情展示以名称字段优先,历史仅有 id 的旧数据回退用 JOIN 关联名称。
|
||
alter table crm_crm_expansion
|
||
add column if not exists supplier_name varchar(255);
|
||
|
||
alter table crm_crm_expansion
|
||
add column if not exists h3c_contact_name varchar(255);
|
||
|
||
comment on column crm_crm_expansion.supplier_name is '进货商名称(下拉选中冗余存名;手动输入时存文字)';
|
||
comment on column crm_crm_expansion.h3c_contact_name is '新华三对接人名称(下拉选中冗余存名;手动输入时存文字)';
|
||
|
||
-- 5.7) CRM 拓展主表新增字段:是否有维保项目机会
|
||
-- 使用系统字典 sys_is:1是 / 0否
|
||
alter table crm_crm_expansion
|
||
add column if not exists has_maintenance_opportunity varchar(10);
|
||
|
||
comment on column crm_crm_expansion.has_maintenance_opportunity is '是否有维保项目机会(系统是否字典 sys_is:1是 / 0否)';
|
||
|
||
-- 6) CRM 与 OMS 字典码值映射表:用于商机推送 OMS / OMS 导入回传时做字典码值转换
|
||
create table if not exists crm_oms_dict_mapping (
|
||
id bigint generated by default as identity primary key,
|
||
dict_type varchar(50) not null,
|
||
crm_value varchar(100) not null,
|
||
crm_label varchar(200),
|
||
oms_value varchar(100) not null,
|
||
oms_label varchar(200),
|
||
remark varchar(500),
|
||
status smallint not null default 1,
|
||
is_default boolean not null default false,
|
||
created_at timestamptz not null default now(),
|
||
updated_at timestamptz not null default now(),
|
||
constraint uk_crm_oms_dict_mapping unique (dict_type, crm_value, oms_value)
|
||
);
|
||
|
||
comment on table crm_oms_dict_mapping is 'CRM与OMS字典码值映射表';
|
||
comment on column crm_oms_dict_mapping.dict_type is '字典类型(如 opportunity_stage 商机阶段、opportunity_type 商机类型)';
|
||
comment on column crm_oms_dict_mapping.crm_value is 'CRM侧字典码值(item_value)';
|
||
comment on column crm_oms_dict_mapping.crm_label is 'CRM侧字典标签(冗余,便于核对)';
|
||
comment on column crm_oms_dict_mapping.oms_value is 'OMS侧码值';
|
||
comment on column crm_oms_dict_mapping.oms_label is 'OMS侧标签(冗余,便于核对)';
|
||
comment on column crm_oms_dict_mapping.remark is '备注';
|
||
comment on column crm_oms_dict_mapping.status is '状态:1 启用 0 停用';
|
||
comment on column crm_oms_dict_mapping.is_default is '是否为默认映射:true 是 false 否(用于CRM推OMS时的默认匹配)';
|
||
comment on column crm_oms_dict_mapping.created_at is '创建时间';
|
||
comment on column crm_oms_dict_mapping.updated_at is '更新时间';
|
||
|
||
-- 7) 初始化数据:项目阶段(sj_xmjd)映射
|
||
insert into crm_oms_dict_mapping (dict_type, crm_value, crm_label, oms_value, oms_label, is_default)
|
||
values
|
||
('sj_xmjd', 'S0', 'S0-配置报价', 'S0', 'S0-配置报价', true),
|
||
('sj_xmjd', 'S1', 'S1-深化设计', 'S1', 'S1-标前引导', true),
|
||
('sj_xmjd', 'S1', 'S1-深化设计', 'S2', 'S2-招投标签', false),
|
||
('sj_xmjd', 'S2', 'S2-招投标签', 'S3', 'S3-招投标签期', true),
|
||
('sj_xmjd', 'S3', 'S3-中标未下单', 'S4A', 'S4A-中标未签(总包)', false),
|
||
('sj_xmjd', 'S3', 'S3-中标未下单', 'S4B', 'S4B-中标未签(省代)', false),
|
||
('sj_xmjd', 'S3', 'S3-中标未下单', 'S4C', 'S4C-中标未签(汇智)', true),
|
||
('sj_xmjd', 'S4', 'S4-下单未签单', 'S5', 'S5-订单合同签订期', true),
|
||
('sj_xmjd', 'S5', 'S5-已签单', 'S6', 'S6-订单合同已生效', true),
|
||
('sj_xmjd', 'S5', 'S5-已签单', 'S7A', 'S7A-订单部分发货', false),
|
||
('sj_xmjd', 'S5', 'S5-已签单', 'S7B', 'S7B-订单全部发货', false),
|
||
('sj_xmjd', 'S5', 'S5-已签单', 'S8', 'S8-已签收', false),
|
||
('sj_xmjd', 'L', 'L-已丢单', 'L', 'L-已丢单', true)
|
||
on conflict (dict_type, crm_value, oms_value) do nothing;
|
||
|
||
-- 8) 渠道拓展覆盖地市:改为从表存储(便于后期统计)
|
||
-- 覆盖关系存 crm_channel_expansion_coverage,每行一个覆盖项(省/市)。
|
||
-- 主表原有的 coverage_province / coverage_city 两列已废弃,
|
||
-- 历史数据迁移到从表后删除,查询/写入均改为读写从表,避免冗余与不一致。
|
||
|
||
create table if not exists crm_channel_expansion_coverage (
|
||
id bigserial primary key,
|
||
channel_id bigint not null references crm_channel_expansion(id) on delete cascade,
|
||
province varchar(100),
|
||
city varchar(100)
|
||
);
|
||
|
||
comment on table crm_channel_expansion_coverage is '渠道拓展覆盖地市明细(每行一个覆盖项)';
|
||
comment on column crm_channel_expansion_coverage.province is '覆盖省份(cnarea 一级区域名称,city 为空表示全省)';
|
||
comment on column crm_channel_expansion_coverage.city is '覆盖市/区/县(cnarea 二级区域名称)';
|
||
|
||
create index if not exists idx_cec_channel_id on crm_channel_expansion_coverage(channel_id);
|
||
create index if not exists idx_cec_province on crm_channel_expansion_coverage(province);
|
||
create index if not exists idx_cec_city on crm_channel_expansion_coverage(city);
|
||
|
||
|
||
-- ---------------------------------------------------------------------
|
||
-- 9.5) 销售人员拓展所属区域:改为从表存储(参考渠道拓展"覆盖地市"结构)
|
||
-- 所属区域为多选下拉,每个选中项存为一行(省/市),
|
||
-- 关联 crm_sales_expansion(id),on delete cascade。
|
||
-- ---------------------------------------------------------------------
|
||
|
||
create table if not exists crm_sales_expansion_coverage (
|
||
id bigserial primary key,
|
||
sales_expansion_id bigint not null references crm_sales_expansion(id) on delete cascade,
|
||
province varchar(100),
|
||
city varchar(100)
|
||
);
|
||
|
||
comment on table crm_sales_expansion_coverage is '销售人员拓展所属区域明细(每行一个区域项)';
|
||
comment on column crm_sales_expansion_coverage.province is '所属省份(cnarea 一级区域名称,city 为空表示全省)';
|
||
comment on column crm_sales_expansion_coverage.city is '所属市/区/县(cnarea 二级区域名称)';
|
||
|
||
create index if not exists idx_csec_sales_expansion_id on crm_sales_expansion_coverage(sales_expansion_id);
|
||
create index if not exists idx_csec_province on crm_sales_expansion_coverage(province);
|
||
create index if not exists idx_csec_city on crm_sales_expansion_coverage(city);
|
||
|
||
|
||
-- ---------------------------------------------------------------------
|
||
-- 9) work_checkin.id 序列同步(打卡主键改为 identity 自动生成)
|
||
-- 背景:历史版本 insertCheckIn 使用 max(id)+1 显式主键,identity 序列
|
||
-- 从未推进;且历史遗留存在 work_checkin_id_seq / _seq1 双序列。
|
||
-- 现 insertCheckIn 已改为由 identity 自动生成主键,需将 identity 实际
|
||
-- 绑定的序列同步到表内 max(id),避免后续插入主键冲突。
|
||
-- 使用 pg_get_serial_sequence 动态解析实际序列,避免对错序列。
|
||
-- 幂等:重复执行结果一致,可安全用于任意环境。
|
||
-- ---------------------------------------------------------------------
|
||
do $$
|
||
declare
|
||
seq_name text;
|
||
begin
|
||
select pg_get_serial_sequence('work_checkin', 'id') into seq_name;
|
||
if seq_name is not null then
|
||
execute format('select setval(%L, coalesce((select max(id) from work_checkin), 0) + 1, false)', seq_name);
|
||
raise notice 'work_checkin.id 序列 % 已同步', seq_name;
|
||
else
|
||
raise notice '未找到 work_checkin.id 的 identity 序列';
|
||
end if;
|
||
end $$;
|
||
|
||
|
||
-- ---------------------------------------------------------------------
|
||
-- 10) 渠道拓展新增字段:注册资金
|
||
-- 需求:渠道拓展页面新增「注册资金」字段,必填,前端位置在「人员规模」
|
||
-- 字段之后。单位与年度营业额一致(万元),numeric(18,2)。
|
||
-- 幂等:add column if not exists,可安全用于任意环境。
|
||
-- ---------------------------------------------------------------------
|
||
|
||
alter table crm_channel_expansion
|
||
add column if not exists registered_capital numeric(18, 2);
|
||
|
||
comment on column crm_channel_expansion.registered_capital is '注册资金(万元)';
|
||
|
||
|
||
-- ---------------------------------------------------------------------
|
||
-- 11) 渠道拓展联系人新增字段:工作职责 / 生日 / 是否加企业微信 / 特别说明
|
||
-- 需求:渠道联系人固定 6 行,工作职责不可编辑,固定为
|
||
-- 销售负责人、技术负责人、商务负责人、宣传负责人、
|
||
-- 订单通知接单人、汇智日常联络人。
|
||
-- 除生日选填外,其余联系人字段均必填(至少完整填写一行)。
|
||
-- 是否加企业微信使用系统「是否」字典(sys_is):是(1) / 否(0)。
|
||
-- 工作职责为固定 6 项:销售负责人 / 技术负责人 / 商务负责人 /
|
||
-- 宣传负责人 / 订单通知接单人 / 汇智日常联络人。
|
||
-- 幂等:add column if not exists,可安全用于任意环境。
|
||
-- ---------------------------------------------------------------------
|
||
|
||
alter table crm_channel_expansion_contact
|
||
add column if not exists duty varchar(50);
|
||
|
||
alter table crm_channel_expansion_contact
|
||
add column if not exists birthday date;
|
||
|
||
alter table crm_channel_expansion_contact
|
||
add column if not exists wecom_added varchar(100);
|
||
|
||
alter table crm_channel_expansion_contact
|
||
add column if not exists special_note text;
|
||
|
||
comment on column crm_channel_expansion_contact.duty is '工作职责(固定6项之一:销售负责人/技术负责人/商务负责人/宣传负责人/订单通知接单人/汇智日常联络人)';
|
||
comment on column crm_channel_expansion_contact.birthday is '生日';
|
||
comment on column crm_channel_expansion_contact.wecom_added is '是否加企业微信(系统是否字典 sys_is:1是 / 0否)';
|
||
comment on column crm_channel_expansion_contact.special_note is '特别说明';
|
||
|
||
commit;
|