This commit is contained in:
wk committed 2026-10-07 08:59:03 +08:00
commit 737244fa9e
36 files changed
+3309 -246

No files matched your search

+88 -13
View File
@@ -132,10 +132,14 @@ ON CONFLICT (id) DO UPDATE SET
permission = EXCLUDED.permission,
visible = EXCLUDED.visible;
-- 初始菜单(运营派单子菜单,parent_id=3,id:36-37)
-- 初始菜单(运营派单子菜单,parent_id=3,id:55-56)
-- 运营派单域统一 id 分配(避免历史上 36/37 被两段 INSERT 复用而互相覆盖):
-- 34 运维费定价 / 35 勘察费用(归属项目管理 parent_id=2) / 36 电工登记管理
-- 37-46 按钮权限
-- 55 报修派单 / 56 维保派单
INSERT INTO sys_menu (id, parent_id, menu_name, menu_path, component, icon, sort_order, menu_type, permission, visible) VALUES
(36, 3, '报修派单', '/dispatch/repair', 'dispatch/repair/index', 'ToolOutlined', 1, 2, 'dispatch:repair', 1),
(37, 3, '维保派单', '/dispatch/maintenance', 'dispatch/maintenance/index', 'ToolOutlined', 2, 2, 'dispatch:maintenance',1)
(55, 3, '报修派单', '/dispatch/repair', 'dispatch/repair/index', 'ToolOutlined', 4, 2, 'dispatch:repair', 1),
(56, 3, '维保派单', '/dispatch/maintenance', 'dispatch/maintenance/index', 'ToolOutlined', 5, 2, 'dispatch:maintenance',1)
ON CONFLICT (id) DO UPDATE SET
parent_id = EXCLUDED.parent_id,
menu_name = EXCLUDED.menu_name,
@@ -147,17 +151,17 @@ ON CONFLICT (id) DO UPDATE SET
permission = EXCLUDED.permission,
visible = EXCLUDED.visible;
-- 运营派单子菜单(parent_id=3,id:34-36 为菜单项,37-46 为按钮权限)
-- 运营派单子菜单(parent_id=3;其中 35 勘察费用及其按钮 40/41/42 已归属项目管理 parent_id=2;id:34/36 为菜单项,37-39/43-46 为按钮权限)
INSERT INTO sys_menu (id, parent_id, menu_name, menu_path, component, icon, sort_order, menu_type, permission, visible) VALUES
(34, 3, '运维费定价', '/dispatch/price', 'dispatch/price/index', 'MoneyCollectOutlined', 1, 2, 'dispatch:price', 1),
(35, 3, '电工派单成本价', '/dispatch/cost', 'dispatch/cost/index', 'AccountBookOutlined', 2, 2, 'dispatch:cost', 1),
(36, 3, '电工登记管理', '/dispatch/worker', 'dispatch/worker/index', 'ToolOutlined', 3, 2, 'dispatch:worker', 1),
(34, 3, '运维费定价', '/dispatch/price', 'dispatch/price/index', 'MoneyCollectOutlined', 2, 2, 'dispatch:price', 1),
(35, 2, '勘察费用', '/dispatch/cost', 'dispatch/cost/index', 'AccountBookOutlined', 8, 2, 'dispatch:cost', 1),
(36, 3, '电工登记管理', '/dispatch/worker', 'dispatch/worker/index', 'ToolOutlined', 1, 2, 'dispatch:worker', 1),
(37, 3, '新增价目', NULL, NULL, NULL, 1, 3, 'price:create', 1),
(38, 3, '编辑价目', NULL, NULL, NULL, 2, 3, 'price:update', 1),
(39, 3, '删除价目', NULL, NULL, NULL, 3, 3, 'price:delete', 1),
(40, 3, '新增成本价', NULL, NULL, NULL, 4, 3, 'cost:create', 1),
(41, 3, '编辑成本价', NULL, NULL, NULL, 5, 3, 'cost:update', 1),
(42, 3, '删除成本价', NULL, NULL, NULL, 6, 3, 'cost:delete', 1),
(40, 2, '新增勘察费用', NULL, NULL, NULL, 9, 3, 'cost:create', 1),
(41, 2, '编辑勘察费用', NULL, NULL, NULL, 10, 3, 'cost:update', 1),
(42, 2, '删除勘察费用', NULL, NULL, NULL, 11, 3, 'cost:delete', 1),
(43, 3, '新增电工', NULL, NULL, NULL, 7, 3, 'worker:create', 1),
(44, 3, '编辑电工', NULL, NULL, NULL, 8, 3, 'worker:update', 1),
(45, 3, '删除电工', NULL, NULL, NULL, 9, 3, 'worker:delete', 1),
@@ -256,11 +260,11 @@ ON CONFLICT (user_id, role_id) DO NOTHING;
INSERT INTO sys_role_menu (role_id, menu_id) VALUES
(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (1, 11),
(1, 12), (1, 13), (1, 14), (1, 15), (1, 16), (1, 17), (1, 18), (1, 19), (1, 20), (1, 21), (1, 22), (1, 23),
(1, 24), (1, 27), (1, 28), (1, 29), (1, 30), (1, 31), (1, 32), (1, 33), (1, 36), (1, 37),
(1, 24), (1, 27), (1, 28), (1, 29), (1, 30), (1, 31), (1, 32), (1, 33), (1, 55), (1, 56),
(1, 34), (1, 35), (1, 36), (1, 37), (1, 38), (1, 39), (1, 40), (1, 41), (1, 42), (1, 43), (1, 44), (1, 45), (1, 46),
(2, 1), (2, 2), (2, 5),
(2, 12), (2, 13), (2, 14), (2, 15), (2, 16), (2, 17), (2, 18), (2, 19), (2, 20), (2, 21), (2, 22), (2, 23),
(2, 24), (2, 27), (2, 28), (2, 29), (2, 30), (2, 31), (2, 32), (2, 33), (2, 36), (2, 37)
(2, 24), (2, 27), (2, 28), (2, 29), (2, 30), (2, 31), (2, 32), (2, 33), (2, 55), (2, 56)
ON CONFLICT (role_id, menu_id) DO NOTHING;
-- 移除已废弃的菜单(客户建筑/客户房间,id=25/26)及其角色绑定(幂等清理,确保每次执行都收敛)
@@ -330,8 +334,79 @@ INSERT INTO sys_job (job_key, job_name, cron_expression, params, retry_times, re
'日志清理任务:每日 03:00 清理早于 keepDays 天的操作日志与任务日志,默认保留 90 天')
ON CONFLICT (job_key) DO NOTHING;
-- ------------------------------------------------------------
-- 9. 通知域菜单(系统管理 parent_id=6,id:51 为菜单项,52-54 为按钮权限)
-- ------------------------------------------------------------
INSERT INTO sys_menu (id, parent_id, menu_name, menu_path, component, icon, sort_order, menu_type, permission, visible) VALUES
(51, 6, '通知管理', '/system/notice', 'system/notice/index', 'BellOutlined', 7, 2, 'notice:rule', 1),
(52, 51, '保存规则', NULL, NULL, NULL, 1, 3, 'notice:rule:update', 1),
(53, 51, '删除规则', NULL, NULL, NULL, 2, 3, 'notice:rule:delete', 1),
(54, 51, '群发消息', NULL, NULL, NULL, 3, 3, 'notice:batch', 1)
ON CONFLICT (id) DO UPDATE SET
parent_id = EXCLUDED.parent_id,
menu_name = EXCLUDED.menu_name,
menu_path = EXCLUDED.menu_path,
component = EXCLUDED.component,
icon = EXCLUDED.icon,
sort_order = EXCLUDED.sort_order,
menu_type = EXCLUDED.menu_type,
permission = EXCLUDED.permission,
visible = EXCLUDED.visible;
-- 角色-菜单绑定:ADMIN(role_id=1)拥有 51-54
INSERT INTO sys_role_menu (role_id, menu_id) VALUES
(1, 51), (1, 52), (1, 53), (1, 54)
ON CONFLICT (role_id, menu_id) DO NOTHING;
-- 重置 sys_menu 自增序列
SELECT setval('sys_menu_id_seq', 56, true);
-- ------------------------------------------------------------
-- 10. 通知规则扫描任务种子(sys_job,按 job_key 幂等)
-- ------------------------------------------------------------
INSERT INTO sys_job (job_key, job_name, cron_expression, params, retry_times, retry_interval, status, remark) VALUES
('notice_scan', '通知规则扫描', '0 0 8 * * *', '{}'::jsonb, 1, 300, 1,
'遍历启用的扫描式通知规则,按模板与接收对象生成站内通知(幂等,默认每日 08:00)')
ON CONFLICT (job_key) DO NOTHING;
-- ------------------------------------------------------------
-- 11. 通知规则种子(sys_notice_rule,按 rule_key 幂等;接收对象可在「通知管理」页调整)
-- ------------------------------------------------------------
INSERT INTO sys_notice_rule (rule_key, rule_name, event_key, trigger_mode, enabled, advance_days, title_tpl, content_tpl, receiver_config, remark) VALUES
('cert_expire', '电工资质证照到期提醒', 'cert_expire', 1, 1, 30,
'电工【{workerName}】的{certType}{expireState}',
'证书编号:{certNo};发证机关:{issueAuthority};有效期至:{expireDate};{remainDaysText},请及时提醒电工办理续期',
'{"users":{"roles":["ADMIN"],"ids":[]},"workers":{"mode":"event","ids":[]}}'::jsonb,
'扫描 worker_cert 中 advance_days 天内到期或已过期的证照,通知 ADMIN 与证照所属电工'),
('worker_audit_result', '电工入驻审核结果通知', 'worker_audit_result', 2, 1, NULL,
'您的入驻审核{auditState}',
'审核{auditState};{auditRemarkText}如资料有误,请修改后重新提交。',
'{"users":{"roles":[],"ids":[]},"workers":{"mode":"event","ids":[]}}'::jsonb,
'审核通过/驳回时实时通知电工本人(业务埋点触发)'),
('dispatch_assign', '工单派单通知', 'dispatch_assign', 2, 1, NULL,
'您有新的{orderTypeName}工单',
'工单编号:{orderNo};客户:{customerName};{detailText}请及时在电工端查看并接单。',
'{"users":{"roles":[],"ids":[]},"workers":{"mode":"event","ids":[]}}'::jsonb,
'勘察/安装/维保/报修派单时实时通知被指派电工(业务埋点触发)'),
('contract_expire', '客户合同到期提醒', 'contract_expire', 1, 1, 30,
'客户【{customerName}】的合同{expireState}',
'合同编号:{contractNo};合同名称:{contractName};到期日:{endDate};{remainDaysText},请及时跟进续签。',
'{"users":{"roles":["ADMIN"],"ids":[]},"workers":{"mode":"none","ids":[]}}'::jsonb,
'扫描 contract 中 advance_days 天内到期或已过期的合同,通知 ADMIN'),
('visit_plan', '客户拜访计划提醒', 'visit_plan', 1, 1, 0,
'客户拜访计划待执行:{customerName}',
'计划拜访日期:{planDate};{remainDaysText}。请及时完成拜访。',
'{"users":{"roles":["ADMIN"],"ids":[]},"workers":{"mode":"none","ids":[]}}'::jsonb,
'扫描 customer_visit 中未执行且计划日期已到/超期的拜访计划,通知 ADMIN'),
('order_timeout', '工单超时未接单提醒', 'order_timeout', 1, 1, 1,
'工单超时未接单:{orderTypeName}',
'工单编号:{orderNo};客户:{customerName};已派单 {staleDays} 天仍未接单,请及时跟进。',
'{"users":{"roles":["ADMIN"],"ids":[]},"workers":{"mode":"none","ids":[]}}'::jsonb,
'扫描派单后超过 advance_days 天仍未接单的工单,通知 ADMIN')
ON CONFLICT (rule_key) DO NOTHING;
COMMIT;
-- ============================================================
-- 完 · 系统表种子数据(4 角色 + 50 菜单 + 43 字典 + 1 管理员 + 2 定时任务 + 绑定关系)
-- 完 · 系统表种子数据(4 角色 + 54 菜单 + 43 字典 + 1 管理员 + 3 定时任务 + 6 通知规则 + 绑定关系)
-- ============================================================
@@ -138,14 +138,14 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_notice_biz ON sys_notice (notice_type,
-- ------------------------------------------------------------
-- 6) 菜单与权限
-- 「运营派单」由顶级菜单项改为目录,运维费定价/成本价/电工登记作为其子菜单
-- 「运营派单」由顶级菜单项改为目录,运维费定价/电工登记作为其子菜单(勘察费用归属「项目管理」)
-- ------------------------------------------------------------
UPDATE sys_menu SET menu_type = 1 WHERE id = 3;
INSERT INTO sys_menu (id, parent_id, menu_name, menu_path, component, icon, sort_order, menu_type, permission, visible) VALUES
(34, 3, '运维费定价', '/dispatch/price', 'dispatch/price/index', 'MoneyCollectOutlined', 1, 2, 'dispatch:price', 1),
(35, 3, '电工派单成本价', '/dispatch/cost', 'dispatch/cost/index', 'AccountBookOutlined', 2, 2, 'dispatch:cost', 1),
(36, 3, '电工登记管理', '/dispatch/worker', 'dispatch/worker/index', 'ToolOutlined', 3, 2, 'dispatch:worker', 1)
(34, 3, '运维费定价', '/dispatch/price', 'dispatch/price/index', 'MoneyCollectOutlined', 2, 2, 'dispatch:price', 1),
(35, 2, '勘察费用', '/dispatch/cost', 'dispatch/cost/index', 'AccountBookOutlined', 8, 2, 'dispatch:cost', 1),
(36, 3, '电工登记管理', '/dispatch/worker', 'dispatch/worker/index', 'ToolOutlined', 1, 2, 'dispatch:worker', 1)
ON CONFLICT (id) DO UPDATE SET
parent_id = EXCLUDED.parent_id,
menu_name = EXCLUDED.menu_name,
@@ -162,9 +162,9 @@ INSERT INTO sys_menu (id, parent_id, menu_name, menu_path, component, icon, sort
(37, 3, '新增价目', NULL, NULL, NULL, 1, 3, 'price:create', 1),
(38, 3, '编辑价目', NULL, NULL, NULL, 2, 3, 'price:update', 1),
(39, 3, '删除价目', NULL, NULL, NULL, 3, 3, 'price:delete', 1),
(40, 3, '新增成本价', NULL, NULL, NULL, 4, 3, 'cost:create', 1),
(41, 3, '编辑成本价', NULL, NULL, NULL, 5, 3, 'cost:update', 1),
(42, 3, '删除成本价', NULL, NULL, NULL, 6, 3, 'cost:delete', 1),
(40, 2, '新增勘察费用', NULL, NULL, NULL, 9, 3, 'cost:create', 1),
(41, 2, '编辑勘察费用', NULL, NULL, NULL, 10, 3, 'cost:update', 1),
(42, 2, '删除勘察费用', NULL, NULL, NULL, 11, 3, 'cost:delete', 1),
(43, 3, '新增电工', NULL, NULL, NULL, 7, 3, 'worker:create', 1),
(44, 3, '编辑电工', NULL, NULL, NULL, 8, 3, 'worker:update', 1),
(45, 3, '删除电工', NULL, NULL, NULL, 9, 3, 'worker:delete', 1),
@@ -0,0 +1,161 @@
-- 可配置消息通知中心
-- 背景:现有站内通知为硬编码单点(仅「证照到期」一种、标题模板写死、接收人写死为 ADMIN),
-- 且仅 Web 管理端可见;两个移动端(管理端 App / 电工端 App)没有消息中心。
-- 本期建立「可配置 + 两端统一」的站内消息中心:
-- - 改造 sys_notice:新增 receiver_type(user|worker),两端共用一套消息数据;
-- - 新增 sys_notice_rule(通知规则模板 + 接收对象配置);
-- - 新增 sys_notice_batch(手动群发批次/发送记录);
-- - 新增内置任务 notice_scan(扫描式规则统一入口)与首批规则种子;
-- - 挂载系统管理下的「通知管理」菜单与按钮权限。
-- 幂等:新增列带 DEFAULT + IF NOT EXISTS;建表/索引用 IF NOT EXISTS;菜单/绑定用 ON CONFLICT;
-- 任务与规则种子用 ON CONFLICT DO NOTHING。
-- 注意:菜单 id 51-54,避开 20261001(34-46)与 20261002(47-50)已占用区间。
BEGIN;
-- ------------------------------------------------------------
-- 1) 改造 sys_notice:增加接收人类型与来源引用
-- ------------------------------------------------------------
ALTER TABLE sys_notice ADD COLUMN IF NOT EXISTS receiver_type VARCHAR(16) NOT NULL DEFAULT 'user'; -- 接收人类型:user-管理端用户 worker-电工
ALTER TABLE sys_notice ADD COLUMN IF NOT EXISTS rule_id BIGINT; -- 来源通知规则(→ sys_notice_rule.id)
ALTER TABLE sys_notice ADD COLUMN IF NOT EXISTS batch_id BIGINT; -- 来源群发批次(→ sys_notice_batch.id)
COMMENT ON COLUMN sys_notice.receiver_type IS '接收人类型:user-管理端用户 worker-电工';
COMMENT ON COLUMN sys_notice.rule_id IS '来源通知规则(→ sys_notice_rule.id)';
COMMENT ON COLUMN sys_notice.batch_id IS '来源群发批次(→ sys_notice_batch.id)';
-- 幂等键升级:加入 receiver_type(user 与 worker 的 id 空间不同,必须区分)
DROP INDEX IF EXISTS uk_sys_notice_biz;
CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_notice_deliver
ON sys_notice (notice_type, biz_type, biz_id, receiver_type, receiver_id);
CREATE INDEX IF NOT EXISTS idx_sys_notice_receiver_type ON sys_notice (receiver_type, receiver_id, is_read);
-- ------------------------------------------------------------
-- 2) 通知规则表(规则模板 + 接收对象配置)
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS sys_notice_rule (
id BIGSERIAL PRIMARY KEY,
rule_key VARCHAR(64) NOT NULL, -- 规则键(唯一)
rule_name VARCHAR(64) NOT NULL, -- 规则名称
event_key VARCHAR(64) NOT NULL, -- 事件键(对应代码事件注册表)
trigger_mode SMALLINT NOT NULL DEFAULT 1, -- 触发方式:1扫描式 2埋点式
enabled SMALLINT NOT NULL DEFAULT 1, -- 状态:1启用 0停用
advance_days INT, -- 提前天数(扫描式)
title_tpl VARCHAR(128) NOT NULL, -- 标题模板(支持 {变量})
content_tpl VARCHAR(512) NOT NULL, -- 正文模板(支持 {变量})
receiver_config JSONB NOT NULL DEFAULT '{"users":{"roles":[],"ids":[]},"workers":{"mode":"none","ids":[]}}'::jsonb, -- 接收对象配置
remark VARCHAR(255), -- 备注
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
COMMENT ON TABLE sys_notice_rule IS '通知规则表(模板 + 接收对象)';
COMMENT ON COLUMN sys_notice_rule.id IS '自增主键';
COMMENT ON COLUMN sys_notice_rule.rule_key IS '规则键(唯一)';
COMMENT ON COLUMN sys_notice_rule.rule_name IS '规则名称';
COMMENT ON COLUMN sys_notice_rule.event_key IS '事件键(对应代码事件注册表)';
COMMENT ON COLUMN sys_notice_rule.trigger_mode IS '触发方式:1扫描式 2埋点式';
COMMENT ON COLUMN sys_notice_rule.enabled IS '状态:1启用 0停用';
COMMENT ON COLUMN sys_notice_rule.advance_days IS '提前天数(扫描式)';
COMMENT ON COLUMN sys_notice_rule.title_tpl IS '标题模板(支持 {变量})';
COMMENT ON COLUMN sys_notice_rule.content_tpl IS '正文模板(支持 {变量})';
COMMENT ON COLUMN sys_notice_rule.receiver_config IS '接收对象配置:users{roles,ids} + workers{mode:none|event|all|ids|status,ids,auditStatus,status}';
COMMENT ON COLUMN sys_notice_rule.remark IS '备注';
COMMENT ON COLUMN sys_notice_rule.created_at IS '创建时间';
COMMENT ON COLUMN sys_notice_rule.updated_at IS '更新时间';
CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_notice_rule_key ON sys_notice_rule (rule_key);
CREATE INDEX IF NOT EXISTS idx_sys_notice_rule_event ON sys_notice_rule (event_key, trigger_mode, enabled);
-- ------------------------------------------------------------
-- 3) 手动群发批次表(发送记录)
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS sys_notice_batch (
id BIGSERIAL PRIMARY KEY,
title VARCHAR(128) NOT NULL, -- 消息标题
content VARCHAR(512) NOT NULL, -- 消息正文
receiver_config JSONB NOT NULL DEFAULT '{"users":{"roles":[],"ids":[]},"workers":{"mode":"none","ids":[]}}'::jsonb, -- 接收对象快照
receiver_count INT NOT NULL DEFAULT 0, -- 实际接收人数
sent_by BIGINT, -- 发送人(→ sys_user.id)
sent_at TIMESTAMPTZ NOT NULL DEFAULT NOW() -- 发送时间
);
COMMENT ON TABLE sys_notice_batch IS '手动群发批次表(发送记录)';
COMMENT ON COLUMN sys_notice_batch.id IS '自增主键';
COMMENT ON COLUMN sys_notice_batch.title IS '消息标题';
COMMENT ON COLUMN sys_notice_batch.content IS '消息正文';
COMMENT ON COLUMN sys_notice_batch.receiver_config IS '接收对象快照';
COMMENT ON COLUMN sys_notice_batch.receiver_count IS '实际接收人数';
COMMENT ON COLUMN sys_notice_batch.sent_by IS '发送人(→ sys_user.id)';
COMMENT ON COLUMN sys_notice_batch.sent_at IS '发送时间';
-- ------------------------------------------------------------
-- 4) 菜单与权限(系统管理 parent_id=6 下新增「通知管理」+ 3 个按钮权限)
-- ------------------------------------------------------------
INSERT INTO sys_menu (id, parent_id, menu_name, menu_path, component, icon, sort_order, menu_type, permission, visible) VALUES
(51, 6, '通知管理', '/system/notice', 'system/notice/index', 'BellOutlined', 7, 2, 'notice:rule', 1),
(52, 51, '保存规则', NULL, NULL, NULL, 1, 3, 'notice:rule:update', 1),
(53, 51, '删除规则', NULL, NULL, NULL, 2, 3, 'notice:rule:delete', 1),
(54, 51, '群发消息', NULL, NULL, NULL, 3, 3, 'notice:batch', 1)
ON CONFLICT (id) DO UPDATE SET
parent_id = EXCLUDED.parent_id,
menu_name = EXCLUDED.menu_name,
menu_path = EXCLUDED.menu_path,
component = EXCLUDED.component,
icon = EXCLUDED.icon,
sort_order = EXCLUDED.sort_order,
menu_type = EXCLUDED.menu_type,
permission = EXCLUDED.permission,
visible = EXCLUDED.visible;
-- 角色绑定:ADMIN(role_id=1)拥有 51~54
INSERT INTO sys_role_menu (role_id, menu_id) VALUES
(1, 51), (1, 52), (1, 53), (1, 54)
ON CONFLICT (role_id, menu_id) DO NOTHING;
-- 重置 sys_menu 自增序列,避免后续插入 id 冲突
SELECT setval('sys_menu_id_seq', 54, true);
-- ------------------------------------------------------------
-- 5) 内置任务种子:通知规则扫描(扫描式规则的统一入口)
-- ------------------------------------------------------------
INSERT INTO sys_job (job_key, job_name, cron_expression, params, retry_times, retry_interval, status, remark) VALUES
('notice_scan', '通知规则扫描', '0 0 8 * * *', '{}'::jsonb, 1, 300, 1,
'遍历启用的扫描式通知规则,按模板与接收对象生成站内通知(幂等,默认每日 08:00)')
ON CONFLICT (job_key) DO NOTHING;
-- ------------------------------------------------------------
-- 6) 首批通知规则种子(按 rule_key 幂等;接收对象均可在「通知管理」页调整)
-- ------------------------------------------------------------
INSERT INTO sys_notice_rule (rule_key, rule_name, event_key, trigger_mode, enabled, advance_days, title_tpl, content_tpl, receiver_config, remark) VALUES
('cert_expire', '电工资质证照到期提醒', 'cert_expire', 1, 1, 30,
'电工【{workerName}】的{certType}{expireState}',
'证书编号:{certNo};发证机关:{issueAuthority};有效期至:{expireDate};{remainDaysText},请及时提醒电工办理续期',
'{"users":{"roles":["ADMIN"],"ids":[]},"workers":{"mode":"event","ids":[]}}'::jsonb,
'扫描 worker_cert 中 advance_days 天内到期或已过期的证照,通知 ADMIN 与证照所属电工'),
('worker_audit_result', '电工入驻审核结果通知', 'worker_audit_result', 2, 1, NULL,
'您的入驻审核{auditState}',
'审核{auditState};{auditRemarkText}如资料有误,请修改后重新提交。',
'{"users":{"roles":[],"ids":[]},"workers":{"mode":"event","ids":[]}}'::jsonb,
'审核通过/驳回时实时通知电工本人(业务埋点触发)'),
('dispatch_assign', '工单派单通知', 'dispatch_assign', 2, 1, NULL,
'您有新的{orderTypeName}工单',
'工单编号:{orderNo};客户:{customerName};{detailText}请及时在电工端查看并接单。',
'{"users":{"roles":[],"ids":[]},"workers":{"mode":"event","ids":[]}}'::jsonb,
'勘察/安装/维保/报修派单时实时通知被指派电工(业务埋点触发)'),
('contract_expire', '客户合同到期提醒', 'contract_expire', 1, 1, 30,
'客户【{customerName}】的合同{expireState}',
'合同编号:{contractNo};合同名称:{contractName};到期日:{endDate};{remainDaysText},请及时跟进续签。',
'{"users":{"roles":["ADMIN"],"ids":[]},"workers":{"mode":"none","ids":[]}}'::jsonb,
'扫描 contract 中 advance_days 天内到期或已过期的合同,通知 ADMIN'),
('visit_plan', '客户拜访计划提醒', 'visit_plan', 1, 1, 0,
'客户拜访计划待执行:{customerName}',
'计划拜访日期:{planDate};{remainDaysText}。请及时完成拜访。',
'{"users":{"roles":["ADMIN"],"ids":[]},"workers":{"mode":"none","ids":[]}}'::jsonb,
'扫描 customer_visit 中未执行且计划日期已到/超期的拜访计划,通知 ADMIN'),
('order_timeout', '工单超时未接单提醒', 'order_timeout', 1, 1, 1,
'工单超时未接单:{orderTypeName}',
'工单编号:{orderNo};客户:{customerName};已派单 {staleDays} 天仍未接单,请及时跟进。',
'{"users":{"roles":["ADMIN"],"ids":[]},"workers":{"mode":"none","ids":[]}}'::jsonb,
'扫描派单后超过 advance_days 天仍未接单的工单,通知 ADMIN')
ON CONFLICT (rule_key) DO NOTHING;
COMMIT;