通知修订

This commit is contained in:
chenxing
2026-09-01 14:09:24 +08:00
parent 83975ad93b
commit 6375562c8d
60 changed files with 3048 additions and 1825 deletions
+2 -7
View File
@@ -1,7 +1,5 @@
server:
port: 8070
servlet:
context-path: /notice
spring:
mvc:
@@ -47,11 +45,6 @@ spring:
file:
upload-path: D:/data/upload
# 定时发送任务
timing-send:
enabled: true
cron: "0 * * * * ?" # 每分钟检查一次
# 短信模块配置
sms:
enabled: true
@@ -75,3 +68,5 @@ yh:
enabled: true
base-host: http://base.yunhaixingtong.com
user-center-url: http://base.yunhaixingtong.com/userbase
# 班级管理(bschclass)服务基址
bschclass: http://base.yunhaixingtong.com/bschclass
@@ -0,0 +1,72 @@
server:
port: 8070
spring:
mvc:
date-format: yyyy-MM-dd HH:mm:ss
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
datasource:
url: jdbc:mysql://localhost:3306/bsch_notice?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
min-idle: 10
max-active: 30
#jpa
jpa:
database: MySQL
show-sql: true
hibernate:
# 开发期使用 update 自动建表;生产环境设置成 none
ddl-auto: update
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
properties:
hibernate.order_by.default_null_ordering: last
open-in-view: true
#文件上传
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
#本地关闭 rabbit
rabbitmq:
listener:
direct:
auto-startup: false
simple:
auto-startup: false
# 文件上传存储路径(Docker 部署时与 volume 挂载一致)
file:
upload-path: D:/data/upload
# 短信模块配置
sms:
enabled: true
module-id: notice
# 单点登录 / 应用间签名鉴权(基础平台 yh-auth / yh-app-auth)
yh:
sso:
server-url-prefix: http://sso.yunhaixingtong.com/cas/
client-host-url: http://localhost:8070
allow-headers: all
allow-origins: all
url-pattern: /api/*
mobi-api-pattern: /mobiapi/*
app-auth:
enabled: true
# 本应用自身身份(客户端签名用)
app-key: 100001
app-secret: ec4e860206374c80938719fff8e14a86
open:
enabled: true
base-host: http://base.yunhaixingtong.com
user-center-url: http://base.yunhaixingtong.com/userbase
# 班级管理(bschclass)服务基址
bschclass: http://base.yunhaixingtong.com/bschclass
@@ -0,0 +1,16 @@
-- ============================================================
-- notice 表补 sch_id 列(多租户隔离)
-- 决策 D3:发布时从 BoaUser.currentRole.schId 填充,查询时按校过滤
--
-- 对应实体:Notice.schId / NoticeRepository 多租户统计方法
--
-- 执行方式:由 DBA 手动在对应环境执行,AI 不代跑
-- MySQL 5.7+ 兼容
-- ============================================================
-- 1) 加列
ALTER TABLE `notice`
ADD COLUMN `sch_id` INT NULL COMMENT '学校ID(多租户隔离:发布时从当前用户角色填充)';
-- 2) 加索引(用于按学校过滤查询)
CREATE INDEX `idx_notice_sch_id` ON `notice` (`sch_id`);
@@ -0,0 +1,159 @@
-- ============================================================
-- 存量数据回填脚本
-- 1. notice.sch_id:按发布人所属学校回填(从 sys_user_role_rel 取 main=1 的 sch_id)
-- 2. notice_receiver:从 notice.receive_list JSON 字符串展开为关联表行
--
-- 幂等设计:可重复执行,已存在的数据不会重复插入
-- 执行方式:由 DBA 手动在对应环境执行,AI 不代跑
-- MySQL 5.7+ 兼容
-- ============================================================
-- ============================================================
-- Part 1:回填 notice.sch_id
-- ============================================================
-- 方式一:如果 base_user / sys_user 表有 sch_id 字段,直接关联回填
-- 注意:需根据实际平台库表结构调整关联条件
UPDATE `notice` n
INNER JOIN (
SELECT DISTINCT u.login_name, u.sch_id
FROM base_user u
WHERE u.sch_id IS NOT NULL
) t ON n.publisher_account = t.login_name
SET n.sch_id = t.sch_id
WHERE n.sch_id IS NULL
AND n.publisher_account IS NOT NULL
AND n.publisher_account != '';
-- 方式二(备用):如果用户学校关系在 sys_user_role_rel 表
-- 取每个用户的主身份学校(is_main=1),回填 sch_id
-- 取消注释后执行(视实际库表结构选用)
--
-- UPDATE `notice` n
-- INNER JOIN (
-- SELECT r.account, r.sch_id
-- FROM sys_user_role_rel r
-- WHERE r.is_main = 1
-- AND r.sch_id IS NOT NULL
-- ) t ON n.publisher_account = t.account
-- SET n.sch_id = t.sch_id
-- WHERE n.sch_id IS NULL
-- AND n.publisher_account IS NOT NULL
-- AND n.publisher_account != '';
-- ============================================================
-- Part 2:从 notice.receive_list 展开到 notice_receiver 关联表
-- ============================================================
-- 说明:
-- - notice.receive_list 存储格式有两种:
-- 1) "ALL"(全员通知)—— 不写明细行,跳过
-- 2) JSON 数组 ["account1","account2",...] 或逗号分隔串
-- - 本脚本使用 MySQL JSON 函数解析(MySQL 5.7+ 支持 JSON_EXTRACT)
-- - 对于非标准 JSON 格式(逗号分隔串),使用循环逐条插入
-- - 幂等:每次插入前先删除该通知的旧接收人记录
-- 注意:MySQL 5.7 的 JSON_TABLE 不可用,这里用存储过程逐条解析
-- 如果 receive_list 是标准 JSON 数组格式,可以直接用 JSON_EXTRACT
DELIMITER $$
-- 存储过程:展开单个通知的接收人列表
DROP PROCEDURE IF EXISTS `expand_notice_receivers`$$
CREATE PROCEDURE `expand_notice_receivers`()
BEGIN
DECLARE v_done INT DEFAULT 0;
DECLARE v_notice_id INT;
DECLARE v_receive_list TEXT;
DECLARE cur CURSOR FOR
SELECT id, receive_list
FROM notice
WHERE receive_list IS NOT NULL
AND TRIM(receive_list) != ''
AND UPPER(TRIM(receive_list)) != 'ALL'
AND NOT EXISTS (
SELECT 1 FROM notice_receiver WHERE notice_id = notice.id LIMIT 1
);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = 1;
OPEN cur;
read_loop: LOOP
FETCH cur INTO v_notice_id, v_receive_list;
IF v_done = 1 THEN
LEAVE read_loop;
END IF;
-- 清理旧数据(幂等)
DELETE FROM notice_receiver WHERE notice_id = v_notice_id;
-- 尝试 JSON 数组解析
-- receive_list 格式: ["account1","account2"] 或 account1,account2
SET v_receive_list = TRIM(v_receive_list);
-- 去除首尾方括号(如有)
IF LEFT(v_receive_list, 1) = '[' AND RIGHT(v_receive_list, 1) = ']' THEN
SET v_receive_list = SUBSTRING(v_receive_list, 2, CHAR_LENGTH(v_receive_list) - 2);
END IF;
-- 替换引号为空,按逗号分隔
SET v_receive_list = REPLACE(REPLACE(v_receive_list, '"', ''), '''', '');
-- 逐条插入
-- 简单实现:用 FIND_IN_SET 不适用于变量,改用临时表
BEGIN
DECLARE v_pos INT DEFAULT 1;
DECLARE v_account VARCHAR(64);
DECLARE v_remaining TEXT;
SET v_remaining = v_receive_list;
WHILE v_remaining IS NOT NULL AND TRIM(v_remaining) != '' DO
IF LOCATE(',', v_remaining) > 0 THEN
SET v_account = TRIM(SUBSTRING_INDEX(v_remaining, ',', 1));
SET v_remaining = SUBSTRING(v_remaining, LOCATE(',', v_remaining) + 1);
ELSE
SET v_account = TRIM(v_remaining);
SET v_remaining = NULL;
END IF;
IF v_account != '' AND v_account IS NOT NULL THEN
INSERT INTO notice_receiver (notice_id, account, receive_type, create_time)
VALUES (v_notice_id, v_account, 1, NOW());
END IF;
END WHILE;
END;
END LOOP;
CLOSE cur;
END$$
DELIMITER ;
-- 执行存储过程
CALL expand_notice_receivers();
-- 清理临时存储过程
DROP PROCEDURE IF EXISTS `expand_notice_receivers`;
-- ============================================================
-- 回填结果验证查询(执行后手动检查)
-- ============================================================
-- 检查1:sch_id 回填覆盖率
-- SELECT
-- COUNT(*) AS total,
-- SUM(CASE WHEN sch_id IS NOT NULL THEN 1 ELSE 0 END) AS sch_id_filled,
-- SUM(CASE WHEN sch_id IS NULL THEN 1 ELSE 0 END) AS sch_id_null
-- FROM notice;
-- 检查2:notice_receiver 展开行数
-- SELECT COUNT(*) FROM notice_receiver;
-- 检查3:未展开的通知(receive_list 非空非 ALL 但 receiver 表无记录)
-- SELECT n.id, n.receive_list
-- FROM notice n
-- LEFT JOIN notice_receiver r ON r.notice_id = n.id
-- WHERE n.receive_list IS NOT NULL
-- AND TRIM(n.receive_list) != ''
-- AND UPPER(TRIM(n.receive_list)) != 'ALL'
-- AND r.id IS NULL;
@@ -0,0 +1,24 @@
-- ============================================================
-- notice_receiver 建表(替代 notice.receive_list JSON 字符串存储)
-- 决策 D2-B:拆关联表,支撑阅读情况/催收/统计 SQL 化
--
-- 对应实体:com.yunhai.notice.entity.NoticeReceiver
-- 索引:idx_notice_id(notice_id) + idx_account(account)
--
-- 执行方式:由 DBA 手动在对应环境执行,AI 不代跑
-- MySQL 5.7+ 兼容
-- ============================================================
CREATE TABLE IF NOT EXISTS `notice_receiver` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`notice_id` INT NOT NULL COMMENT '通知ID(关联 notice.id)',
`account` VARCHAR(64) NOT NULL COMMENT '接收人登录账号',
`receive_type` INT NOT NULL DEFAULT 1 COMMENT '接收类型:1 接收 / 2 抄送',
`create_by` VARCHAR(64) NULL COMMENT '创建人登录账号(审计填充)',
`create_time` DATETIME NULL COMMENT '创建时间(审计填充)',
`update_by` VARCHAR(64) NULL COMMENT '更新人登录账号(审计填充)',
`update_time` DATETIME NULL COMMENT '更新时间(审计填充)',
PRIMARY KEY (`id`),
KEY `idx_notice_id` (`notice_id`),
KEY `idx_account` (`account`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='通知接收人关联表';