22 Commits
Author SHA1 Message Date
wanghaoandClaude 570ed10c33 revert(watch): 还原listByWatch绑定过滤改动,恢复仅排序逻辑
Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-07 15:50:32 +08:00
wanghao d47737de5e Merge remote-tracking branch 'origin/xc' into xc 2026-09-07 15:39:06 +08:00
wanghaoandClaude 991dbabe8a fix(watch): listByWatch改为只展示未绑定手表的用户
Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-07 15:34:40 +08:00
lianlonggang 2f5712a678 feat(watch): listCustom 接口与导出增加 eventId、locateTime 字段
1. AbnormalEvent 新增 eventId、locateTime 字段
2. listCustom/largeScreenListCustom/listCustomForMap 三个接口返回新字段
3. 导出 Excel 通过 @Excel 注解自动支持新字段(顺序 12、13)
4. locateTime 时间格式化为 yyyy-MM-dd HH:mm:ss
5. 修正 createMonitorData 中遗漏的 eventId 与 locateTime 字段赋值
6. DDL 表名修正为 QH_WAT_MONITOR_DATA(项目实际表名)
2026-09-03 13:43:09 +08:00
lianlonggang 41bce5c0b2 feat(watch): notice 入参新增 eventId、locateTime;新增 updateMonitorGps 接口
1. WatchNotifyVo、WatchMonitorData 新增 eventId 与 locateTime 字段
2. 新增 POST /watchApi/updateMonitorGps 接口
3. watchNo + eventId 联合定位告警数据,任一缺失则忽略
4. 已存在 lon/lat 数据则忽略本次更新,避免覆盖
5. GPS84 → GCJ02 坐标转换 + 高德地址反查(参考 createMonitorData 逻辑)
6. 仅更新 GPS 相关字段,不推送大屏与短信
2026-09-03 10:52:44 +08:00
lianlonggang 5c8b56430d feat(db): watch_monitor_data 表新增 EVENT_ID 与 LOCATE_TIME 字段
为支持手表告警事件与定时GPS位置上报的关联,新增两个字段:
- EVENT_ID(事件ID,用于告警事件与GPS位置更新关联)
- LOCATE_TIME(定位时间,手表定时上报的GPS定位时间)

同时新增 IDX_EVENT_ID 单列索引与 IDX_WATCH_NO_EVENT_ID 联合索引,
优化 watchNo + eventId 联合定位查询性能。

数据库:118-DM 达梦数据库,SQL 全大写规范。
2026-09-03 10:52:38 +08:00
wanghaoandClaude 674891eba3 fix(watch): QH_WAT_USER_DATA并发写入唯一约束冲突时忽略重复插入
notice接口并发上报同一手表同一天数据时,先删后插存在竞态,
两个线程同时插入触发唯一约束WATCH_USER_DATA_WATCH_NO,
捕获DuplicateKeyException降级为warn日志,数据不丢失

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-25 11:05:26 +08:00
wanghao a8e8b53203 style(message): 精简权限过滤兜底分支注释 2026-08-10 16:40:20 +08:00
wanghao a835b874ad fix(message): notice_role仅用于菜单可见,列表只可查看本人创建
- applyAdminPermissionFilter 白名单移除 notice_role,使其落入兜底分支
- 兜底过滤字段由 loginUser.getId() 修正为 getUsername(),对齐 createBy 存储
2026-08-10 16:36:30 +08:00
wanghao b6058c5f80 feat(message): 消息通知列表权限白名单加入notice_role + 兜底本人创建可见 2026-08-10 16:03:30 +08:00
pengjie 245cffecb0 fix: 清除因PowerShell Set-Content引入的UTF-8 BOM字符 2026-08-10 10:21:23 +08:00
pengjie b7525d6c7c fix: 修复表重命名脚本语法,改用达梦兼容的 ALTER TABLE RENAME TO 2026-08-10 10:17:16 +08:00
pengjie 1ad322c16a refactor: 缩短急救宣教相关表名 QH_EME_FIRST_AID_* -> QH_EME_FIR_AID_*,解决表名超长问题 2026-08-10 10:14:40 +08:00
lianlonggang d08d20f1ee style(all): 去客户化处理 2026-08-06 17:47:04 +08:00
pengjieandClaude c260b1d79b style: AsyncExportService import合并为通配符
Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-05 09:57:28 +08:00
pengjieandClaude 1028a4e4e1 fix: SysUserServiceImpl注入ISysBaseAPI产生循环依赖,加@Lazy解决
Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-05 09:12:37 +08:00
pengjieandClaude 4a15ebe0d2 feat: 补充IM个人资料同步 + 群成员头像导入修复
1. 在8处头像/名称变更点补充imHelloApi.accountReg()调用,同步更新IM个人资料:
   - SysUserController.updateUserAvatar 用户换头像
   - SysUserController.appEdit 移动端编辑资料
   - SysUserController.edit 后台编辑用户
   - EmergencyProfessionUserServiceImpl.customEdit 应急人员编辑
   - EmergencyCenterAdminServiceImpl.updateAdmin 中心管理员编辑
   - HealthUserEmployeeExServiceImpl.updateUserInfo 员工编辑
   - ConDoctorApiController.update 专家端个人简介修改
   - AsyncExportService.importDoctor 批量导入医生
   所有syncImProfile方法内部try-catch兜底,失败不影响主流程。
2. AddGroupMemberDTO新增memberAvatar字段,TencentCloudImUtil.addGroupMember
   导入IM账号时传递FaceUrl,EmergencyApiServiceImpl.addGroupUser构建头像映射。
3. jeecg-system-biz/pom.xml新增health-im-api依赖。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-04 20:03:20 +08:00
pengjie 0ae963c4cf Revert "fix(im): 邀请入群时使用真实用户身份调用IM API,系统通知显示真实用户名而非administrator"
This reverts commit 07d6f21fed.
2026-08-04 19:33:13 +08:00
pengjieandClaude 07d6f21fed fix(im): 邀请入群时使用真实用户身份调用IM API,系统通知显示真实用户名而非administrator
- AddGroupMemberDTO 新增 fromAccount 内部字段
- TencentCloudImUtil 新增带 identifier 参数的 getHttpsUrl 重载
- addGroupMember 检测 fromAccount,有则用该用户 UserSig
- EmergencyApiServiceImpl.addGroupUser 传入当前登录用户ID

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-04 18:58:16 +08:00
pengjieandClaude 26ae76a398 fix(im): 创建应急群聊时群名称固定为"应急求助"
Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-04 16:18:13 +08:00
pengjieandClaude 468314df64 refactor(emergency): searchExpert改为两表合集查询,同时搜索QH_EME_PROFESS_USER和qh_con_doctor
原来只查QH_EME_PROFESS_USER再补充qh_con_doctor字段,导致只在qh_con_doctor
中的专家搜不到。改为:
1. 分别查询两表(各自过滤name/排除已入群)
2. LinkedHashMap按userId去重合并
3. sys_user兜底填充realname/avatar/phone/deptName
4. 对profUsers单独补qh_con_doctor专家字段
5. 内存分页返回

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-04 11:42:47 +08:00
pengjie 3b7f260103 fix(emergency): myParticipatedOrders接口补充返回当前用户自己发起/被救助的应急工单 2026-08-04 11:41:47 +08:00
45 changed files with 1251 additions and 772 deletions
+81 -81
View File
@@ -6,7 +6,7 @@
-- 1. 资源分类/标签统一表 -- 1. 资源分类/标签统一表
-- TYPE: 1=分类(树形), 2=标签(扁平) -- TYPE: 1=分类(树形), 2=标签(扁平)
CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_CATEGORY" ( CREATE TABLE "QH_EME_FIR_AID_RES_CATE" (
"ID" VARCHAR2(32) NOT NULL, "ID" VARCHAR2(32) NOT NULL,
"NAME" VARCHAR2(100) NOT NULL, "NAME" VARCHAR2(100) NOT NULL,
"TYPE" NUMBER(1) DEFAULT 1 NOT NULL, "TYPE" NUMBER(1) DEFAULT 1 NOT NULL,
@@ -22,21 +22,21 @@ CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_CATEGORY" (
"MEMO" VARCHAR2(500), "MEMO" VARCHAR2(500),
PRIMARY KEY ("ID") PRIMARY KEY ("ID")
); );
COMMENT ON TABLE "QH_EME_FIRST_AID_RESOURCE_CATEGORY" IS '急救宣教资源分类/标签'; COMMENT ON TABLE "QH_EME_FIR_AID_RES_CATE" IS '急救宣教资源分类/标签';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."ID" IS '主键'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."ID" IS '主键';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."NAME" IS '名称'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."NAME" IS '名称';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."TYPE" IS '类型:1=分类,2=标签'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."TYPE" IS '类型:1=分类,2=标签';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."PARENT_ID" IS '父分类ID(根分类为NULL标签指向所属分类ID)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."PARENT_ID" IS '父分类ID(根分类为NULL标签指向所属分类ID)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."DESCRIPTION" IS '描述'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."DESCRIPTION" IS '描述';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."SORT_NO" IS '排序号'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."SORT_NO" IS '排序号';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."STATUS" IS '状态(1=正常,2=冻结)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."STATUS" IS '状态(1=正常,2=冻结)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."DEL_FLAG" IS '删除标记(0=正常,1=已删除)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."DEL_FLAG" IS '删除标记(0=正常,1=已删除)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."MEMO" IS '备注'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."MEMO" IS '备注';
CREATE INDEX "IDX_FA_CATEGORY_TYPE" ON "QH_EME_FIRST_AID_RESOURCE_CATEGORY"("TYPE"); CREATE INDEX "IDX_FA_CATEGORY_TYPE" ON "QH_EME_FIR_AID_RES_CATE"("TYPE");
CREATE INDEX "IDX_FA_CATEGORY_PARENT_ID" ON "QH_EME_FIRST_AID_RESOURCE_CATEGORY"("PARENT_ID"); CREATE INDEX "IDX_FA_CATEGORY_PARENT_ID" ON "QH_EME_FIR_AID_RES_CATE"("PARENT_ID");
-- 2. 资源表 -- 2. 资源表
CREATE TABLE "QH_EME_FIRST_AID_RESOURCE" ( CREATE TABLE "QH_EME_FIR_AID_RES" (
"ID" VARCHAR2(32) NOT NULL, "ID" VARCHAR2(32) NOT NULL,
"TITLE" VARCHAR2(200) NOT NULL, "TITLE" VARCHAR2(200) NOT NULL,
"SUMMARY" VARCHAR2(500), "SUMMARY" VARCHAR2(500),
@@ -65,35 +65,35 @@ CREATE TABLE "QH_EME_FIRST_AID_RESOURCE" (
"MEMO" VARCHAR2(500), "MEMO" VARCHAR2(500),
PRIMARY KEY ("ID") PRIMARY KEY ("ID")
); );
COMMENT ON TABLE "QH_EME_FIRST_AID_RESOURCE" IS '急救宣教资源'; COMMENT ON TABLE "QH_EME_FIR_AID_RES" IS '急救宣教资源';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."ID" IS '主键'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."ID" IS '主键';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."TITLE" IS '标题'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."TITLE" IS '标题';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."SUMMARY" IS '摘要/简介'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."SUMMARY" IS '摘要/简介';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."CONTENT_TYPE" IS '内容类型:IMAGE_TEXT=图文/VIDEO=视频/AUDIO=音频/PDF'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."CONTENT_TYPE" IS '内容类型:IMAGE_TEXT=图文/VIDEO=视频/AUDIO=音频/PDF';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."CATEGORY_ID" IS '所属分类ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."CATEGORY_ID" IS '所属分类ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."APPLICABLE_SCENARIO" IS '适用场景'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."APPLICABLE_SCENARIO" IS '适用场景';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."TAGS" IS '标签ID列表(逗号分隔)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."TAGS" IS '标签ID列表(逗号分隔)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."CONTENT" IS '正文内容(富文本HTML)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."CONTENT" IS '正文内容(富文本HTML)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."COVER_IMAGE" IS '封面图URL'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."COVER_IMAGE" IS '封面图URL';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."FILE_URL" IS '附件URL列表(JSON数组)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."FILE_URL" IS '附件URL列表(JSON数组)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."EFFECTIVE_TIME" IS '生效时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."EFFECTIVE_TIME" IS '生效时间';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."EXPIRY_TIME" IS '失效时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."EXPIRY_TIME" IS '失效时间';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."AUDIT_STATUS" IS '审核状态(NULL=无审核/10=待审核/11=已通过/12=已驳回)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."AUDIT_STATUS" IS '审核状态(NULL=无审核/10=待审核/11=已通过/12=已驳回)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."AUDIT_REJECT_REASON" IS '驳回原因'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."AUDIT_REJECT_REASON" IS '驳回原因';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."AUDIT_BY" IS '审核人'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."AUDIT_BY" IS '审核人';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."AUDIT_BY_ID" IS '审核人ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."AUDIT_BY_ID" IS '审核人ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."AUDIT_TIME" IS '审核时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."AUDIT_TIME" IS '审核时间';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."VIEW_COUNT" IS '浏览次数'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."VIEW_COUNT" IS '浏览次数';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."FAVORITE_COUNT" IS '收藏次数'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."FAVORITE_COUNT" IS '收藏次数';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."STATUS" IS '发布状态(0=草稿,1=已发布,2=已下架)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."STATUS" IS '发布状态(0=草稿,1=已发布,2=已下架)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."DEL_FLAG" IS '删除标记(0=正常,1=已删除)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."DEL_FLAG" IS '删除标记(0=正常,1=已删除)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."MEMO" IS '备注'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."MEMO" IS '备注';
CREATE INDEX "IDX_FA_RESOURCE_CATEGORY_ID" ON "QH_EME_FIRST_AID_RESOURCE"("CATEGORY_ID"); CREATE INDEX "IDX_FA_RESOURCE_CATEGORY_ID" ON "QH_EME_FIR_AID_RES"("CATEGORY_ID");
CREATE INDEX "IDX_FA_RESOURCE_AUDIT_STATUS" ON "QH_EME_FIRST_AID_RESOURCE"("AUDIT_STATUS"); CREATE INDEX "IDX_FA_RESOURCE_AUDIT_STATUS" ON "QH_EME_FIR_AID_RES"("AUDIT_STATUS");
CREATE INDEX "IDX_FA_RESOURCE_EFFECTIVE_TIME" ON "QH_EME_FIRST_AID_RESOURCE"("EFFECTIVE_TIME"); CREATE INDEX "IDX_FA_RESOURCE_EFFECTIVE_TIME" ON "QH_EME_FIR_AID_RES"("EFFECTIVE_TIME");
-- 3. 用户行为记录表阅读+收藏 -- 3. 用户行为记录表阅读+收藏
CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_USER_ACTION" ( CREATE TABLE "QH_EME_FIR_AID_RES_UACT" (
"ID" VARCHAR2(32) NOT NULL, "ID" VARCHAR2(32) NOT NULL,
"RESOURCE_ID" VARCHAR2(32) NOT NULL, "RESOURCE_ID" VARCHAR2(32) NOT NULL,
"USER_ID" VARCHAR2(50) NOT NULL, "USER_ID" VARCHAR2(50) NOT NULL,
@@ -101,16 +101,16 @@ CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_USER_ACTION" (
"CREATE_TIME" TIMESTAMP, "CREATE_TIME" TIMESTAMP,
PRIMARY KEY ("ID") PRIMARY KEY ("ID")
); );
COMMENT ON TABLE "QH_EME_FIRST_AID_RESOURCE_USER_ACTION" IS '用户行为记录(阅读/收藏)'; COMMENT ON TABLE "QH_EME_FIR_AID_RES_UACT" IS '用户行为记录(阅读/收藏)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_USER_ACTION"."ID" IS '主键'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_UACT"."ID" IS '主键';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_USER_ACTION"."RESOURCE_ID" IS '资源ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_UACT"."RESOURCE_ID" IS '资源ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_USER_ACTION"."USER_ID" IS '用户ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_UACT"."USER_ID" IS '用户ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_USER_ACTION"."TYPE" IS '行为类型:1=阅读,2=收藏'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_UACT"."TYPE" IS '行为类型:1=阅读,2=收藏';
CREATE UNIQUE INDEX "UK_FA_USER_ACTION" ON "QH_EME_FIRST_AID_RESOURCE_USER_ACTION"("RESOURCE_ID", "USER_ID", "TYPE"); CREATE UNIQUE INDEX "UK_FA_USER_ACTION" ON "QH_EME_FIR_AID_RES_UACT"("RESOURCE_ID", "USER_ID", "TYPE");
CREATE INDEX "IDX_FA_USER_ACTION_USER_TYPE" ON "QH_EME_FIRST_AID_RESOURCE_USER_ACTION"("USER_ID", "TYPE"); CREATE INDEX "IDX_FA_USER_ACTION_USER_TYPE" ON "QH_EME_FIR_AID_RES_UACT"("USER_ID", "TYPE");
-- 4. 版本历史表 -- 4. 版本历史表
CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_VERSION" ( CREATE TABLE "QH_EME_FIR_AID_RES_VER" (
"ID" VARCHAR2(32) NOT NULL, "ID" VARCHAR2(32) NOT NULL,
"RESOURCE_ID" VARCHAR2(32) NOT NULL, "RESOURCE_ID" VARCHAR2(32) NOT NULL,
"VERSION_NO" NUMBER(10) NOT NULL, "VERSION_NO" NUMBER(10) NOT NULL,
@@ -122,18 +122,18 @@ CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_VERSION" (
"CREATE_TIME" TIMESTAMP, "CREATE_TIME" TIMESTAMP,
PRIMARY KEY ("ID") PRIMARY KEY ("ID")
); );
COMMENT ON TABLE "QH_EME_FIRST_AID_RESOURCE_VERSION" IS '资源版本历史'; COMMENT ON TABLE "QH_EME_FIR_AID_RES_VER" IS '资源版本历史';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."ID" IS '主键'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."ID" IS '主键';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."RESOURCE_ID" IS '资源ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."RESOURCE_ID" IS '资源ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."VERSION_NO" IS '版本号'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."VERSION_NO" IS '版本号';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."TITLE" IS '版本时的标题'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."TITLE" IS '版本时的标题';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."CONTENT" IS '版本时的正文内容'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."CONTENT" IS '版本时的正文内容';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."CHANGE_DESCRIPTION" IS '变更描述'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."CHANGE_DESCRIPTION" IS '变更描述';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."IS_CURRENT" IS '是否当前版本(1=,0=)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."IS_CURRENT" IS '是否当前版本(1=,0=)';
CREATE INDEX "IDX_FA_VERSION_RESOURCE_ID" ON "QH_EME_FIRST_AID_RESOURCE_VERSION"("RESOURCE_ID"); CREATE INDEX "IDX_FA_VERSION_RESOURCE_ID" ON "QH_EME_FIR_AID_RES_VER"("RESOURCE_ID");
-- 5. 审核记录表 -- 5. 审核记录表
CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_AUDIT" ( CREATE TABLE "QH_EME_FIR_AID_RES_AUD" (
"ID" VARCHAR2(32) NOT NULL, "ID" VARCHAR2(32) NOT NULL,
"RESOURCE_ID" VARCHAR2(32) NOT NULL, "RESOURCE_ID" VARCHAR2(32) NOT NULL,
"AUDIT_STATUS" NUMBER(2), "AUDIT_STATUS" NUMBER(2),
@@ -144,19 +144,19 @@ CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_AUDIT" (
"CREATE_TIME" TIMESTAMP DEFAULT SYSDATE, "CREATE_TIME" TIMESTAMP DEFAULT SYSDATE,
PRIMARY KEY ("ID") PRIMARY KEY ("ID")
); );
COMMENT ON TABLE "QH_EME_FIRST_AID_RESOURCE_AUDIT" IS '急救宣教资源审核记录'; COMMENT ON TABLE "QH_EME_FIR_AID_RES_AUD" IS '急救宣教资源审核记录';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_AUDIT"."ID" IS '主键'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_AUD"."ID" IS '主键';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_AUDIT"."RESOURCE_ID" IS '关联资源ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_AUD"."RESOURCE_ID" IS '关联资源ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_AUDIT"."AUDIT_STATUS" IS '审核状态:10=待审核,11=已通过,12=已驳回'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_AUD"."AUDIT_STATUS" IS '审核状态:10=待审核,11=已通过,12=已驳回';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_AUDIT"."AUDIT_REJECT_REASON" IS '驳回原因'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_AUD"."AUDIT_REJECT_REASON" IS '驳回原因';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_AUDIT"."AUDIT_BY" IS '审核人'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_AUD"."AUDIT_BY" IS '审核人';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_AUDIT"."AUDIT_BY_ID" IS '审核人ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_AUD"."AUDIT_BY_ID" IS '审核人ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_AUDIT"."AUDIT_TIME" IS '审核时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_AUD"."AUDIT_TIME" IS '审核时间';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_AUDIT"."CREATE_TIME" IS '创建时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_AUD"."CREATE_TIME" IS '创建时间';
CREATE INDEX "IDX_FA_AUDIT_RESOURCE_ID" ON "QH_EME_FIRST_AID_RESOURCE_AUDIT"("RESOURCE_ID"); CREATE INDEX "IDX_FA_AUDIT_RESOURCE_ID" ON "QH_EME_FIR_AID_RES_AUD"("RESOURCE_ID");
-- 6. 推送记录表 -- 6. 推送记录表
CREATE TABLE "QH_EME_FIRST_AID_PUSH_RECORD" ( CREATE TABLE "QH_EME_FIR_AID_PUSH_RD" (
"ID" VARCHAR2(32) NOT NULL, "ID" VARCHAR2(32) NOT NULL,
"RESOURCE_ID" VARCHAR2(32) NOT NULL, "RESOURCE_ID" VARCHAR2(32) NOT NULL,
"RESOURCE_TITLE" VARCHAR2(200) DEFAULT NULL, "RESOURCE_TITLE" VARCHAR2(200) DEFAULT NULL,
@@ -169,17 +169,17 @@ CREATE TABLE "QH_EME_FIRST_AID_PUSH_RECORD" (
PRIMARY KEY ("ID"), PRIMARY KEY ("ID"),
CONSTRAINT "UK_ORDER_RESOURCE" UNIQUE ("ORDER_ID", "RESOURCE_ID") CONSTRAINT "UK_ORDER_RESOURCE" UNIQUE ("ORDER_ID", "RESOURCE_ID")
); );
COMMENT ON TABLE "QH_EME_FIRST_AID_PUSH_RECORD" IS '急救宣教推送记录表'; COMMENT ON TABLE "QH_EME_FIR_AID_PUSH_RD" IS '急救宣教推送记录表';
COMMENT ON COLUMN "QH_EME_FIRST_AID_PUSH_RECORD"."ID" IS '主键'; COMMENT ON COLUMN "QH_EME_FIR_AID_PUSH_RD"."ID" IS '主键';
COMMENT ON COLUMN "QH_EME_FIRST_AID_PUSH_RECORD"."RESOURCE_ID" IS '资源ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_PUSH_RD"."RESOURCE_ID" IS '资源ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_PUSH_RECORD"."RESOURCE_TITLE" IS '资源标题冗余'; COMMENT ON COLUMN "QH_EME_FIR_AID_PUSH_RD"."RESOURCE_TITLE" IS '资源标题冗余';
COMMENT ON COLUMN "QH_EME_FIRST_AID_PUSH_RECORD"."ORDER_ID" IS '关联应急工单ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_PUSH_RD"."ORDER_ID" IS '关联应急工单ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_PUSH_RECORD"."TARGET_USER_ID" IS '推送目标用户ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_PUSH_RD"."TARGET_USER_ID" IS '推送目标用户ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_PUSH_RECORD"."PUSH_BY" IS '推送人'; COMMENT ON COLUMN "QH_EME_FIR_AID_PUSH_RD"."PUSH_BY" IS '推送人';
COMMENT ON COLUMN "QH_EME_FIRST_AID_PUSH_RECORD"."PUSH_BY_ID" IS '推送人ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_PUSH_RD"."PUSH_BY_ID" IS '推送人ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_PUSH_RECORD"."PUSH_TIME" IS '推送时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_PUSH_RD"."PUSH_TIME" IS '推送时间';
COMMENT ON COLUMN "QH_EME_FIRST_AID_PUSH_RECORD"."TENANT_ID" IS '租户ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_PUSH_RD"."TENANT_ID" IS '租户ID';
CREATE INDEX "IDX_FA_PUSH_RECORD_ORDER_ID" ON "QH_EME_FIRST_AID_PUSH_RECORD"("ORDER_ID"); CREATE INDEX "IDX_FA_PUSH_RECORD_ORDER_ID" ON "QH_EME_FIR_AID_PUSH_RD"("ORDER_ID");
-- 7. 字典数据 -- 7. 字典数据
-- 7.1 内容类型 -- 7.1 内容类型
@@ -0,0 +1,28 @@
-- =====================================================
-- 缩短急救宣教相关表名达梦数据库
-- 原因原表名超过数据库限制
-- 日期2026-08-10
-- =====================================================
-- 1. 急救资源分类表
ALTER TABLE QH_EME_FIRST_AID_RESOURCE_CATEGORY RENAME TO QH_EME_FIR_AID_RES_CATE;
-- 2. 用户操作记录表
ALTER TABLE QH_EME_FIRST_AID_RESOURCE_USER_ACTION RENAME TO QH_EME_FIR_AID_RES_UACT;
-- 3. 资源版本表
ALTER TABLE QH_EME_FIRST_AID_RESOURCE_VERSION RENAME TO QH_EME_FIR_AID_RES_VER;
-- 4. 资源审核表
ALTER TABLE QH_EME_FIRST_AID_RESOURCE_AUDIT RENAME TO QH_EME_FIR_AID_RES_AUD;
-- 5. 推送记录表
ALTER TABLE QH_EME_FIRST_AID_PUSH_RECORD RENAME TO QH_EME_FIR_AID_PUSH_RD;
-- 6. 急救资源主表最后执行避免外键依赖
ALTER TABLE QH_EME_FIRST_AID_RESOURCE RENAME TO QH_EME_FIR_AID_RES;
-- =====================================================
-- 验证确认新表名已生效
-- SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME LIKE 'QH_EME_FIR_AID_%';
-- =====================================================
@@ -0,0 +1,10 @@
-- QH_WAT_MONITOR_DATA 新增 EVENT_ID事件ID LOCATE_TIME定位时间字段
-- 数据库118-DM 达梦数据库SQL 全大写规范
ALTER TABLE "QH_WAT_MONITOR_DATA" ADD "EVENT_ID" VARCHAR(64) DEFAULT NULL;
ALTER TABLE "QH_WAT_MONITOR_DATA" ADD "LOCATE_TIME" DATETIME DEFAULT NULL;
COMMENT ON COLUMN "QH_WAT_MONITOR_DATA"."EVENT_ID" IS '事件ID';
COMMENT ON COLUMN "QH_WAT_MONITOR_DATA"."LOCATE_TIME" IS '定位时间';
CREATE INDEX "IDX_EVENT_ID" ON "QH_WAT_MONITOR_DATA"("EVENT_ID");
CREATE INDEX "IDX_WATCH_NO_EVENT_ID" ON "QH_WAT_MONITOR_DATA"("WATCH_NO", "EVENT_ID");
@@ -15,24 +15,31 @@ import com.renkang.consultation.entity.ConDoctorExAndUser;
import com.renkang.consultation.service.IConDoctorService; import com.renkang.consultation.service.IConDoctorService;
import com.renkang.consultation.util.TempUtil; import com.renkang.consultation.util.TempUtil;
import com.renkang.consultation.vo.ConDoctorVO; import com.renkang.consultation.vo.ConDoctorVO;
import com.renkang.im.api.IMHelloApi;
import com.renkang.im.entity.ConSessionRequestDO;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.jeecg.bean.request.ListUser;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.util.DictUtil; import org.jeecg.common.system.util.DictUtil;
import org.jeecg.common.system.vo.DictModel; import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.LoginUserNew;
import org.jeecg.util.RSAEncryptUtils; import org.jeecg.util.RSAEncryptUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@Slf4j
@RestController @RestController
@RequestMapping(RequestPrefix.conDoctor) @RequestMapping(RequestPrefix.conDoctor)
public class ConDoctorApiController { public class ConDoctorApiController {
@@ -46,6 +53,8 @@ public class ConDoctorApiController {
@Autowired @Autowired
private DictUtil dictUtil; private DictUtil dictUtil;
@Autowired
private IMHelloApi imHelloApi;
/** /**
* 分页列表查询 * 分页列表查询
@@ -133,12 +142,28 @@ public class ConDoctorApiController {
} }
boolean flag = conDoctorService.updateById(conDoctor); boolean flag = conDoctorService.updateById(conDoctor);
if (flag){ if (flag){
// 同步IM个人资料
syncImProfile(conDoctor.getId());
return Result.ok("更新成功!"); return Result.ok("更新成功!");
} }
return Result.error("更新失败!"); return Result.error("更新失败!");
} }
private void syncImProfile(String userId) {
try {
List<LoginUserNew> users = isysBaseApi.listUserByIds(new ListUser(Collections.singletonList(userId)));
if (CollectionUtils.isEmpty(users)) {
return;
}
ConSessionRequestDO req = new ConSessionRequestDO();
req.setAccountList(Collections.singletonList(users.get(0)));
imHelloApi.accountReg(req);
} catch (Exception e) {
log.error("同步IM个人资料失败, userId: {}", userId, e);
}
}
@Operation(summary = "查询医生信息", description = "查询医生信息") @Operation(summary = "查询医生信息", description = "查询医生信息")
@GetMapping("/selectDoctorInfo") @GetMapping("/selectDoctorInfo")
@@ -19,6 +19,8 @@ import com.renkang.consultation.mapper.ConSessionMapper;
import com.renkang.consultation.service.IConDoctorService; import com.renkang.consultation.service.IConDoctorService;
import com.renkang.consultation.service.IConSessionService; import com.renkang.consultation.service.IConSessionService;
import com.renkang.consultation.vo.ConDoctorExportVO; import com.renkang.consultation.vo.ConDoctorExportVO;
import com.renkang.im.api.IMHelloApi;
import com.renkang.im.entity.ConSessionRequestDO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
@@ -62,10 +64,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.ArrayList; import java.util.*;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -98,6 +97,8 @@ public class AsyncExportService {
private ConHelperMapper conHelperMapper; private ConHelperMapper conHelperMapper;
@Autowired @Autowired
private AsyncTaskExecutor taskExecutor; private AsyncTaskExecutor taskExecutor;
@Autowired
private IMHelloApi imHelloApi;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void userToDoctorExportXls(ConSessionDTO dto, CommonExportsInfo info, String empFinish, String errCode, String sheetName, String fileName) { public void userToDoctorExportXls(ConSessionDTO dto, CommonExportsInfo info, String empFinish, String errCode, String sheetName, String fileName) {
@@ -580,6 +581,8 @@ public class AsyncExportService {
BeanUtils.copyProperties(excelVo, conDoctor); BeanUtils.copyProperties(excelVo, conDoctor);
conDoctor.setId(userId); conDoctor.setId(userId);
conDoctorService.saveDoctor(conDoctor); conDoctorService.saveDoctor(conDoctor);
// 同步注册IM账号
importImAccount(userId);
info.setHandleMsg(index++ + "/" + userList.size()); info.setHandleMsg(index++ + "/" + userList.size());
info.setExportStatus("0"); info.setExportStatus("0");
info.setId(commonExportsInfo.getId()); info.setId(commonExportsInfo.getId());
@@ -598,6 +601,20 @@ public class AsyncExportService {
sysBaseAPI.updateExportsInfo(info); sysBaseAPI.updateExportsInfo(info);
} }
private void importImAccount(String userId) {
try {
List<LoginUserNew> users = sysBaseAPI.listUserByIds(new ListUser(Collections.singletonList(userId)));
if (CollectionUtils.isEmpty(users)) {
return;
}
ConSessionRequestDO req = new ConSessionRequestDO();
req.setAccountList(java.util.Collections.singletonList(users.get(0)));
imHelloApi.accountReg(req);
} catch (Exception e) {
log.error("导入IM账号失败, userId: {}", userId, e);
}
}
private class UserToDoctorExportHandler implements PoiExportHandler<UserToDoctorExport, SessionFilter> { private class UserToDoctorExportHandler implements PoiExportHandler<UserToDoctorExport, SessionFilter> {
@Override @Override
@@ -275,7 +275,7 @@
## 2. 标签管理 `emergency/firstAid/tag` ## 2. 标签管理 `emergency/firstAid/tag`
标签与分类共用 `QH_EME_FIRST_AID_RESOURCE_CATEGORY` 表,`type=2` 区分。标签通过 `parentId` 绑定到分类。 标签与分类共用 `QH_EME_FIR_AID_RES_CATE` 表,`type=2` 区分。标签通过 `parentId` 绑定到分类。
### 2.1 分页列表 `GET /tag/list` ### 2.1 分页列表 `GET /tag/list`
@@ -19,7 +19,7 @@ import java.util.Date;
* @Date: 2026-06-24 * @Date: 2026-06-24
*/ */
@Data @Data
@TableName("QH_EME_FIRST_AID_PUSH_RECORD") @TableName("QH_EME_FIR_AID_PUSH_RD")
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@Schema(title = "first_aid_push_record对象", description = "急救宣教推送记录") @Schema(title = "first_aid_push_record对象", description = "急救宣教推送记录")
@@ -19,7 +19,7 @@ import lombok.experimental.Accessors;
* @Version: V1.0 * @Version: V1.0
*/ */
@Data @Data
@TableName("QH_EME_FIRST_AID_RESOURCE") @TableName("QH_EME_FIR_AID_RES")
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@Schema(title = "first_aid_resource对象", description = "急救宣教资源") @Schema(title = "first_aid_resource对象", description = "急救宣教资源")
@@ -21,7 +21,7 @@ import java.util.Date;
* @Version: V1.0 * @Version: V1.0
*/ */
@Data @Data
@TableName("QH_EME_FIRST_AID_RESOURCE_AUDIT") @TableName("QH_EME_FIR_AID_RES_AUD")
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@Schema(title = "first_aid_resource_audit对象", description = "急救宣教资源审核记录") @Schema(title = "first_aid_resource_audit对象", description = "急救宣教资源审核记录")
@@ -19,7 +19,7 @@ import lombok.experimental.Accessors;
* @Version: V1.0 * @Version: V1.0
*/ */
@Data @Data
@TableName("QH_EME_FIRST_AID_RESOURCE_CATEGORY") @TableName("QH_EME_FIR_AID_RES_CATE")
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@Schema(title = "first_aid_resource_category对象", description = "急救宣教资源分类/标签") @Schema(title = "first_aid_resource_category对象", description = "急救宣教资源分类/标签")
@@ -17,7 +17,7 @@ import lombok.experimental.Accessors;
* @Version: V1.0 * @Version: V1.0
*/ */
@Data @Data
@TableName("QH_EME_FIRST_AID_RESOURCE_USER_ACTION") @TableName("QH_EME_FIR_AID_RES_UACT")
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@Schema(title = "first_aid_resource_user_action对象", description = "用户行为记录(阅读/收藏)") @Schema(title = "first_aid_resource_user_action对象", description = "用户行为记录(阅读/收藏)")
@@ -17,7 +17,7 @@ import lombok.experimental.Accessors;
* @Version: V1.0 * @Version: V1.0
*/ */
@Data @Data
@TableName("QH_EME_FIRST_AID_RESOURCE_VERSION") @TableName("QH_EME_FIR_AID_RES_VER")
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@Schema(title = "first_aid_resource_version对象", description = "资源版本历史") @Schema(title = "first_aid_resource_version对象", description = "资源版本历史")
@@ -88,7 +88,7 @@ public interface EmergencyOrderApiService {
IPage<EmployeeVO> searchEmployee(String realname, String orgCode, String workNo, String phone, String excludeSessionId, Integer pageNo, Integer pageSize); IPage<EmployeeVO> searchEmployee(String realname, String orgCode, String workNo, String phone, String excludeSessionId, Integer pageNo, Integer pageSize);
/** /**
* 查询当前登录人参与的应急工单列表sessionNow=1 * 查询当前登录人参与的应急工单列表 + 自己发起/被救助的应急工单
*/ */
IPage<MyParticipatedOrderVO> myParticipatedOrders(Integer pageNo, Integer pageSize); IPage<MyParticipatedOrderVO> myParticipatedOrders(Integer pageNo, Integer pageSize);
@@ -1384,11 +1384,17 @@ public class EmergencyApiServiceImpl implements EmergencyApiService {
if (newMemberList.isEmpty()) { if (newMemberList.isEmpty()) {
ExceptionAssertsUtil.fail("所选成员已在群聊中"); ExceptionAssertsUtil.fail("所选成员已在群聊中");
} }
// 查询成员名称用于IM账号导入 // 查询成员名称和头像用于IM账号导入
Map<String, String> memberNameMap = new HashMap<>(); Map<String, String> memberNameMap = new HashMap<>();
Map<String, String> memberAvatarMap = new HashMap<>();
List<EmergencyProfessionUser> profUsers = emergencyProfessionUserMapper.selectList( List<EmergencyProfessionUser> profUsers = emergencyProfessionUserMapper.selectList(
new LambdaQueryWrapper<EmergencyProfessionUser>().in(EmergencyProfessionUser::getUserId, newMemberList)); new LambdaQueryWrapper<EmergencyProfessionUser>().in(EmergencyProfessionUser::getUserId, newMemberList));
profUsers.forEach(u -> memberNameMap.put(u.getUserId(), u.getRealname())); profUsers.forEach(u -> {
memberNameMap.put(u.getUserId(), u.getRealname());
if (StrUtil.isNotBlank(u.getAvatar())) {
memberAvatarMap.put(u.getUserId(), u.getAvatar());
}
});
List<String> remainingIds = newMemberList.stream() List<String> remainingIds = newMemberList.stream()
.filter(id -> !memberNameMap.containsKey(id)).collect(Collectors.toList()); .filter(id -> !memberNameMap.containsKey(id)).collect(Collectors.toList());
if (!remainingIds.isEmpty()) { if (!remainingIds.isEmpty()) {
@@ -1396,6 +1402,9 @@ public class EmergencyApiServiceImpl implements EmergencyApiService {
if (StrUtil.isNotBlank(u.getRealname())) { if (StrUtil.isNotBlank(u.getRealname())) {
memberNameMap.put(id, u.getRealname()); memberNameMap.put(id, u.getRealname());
} }
if (StrUtil.isNotBlank(u.getAvatar())) {
memberAvatarMap.put(id, u.getAvatar());
}
}); });
} }
AddGroupMemberDTO addGroupMemberDTO = new AddGroupMemberDTO(); AddGroupMemberDTO addGroupMemberDTO = new AddGroupMemberDTO();
@@ -1404,6 +1413,7 @@ public class EmergencyApiServiceImpl implements EmergencyApiService {
AddGroupMemberDTO.MemberListDTO memberListDTO = new AddGroupMemberDTO.MemberListDTO(); AddGroupMemberDTO.MemberListDTO memberListDTO = new AddGroupMemberDTO.MemberListDTO();
memberListDTO.setMemberAccount(userId); memberListDTO.setMemberAccount(userId);
memberListDTO.setMemberName(memberNameMap.get(userId)); memberListDTO.setMemberName(memberNameMap.get(userId));
memberListDTO.setMemberAvatar(memberAvatarMap.get(userId));
return memberListDTO; return memberListDTO;
}).collect(Collectors.toList())); }).collect(Collectors.toList()));
//添加群成员 //添加群成员
@@ -923,15 +923,8 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService {
@Override @Override
public IPage<EmergencyProfessionUser> searchExpert(String realname, String centerId, String excludeSessionId, Integer pageNo, Integer pageSize) { public IPage<EmergencyProfessionUser> searchExpert(String realname, String centerId, String excludeSessionId, Integer pageNo, Integer pageSize) {
LambdaQueryWrapper<EmergencyProfessionUser> query = new LambdaQueryWrapper<>(); // ---- 1. 收集需要排除的userId(已在群中的人) ----
query.eq(EmergencyProfessionUser::getType, "6"); Set<String> excludeUserIds = new HashSet<>();
if (StrUtil.isNotBlank(realname)) {
query.like(EmergencyProfessionUser::getRealname, realname);
}
if (StrUtil.isNotBlank(centerId)) {
query.eq(EmergencyProfessionUser::getCenterId, centerId);
}
// 排除已在群中的人员
if (StrUtil.isNotBlank(excludeSessionId)) { if (StrUtil.isNotBlank(excludeSessionId)) {
Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>() Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
.eq(Order::getSessionId, excludeSessionId)); .eq(Order::getSessionId, excludeSessionId));
@@ -939,67 +932,117 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService {
List<OrderOperator> ops = orderOperatorMapper.selectList( List<OrderOperator> ops = orderOperatorMapper.selectList(
new LambdaQueryWrapper<OrderOperator>() new LambdaQueryWrapper<OrderOperator>()
.eq(OrderOperator::getOrderId, order.getId())); .eq(OrderOperator::getOrderId, order.getId()));
List<String> existUserIds = ops.stream().map(OrderOperator::getUserId).collect(Collectors.toList()); excludeUserIds.addAll(ops.stream().map(OrderOperator::getUserId).collect(Collectors.toList()));
if (!existUserIds.isEmpty()) {
query.notIn(EmergencyProfessionUser::getUserId, existUserIds);
}
} }
} }
Page<EmergencyProfessionUser> page = new Page<>(pageNo != null ? pageNo : 1, pageSize != null ? pageSize : 10);
IPage<EmergencyProfessionUser> result = emergencyProfessionUserMapper.selectPage(page, query); // ---- 2. 查询 QH_EME_PROFESS_USER(急救专业人员) ----
// 批量查询系统用户信息,填充科室(部门)名称 LambdaQueryWrapper<EmergencyProfessionUser> profQuery = new LambdaQueryWrapper<>();
List<String> userIds = result.getRecords().stream() profQuery.eq(EmergencyProfessionUser::getType, "6");
if (StrUtil.isNotBlank(realname)) {
profQuery.like(EmergencyProfessionUser::getRealname, realname);
}
if (StrUtil.isNotBlank(centerId)) {
profQuery.eq(EmergencyProfessionUser::getCenterId, centerId);
}
if (!excludeUserIds.isEmpty()) {
profQuery.notIn(EmergencyProfessionUser::getUserId, excludeUserIds);
}
List<EmergencyProfessionUser> profUsers = emergencyProfessionUserMapper.selectList(profQuery);
// ---- 3. 查询 qh_con_doctor(咨询专家),排除已在 profUsers 或已在群中的 ----
List<String> skipIds = new ArrayList<>(excludeUserIds);
profUsers.forEach(u -> skipIds.add(u.getUserId()));
List<EmergencyProfessionUser> doctorUsers = conDoctorMapper.searchDoctorByName(realname, skipIds);
// ---- 4. 合并两条结果(profUsers 优先,doctorUsers 追加) ----
Map<String, EmergencyProfessionUser> mergedMap = new LinkedHashMap<>();
for (EmergencyProfessionUser u : profUsers) {
mergedMap.put(u.getUserId(), u);
}
// 从 qh_con_doctor 来的记录,不入 mergedMap 时用 doctorName 兜底 realname/avatar
for (EmergencyProfessionUser u : doctorUsers) {
mergedMap.putIfAbsent(u.getUserId(), u);
}
List<EmergencyProfessionUser> allRecords = new ArrayList<>(mergedMap.values());
// ---- 5. 批量查询 sys_user,统一填充 realname/avatar/phone/deptName ----
List<String> allUserIds = allRecords.stream()
.map(EmergencyProfessionUser::getUserId).collect(Collectors.toList()); .map(EmergencyProfessionUser::getUserId).collect(Collectors.toList());
if (!userIds.isEmpty()) { if (!allUserIds.isEmpty()) {
Map<String, LoginUserNew> userMap = emergencyCloudManager.listUser(userIds); Map<String, LoginUserNew> userMap = emergencyCloudManager.listUser(allUserIds);
result.getRecords().forEach(prof -> { allRecords.forEach(prof -> {
LoginUserNew sysUser = userMap.get(prof.getUserId()); LoginUserNew sysUser = userMap.get(prof.getUserId());
if (sysUser != null && StrUtil.isNotBlank(sysUser.getOrgCode())) {
prof.setDeptName(emergencyCacheManager.getUserDepart(sysUser.getOrgCode()).getDepartName());
}
if (sysUser != null) { if (sysUser != null) {
prof.setPhone(sysUser.getPhone()); // 兜底:从 qh_con_doctor 来的记录没有 realname/avatar,用 sys_user 填充
if (StrUtil.isBlank(prof.getRealname())) {
prof.setRealname(sysUser.getRealname());
}
if (StrUtil.isBlank(prof.getAvatar())) {
prof.setAvatar(sysUser.getAvatar());
}
if (StrUtil.isNotBlank(sysUser.getOrgCode())) {
prof.setDeptName(emergencyCacheManager.getUserDepart(sysUser.getOrgCode()).getDepartName());
}
if (StrUtil.isBlank(prof.getPhone())) {
prof.setPhone(sysUser.getPhone());
}
} }
}); });
} }
// 批量查询 con_doctor 专家资料,补充专家字段
if (!userIds.isEmpty()) { // ---- 6. 对 profUsers 补充 qh_con_doctor 专家字段 ----
List<EmergencyProfessionUser> doctorList = conDoctorMapper.selectDoctorByIds(userIds); List<String> profUserIds = profUsers.stream()
.map(EmergencyProfessionUser::getUserId).collect(Collectors.toList());
if (!profUserIds.isEmpty()) {
List<EmergencyProfessionUser> doctorList = conDoctorMapper.selectDoctorByIds(profUserIds);
if (CollectionUtils.isNotEmpty(doctorList)) { if (CollectionUtils.isNotEmpty(doctorList)) {
Map<String, EmergencyProfessionUser> doctorMap = doctorList.stream() Map<String, EmergencyProfessionUser> doctorMap = doctorList.stream()
.collect(Collectors.toMap(EmergencyProfessionUser::getUserId, e -> e, (a, b) -> a)); .collect(Collectors.toMap(EmergencyProfessionUser::getUserId, e -> e, (a, b) -> a));
result.getRecords().forEach(prof -> { profUsers.forEach(prof -> {
EmergencyProfessionUser doc = doctorMap.get(prof.getUserId()); EmergencyProfessionUser doc = doctorMap.get(prof.getUserId());
if (doc == null) { if (doc == null) return;
return; copyDoctorFields(doc, prof);
}
prof.setDoctorName(doc.getDoctorName());
prof.setDoctorNo(doc.getDoctorNo());
prof.setPhoto(doc.getPhoto());
prof.setResourceName(doc.getResourceName());
prof.setDepartmentId(doc.getDepartmentId());
prof.setDepartmentName(doc.getDepartmentName());
prof.setDoctorTitle(doc.getDoctorTitle());
prof.setDoctorJob(doc.getDoctorJob());
prof.setDoctorStatus(doc.getDoctorStatus());
prof.setIsAccept(doc.getIsAccept());
prof.setDoctorType(doc.getDoctorType());
prof.setAudioStatus(doc.getAudioStatus());
prof.setTfJumpHoliday(doc.getTfJumpHoliday());
prof.setExperience(doc.getExperience());
prof.setSort(doc.getSort());
prof.setTfRecommend(doc.getTfRecommend());
prof.setIntroduction(doc.getIntroduction());
// 已有字段,con_doctor 有值时覆盖为更权威的专家资料
if (StrUtil.isNotBlank(doc.getGoodAt())) prof.setGoodAt(doc.getGoodAt());
if (StrUtil.isNotBlank(doc.getSchool())) prof.setSchool(doc.getSchool());
if (StrUtil.isNotBlank(doc.getEdu())) prof.setEdu(doc.getEdu());
}); });
} }
} }
// ---- 7. 内存分页 ----
int total = allRecords.size();
int pn = pageNo != null ? pageNo : 1;
int ps = pageSize != null ? pageSize : 10;
int fromIndex = Math.min((pn - 1) * ps, total);
int toIndex = Math.min(fromIndex + ps, total);
List<EmergencyProfessionUser> pageRecords = allRecords.subList(fromIndex, toIndex);
IPage<EmergencyProfessionUser> result = new Page<>(pn, ps, total);
result.setRecords(pageRecords);
return result; return result;
} }
private void copyDoctorFields(EmergencyProfessionUser doc, EmergencyProfessionUser prof) {
prof.setDoctorName(doc.getDoctorName());
prof.setDoctorNo(doc.getDoctorNo());
prof.setPhoto(doc.getPhoto());
prof.setResourceName(doc.getResourceName());
prof.setDepartmentId(doc.getDepartmentId());
prof.setDepartmentName(doc.getDepartmentName());
prof.setDoctorTitle(doc.getDoctorTitle());
prof.setDoctorJob(doc.getDoctorJob());
prof.setDoctorStatus(doc.getDoctorStatus());
prof.setIsAccept(doc.getIsAccept());
prof.setDoctorType(doc.getDoctorType());
prof.setAudioStatus(doc.getAudioStatus());
prof.setTfJumpHoliday(doc.getTfJumpHoliday());
prof.setExperience(doc.getExperience());
prof.setSort(doc.getSort());
prof.setTfRecommend(doc.getTfRecommend());
prof.setIntroduction(doc.getIntroduction());
if (StrUtil.isNotBlank(doc.getGoodAt())) prof.setGoodAt(doc.getGoodAt());
if (StrUtil.isNotBlank(doc.getSchool())) prof.setSchool(doc.getSchool());
if (StrUtil.isNotBlank(doc.getEdu())) prof.setEdu(doc.getEdu());
}
@Override @Override
public IPage<EmployeeVO> searchEmployee(String realname, String orgCode, String workNo, String phone, String excludeSessionId, Integer pageNo, Integer pageSize) { public IPage<EmployeeVO> searchEmployee(String realname, String orgCode, String workNo, String phone, String excludeSessionId, Integer pageNo, Integer pageSize) {
// 收集需要在结果中排除的用户ID // 收集需要在结果中排除的用户ID
@@ -1045,25 +1088,44 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService {
@Override @Override
public IPage<MyParticipatedOrderVO> myParticipatedOrders(Integer pageNo, Integer pageSize) { public IPage<MyParticipatedOrderVO> myParticipatedOrders(Integer pageNo, Integer pageSize) {
String userId = GlobalUtils.getLoginUser().getId(); String userId = GlobalUtils.getLoginUser().getId();
// 1. 查当前登录人参与的所有工单ID去重 // 1. 查当前登录人参与的工单ID(从order_operator表
List<String> orderIds = orderOperatorMapper.selectList( List<String> participatedOrderIds = orderOperatorMapper.selectList(
new LambdaQueryWrapper<OrderOperator>() new LambdaQueryWrapper<OrderOperator>()
.select(OrderOperator::getOrderId) .select(OrderOperator::getOrderId)
.eq(OrderOperator::getUserId, userId) .eq(OrderOperator::getUserId, userId)
).stream().map(OrderOperator::getOrderId).distinct().collect(Collectors.toList()); ).stream().map(OrderOperator::getOrderId).distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(orderIds)) {
// 2. 查当前用户自己发起的或被救助的应急工单ID(从order表)
List<String> ownOrderIds = orderMapper.selectList(
new LambdaQueryWrapper<Order>()
.select(Order::getId)
.and(w -> w.eq(Order::getInitiatorUserId, userId).or().eq(Order::getSalvageUserId, userId))
.eq(Order::getDelFlag, CommonConstant.DEL_FLAG_0)
.eq(Order::getStatus, 1)
).stream().map(Order::getId).distinct().collect(Collectors.toList());
// 3. 合并去重
Set<String> allOrderIds = new LinkedHashSet<>();
if (CollectionUtils.isNotEmpty(participatedOrderIds)) {
allOrderIds.addAll(participatedOrderIds);
}
if (CollectionUtils.isNotEmpty(ownOrderIds)) {
allOrderIds.addAll(ownOrderIds);
}
if (CollectionUtils.isEmpty(allOrderIds)) {
return new Page<>(pageNo != null ? pageNo : 1, pageSize != null ? pageSize : 10); return new Page<>(pageNo != null ? pageNo : 1, pageSize != null ? pageSize : 10);
} }
// 2. 查正在应急的工单
// 4. 分页查询正在应急的工单
Page<Order> page = new Page<>(pageNo != null ? pageNo : 1, pageSize != null ? pageSize : 10); Page<Order> page = new Page<>(pageNo != null ? pageNo : 1, pageSize != null ? pageSize : 10);
LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
wrapper.in(Order::getId, orderIds); wrapper.in(Order::getId, new ArrayList<>(allOrderIds));
wrapper.eq(Order::getSessionNow, true); wrapper.eq(Order::getSessionNow, true);
wrapper.eq(Order::getDelFlag, CommonConstant.DEL_FLAG_0); wrapper.eq(Order::getDelFlag, CommonConstant.DEL_FLAG_0);
wrapper.eq(Order::getStatus, 1); wrapper.eq(Order::getStatus, 1);
wrapper.orderByDesc(Order::getCreateTime); wrapper.orderByDesc(Order::getCreateTime);
IPage<Order> srcPage = orderMapper.selectPage(page, wrapper); IPage<Order> srcPage = orderMapper.selectPage(page, wrapper);
// 3. 映射VO // 5. 映射VO
Page<MyParticipatedOrderVO> targetPage = new Page<>(srcPage.getCurrent(), srcPage.getSize(), srcPage.getTotal()); Page<MyParticipatedOrderVO> targetPage = new Page<>(srcPage.getCurrent(), srcPage.getSize(), srcPage.getTotal());
if (CollectionUtils.isEmpty(srcPage.getRecords())) { if (CollectionUtils.isEmpty(srcPage.getRecords())) {
return targetPage; return targetPage;
@@ -35,4 +35,31 @@ public interface ConDoctorMapper {
"<foreach collection='doctorIds' item='id' open='(' separator=',' close=')'>#{id}</foreach>" + "<foreach collection='doctorIds' item='id' open='(' separator=',' close=')'>#{id}</foreach>" +
"</script>") "</script>")
List<EmergencyProfessionUser> selectDoctorByIds(@Param("doctorIds") List<String> doctorIds); List<EmergencyProfessionUser> selectDoctorByIds(@Param("doctorIds") List<String> doctorIds);
/**
* 搜索专家(从 qh_con_doctor 表),排除已在应急专业人员表或已在群中的用户
*
* @param name 医生姓名,模糊匹配
* @param excludeIds 需要排除的用户ID集合(已从 QH_EME_PROFESS_USER 查到 + 已在群中的)
* @return 以 EmergencyProfessionUser 承载结果,基础字段由 SQL 别名映射
*/
@Select("<script>" +
"SELECT id AS userId, doctor_name AS realname, photo AS avatar, " +
"doctor_name AS doctorName, doctor_no AS doctorNo, " +
"resource_name AS resourceName, department_id AS departmentId, department_name AS departmentName, " +
"doctor_title AS doctorTitle, doctor_job AS doctorJob, doctor_status AS doctorStatus, " +
"is_accept AS isAccept, type AS doctorType, audio_status AS audioStatus, tf_jump_holiday AS tfJumpHoliday, " +
"experience, good_at AS goodAt, school, e_q AS edu, sort, " +
"tf_recommend AS tfRecommend, introduction " +
"FROM qh_con_doctor " +
"WHERE del_flag = '0' AND status = '1' " +
"<if test='name != null and name != \"\"'>" +
"AND doctor_name LIKE CONCAT('%', CONCAT(#{name}, '%')) " +
"</if>" +
"<if test='excludeIds != null and excludeIds.size() > 0'>" +
"AND id NOT IN " +
"<foreach collection='excludeIds' item='id' open='(' separator=',' close=')'>#{id}</foreach>" +
"</if>" +
"</script>")
List<EmergencyProfessionUser> searchDoctorByName(@Param("name") String name, @Param("excludeIds") List<String> excludeIds);
} }
@@ -20,38 +20,38 @@ public interface FirstAidResourceCategoryMapper extends BaseMapper<FirstAidResou
/** /**
* 查询某分类下的标签数量(级联删除校验用,TYPE=2) * 查询某分类下的标签数量(级联删除校验用,TYPE=2)
*/ */
@Select("SELECT COUNT(*) FROM QH_EME_FIRST_AID_RESOURCE_CATEGORY WHERE PARENT_ID = #{parentId} AND TYPE = 2 AND DEL_FLAG = 0") @Select("SELECT COUNT(*) FROM QH_EME_FIR_AID_RES_CATE WHERE PARENT_ID = #{parentId} AND TYPE = 2 AND DEL_FLAG = 0")
Integer countChildrenByParentId(@Param("parentId") String parentId); Integer countChildrenByParentId(@Param("parentId") String parentId);
/** /**
* 查询某分类下的资源数量(级联删除校验用) * 查询某分类下的资源数量(级联删除校验用)
*/ */
@Select("SELECT COUNT(*) FROM QH_EME_FIRST_AID_RESOURCE WHERE CATEGORY_ID = #{categoryId} AND DEL_FLAG = 0") @Select("SELECT COUNT(*) FROM QH_EME_FIR_AID_RES WHERE CATEGORY_ID = #{categoryId} AND DEL_FLAG = 0")
Integer countResourcesByCategoryId(@Param("categoryId") String categoryId); Integer countResourcesByCategoryId(@Param("categoryId") String categoryId);
/** /**
* 查询引用某标签的资源数量(标签删除校验用) * 查询引用某标签的资源数量(标签删除校验用)
*/ */
@Select("SELECT COUNT(*) FROM QH_EME_FIRST_AID_RESOURCE WHERE DEL_FLAG = 0 AND CONCAT(',', TAGS, ',') LIKE CONCAT('%,', #{tagId}, ',%')") @Select("SELECT COUNT(*) FROM QH_EME_FIR_AID_RES WHERE DEL_FLAG = 0 AND CONCAT(',', TAGS, ',') LIKE CONCAT('%,', #{tagId}, ',%')")
Integer countResourcesByTagId(@Param("tagId") String tagId); Integer countResourcesByTagId(@Param("tagId") String tagId);
/** /**
* 按父分类ID查询标签列表(TYPE=2) * 按父分类ID查询标签列表(TYPE=2)
*/ */
@Select("SELECT * FROM QH_EME_FIRST_AID_RESOURCE_CATEGORY WHERE PARENT_ID = #{parentId} AND TYPE = 2 AND STATUS = 1 AND DEL_FLAG = 0 ORDER BY SORT_NO ASC") @Select("SELECT * FROM QH_EME_FIR_AID_RES_CATE WHERE PARENT_ID = #{parentId} AND TYPE = 2 AND STATUS = 1 AND DEL_FLAG = 0 ORDER BY SORT_NO ASC")
List<FirstAidResourceCategory> selectByParentId(@Param("parentId") String parentId); List<FirstAidResourceCategory> selectByParentId(@Param("parentId") String parentId);
/** /**
* 按类型查询分类/标签列表 * 按类型查询分类/标签列表
*/ */
@Select("SELECT * FROM QH_EME_FIRST_AID_RESOURCE_CATEGORY WHERE TYPE = #{type} AND STATUS = 1 AND DEL_FLAG = 0 ORDER BY SORT_NO ASC, CREATE_TIME DESC") @Select("SELECT * FROM QH_EME_FIR_AID_RES_CATE WHERE TYPE = #{type} AND STATUS = 1 AND DEL_FLAG = 0 ORDER BY SORT_NO ASC, CREATE_TIME DESC")
List<FirstAidResourceCategory> selectByType(@Param("type") Integer type); List<FirstAidResourceCategory> selectByType(@Param("type") Integer type);
/** /**
* 按类型+父分类查询标签列表 * 按类型+父分类查询标签列表
*/ */
@Select("<script>" + @Select("<script>" +
"SELECT * FROM QH_EME_FIRST_AID_RESOURCE_CATEGORY WHERE TYPE = #{type} AND STATUS = 1 AND DEL_FLAG = 0" + "SELECT * FROM QH_EME_FIR_AID_RES_CATE WHERE TYPE = #{type} AND STATUS = 1 AND DEL_FLAG = 0" +
"<if test='parentId != null and parentId != \"\"'> AND PARENT_ID = #{parentId}</if>" + "<if test='parentId != null and parentId != \"\"'> AND PARENT_ID = #{parentId}</if>" +
" ORDER BY SORT_NO ASC, CREATE_TIME DESC" + " ORDER BY SORT_NO ASC, CREATE_TIME DESC" +
"</script>") "</script>")
@@ -60,7 +60,7 @@ public interface FirstAidResourceCategoryMapper extends BaseMapper<FirstAidResou
/** /**
* 查询所有根分类(PARENT_ID IS NULL * 查询所有根分类(PARENT_ID IS NULL
*/ */
@Select("SELECT * FROM QH_EME_FIRST_AID_RESOURCE_CATEGORY WHERE TYPE = 1 AND PARENT_ID IS NULL AND STATUS = 1 AND DEL_FLAG = 0 ORDER BY SORT_NO ASC") @Select("SELECT * FROM QH_EME_FIR_AID_RES_CATE WHERE TYPE = 1 AND PARENT_ID IS NULL AND STATUS = 1 AND DEL_FLAG = 0 ORDER BY SORT_NO ASC")
List<FirstAidResourceCategory> selectRootCategories(); List<FirstAidResourceCategory> selectRootCategories();
} }
@@ -19,24 +19,24 @@ public interface FirstAidResourceMapper extends BaseMapper<FirstAidResource> {
/** /**
* 查询某分类下的资源数量(级联删除校验用) * 查询某分类下的资源数量(级联删除校验用)
*/ */
@Select("SELECT COUNT(*) FROM QH_EME_FIRST_AID_RESOURCE WHERE CATEGORY_ID = #{categoryId} AND DEL_FLAG = 0") @Select("SELECT COUNT(*) FROM QH_EME_FIR_AID_RES WHERE CATEGORY_ID = #{categoryId} AND DEL_FLAG = 0")
Integer countByCategoryId(@Param("categoryId") String categoryId); Integer countByCategoryId(@Param("categoryId") String categoryId);
/** /**
* 浏览计数+1 * 浏览计数+1
*/ */
@Update("UPDATE QH_EME_FIRST_AID_RESOURCE SET VIEW_COUNT = VIEW_COUNT + 1 WHERE ID = #{id}") @Update("UPDATE QH_EME_FIR_AID_RES SET VIEW_COUNT = VIEW_COUNT + 1 WHERE ID = #{id}")
void incrementViewCount(@Param("id") String id); void incrementViewCount(@Param("id") String id);
/** /**
* 收藏计数+1 * 收藏计数+1
*/ */
@Update("UPDATE QH_EME_FIRST_AID_RESOURCE SET FAVORITE_COUNT = FAVORITE_COUNT + 1 WHERE ID = #{id}") @Update("UPDATE QH_EME_FIR_AID_RES SET FAVORITE_COUNT = FAVORITE_COUNT + 1 WHERE ID = #{id}")
void incrementFavoriteCount(@Param("id") String id); void incrementFavoriteCount(@Param("id") String id);
/** /**
* 收藏计数-1 * 收藏计数-1
*/ */
@Update("UPDATE QH_EME_FIRST_AID_RESOURCE SET FAVORITE_COUNT = FAVORITE_COUNT - 1 WHERE ID = #{id} AND FAVORITE_COUNT > 0") @Update("UPDATE QH_EME_FIR_AID_RES SET FAVORITE_COUNT = FAVORITE_COUNT - 1 WHERE ID = #{id} AND FAVORITE_COUNT > 0")
void decrementFavoriteCount(@Param("id") String id); void decrementFavoriteCount(@Param("id") String id);
} }
@@ -24,7 +24,7 @@ public interface FirstAidResourceUserActionMapper extends BaseMapper<FirstAidRes
* 查询用户对一批资源的收藏状态 * 查询用户对一批资源的收藏状态
*/ */
@Select("<script>" + @Select("<script>" +
"SELECT RESOURCE_ID FROM QH_EME_FIRST_AID_RESOURCE_USER_ACTION " + "SELECT RESOURCE_ID FROM QH_EME_FIR_AID_RES_UACT " +
"WHERE USER_ID = #{userId} AND TYPE = 2 " + "WHERE USER_ID = #{userId} AND TYPE = 2 " +
"AND RESOURCE_ID IN " + "AND RESOURCE_ID IN " +
"<foreach collection='resourceIds' item='id' open='(' separator=',' close=')'>" + "<foreach collection='resourceIds' item='id' open='(' separator=',' close=')'>" +
@@ -37,8 +37,8 @@ public interface FirstAidResourceUserActionMapper extends BaseMapper<FirstAidRes
/** /**
* 查询用户的收藏资源列表(分页) * 查询用户的收藏资源列表(分页)
*/ */
@Select("SELECT R.* FROM QH_EME_FIRST_AID_RESOURCE R " + @Select("SELECT R.* FROM QH_EME_FIR_AID_RES R " +
"INNER JOIN QH_EME_FIRST_AID_RESOURCE_USER_ACTION A ON R.ID = A.RESOURCE_ID " + "INNER JOIN QH_EME_FIR_AID_RES_UACT A ON R.ID = A.RESOURCE_ID " +
"WHERE A.USER_ID = #{userId} AND A.TYPE = 2 AND R.DEL_FLAG = 0 " + "WHERE A.USER_ID = #{userId} AND A.TYPE = 2 AND R.DEL_FLAG = 0 " +
"ORDER BY A.CREATE_TIME DESC") "ORDER BY A.CREATE_TIME DESC")
IPage<FirstAidResource> selectFavoritePage(Page<FirstAidResource> page, @Param("userId") String userId); IPage<FirstAidResource> selectFavoritePage(Page<FirstAidResource> page, @Param("userId") String userId);
@@ -20,18 +20,18 @@ public interface FirstAidResourceVersionMapper extends BaseMapper<FirstAidResour
/** /**
* 查询某资源的最高版本号 * 查询某资源的最高版本号
*/ */
@Select("SELECT MAX(VERSION_NO) FROM QH_EME_FIRST_AID_RESOURCE_VERSION WHERE RESOURCE_ID = #{resourceId}") @Select("SELECT MAX(VERSION_NO) FROM QH_EME_FIR_AID_RES_VER WHERE RESOURCE_ID = #{resourceId}")
Integer selectMaxVersionNo(@Param("resourceId") String resourceId); Integer selectMaxVersionNo(@Param("resourceId") String resourceId);
/** /**
* 查询某资源的所有版本历史(按版本号倒序) * 查询某资源的所有版本历史(按版本号倒序)
*/ */
@Select("SELECT * FROM QH_EME_FIRST_AID_RESOURCE_VERSION WHERE RESOURCE_ID = #{resourceId} ORDER BY VERSION_NO DESC") @Select("SELECT * FROM QH_EME_FIR_AID_RES_VER WHERE RESOURCE_ID = #{resourceId} ORDER BY VERSION_NO DESC")
List<FirstAidResourceVersion> selectByResourceId(@Param("resourceId") String resourceId); List<FirstAidResourceVersion> selectByResourceId(@Param("resourceId") String resourceId);
/** /**
* 查询某资源的所有非当前版本ID(按版本号降序),用于清理旧版本 * 查询某资源的所有非当前版本ID(按版本号降序),用于清理旧版本
*/ */
@Select("SELECT ID FROM QH_EME_FIRST_AID_RESOURCE_VERSION WHERE RESOURCE_ID = #{resourceId} AND IS_CURRENT = 0 ORDER BY VERSION_NO DESC") @Select("SELECT ID FROM QH_EME_FIR_AID_RES_VER WHERE RESOURCE_ID = #{resourceId} AND IS_CURRENT = 0 ORDER BY VERSION_NO DESC")
List<String> selectNonCurrentVersionIds(@Param("resourceId") String resourceId); List<String> selectNonCurrentVersionIds(@Param("resourceId") String resourceId);
} }
@@ -14,8 +14,14 @@ import com.renkang.emergency.entity.EmergencyCenterAdmin;
import com.renkang.emergency.manager.EmergencyCloudManager; import com.renkang.emergency.manager.EmergencyCloudManager;
import com.renkang.emergency.mapper.EmergencyCenterAdminMapper; import com.renkang.emergency.mapper.EmergencyCenterAdminMapper;
import com.renkang.emergency.service.IEmergencyCenterAdminService; import com.renkang.emergency.service.IEmergencyCenterAdminService;
import com.renkang.im.api.IMHelloApi;
import com.renkang.im.entity.ConSessionRequestDO;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.bean.request.ListUser;
import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.ExceptionAssertsUtil; import org.jeecg.common.exception.ExceptionAssertsUtil;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUserNew;
import org.jeecg.common.system.vo.SysUserModel; import org.jeecg.common.system.vo.SysUserModel;
import org.jeecg.common.util.CheckPasswordUtil; import org.jeecg.common.util.CheckPasswordUtil;
import org.jeecg.common.util.PasswordUtil; import org.jeecg.common.util.PasswordUtil;
@@ -37,6 +43,7 @@ import java.util.List;
* @Author YangYuanChen * @Author YangYuanChen
* @Data 20242024/8/21下午2:06 * @Data 20242024/8/21下午2:06
*/ */
@Slf4j
@Service @Service
public class EmergencyCenterAdminServiceImpl extends ServiceImpl<EmergencyCenterAdminMapper, EmergencyCenterAdmin> implements IEmergencyCenterAdminService { public class EmergencyCenterAdminServiceImpl extends ServiceImpl<EmergencyCenterAdminMapper, EmergencyCenterAdmin> implements IEmergencyCenterAdminService {
@@ -44,6 +51,10 @@ public class EmergencyCenterAdminServiceImpl extends ServiceImpl<EmergencyCenter
private EmergencyCloudManager cloudManager; private EmergencyCloudManager cloudManager;
@Autowired @Autowired
private RedisStreamUtil redisStreamUtil; private RedisStreamUtil redisStreamUtil;
@Autowired
private IMHelloApi imHelloApi;
@Autowired
private ISysBaseAPI sysBaseAPI;
@Override @Override
public IPage<EmergencyCenterAdmin> customPage(String centerId, String type, String realName, Integer pageNo, Integer pageSize) { public IPage<EmergencyCenterAdmin> customPage(String centerId, String type, String realName, Integer pageNo, Integer pageSize) {
@@ -101,6 +112,21 @@ public class EmergencyCenterAdminServiceImpl extends ServiceImpl<EmergencyCenter
// 修改system // 修改system
updateUserStream(byId.getUserId(), admin.getRealname()); updateUserStream(byId.getUserId(), admin.getRealname());
// 同步IM个人资料
syncImProfile(byId.getUserId());
}
private void syncImProfile(String userId) {
try {
List<LoginUserNew> users = sysBaseAPI.listUserByIds(new ListUser(Collections.singletonList(userId)));
if (CollUtil.isNotEmpty(users)) {
ConSessionRequestDO req = new ConSessionRequestDO();
req.setAccountList(Collections.singletonList(users.get(0)));
imHelloApi.accountReg(req);
}
} catch (Exception e) {
log.error("同步IM个人资料失败, userId: {}", userId, e);
}
} }
@Override @Override
@@ -17,8 +17,14 @@ import com.renkang.emergency.manager.PermissionManager;
import com.renkang.emergency.mapper.EmergencyProfessionUserMapper; import com.renkang.emergency.mapper.EmergencyProfessionUserMapper;
import com.renkang.emergency.mapper.EmergencySchedulesNewItemMapper; import com.renkang.emergency.mapper.EmergencySchedulesNewItemMapper;
import com.renkang.emergency.service.EmergencyProfessionUserService; import com.renkang.emergency.service.EmergencyProfessionUserService;
import com.renkang.im.api.IMHelloApi;
import com.renkang.im.entity.ConSessionRequestDO;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.bean.request.ListUser;
import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.ExceptionAssertsUtil; import org.jeecg.common.exception.ExceptionAssertsUtil;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUserNew;
import org.jeecg.common.system.vo.SysUserModel; import org.jeecg.common.system.vo.SysUserModel;
import org.jeecg.common.util.PasswordUtil; import org.jeecg.common.util.PasswordUtil;
import org.jeecg.redis.RedisStreamKeyEnum; import org.jeecg.redis.RedisStreamKeyEnum;
@@ -27,6 +33,7 @@ import org.jeecg.util.RSAEncryptUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -37,6 +44,7 @@ import java.util.stream.Collectors;
* @author stan * @author stan
* @since 2024-09-12 09:38:13 * @since 2024-09-12 09:38:13
*/ */
@Slf4j
@Service @Service
public class EmergencyProfessionUserServiceImpl extends ServiceImpl<EmergencyProfessionUserMapper, EmergencyProfessionUser> implements EmergencyProfessionUserService { public class EmergencyProfessionUserServiceImpl extends ServiceImpl<EmergencyProfessionUserMapper, EmergencyProfessionUser> implements EmergencyProfessionUserService {
@@ -48,6 +56,10 @@ public class EmergencyProfessionUserServiceImpl extends ServiceImpl<EmergencyPro
private PermissionManager permissionManager; private PermissionManager permissionManager;
@Autowired @Autowired
private EmergencySchedulesNewItemMapper emergencySchedulesNewItemMapper; private EmergencySchedulesNewItemMapper emergencySchedulesNewItemMapper;
@Autowired
private IMHelloApi imHelloApi;
@Autowired
private ISysBaseAPI sysBaseAPI;
@Override @Override
public IPage<EmergencyProfessionUser> customPage(String name, String centerId, int type, int pageNo, int pageSize) { public IPage<EmergencyProfessionUser> customPage(String name, String centerId, int type, int pageNo, int pageSize) {
@@ -145,6 +157,21 @@ public class EmergencyProfessionUserServiceImpl extends ServiceImpl<EmergencyPro
} }
// 修改system // 修改system
updateUserStream(oldData.getUserId(), data.getRealname(), data.getAvatar()); updateUserStream(oldData.getUserId(), data.getRealname(), data.getAvatar());
// 同步IM个人资料
syncImProfile(oldData.getUserId());
}
private void syncImProfile(String userId) {
try {
List<LoginUserNew> users = sysBaseAPI.listUserByIds(new ListUser(Collections.singletonList(userId)));
if (CollUtil.isNotEmpty(users)) {
ConSessionRequestDO req = new ConSessionRequestDO();
req.setAccountList(Collections.singletonList(users.get(0)));
imHelloApi.accountReg(req);
}
} catch (Exception e) {
log.error("同步IM个人资料失败, userId: {}", userId, e);
}
} }
@Override @Override
@@ -1,520 +1,4 @@
[ [
{
"id": 10641,
"empId": "f497b917da064874b022e036ddb7804b",
"treatPlanResponse": "",
"dietSuggestionResponse": "",
"sportGuideResponse": "",
"lifeManageResponse": "",
"createDate": "2025-08-01 12:43:33",
"updateDate": "2025-08-05 10:43:33",
"createBy": "13263",
"updateBy": "13263",
"delFlag": "0",
"dataLevel": "0",
"negativeList": "",
"flagFat": 2,
"bmi": 27.02,
"height": 176,
"weight": 81.8,
"bmiCurrent": 26.4,
"hypertension": 1,
"systolicPressureAvg": 106,
"systolicPressureTarget": 120,
"systolicPressureCurrent": 122,
"diastolicPressureAvg": 71,
"diastolicPressureTarget": 90,
"diastolicPressureCurrent": 87,
"diabetes": 1,
"glu": 5.79,
"bloodSugarTarget": "6.1",
"bloodSugarCurrent": 6.2,
"ldl": 0,
"ldlTarget": "3.4",
"ldlCurrent": 0,
"tc": 4.71,
"tcTarget": "5.2",
"tcCurrent": 4.53,
"tg": 0,
"tgTarget": "1.7",
"tgCurrent": 0,
"uricAcid": 0,
"uricAcidTarget": "420",
"uricAcidCurrent": 350,
"homocysteine": 15.04,
"homocysteineTarget": "13.54",
"homocysteineCurrent": 0,
"workUnit": "新疆油田储气库有限公司-机关",
"workUnitId": "103074",
"age": 36,
"sex": "男",
"name": "连龙刚",
"careLiaisonName": "刘一"
},
{
"id": 10641,
"empId": "f497b917da064874b022e036ddb7804b",
"treatPlanResponse": "",
"dietSuggestionResponse": "",
"sportGuideResponse": "",
"lifeManageResponse": "",
"createDate": "2025-09-05 11:43:33",
"updateDate": "2025-09-05 11:43:33",
"createBy": "13263",
"updateBy": "13263",
"delFlag": "0",
"dataLevel": "0",
"negativeList": "",
"flagFat": 2,
"bmi": 27.02,
"height": 176,
"weight": 81.8,
"bmiCurrent": 26.4,
"hypertension": 1,
"systolicPressureAvg": 106,
"systolicPressureTarget": 120,
"systolicPressureCurrent": 122,
"diastolicPressureAvg": 71,
"diastolicPressureTarget": 90,
"diastolicPressureCurrent": 87,
"diabetes": 1,
"glu": 5.79,
"bloodSugarTarget": "6.1",
"bloodSugarCurrent": 6.2,
"ldl": 0,
"ldlTarget": "3.4",
"ldlCurrent": 0,
"tc": 4.71,
"tcTarget": "5.2",
"tcCurrent": 4.53,
"tg": 0,
"tgTarget": "1.7",
"tgCurrent": 0,
"uricAcid": 0,
"uricAcidTarget": "420",
"uricAcidCurrent": 350,
"homocysteine": 15.04,
"homocysteineTarget": "13.54",
"homocysteineCurrent": 0,
"workUnit": "新疆油田储气库有限公司-机关",
"workUnitId": "103074",
"age": 41,
"sex": "男",
"name": "李苏望",
"careLiaisonName": "陈二"
},
{
"id": 10641,
"empId": "f497b917da064874b022e036ddb7804b",
"treatPlanResponse": "",
"dietSuggestionResponse": "",
"sportGuideResponse": "",
"lifeManageResponse": "",
"createDate": "2025-07-05 11:43:33",
"updateDate": "2025-07-05 11:43:33",
"createBy": "13263",
"updateBy": "13263",
"delFlag": "0",
"dataLevel": "0",
"negativeList": "",
"flagFat": 2,
"bmi": 27.02,
"height": 176,
"weight": 81.8,
"bmiCurrent": 26.4,
"hypertension": 1,
"systolicPressureAvg": 106,
"systolicPressureTarget": 120,
"systolicPressureCurrent": 122,
"diastolicPressureAvg": 71,
"diastolicPressureTarget": 90,
"diastolicPressureCurrent": 87,
"diabetes": 1,
"glu": 5.79,
"bloodSugarTarget": "6.1",
"bloodSugarCurrent": 6.2,
"ldl": 0,
"ldlTarget": "3.4",
"ldlCurrent": 0,
"tc": 4.71,
"tcTarget": "5.2",
"tcCurrent": 4.53,
"tg": 0,
"tgTarget": "1.7",
"tgCurrent": 0,
"uricAcid": 0,
"uricAcidTarget": "420",
"uricAcidCurrent": 350,
"homocysteine": 15.04,
"homocysteineTarget": "13.54",
"homocysteineCurrent": 0,
"workUnit": "新疆油田储气库有限公司-机关",
"workUnitId": "103074",
"age": 29,
"sex": "男",
"name": "王先森",
"careLiaisonName": "张三"
},
{
"id": 10641,
"empId": "f497b917da064874b022e036ddb7804b",
"treatPlanResponse": "",
"dietSuggestionResponse": "",
"sportGuideResponse": "",
"lifeManageResponse": "",
"createDate": "2024-09-05 11:43:33",
"updateDate": "2024-09-05 11:43:33",
"createBy": "13263",
"updateBy": "13263",
"delFlag": "0",
"dataLevel": "0",
"negativeList": "",
"flagFat": 2,
"bmi": 27.02,
"height": 176,
"weight": 81.8,
"bmiCurrent": 26.4,
"hypertension": 1,
"systolicPressureAvg": 106,
"systolicPressureTarget": 120,
"systolicPressureCurrent": 122,
"diastolicPressureAvg": 71,
"diastolicPressureTarget": 90,
"diastolicPressureCurrent": 87,
"diabetes": 1,
"glu": 5.79,
"bloodSugarTarget": "6.1",
"bloodSugarCurrent": 6.2,
"ldl": 0,
"ldlTarget": "3.4",
"ldlCurrent": 0,
"tc": 4.71,
"tcTarget": "5.2",
"tcCurrent": 4.53,
"tg": 0,
"tgTarget": "1.7",
"tgCurrent": 0,
"uricAcid": 0,
"uricAcidTarget": "420",
"uricAcidCurrent": 350,
"homocysteine": 15.04,
"homocysteineTarget": "13.54",
"homocysteineCurrent": 0,
"workUnit": "新疆油田储气库有限公司-机关",
"workUnitId": "103074",
"age": 50,
"sex": "男",
"name": "阿尔麦江.买买提",
"careLiaisonName": "李四"
},
{
"id": 10641,
"empId": "f497b917da064874b022e036ddb7804b",
"treatPlanResponse": "",
"dietSuggestionResponse": "",
"sportGuideResponse": "",
"lifeManageResponse": "",
"createDate": "2025-06-05 11:43:33",
"updateDate": "2025-06-05 11:43:33",
"createBy": "13263",
"updateBy": "13263",
"delFlag": "0",
"dataLevel": "0",
"negativeList": "",
"flagFat": 2,
"bmi": 27.02,
"height": 176,
"weight": 81.8,
"bmiCurrent": 26.4,
"hypertension": 1,
"systolicPressureAvg": 106,
"systolicPressureTarget": 120,
"systolicPressureCurrent": 122,
"diastolicPressureAvg": 71,
"diastolicPressureTarget": 90,
"diastolicPressureCurrent": 87,
"diabetes": 1,
"glu": 5.79,
"bloodSugarTarget": "6.1",
"bloodSugarCurrent": 6.2,
"ldl": 0,
"ldlTarget": "3.4",
"ldlCurrent": 0,
"tc": 4.71,
"tcTarget": "5.2",
"tcCurrent": 4.53,
"tg": 0,
"tgTarget": "1.7",
"tgCurrent": 0,
"uricAcid": 0,
"uricAcidTarget": "420",
"uricAcidCurrent": 350,
"homocysteine": 15.04,
"homocysteineTarget": "13.54",
"homocysteineCurrent": 0,
"workUnit": "新疆油田储气库有限公司-机关",
"workUnitId": "103074",
"age": 24,
"sex": "女",
"name": "古力娜扎.艾卡尔",
"careLiaisonName": "王五"
},
{
"id": 10641,
"empId": "f497b917da064874b022e036ddb7804b",
"treatPlanResponse": "",
"dietSuggestionResponse": "",
"sportGuideResponse": "",
"lifeManageResponse": "",
"createDate": "2024-09-15 11:43:33",
"updateDate": "2024-09-15 11:43:33",
"createBy": "13263",
"updateBy": "13263",
"delFlag": "0",
"dataLevel": "0",
"negativeList": "",
"flagFat": 2,
"bmi": 27.02,
"height": 176,
"weight": 81.8,
"bmiCurrent": 26.4,
"hypertension": 1,
"systolicPressureAvg": 106,
"systolicPressureTarget": 120,
"systolicPressureCurrent": 122,
"diastolicPressureAvg": 71,
"diastolicPressureTarget": 90,
"diastolicPressureCurrent": 87,
"diabetes": 1,
"glu": 5.79,
"bloodSugarTarget": "6.1",
"bloodSugarCurrent": 6.2,
"ldl": 0,
"ldlTarget": "3.4",
"ldlCurrent": 0,
"tc": 4.71,
"tcTarget": "5.2",
"tcCurrent": 4.53,
"tg": 0,
"tgTarget": "1.7",
"tgCurrent": 0,
"uricAcid": 0,
"uricAcidTarget": "420",
"uricAcidCurrent": 350,
"homocysteine": 15.04,
"homocysteineTarget": "13.54",
"homocysteineCurrent": 0,
"workUnit": "新疆油田储气库有限公司-机关",
"workUnitId": "103074",
"age": 37,
"sex": "男",
"name": "梁文斌",
"careLiaisonName": "赵六"
},
{
"id": 10641,
"empId": "f497b917da064874b022e036ddb7804b",
"treatPlanResponse": "",
"dietSuggestionResponse": "",
"sportGuideResponse": "",
"lifeManageResponse": "",
"createDate": "2025-01-05 11:43:33",
"updateDate": "2025-01-05 11:43:33",
"createBy": "13263",
"updateBy": "13263",
"delFlag": "0",
"dataLevel": "0",
"negativeList": "",
"flagFat": 2,
"bmi": 27.02,
"height": 176,
"weight": 81.8,
"bmiCurrent": 26.4,
"hypertension": 1,
"systolicPressureAvg": 106,
"systolicPressureTarget": 120,
"systolicPressureCurrent": 122,
"diastolicPressureAvg": 71,
"diastolicPressureTarget": 90,
"diastolicPressureCurrent": 87,
"diabetes": 1,
"glu": 5.79,
"bloodSugarTarget": "6.1",
"bloodSugarCurrent": 6.2,
"ldl": 0,
"ldlTarget": "3.4",
"ldlCurrent": 0,
"tc": 4.71,
"tcTarget": "5.2",
"tcCurrent": 4.53,
"tg": 0,
"tgTarget": "1.7",
"tgCurrent": 0,
"uricAcid": 0,
"uricAcidTarget": "420",
"uricAcidCurrent": 350,
"homocysteine": 15.04,
"homocysteineTarget": "13.54",
"homocysteineCurrent": 0,
"workUnit": "新疆油田储气库有限公司-机关",
"workUnitId": "103074",
"age": 46,
"sex": "男",
"name": "加海洋",
"careLiaisonName": "孙七"
},
{
"id": 10641,
"empId": "f497b917da064874b022e036ddb7804b",
"treatPlanResponse": "",
"dietSuggestionResponse": "",
"sportGuideResponse": "",
"lifeManageResponse": "",
"createDate": "2025-09-02 11:43:33",
"updateDate": "2025-09-02 11:43:33",
"createBy": "13263",
"updateBy": "13263",
"delFlag": "0",
"dataLevel": "0",
"negativeList": "",
"flagFat": 2,
"bmi": 27.02,
"height": 176,
"weight": 81.8,
"bmiCurrent": 26.4,
"hypertension": 1,
"systolicPressureAvg": 106,
"systolicPressureTarget": 120,
"systolicPressureCurrent": 122,
"diastolicPressureAvg": 71,
"diastolicPressureTarget": 90,
"diastolicPressureCurrent": 87,
"diabetes": 1,
"glu": 5.79,
"bloodSugarTarget": "6.1",
"bloodSugarCurrent": 6.2,
"ldl": 0,
"ldlTarget": "3.4",
"ldlCurrent": 0,
"tc": 4.71,
"tcTarget": "5.2",
"tcCurrent": 4.53,
"tg": 0,
"tgTarget": "1.7",
"tgCurrent": 0,
"uricAcid": 0,
"uricAcidTarget": "420",
"uricAcidCurrent": 350,
"homocysteine": 15.04,
"homocysteineTarget": "13.54",
"homocysteineCurrent": 0,
"workUnit": "新疆油田储气库有限公司-机关",
"workUnitId": "103074",
"age": 41,
"sex": "女",
"name": "周八"
},
{
"id": 10641,
"empId": "f497b917da064874b022e036ddb7804b",
"treatPlanResponse": "",
"dietSuggestionResponse": "",
"sportGuideResponse": "",
"lifeManageResponse": "",
"createDate": "2025-09-07 11:43:33",
"updateDate": "2025-09-07 11:43:33",
"createBy": "13263",
"updateBy": "13263",
"delFlag": "0",
"dataLevel": "0",
"negativeList": "",
"flagFat": 2,
"bmi": 27.02,
"height": 176,
"weight": 81.8,
"bmiCurrent": 26.4,
"hypertension": 1,
"systolicPressureAvg": 106,
"systolicPressureTarget": 120,
"systolicPressureCurrent": 122,
"diastolicPressureAvg": 71,
"diastolicPressureTarget": 90,
"diastolicPressureCurrent": 87,
"diabetes": 1,
"glu": 5.79,
"bloodSugarTarget": "6.1",
"bloodSugarCurrent": 6.2,
"ldl": 0,
"ldlTarget": "3.4",
"ldlCurrent": 0,
"tc": 4.71,
"tcTarget": "5.2",
"tcCurrent": 4.53,
"tg": 0,
"tgTarget": "1.7",
"tgCurrent": 0,
"uricAcid": 0,
"uricAcidTarget": "420",
"uricAcidCurrent": 350,
"homocysteine": 15.04,
"homocysteineTarget": "13.54",
"homocysteineCurrent": 0,
"workUnit": "新疆油田储气库有限公司-机关",
"workUnitId": "103074",
"age": 28,
"sex": "女",
"name": "吴九"
},
{
"id": 10641,
"empId": "f497b917da064874b022e036ddb7804b",
"treatPlanResponse": "",
"dietSuggestionResponse": "",
"sportGuideResponse": "",
"lifeManageResponse": "",
"createDate": "2025-09-06 11:43:33",
"updateDate": "2025-09-06 11:43:33",
"createBy": "13263",
"updateBy": "13263",
"delFlag": "0",
"dataLevel": "0",
"negativeList": "",
"flagFat": 2,
"bmi": 27.02,
"height": 176,
"weight": 81.8,
"bmiCurrent": 26.4,
"hypertension": 1,
"systolicPressureAvg": 106,
"systolicPressureTarget": 120,
"systolicPressureCurrent": 122,
"diastolicPressureAvg": 71,
"diastolicPressureTarget": 90,
"diastolicPressureCurrent": 87,
"diabetes": 1,
"glu": 5.79,
"bloodSugarTarget": "6.1",
"bloodSugarCurrent": 6.2,
"ldl": 0,
"ldlTarget": "3.4",
"ldlCurrent": 0,
"tc": 4.71,
"tcTarget": "5.2",
"tcCurrent": 4.53,
"tg": 0,
"tgTarget": "1.7",
"tgCurrent": 0,
"uricAcid": 0,
"uricAcidTarget": "420",
"uricAcidCurrent": 350,
"homocysteine": 15.04,
"homocysteineTarget": "13.54",
"homocysteineCurrent": 0,
"workUnit": "新疆油田储气库有限公司-机关",
"workUnitId": "103074",
"age": 36,
"sex": "男",
"name": "郑十"
}
] ]
@@ -7,7 +7,7 @@
-- TYPE: 1=分类, 2=标签 -- TYPE: 1=分类, 2=标签
-- 分类支持多级树形PARENT_ID 指向父分类NULL=根分类 -- 分类支持多级树形PARENT_ID 指向父分类NULL=根分类
-- 标签为全局独立不归属分类 -- 标签为全局独立不归属分类
CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_CATEGORY" ( CREATE TABLE "QH_EME_FIR_AID_RES_CATE" (
"ID" VARCHAR2(32) NOT NULL, "ID" VARCHAR2(32) NOT NULL,
"NAME" VARCHAR2(100) NOT NULL, "NAME" VARCHAR2(100) NOT NULL,
"TYPE" NUMBER(1) DEFAULT 1 NOT NULL, "TYPE" NUMBER(1) DEFAULT 1 NOT NULL,
@@ -24,26 +24,26 @@ CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_CATEGORY" (
PRIMARY KEY ("ID") PRIMARY KEY ("ID")
); );
COMMENT ON TABLE "QH_EME_FIRST_AID_RESOURCE_CATEGORY" IS '急救宣教资源分类/标签'; COMMENT ON TABLE "QH_EME_FIR_AID_RES_CATE" IS '急救宣教资源分类/标签';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."ID" IS '主键'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."ID" IS '主键';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."NAME" IS '名称'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."NAME" IS '名称';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."TYPE" IS '类型:1=分类,2=标签'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."TYPE" IS '类型:1=分类,2=标签';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."PARENT_ID" IS '父分类ID(分类树形结构,标签为NULL)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."PARENT_ID" IS '父分类ID(分类树形结构,标签为NULL)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."DESCRIPTION" IS '描述'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."DESCRIPTION" IS '描述';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."SORT_NO" IS '排序号'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."SORT_NO" IS '排序号';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."STATUS" IS '状态(1=正常,2=冻结)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."STATUS" IS '状态(1=正常,2=冻结)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."CREATE_BY" IS '创建人'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."CREATE_BY" IS '创建人';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."CREATE_TIME" IS '创建时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."CREATE_TIME" IS '创建时间';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."UPDATE_BY" IS '更新人'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."UPDATE_BY" IS '更新人';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."UPDATE_TIME" IS '更新时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."UPDATE_TIME" IS '更新时间';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."DEL_FLAG" IS '删除标记(0=正常,1=已删除)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."DEL_FLAG" IS '删除标记(0=正常,1=已删除)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_CATEGORY"."MEMO" IS '备注'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_CATE"."MEMO" IS '备注';
CREATE INDEX "IDX_FA_CATEGORY_TYPE" ON "QH_EME_FIRST_AID_RESOURCE_CATEGORY"("TYPE"); CREATE INDEX "IDX_FA_CATEGORY_TYPE" ON "QH_EME_FIR_AID_RES_CATE"("TYPE");
CREATE INDEX "IDX_FA_CATEGORY_PARENT_ID" ON "QH_EME_FIRST_AID_RESOURCE_CATEGORY"("PARENT_ID"); CREATE INDEX "IDX_FA_CATEGORY_PARENT_ID" ON "QH_EME_FIR_AID_RES_CATE"("PARENT_ID");
-- 2. 急救宣教资源表 -- 2. 急救宣教资源表
CREATE TABLE "QH_EME_FIRST_AID_RESOURCE" ( CREATE TABLE "QH_EME_FIR_AID_RES" (
"ID" VARCHAR2(32) NOT NULL, "ID" VARCHAR2(32) NOT NULL,
"TITLE" VARCHAR2(200) NOT NULL, "TITLE" VARCHAR2(200) NOT NULL,
"SUMMARY" VARCHAR2(500), "SUMMARY" VARCHAR2(500),
@@ -72,40 +72,40 @@ CREATE TABLE "QH_EME_FIRST_AID_RESOURCE" (
PRIMARY KEY ("ID") PRIMARY KEY ("ID")
); );
COMMENT ON TABLE "QH_EME_FIRST_AID_RESOURCE" IS '急救宣教资源'; COMMENT ON TABLE "QH_EME_FIR_AID_RES" IS '急救宣教资源';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."ID" IS '主键'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."ID" IS '主键';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."TITLE" IS '标题'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."TITLE" IS '标题';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."SUMMARY" IS '摘要/简介(列表展示用)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."SUMMARY" IS '摘要/简介(列表展示用)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."CONTENT_TYPE" IS '内容类型:IMAGE_TEXT(图文)/VIDEO(视频)/AUDIO(音频)/PDF(PDF)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."CONTENT_TYPE" IS '内容类型:IMAGE_TEXT(图文)/VIDEO(视频)/AUDIO(音频)/PDF(PDF)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."CATEGORY_ID" IS '所属分类ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."CATEGORY_ID" IS '所属分类ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."APPLICABLE_SCENARIO" IS '适用场景'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."APPLICABLE_SCENARIO" IS '适用场景';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."TAGS" IS '标签ID列表(逗号分隔)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."TAGS" IS '标签ID列表(逗号分隔)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."CONTENT" IS '正文内容(富文本HTML)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."CONTENT" IS '正文内容(富文本HTML)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."COVER_IMAGE" IS '封面图URL'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."COVER_IMAGE" IS '封面图URL';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."FILE_URL" IS '附件URL列表(JSON数组)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."FILE_URL" IS '附件URL列表(JSON数组)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."EFFECTIVE_TIME" IS '生效时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."EFFECTIVE_TIME" IS '生效时间';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."EXPIRY_TIME" IS '失效时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."EXPIRY_TIME" IS '失效时间';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."AUDIT_STATUS" IS '审核状态(NULL=无审核/10=待审核/11=已通过/12=已驳回)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."AUDIT_STATUS" IS '审核状态(NULL=无审核/10=待审核/11=已通过/12=已驳回)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."AUDIT_REJECT_REASON" IS '驳回原因'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."AUDIT_REJECT_REASON" IS '驳回原因';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."AUDIT_BY" IS '审核人'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."AUDIT_BY" IS '审核人';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."AUDIT_TIME" IS '审核时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."AUDIT_TIME" IS '审核时间';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."VIEW_COUNT" IS '浏览次数'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."VIEW_COUNT" IS '浏览次数';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."FAVORITE_COUNT" IS '收藏次数'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."FAVORITE_COUNT" IS '收藏次数';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."STATUS" IS '发布状态(0=草稿,1=已发布,2=已下架)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."STATUS" IS '发布状态(0=草稿,1=已发布,2=已下架)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."CREATE_BY" IS '创建人'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."CREATE_BY" IS '创建人';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."CREATE_TIME" IS '创建时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."CREATE_TIME" IS '创建时间';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."UPDATE_BY" IS '更新人'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."UPDATE_BY" IS '更新人';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."UPDATE_TIME" IS '更新时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."UPDATE_TIME" IS '更新时间';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."DEL_FLAG" IS '删除标记(0=正常,1=已删除)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."DEL_FLAG" IS '删除标记(0=正常,1=已删除)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."MEMO" IS '备注'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."MEMO" IS '备注';
CREATE INDEX "IDX_FA_RESOURCE_CATEGORY_ID" ON "QH_EME_FIRST_AID_RESOURCE"("CATEGORY_ID"); CREATE INDEX "IDX_FA_RESOURCE_CATEGORY_ID" ON "QH_EME_FIR_AID_RES"("CATEGORY_ID");
CREATE INDEX "IDX_FA_RESOURCE_AUDIT_STATUS" ON "QH_EME_FIRST_AID_RESOURCE"("AUDIT_STATUS"); CREATE INDEX "IDX_FA_RESOURCE_AUDIT_STATUS" ON "QH_EME_FIR_AID_RES"("AUDIT_STATUS");
CREATE INDEX "IDX_FA_RESOURCE_EFFECTIVE_TIME" ON "QH_EME_FIRST_AID_RESOURCE"("EFFECTIVE_TIME"); CREATE INDEX "IDX_FA_RESOURCE_EFFECTIVE_TIME" ON "QH_EME_FIR_AID_RES"("EFFECTIVE_TIME");
-- 3. 用户行为记录表阅读+收藏合一 -- 3. 用户行为记录表阅读+收藏合一
-- TYPE: 1=阅读, 2=收藏 -- TYPE: 1=阅读, 2=收藏
CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_USER_ACTION" ( CREATE TABLE "QH_EME_FIR_AID_RES_UACT" (
"ID" VARCHAR2(32) NOT NULL, "ID" VARCHAR2(32) NOT NULL,
"RESOURCE_ID" VARCHAR2(32) NOT NULL, "RESOURCE_ID" VARCHAR2(32) NOT NULL,
"USER_ID" VARCHAR2(50) NOT NULL, "USER_ID" VARCHAR2(50) NOT NULL,
@@ -114,20 +114,20 @@ CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_USER_ACTION" (
PRIMARY KEY ("ID") PRIMARY KEY ("ID")
); );
COMMENT ON TABLE "QH_EME_FIRST_AID_RESOURCE_USER_ACTION" IS '用户行为记录(阅读/收藏)'; COMMENT ON TABLE "QH_EME_FIR_AID_RES_UACT" IS '用户行为记录(阅读/收藏)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_USER_ACTION"."ID" IS '主键'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_UACT"."ID" IS '主键';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_USER_ACTION"."RESOURCE_ID" IS '资源ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_UACT"."RESOURCE_ID" IS '资源ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_USER_ACTION"."USER_ID" IS '用户ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_UACT"."USER_ID" IS '用户ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_USER_ACTION"."TYPE" IS '行为类型:1=阅读,2=收藏'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_UACT"."TYPE" IS '行为类型:1=阅读,2=收藏';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_USER_ACTION"."CREATE_TIME" IS '创建时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_UACT"."CREATE_TIME" IS '创建时间';
CREATE UNIQUE INDEX "UK_FA_USER_ACTION" CREATE UNIQUE INDEX "UK_FA_USER_ACTION"
ON "QH_EME_FIRST_AID_RESOURCE_USER_ACTION"("RESOURCE_ID", "USER_ID", "TYPE"); ON "QH_EME_FIR_AID_RES_UACT"("RESOURCE_ID", "USER_ID", "TYPE");
CREATE INDEX "IDX_FA_USER_ACTION_USER_TYPE" ON "QH_EME_FIRST_AID_RESOURCE_USER_ACTION"("USER_ID", "TYPE"); CREATE INDEX "IDX_FA_USER_ACTION_USER_TYPE" ON "QH_EME_FIR_AID_RES_UACT"("USER_ID", "TYPE");
-- 4. 版本历史表 -- 4. 版本历史表
-- 每次编辑资源时自动保存版本快照支持回滚 -- 每次编辑资源时自动保存版本快照支持回滚
CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_VERSION" ( CREATE TABLE "QH_EME_FIR_AID_RES_VER" (
"ID" VARCHAR2(32) NOT NULL, "ID" VARCHAR2(32) NOT NULL,
"RESOURCE_ID" VARCHAR2(32) NOT NULL, "RESOURCE_ID" VARCHAR2(32) NOT NULL,
"VERSION_NO" NUMBER(10) NOT NULL, "VERSION_NO" NUMBER(10) NOT NULL,
@@ -139,17 +139,17 @@ CREATE TABLE "QH_EME_FIRST_AID_RESOURCE_VERSION" (
PRIMARY KEY ("ID") PRIMARY KEY ("ID")
); );
COMMENT ON TABLE "QH_EME_FIRST_AID_RESOURCE_VERSION" IS '资源版本历史'; COMMENT ON TABLE "QH_EME_FIR_AID_RES_VER" IS '资源版本历史';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."ID" IS '主键'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."ID" IS '主键';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."RESOURCE_ID" IS '资源ID'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."RESOURCE_ID" IS '资源ID';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."VERSION_NO" IS '版本号(1,2,3...)'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."VERSION_NO" IS '版本号(1,2,3...)';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."TITLE" IS '版本时的标题'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."TITLE" IS '版本时的标题';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."CONTENT" IS '版本时的正文内容'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."CONTENT" IS '版本时的正文内容';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."CHANGE_DESCRIPTION" IS '变更描述'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."CHANGE_DESCRIPTION" IS '变更描述';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."CREATE_BY" IS '创建人'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."CREATE_BY" IS '创建人';
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE_VERSION"."CREATE_TIME" IS '创建时间'; COMMENT ON COLUMN "QH_EME_FIR_AID_RES_VER"."CREATE_TIME" IS '创建时间';
CREATE INDEX "IDX_FA_VERSION_RESOURCE_ID" ON "QH_EME_FIRST_AID_RESOURCE_VERSION"("RESOURCE_ID"); CREATE INDEX "IDX_FA_VERSION_RESOURCE_ID" ON "QH_EME_FIR_AID_RES_VER"("RESOURCE_ID");
-- ===================================================== -- =====================================================
-- 字典数据需在应用启动后执行 -- 字典数据需在应用启动后执行
@@ -16,7 +16,7 @@
-- 需用户在系统内重新提交审核 -- 需用户在系统内重新提交审核
-- 如需保留为"待审核"状态将下方的 NULL 改为 10 即可 -- 如需保留为"待审核"状态将下方的 NULL 改为 10 即可
UPDATE "QH_EME_FIRST_AID_RESOURCE" UPDATE "QH_EME_FIR_AID_RES"
SET "AUDIT_STATUS" = CASE SET "AUDIT_STATUS" = CASE
WHEN "AUDIT_STATUS" = 0 THEN NULL -- 草稿无法区分是否已提交保守处理 WHEN "AUDIT_STATUS" = 0 THEN NULL -- 草稿无法区分是否已提交保守处理
WHEN "AUDIT_STATUS" = 1 THEN 11 -- 已通过 WHEN "AUDIT_STATUS" = 1 THEN 11 -- 已通过
@@ -62,7 +62,7 @@ SELECT
ELSE '未知状态' ELSE '未知状态'
END AS "审核状态描述", END AS "审核状态描述",
COUNT(*) AS "数量" COUNT(*) AS "数量"
FROM "QH_EME_FIRST_AID_RESOURCE" FROM "QH_EME_FIR_AID_RES"
WHERE "DEL_FLAG" = 0 WHERE "DEL_FLAG" = 0
GROUP BY "AUDIT_STATUS" GROUP BY "AUDIT_STATUS"
ORDER BY "AUDIT_STATUS" ASC NULLS FIRST; ORDER BY "AUDIT_STATUS" ASC NULLS FIRST;
@@ -71,7 +71,7 @@ ORDER BY "AUDIT_STATUS" ASC NULLS FIRST;
-- ===================================================== -- =====================================================
-- 4. 更新表字段注释 -- 4. 更新表字段注释
-- ===================================================== -- =====================================================
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."AUDIT_STATUS" IS COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."AUDIT_STATUS" IS
'审核状态(NULL=无审核/10=待审核/11=已通过/12=已驳回)'; '审核状态(NULL=无审核/10=待审核/11=已通过/12=已驳回)';
COMMIT; COMMIT;
@@ -5,7 +5,7 @@
-- ===================================================== -- =====================================================
-- 注意: null(草稿) 回退为 0但此时无法区分"草稿""待审核" -- 注意: null(草稿) 回退为 0但此时无法区分"草稿""待审核"
UPDATE "QH_EME_FIRST_AID_RESOURCE" UPDATE "QH_EME_FIR_AID_RES"
SET "AUDIT_STATUS" = CASE SET "AUDIT_STATUS" = CASE
WHEN "AUDIT_STATUS" IS NULL THEN 0 -- 草稿 0(待审核) WHEN "AUDIT_STATUS" IS NULL THEN 0 -- 草稿 0(待审核)
WHEN "AUDIT_STATUS" = 10 THEN 0 -- 待审核 0 WHEN "AUDIT_STATUS" = 10 THEN 0 -- 待审核 0
@@ -18,7 +18,7 @@ WHERE "AUDIT_STATUS" IS NULL OR "AUDIT_STATUS" IN (10, 11, 12);
COMMIT; COMMIT;
-- 恢复表字段注释 -- 恢复表字段注释
COMMENT ON COLUMN "QH_EME_FIRST_AID_RESOURCE"."AUDIT_STATUS" IS COMMENT ON COLUMN "QH_EME_FIR_AID_RES"."AUDIT_STATUS" IS
'审核状态(0=待审核,1=已通过,2=已驳回)'; '审核状态(0=待审核,1=已通过,2=已驳回)';
COMMIT; COMMIT;
@@ -0,0 +1,505 @@
-- =====================================================
-- 急救宣教资源 - 种子数据达梦数据库
-- 包含分类扁平一层标签归属分类下资源内容
-- 执行方式在达梦客户端中直接执行本脚本
-- 注意请先确认 QH_EME_FIR_AID_RES_CATE QH_EME_FIR_AID_RES 表已创建
-- =====================================================
-- =====================================================
-- 分类数据TYPE=1扁平一层不设二级
-- =====================================================
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('CAT001', '心肺复苏术CPR', 1, NULL, '成人和儿童心肺复苏技术包括胸外按压人工呼吸及AED使用', 1, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('CAT002', '常见急症急救', 1, NULL, '心脏病脑卒中癫痫过敏等突发急症的识别与院前急救', 2, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('CAT003', '创伤急救处理', 1, NULL, '止血包扎固定搬运等创伤急救四大技术', 3, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('CAT004', '意外伤害急救', 1, NULL, '溺水触电气道异物梗阻坠落伤等意外伤害的应急处置', 4, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('CAT005', '环境相关急症', 1, NULL, '中暑失温冻伤高原反应等环境因素所致急症的急救', 5, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('CAT006', '中毒急救', 1, NULL, '食物中毒煤气中毒化学品中毒及蛇虫咬伤的急救处理', 6, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('CAT007', '特殊人群急救', 1, NULL, '老年人孕产妇婴幼儿等特殊群体的急救要点与注意事项', 7, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('CAT008', '灾害事故急救', 1, NULL, '地震火灾交通事故等大规模灾害事故的自救互救知识', 8, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
-- =====================================================
-- 标签数据TYPE=2PARENT_ID 指向所属分类
-- =====================================================
-- === 心肺复苏术CPR的标签 ===
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG001', '成人CPR', 2, 'CAT001', '成人12岁及以上心肺复苏操作流程与要点', 1, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG002', '儿童与婴儿CPR', 2, 'CAT001', '儿童和婴儿心肺复苏的差异化操作', 2, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG003', 'AED使用', 2, 'CAT001', '自动体外除颤器AED的操作方法和使用场景', 3, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG004', 'AHA指南', 2, 'CAT001', '参考美国心脏协会AHA最新指南编写', 4, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
-- === 常见急症急救的标签 ===
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG005', '心脑血管急症', 2, 'CAT002', '急性心肌梗死脑卒中的早期识别与急救', 1, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG006', '过敏与休克', 2, 'CAT002', '严重过敏反应的紧急识别与肾上腺素笔使用', 2, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG007', '突发意识障碍', 2, 'CAT002', '癫痫发作低血糖昏迷晕厥等现场急救', 3, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
-- === 创伤急救处理的标签 ===
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG008', '止血与包扎', 2, 'CAT003', '各类外伤出血的止血方法和包扎技术', 1, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG009', '骨折与固定', 2, 'CAT003', '骨折关节脱位的识别及现场固定搬运技术', 2, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG010', '烧烫伤', 2, 'CAT003', '热烧伤化学烧伤电烧伤的急救和创面处理', 3, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
-- === 意外伤害急救的标签 ===
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG011', '气道异物梗阻', 2, 'CAT004', '海姆立克急救法各年龄段气道梗阻解除', 1, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG012', '溺水与触电', 2, 'CAT004', '溺水救援触电脱离及继发心脏骤停的急救', 2, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
-- === 环境相关急症的标签 ===
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG013', '高温与中暑', 2, 'CAT005', '热痉挛热衰竭热射病的识别与分级急救', 1, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG014', '低温损伤', 2, 'CAT005', '失温低体温症冻伤的分级急救与复温技术', 2, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
-- === 中毒急救的标签 ===
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG015', '食物与气体中毒', 2, 'CAT006', '食物中毒一氧化碳中毒煤气中毒的识别与急救', 1, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG016', '动物咬伤与蜇伤', 2, 'CAT006', '蛇咬伤犬咬伤蜂蜇伤蜱虫叮咬的应急处理', 2, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
-- === 特殊人群急救的标签 ===
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG017', '老年人急救', 2, 'CAT007', '老年人跌倒突发疾病及用药过量的应急处理', 1, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG018', '婴幼儿急救', 2, 'CAT007', '婴幼儿高热惊厥窒息烫伤跌落等常见意外的急救', 2, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
-- === 灾害事故急救的标签 ===
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG019', '火灾与地震', 2, 'CAT008', '火灾逃生地震避震及次生灾害的应急处置', 1, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
INSERT INTO QH_EME_FIR_AID_RES_CATE (ID, NAME, TYPE, PARENT_ID, DESCRIPTION, SORT_NO, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES ('TAG020', '交通事故急救', 2, 'CAT008', '道路交通事故现场的检伤分类伤员解救和转运要领', 2, 1, 'admin', SYSDATE, 'admin', SYSDATE, 0);
-- =====================================================
-- 资源数据
-- 审核状态: 11=已通过 状态: 1=已发布
-- CATEGORY_ID 指向分类TAGS 为逗号分隔的标签ID
-- =====================================================
-- ===================== 心肺复苏术CPR =====================
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES001',
'成人心肺复苏标准操作流程2025 AHA指南',
'详细讲解成人心脏骤停的识别胸外按压人工呼吸及AED使用的完整流程依据美国心脏协会最新指南编写',
'IMAGE_TEXT',
'CAT001',
'发现成人突然倒地无反应无呼吸或濒死喘息时',
'TAG001,TAG003,TAG004',
'<h2>确保现场安全</h2><p>施救前先观察环境确认现场对施救者和患者均安全如存在触电火灾有毒气体等危险先将患者转移到安全区域</p><h2>判断意识和呼吸</h2><ul><li>轻拍患者双肩大声呼喊"喂!你怎么了?"</li><li>观察胸部是否有起伏判断呼吸是否正常5-10秒</li><li>无反应 + 无呼吸/濒死喘息 立即启动应急反应系统</li></ul><h2>呼叫急救</h2><ul><li>指定现场某人拨打120并取AED</li><li>如果独自一人先拨打120开免提再开始CPR</li></ul><h2>胸外按压C - Circulation</h2><ul><li><strong>位置</strong>两乳头连线中点胸骨中下段</li><li><strong>手法</strong>双手十指交叉掌根重叠手臂伸直肩肘腕垂直</li><li><strong>深度</strong>5-6厘米</li><li><strong>频率</strong>100-120次/分钟</li><li><strong>回弹</strong>每次按压后让胸廓完全回弹掌根不离胸壁</li><li>按压/放松时间比1:1</li></ul><h2>开放气道A - Airway</h2><ul><li>仰头提颏法一手压前额一手提下颌</li><li>如有可见异物用手指清除</li></ul><h2>人工呼吸B - Breathing</h2><ul><li>捏住患者鼻翼口对口吹气每次约1秒</li><li>见胸廓隆起为有效</li><li>按压:通气 = 30:2</li><li><strong>如不愿或不方便做人工呼吸可只做单纯胸外按压</strong></li></ul><h2>AED到达后</h2><ul><li>立即开机按语音提示操作</li><li>电极片贴放位置右锁骨下 + 左腋前线第5肋间</li><li>电击后立即继续CPR不要耽误</li></ul><h2>持续至</h2><ul><li>患者恢复自主呼吸和意识</li><li>医务人员到达接管</li><li>施救者精疲力竭</li><li>AED提示不得电击且无需CPR</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 2856, 423, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES002',
'儿童与婴儿CPR差异化操作要点',
'儿童1-12岁和婴儿<1岁的心肺复苏与成人不同本节详细对比差异帮助家长和幼儿工作者掌握正确的急救方法',
'IMAGE_TEXT',
'CAT001',
'儿童或婴儿突发意识丧失无反应无正常呼吸时',
'TAG002,TAG004',
'<h2>儿童CPR1岁至青春期</h2><h3>按压手法</h3><ul><li><strong>单手或双手</strong>根据儿童体型和施救者力量选择</li><li>单手掌根置于胸骨中下段</li><li>双手同成人手法</li></ul><h3>按压深度</h3><ul><li>至少胸廓前后径的1/3约5厘米</li></ul><h3>按压:通气比</h3><ul><li><strong>单人施救30:2</strong></li><li><strong>双人施救15:2</strong></li></ul><h3>AED</h3><ul><li>1-8岁儿童首选儿童电极片/儿童模式</li><li>没有儿童电极片时可用成人电极片代替</li></ul><hr><h2>婴儿CPR<1岁</h2><h3>判断意识</h3><ul><li>轻拍婴儿足底观察反应</li></ul><h3>按压手法</h3><ul><li><strong>双指法</strong>单人施救时用食指和中指指尖垂直按压</li><li><strong>双手环抱拇指法</strong>双人施救时双手环抱婴儿胸部双拇指并排按压</li></ul><h3>按压位置</h3><ul><li>两乳头连线中点稍下方胸骨中段</li></ul><h3>按压深度</h3><ul><li>至少胸廓前后径的1/3约4厘米</li></ul><h3>人工呼吸</h3><ul><li>口对口鼻共同吹气</li><li>每次吹气量以胸廓微微抬起为准不可过度用力</li></ul><h3>按压:通气比</h3><ul><li>单人30:2</li><li>双人15:2</li></ul><h3>AED</h3><ul><li>婴儿首选手动除颤器</li><li>AED仅在没有手动除颤器且确有必要时使用</li></ul><hr><h2>成人与儿童/婴儿CPR差异速查表</h2><table border="1"><tr><th>项目</th><th>成人</th><th>儿童</th><th>婴儿</th></tr><tr><td>按压深度</td><td>5-6cm</td><td>~5cm</td><td>~4cm</td></tr><tr><td>按压手法</td><td>双手</td><td>单手/双手</td><td>双指/双拇指</td></tr><tr><td>单人按压:通气</td><td>30:2</td><td>30:2</td><td>30:2</td></tr><tr><td>双人按压:通气</td><td>30:2</td><td>15:2</td><td>15:2</td></tr></table>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 1678, 312, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES003',
'AED自动体外除颤器完全使用指南',
'AED是什么在哪里能找到怎么用从开机到电击的全流程图解指南AED是抢救心脏骤停的关键设备普通人经过简单学习即可使用',
'IMAGE_TEXT',
'CAT001',
'心脏骤停患者CPR过程中AED到达现场时公共场所发现AED设备时',
'TAG003,TAG004',
'<h2>什么是AED</h2><p>自动体外除颤器Automated External Defibrillator是一种便携式医疗设备可以自动分析心律判断是否需要电击除颤它配有语音提示非专业人员经过简单培训即可安全使用</p><h2>为什么要用AED</h2><ul><li>心脏骤停最常见的初始心律是<strong>心室颤动VF</strong></li><li>电击除颤是终止室颤的唯一有效方法</li><li><strong>每延迟1分钟除颤生存率下降7%-10%</strong></li><li>CPR+AED可将院外心脏骤停生存率提高至50%以上</li></ul><h2>哪里有AED</h2><ul><li>机场火车站地铁站</li><li>大型商场体育场馆</li><li>学校写字楼</li><li>微信搜索"AED"或使用"AED地图"小程序</li></ul><h2>AED操作步骤</h2><h3>第1步开机</h3><ul><li>打开机盖或按下电源键之后全程<strong>按照语音提示操作</strong></li></ul><h3>第2步贴电极片</h3><ul><li>脱去患者胸前衣物擦干皮肤如有水或汗</li><li>将电极片按包装图示贴在裸露的胸前</li><li><strong>位置一</strong>右侧锁骨下方右胸上部</li><li><strong>位置二</strong>左侧腋前线第5肋间左胸下部侧面</li><li>将电极片插头插入主机如已预连则跳过</li></ul><h3>第3步分析心律</h3><ul><li>AED自动分析<strong>任何人不得接触患者</strong></li></ul><h3>第4步电击</h3><ul><li>如需电击AED自动充电并发声警告</li><li>确认<strong>无人接触患者</strong>按下闪烁的放电按钮</li><li>电击后<strong>立即恢复CPR</strong>从胸外按压开始</li></ul><h2>注意事项</h2><ul><li>贴电极片前确认皮肤干燥无过多胸毛</li><li>患者胸部有膏药需撕下并擦净</li><li>体内有起搏器/ICD的患者电极片应避开设备至少2.5厘米</li><li>在水中或金属表面时将患者移至干燥地面再使用</li></ul><h2>AED与CPR配合节奏</h2><p>CPR不间断 AED到达 开机贴片 分析 电击如需 立即CPR 2分钟后AED再次分析 循环</p>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 2103, 388, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
-- ===================== 常见急症急救 =====================
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES004',
'急性心肌梗死的早期识别与院前急救',
'心梗是最常见的致命急症之一本文教您识别心梗的典型和非典型症状以及在救护车到达前如何正确处置',
'IMAGE_TEXT',
'CAT002',
'突感胸痛胸闷出冷汗疑似心脏病发作时',
'TAG005',
'<h2>什么是急性心肌梗死</h2><p>冠状动脉突然堵塞导致心肌缺血坏死黄金抢救时间窗口仅2小时<strong>时间就是心肌时间就是生命</strong></p><h2>典型症状</h2><ul><li><strong>胸痛</strong>胸骨后压榨性闷胀性疼痛持续不缓解>20分钟</li><li><strong>放射痛</strong>疼痛可向左肩左臂内侧颈部下颌背部放射</li><li><strong>伴随症状</strong>出冷汗恶心呕吐呼吸困难濒死感</li></ul><h2>非典型症状尤其警惕</h2><ul><li><strong>女性</strong>可能仅表现为极度疲劳恶心背部或下颌疼痛</li><li><strong>老年人</strong>可能表现为气短乏力意识模糊</li><li><strong>糖尿病患者</strong>可能无痛无痛性心梗仅表现为突发心衰</li></ul><h2>现场急救步骤</h2><ol><li><strong>立即停止一切活动</strong>让患者保持安静取半卧位或坐位切勿平卧</li><li><strong>拨打120</strong>清楚告知"疑似心脏病发作"和具体地址</li><li><strong>服用药物如患者自备</strong>硝酸甘油舌下含服1片5分钟后不缓解可再含1片最多3片阿司匹林嚼服300mg非肠溶片除非有禁忌</li><li><strong>保持气道通畅</strong>解开衣领和腰带</li><li><strong>持续观察</strong>如患者意识丧失无呼吸立即开始CPR</li></ol><h2>禁忌事项</h2><ul><li><strong> 不要让患者自行走动</strong></li><li><strong> 不要自行开车送医院</strong>途中可能发生室颤</li><li><strong> 不要给非患者本人的药物</strong></li><li><strong> 不要用力咳嗽"咳嗽CPR"未被指南推荐</strong></li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 3201, 567, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES005',
'脑卒中中风"120"识别法与急救',
'中风抢救争分夺秒学会"1-2-0"快速识别法及时发现中风前兆"黄金4.5小时"内送医溶栓',
'IMAGE_TEXT',
'CAT002',
'突发面部不对称单侧肢体无力言语不清等疑似中风症状',
'TAG005',
'<h2>认识脑卒中</h2><p>脑卒中分为<strong>缺血性脑梗死占70%</strong><strong>出血性脑出血占30%</strong>无论哪种都需要紧急就医溶栓治疗时间窗仅<strong>4.5小时</strong></p><h2>"中风120"快速识别法</h2><table border="1"><tr><th>数字</th><th>含义</th><th>检查方法</th></tr><tr><td><strong>1</strong></td><td><strong>1</strong>张脸</td><td>让患者微笑观察面部是否对称有无口角歪斜</td></tr><tr><td><strong>2</strong></td><td><strong>2</strong>只胳膊</td><td>让患者平举双臂观察是否有单侧无力或下垂</td></tr><tr><td><strong>0</strong></td><td><strong></strong>听语言</td><td>让患者说一句简单的话观察是否含糊不清或无法表达</td></tr></table><p>以上三项中<strong>任何一项异常</strong>中风可能性约72%应立即拨打120</p><h2>其他警示症状</h2><ul><li>突发剧烈头痛"一生中最剧烈的头痛"</li><li>突发单眼或双眼视力模糊视野缺损</li><li>突发眩晕行走困难平衡失调</li><li>突发意识障碍或晕厥</li></ul><h2>现场急救步骤</h2><ol><li><strong>立即拨打120</strong>记录发病时间必须精确到分钟</li><li>让患者平卧头偏向一侧防呕吐误吸</li><li>解开衣领和腰带保持气道通畅</li><li>如有呕吐清除口腔呕吐物</li><li>安抚患者情绪减少不必要的搬动</li><li>如意识丧失无呼吸立即CPR</li></ol><h2>绝对禁忌</h2><ul><li><strong> 不要给患者喂水喂食喂药</strong>可能吞咽困难导致窒息</li><li><strong> 不要摇晃患者</strong></li><li><strong> 不要掐人中针刺指尖放血等偏方</strong></li><li><strong> 不要让患者自行去厕所</strong></li><li><strong> 不要等待"观察一下"</strong>时间就是大脑</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 2567, 445, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES006',
'严重过敏反应与肾上腺素笔使用',
'食物药物蜂蜇等引发的过敏性休克可在数分钟内致命学会识别过敏反应升级信号掌握肾上腺素笔的正确使用方法',
'IMAGE_TEXT',
'CAT002',
'进食服药后突发皮疹喉头水肿呼吸困难血压下降等症状',
'TAG006',
'<h2>认识严重过敏反应</h2><p>严重过敏反应Anaphylaxis是IgE介导的全身性超敏反应<strong>可在数分钟内出现气道阻塞和休克</strong>常见诱因食物花生海鲜鸡蛋药物青霉素昆虫蜇伤乳胶</p><h2>识别过敏反应的升级信号</h2><ul><li><strong>皮肤</strong>荨麻疹潮红瘙痒血管性水肿尤其是口唇眼睑肿胀</li><li><strong>呼吸系统</strong>喉咙发紧声音嘶哑喘鸣呼吸困难</li><li><strong>消化系统</strong>恶心呕吐腹痛腹泻</li><li><strong>心血管系统</strong>头晕心动过速血压下降意识模糊</li><li><strong>注意</strong>皮肤症状可能缺失约10%-20%的严重过敏反应<strong>没有皮疹</strong></li></ul><h2>肾上腺素笔使用指南</h2><p>肾上腺素是唯一能逆转严重过敏反应的药物<strong>确诊后应立即注射刻不容缓</strong></p><h3>操作步骤</h3><ol><li><strong>取下安全帽蓝色</strong>不要触碰橙色针头端</li><li><strong>握拳包裹</strong>橙色端垂直紧贴大腿外侧中部可隔着裤子</li><li><strong>用力下压</strong>听到"咔嗒"声后保持10秒让药液完全注入</li><li><strong>拔出按摩</strong>在注射部位按摩10秒</li><li><strong>拨打120</strong>即使症状缓解也必须就医可能发生迟发性反应</li></ol><h2>重要提示</h2><ul><li>肾上腺素应注射在大腿外侧肌肉最丰厚处<strong>不要注射在臀部或手臂</strong></li><li>如症状无缓解5-15分钟后可注射第二支</li><li>过敏体质者应随身携带2支肾上腺素笔</li><li>不要将肾上腺素笔存放在高温或阳光直射处</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 1456, 289, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES007',
'癫痫发作的现场急救正确姿势',
'癫痫发作时许多"常识性"做法其实有害无益本文纠正常见误区告诉您什么该做什么绝对不该做',
'IMAGE_TEXT',
'CAT002',
'身边有人突发全身抽搐意识丧失时',
'TAG007',
'<h2>正确做法4要4不要</h2><h3> 要做的事</h3><ol><li><strong>保持镇静记录发作时间</strong></li><li><strong>清除周围危险物品</strong>桌椅尖锐物火源等</li><li><strong>保护头部</strong>在头下垫柔软物品衣物靠垫</li><li><strong>侧卧位</strong>发作停止后将患者转为侧卧恢复体位清理口腔分泌物</li></ol><h3> 绝对不要做的事</h3><ul><li><strong> 不要往嘴里塞任何东西</strong>包括手指毛巾筷子压舌板患者不会咬断舌头塞物反而可能导致牙齿断裂异物吸入窒息</li><li><strong> 不要强行按压肢体</strong>抽搐时骨骼脆弱强制约束可能导致骨折</li><li><strong> 不要掐人中灌药针刺</strong></li><li><strong> 不要CPR有正常呼吸脉搏时</strong></li></ul><h2>需要拨打120的情况任一满足</h2><ul><li>发作持续超过5分钟<strong>癫痫持续状态</strong></li><li>首次发作从未诊断过癫痫</li><li>在水中发作</li><li>发作停止后意识未恢复</li><li>发作后再次发作</li><li>患者怀孕</li><li>患者受伤</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 1876, 267, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
-- ===================== 创伤急救处理 =====================
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES008',
'外伤出血的快速止血技术',
'严重外伤出血是创伤致死的首要原因掌握直接压迫止血带填塞止血三种方法关键时刻能救命',
'IMAGE_TEXT',
'CAT003',
'切割伤撕裂伤车祸伤等导致的活动性出血',
'TAG008',
'<h2>出血严重程度判断</h2><table border="1"><tr><th>出血类型</th><th>特征</th><th>危险程度</th></tr><tr><td>毛细血管出血</td><td>缓慢渗出血色鲜红</td><td></td></tr><tr><td>静脉出血</td><td>持续流出血色暗红</td><td></td></tr><tr><td>动脉出血</td><td>喷射状随心跳搏动血色鲜红</td><td> 致命</td></tr></table><p>成人失血>500ml = 危险>1000ml = 休克>2000ml = 死亡</p><h2>直接压迫止血法首选</h2><ol><li>用干净纱布/毛巾/衣物直接按压伤口</li><li>持续用力按压至少10分钟<strong>不要中途掀开查看</strong></li><li>如纱布被血液浸透在上面<strong>再加一层</strong>不要更换会破坏已形成的血凝块</li><li>加压包扎固定</li></ol><h2>止血带止血法四肢大出血专用</h2><ul><li><strong>适应症</strong>直接加压无效的四肢大出血肢体离断</li><li><strong>位置</strong>伤口上方5-8厘米靠近心脏一侧避开关节</li><li><strong>力度</strong>以远端动脉搏动消失出血停止为准</li><li><strong>标记</strong>在患者额头或明显位置写上绑扎时间精确到分钟</li><li><strong>时间</strong>不超过2小时每30分钟松解检查1次但需评估再出血风险</li><li>不要用绳索电线铁丝代替</li></ul><h2>填塞止血法交界部位深部伤口</h2><p>适用于腹股沟腋窝颈部等不便使用止血带的部位</p><ol><li>将止血纱布/干净布条塞入伤口深部</li><li>从最深处向外逐层填塞保持压力</li><li>外部加压包扎固定</li></ol><h2>注意事项</h2><ul><li>穿戴手套如有避免直接接触血液</li><li>不要取出嵌入伤口的异物玻璃等固定异物包扎后送医</li><li>怀疑内出血腹胀休克无外伤但血压持续下降立即送医</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 2134, 378, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES009',
'骨折与脊柱损伤的现场固定与搬运',
'错误的搬运可能让骨折变为截瘫本节讲解骨折的临时固定方法和脊柱损伤的安全搬运技术',
'IMAGE_TEXT',
'CAT003',
'高处坠落交通事故重物砸伤等可能导致骨折或脊柱损伤的场合',
'TAG009',
'<h2>骨折的识别</h2><ul><li>剧烈疼痛活动时加剧</li><li>局部肿胀瘀斑</li><li>畸形与对侧不对称异常弯曲</li><li>反常活动关节以外部位出现活动</li><li>骨擦音/骨擦感</li><li>功能丧失无法承重/活动</li></ul><h2>骨折固定原则</h2><ul><li><strong>固定范围</strong>骨折部位的上下两个关节</li><li>夹板长度应超过骨折上下关节</li><li>夹板与皮肤间用软物衬垫</li><li>固定松紧适度指尖可触及远端动脉搏动</li><li>开放性骨折<strong>不要将外露的骨端推回</strong>覆盖无菌敷料后固定</li></ul><h2>脊柱损伤的识别高度警惕</h2><ul><li>高处坠落>2米交通事故高速撞击跳水头部撞底</li><li>伤后颈部疼痛肢体麻木/无力大小便失禁</li></ul><h2>脊柱损伤安全搬运</h2><h3>🔴 黄金原则除非有立即生命危险火灾爆炸<strong>绝不要移动疑似脊柱损伤的患者</strong>等待专业急救人员</h3><h3>如必须移动</h3><ol><li>保持头--躯干<strong>呈一直线</strong>轴线翻身</li><li>至少3人协作一人固定头颈一人托躯干一人托下肢</li><li>使用硬质担架/门板/桌面</li><li>颈椎用颈托或沙袋/衣物卷固定头部两侧</li></ol><h2>各部位固定要点</h2><ul><li><strong>前臂骨折</strong>夹板固定后三角巾悬吊于胸前屈肘90°</li><li><strong>上臂骨折</strong>夹板固定后上臂紧贴胸壁前臂三角巾悬吊</li><li><strong>大腿骨折</strong>长夹板从腋下至足跟另用短夹板从大腿内侧至小腿</li><li><strong>小腿骨折</strong>夹板从大腿中部至足跟</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 1678, 298, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES010',
'烧烫伤的急救五步法"冲脱泡盖送"',
'烧烫伤是生活中最常见的意外伤害之一记住"冲脱泡盖送"五个字正确处理创面避免二次伤害和留疤',
'IMAGE_TEXT',
'CAT003',
'热液烫伤火焰烧伤热固体烫伤化学烧伤等各类烧烫伤',
'TAG010',
'<h2>急救五步法</h2><h3>最关键的第一反应</h3><ul><li>立即用<strong>流动冷水</strong>冲洗伤处15-30分钟</li><li>水温15-25为宜不要用冰水可能导致血管过度收缩加重损伤</li><li>化学烧伤需冲洗更长时间至少30分钟</li></ul><h3></h3><ul><li>在冷水中<strong>小心去除</strong>覆盖伤处的衣物和饰物戒指手表手镯</li><li>如衣物与皮肤粘连<strong>不要强行撕扯</strong>用剪刀剪开周围衣物</li></ul><h3></h3><ul><li>将伤处浸泡在冷水中持续15-30分钟仅适用于小面积烧伤</li><li>大面积烧伤>10%体表面积不要长时间浸泡可能导致低体温</li></ul><h3></h3><ul><li><strong>清洁无菌的敷料或保鲜膜</strong>覆盖创面</li><li>保鲜膜覆盖可减少疼痛防止感染便于医生观察</li><li>不要用棉花纸巾纤维会粘连创面</li><li>不要涂抹牙膏酱油蛋清香油等偏方</li></ul><h3></h3><ul><li>及时送医小面积浅度烧伤社区医院大面积或深度烧伤烧伤专科</li></ul><h2>烧伤严重程度判断</h2><table border="1"><tr><th>分度</th><th>表现</th><th>处理</th></tr><tr><td>红斑性</td><td>皮肤发红疼痛无水肿和水疱</td><td>自行处理</td></tr><tr><td>水疱性</td><td>大水疱剧痛基底潮红</td><td>门诊处理</td></tr><tr><td></td><td>小水疱疼痛迟钝基底红白相间</td><td>需住院</td></tr><tr><td>焦痂性</td><td>皮肤蜡白或焦黑无痛觉</td><td>需住院手术</td></tr></table><h2>特殊类型烧伤</h2><ul><li><strong>电烧伤</strong>入口小出口大深部组织损伤严重必须就医</li><li><strong>吸入性烧伤</strong>面部烧伤+声音嘶哑+鼻腔有烟灰气道可能已受损立即就医</li><li><strong>化学烧伤</strong>干石灰先刷除再冲洗遇水产生高温</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 3567, 634, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
-- ===================== 意外伤害急救 =====================
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES011',
'海姆立克急救法气道异物梗阻的救命技术',
'"吃东西噎住了"可能数分钟内致命海姆立克法是解除气道梗阻最有效的方法每个人都应该掌握含成人儿童婴儿及自救四种场景',
'IMAGE_TEXT',
'CAT004',
'进食时突然不能说话呼吸困难手抓喉咙V型手势面色发绀',
'TAG011',
'<h2>识别气道异物梗阻</h2><ul><li><strong>完全梗阻</strong>无法说话无法咳嗽无法呼吸面色发紫双手抓颈部典型的"窒息V手势" <strong>立即海姆立克</strong></li><li><strong>部分梗阻</strong>能说话能咳嗽鼓励患者用力咳嗽不要拍背</li></ul><h2>成人/儿童>1岁海姆立克法</h2><ol><li><strong>站位</strong>双脚前后分开稳定重心</li><li><strong>定位</strong>双手环绕患者腰部一手握拳拳心向内置于<strong>肚脐上方两横指</strong>剑突下</li><li><strong>冲击</strong>另一手包住拳头<strong>向内向上</strong>快速用力冲击</li><li><strong>重复</strong>直到异物排出或患者意识丧失</li></ol><h2>婴儿<1岁急救法</h2><ul><li><strong>不要用海姆立克法</strong>婴儿腹部器官脆弱易损伤</li><li>5次拍背 + 5次胸外按压交替</li></ul><ol><li><strong>拍背</strong>将婴儿面朝下放在前臂上头低于躯干用掌根在肩胛骨之间拍击5次</li><li><strong>胸外按压</strong>翻转婴儿面朝上头低于躯干用两指在胸骨中段按压5次</li><li><strong>检查口腔</strong>如异物可见用小指取出<strong>不要盲目掏挖</strong></li><li>重复5+5循环直到异物排出</li></ol><h2>自救方法</h2><ul><li><strong>腹部冲击法</strong>一手握拳置于肚脐上方另一手包住弯腰后向后上方冲击或利用椅背桌角栏杆等硬物顶压腹部</li><li>立即拨打120如能说话</li></ul><h2>患者意识丧失后怎么办</h2><ul><li>将患者平放地面立即开始CPR</li><li>做人工呼吸前检查口腔如有可见异物取出</li><li>CPR的胸外按压也可产生气道压力有助于排出异物</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 4123, 789, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES012',
'溺水急救水中解救与岸上复苏',
'溺水导致的死亡大多是可以避免的了解正确的水中救援方式和岸上心肺复苏要点不要让自己成为第二个溺水者',
'IMAGE_TEXT',
'CAT004',
'发现有人溺水或游泳过程中发生意外时',
'TAG012',
'<h2>水中解救首要原则保证自身安全</h2><ul><li><strong>非专业人员不要贸然下水</strong></li><li><strong></strong>用竹竿树枝衣物伸向溺水者</li><li><strong></strong>抛投救生圈绳索空塑料桶等漂浮物</li><li><strong></strong>划船靠近</li><li><strong></strong>仅受过专业水中救援训练者可游泳接近从后方接近避免被溺水者抱住</li></ul><h2>岸上急救</h2><h3>判断意识和呼吸</h3><p>将溺水者仰卧于硬质平面判断反应和呼吸</p><h3>如无反应+无正常呼吸 立即CPR</h3><ol><li><strong>先开放气道</strong>清理口腔内泥沙水草等异物</li><li><strong>先给5次人工呼吸</strong>溺水是缺氧性心脏骤停先通气</li><li>然后按<strong>30:2</strong>进行CPR</li><li>AED到达后使用擦干胸前皮肤</li></ol><h2>常见误区纠正</h2><ul><li><strong> 不要"控水"</strong>倒背跑按压腹部排水等溺水者胃里的水不会堵塞气道控水只会延误CPR时间增加呕吐误吸风险</li><li><strong> 不要因为溺水者能说话就掉以轻心</strong>可能发生"二次溺水"延迟性肺水肿</li><li><strong> 所有溺水者即使看起来没事都应送医观察</strong></li></ul><h2>冷水溺水特点</h2><ul><li>冷水<10溺水者可能经长时间CPR后存活</li><li>冷水有脑保护作用不要轻易放弃</li><li>切勿在未确认死亡前停止CPR</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 2134, 345, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
-- ===================== 环境相关急症 =====================
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES013',
'中暑的分级识别与急救处理',
'高温天气下中暑高发热痉挛热衰竭热射病是三个逐步升级的阶段热射病病死率高达50%早期识别和正确降温是关键',
'IMAGE_TEXT',
'CAT005',
'高温天气户外工作运动或密闭高温环境中出现头晕恶心等症状',
'TAG013',
'<h2>中暑的三个阶段</h2><h3>1. 热痉挛轻度</h3><ul><li><strong>表现</strong>大量出汗后出现四肢腹部肌肉痉挛抽筋体温正常或略高</li><li><strong>处理</strong>移至阴凉处补充含盐饮料/运动饮料拉伸痉挛肌肉休息</li></ul><h3>2. 热衰竭中度</h3><ul><li><strong>表现</strong>大汗淋淋面色苍白头晕头痛恶心呕吐心跳加快体温升高38-40血压下降</li><li><strong>处理</strong>移至阴凉通风处松开衣物补充含盐冷饮如能吞咽冷水擦拭扇风降温抬高下肢</li><li>如呕吐或意识改变立即就医</li></ul><h3>3. 热射病重度致命</h3><ul><li><strong>表现</strong>体温>40皮肤干热无汗典型意识障碍谵妄抽搐昏迷</li><li><strong>死亡率</strong>高达50%</li><li><strong>处理</strong><ul><li><strong>立即拨打120</strong></li><li><strong>立即开始降温</strong>争分夺秒不要等待救护车</li><li>冷水浸泡最有效将患者浸入冷水中水温<20不断搅动</li><li>或冰袋置于颈部腋下腹股沟大血管走行处</li><li>持续扇风+喷洒冷水</li><li>降温目标<strong>30分钟内将体温降至<39</strong></li></ul></li></ul><h2>预防要点</h2><ul><li>高温时段11:00-15:00减少户外活动</li><li>每小时饮水500-1000ml少量多次勿等口渴再喝</li><li>补充含盐饮料不要只喝纯水</li><li>穿透气浅色衣物</li><li>切勿将儿童或宠物留在密闭车内</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 2345, 412, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES014',
'失温低体温症与冻伤的急救',
'低体温症不仅在极寒环境发生湿冷大风中10也能致命新疆冬季寒冷是失温和冻伤的高风险地区每位职工都应掌握',
'IMAGE_TEXT',
'CAT005',
'寒冷天气户外作业登山受困落水获救后长时间暴露在湿冷阴雨环境中',
'TAG014',
'<h2>低体温症的分级</h2><table border="1"><tr><th>分级</th><th>体温</th><th>表现</th></tr><tr><td>轻度</td><td>32-35</td><td>寒战手脚冰凉精细动作困难</td></tr><tr><td>中度</td><td>28-32</td><td>寒战停止危险信号意识模糊言语不清心跳呼吸减慢</td></tr><tr><td>重度</td><td><28</td><td>昏迷瞳孔散大心跳呼吸极微弱可能被误认为死亡</td></tr></table><h2>低体温症急救步骤</h2><ol><li><strong>脱离冷环境</strong>移到避风保暖处脱去湿衣物</li><li><strong>被动复温</strong>用保温毯睡袋干衣物包裹全身</li><li><strong>主动复温</strong>热水袋/暖宝宝置于<strong>胸部颈部腹股沟</strong>大血管区不要放四肢四肢加热会导致冷血回流心脏引发心律失常</li><li><strong>补充热量</strong>如患者清醒可吞咽给予温热含糖饮料<strong>不要给酒精和咖啡因</strong></li><li><strong>避免剧烈动作</strong>可能诱发室颤</li></ol><h2>急救注意事项</h2><ul><li>判断生命体征要<strong>测60秒</strong>严重低体温时脉搏和呼吸极其缓慢微弱</li><li>对重度低体温者<strong>不要轻易认定为死亡</strong>"Not dead until warm and dead"</li><li>CPR疑似心脏骤停者如无法在10秒内确认脉搏应立即开始CPR</li></ul><h2>冻伤的急救</h2><ul><li><strong>不要用雪搓患处</strong>加重组织损伤</li><li><strong>不要用明火/暖气直接烤</strong>冻伤部位感觉迟钝极易烫伤</li><li><strong>正确复温</strong>将冻伤部位浸泡在<strong>37-42温水</strong>持续15-30分钟水温用健康肢体测试</li><li>复温过程中会出现剧痛和颜色变化变红这是正常现象</li><li>如水疱形成不要刺破</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 1456, 267, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
-- ===================== 中毒急救 =====================
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES015',
'一氧化碳煤气中毒的识别与急救',
'一氧化碳中毒是新疆冬季供暖季最常见的急症之一CO无色无味被称为"沉默杀手"早期识别症状正确处置可避免悲剧',
'IMAGE_TEXT',
'CAT006',
'冬季使用煤炉取暖燃气热水器洗浴在密闭车库发动汽车时',
'TAG015',
'<h2>一氧化碳为什么危险</h2><ul><li>CO与血红蛋白亲和力比O<strong>240倍</strong>空气中极低浓度的CO即可导致严重缺氧</li><li>无色无味无刺激无法靠感官察觉</li><li>中毒早期症状类似"感冒"极易被忽视</li></ul><h2>中毒症状分级</h2><table border="1"><tr><th>程度</th><th>症状</th></tr><tr><td>轻度</td><td>头痛头晕恶心呕吐乏力像感冒</td></tr><tr><td>中度</td><td>剧烈头痛意识模糊嗜睡呼吸急促</td></tr><tr><td>重度</td><td>昏迷抽搐呼吸和循环衰竭大小便失禁</td></tr></table><p>特征性体征<strong>皮肤和黏膜呈樱桃红色</strong>出现时往往已重度中毒</p><h2>急救步骤</h2><ol><li><strong>第一时间开窗通风</strong>不要先做别的</li><li>迅速将患者移到<strong>空气新鲜处</strong>解开衣领和腰带</li><li>拨打120明确告知"一氧化碳中毒"</li><li>如患者无呼吸/心跳立即CPR</li><li><strong>高流量吸氧</strong>由急救人员操作这是最重要的治疗</li></ol><h2>常见误区</h2><ul><li><strong> "屋里放盆水能防煤气中毒"</strong>CO不溶于水完全无效</li><li><strong> "让中毒者喝醋、灌酸菜汤能解毒"</strong>无效且可能导致误吸</li><li><strong> "患者醒了就好了"</strong>CO中毒可能有<strong>迟发性脑病假愈期</strong>必须就医观察</li></ul><h2>预防措施</h2><ul><li>煤炉取暖必须安装排烟管道并定期检查</li><li>燃气热水器严禁安装在浴室或通风不良处</li><li>不在密闭车库发动汽车</li><li>安装<strong>一氧化碳报警器</strong></li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 2876, 378, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES016',
'蛇咬伤犬咬伤与蜂蜇伤的应急处理',
'新疆地区野外作业可能遇到毒蛇野犬蜂群不同动物伤害的急救方法截然不同错误处理可能加重后果',
'IMAGE_TEXT',
'CAT006',
'野外作业户外活动时被蛇咬伤犬咬伤或蜂群攻击',
'TAG016',
'<h2>蛇咬伤急救</h2><h3>毒蛇与无毒蛇咬伤的鉴别</h3><ul><li><strong>毒蛇</strong>一对或单个较深牙痕局部肿胀迅速剧痛发黑</li><li><strong>无毒蛇</strong>两排细密牙痕轻微疼痛无全身症状</li><li><strong>不确定时</strong>一律按毒蛇咬伤处理</li></ul><h3>急救步骤</h3><ol><li><strong>保持镇静</strong>制动<strong>减少活动</strong>降低毒素扩散速度</li><li><strong>固定伤肢</strong>用夹板固定保持伤处低于心脏水平</li><li><strong>去除束缚物</strong>摘除戒指手镯手表等局部会迅速肿胀</li><li><strong>清洗伤口</strong>用清水冲洗如有条件</li><li><strong>立即就医</strong>采集/拍下蛇的照片有助于选择抗蛇毒血清</li></ol><h3>绝对禁忌传统做法大多有害</h3><ul><li><strong> 不要用嘴吸毒</strong>吸出量微乎其微反而导致口咽部吸收中毒</li><li><strong> 不要切口放血</strong>增加感染和损伤</li><li><strong> 不要扎止血带</strong>阻断动脉会导致肢体缺血坏死</li><li><strong> 不要冰敷</strong>加重组织损伤</li></ul><h2>犬咬伤急救</h2><ol><li><strong>冲洗</strong>大量流动清水+肥皂水交替冲洗伤口至少15分钟</li><li><strong>消毒</strong>碘伏或75%酒精消毒</li><li><strong>不缝合不包扎</strong>一般开放性伤口不予缝合包扎利于引流</li><li><strong>立即就医</strong>评估是否需要注射狂犬疫苗和破伤风抗毒素</li></ol><h2>蜂蜇伤的急救</h2><h3>局部反应大多数情况</h3><ol><li><strong>拔除毒刺</strong>用指甲或卡片背面沿皮肤<strong>逆刮</strong>不要用镊子夹可能将毒囊内毒液挤入体内</li><li><strong>清洗</strong>肥皂水冲洗</li><li><strong>冷敷</strong>减轻肿胀和疼痛</li></ol><h3>警惕严重过敏反应</h3><ul><li>被蜇后短时间出现全身荨麻疹呼吸困难面部肿胀 过敏性休克</li><li>使用肾上腺素笔如有+ 立即拨打120</li></ul><h3>多处蜇伤>10处</h3><ul><li>即使无过敏反应也需就医蜂毒累积毒性</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 1567, 234, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
-- ===================== 特殊人群急救 =====================
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES017',
'老年人跌倒后的应急处理',
'跌倒是65岁以上老年人伤害死亡的首位原因老人跌倒后盲目扶起可能造成二次伤害正确做法是"先评估、后处理"',
'IMAGE_TEXT',
'CAT007',
'老年人发生跌倒尤其在居家社区活动如厕洗澡时',
'TAG017',
'<h2>跌倒后第一反应不要急于扶起</h2><p>老人跌倒后<strong>保持原位</strong>先自我检查</p><ol><li>有没有剧烈疼痛尤其是髋部腰部</li><li>手脚能不能活动有没有麻木</li><li>有没有出血</li></ol><h2>目击者的处理步骤</h2><h3>1. 先评估不要立即扶起</h3><ul><li>询问疼痛部位能否活动</li><li>检查有无外伤出血</li><li>观察意识状态</li></ul><h3>2. 怀疑骨折/脊柱损伤 不要移动</h3><ul><li><strong>髋部骨折</strong>伤肢短缩外旋"脚不能动了"</li><li><strong>脊柱骨折</strong>腰背部剧痛下肢麻木或不能动</li><li>发现上述症状<strong>立即拨打120</strong>保持老人平卧保暖</li></ul><h3>3. 确认无骨折 安全扶起</h3><ol><li>协助老人翻身侧卧屈膝</li><li>用椅子做支撑手撑椅面缓慢起身</li><li>如老人头晕先坐一会再尝试站立</li></ol><h2>跌倒后最危险的两种情况</h2><h3>髋部骨折</h3><ul><li>被称为"人生最后一次骨折"骨折后长期卧床易引发肺炎压疮血栓一年内死亡率约20%-30%</li><li>必须有手术意识条件允许尽早手术</li></ul><h3>硬膜下血肿</h3><ul><li>跌倒撞头后<strong>数天至数周</strong>才出现症状"迟发性"</li><li>表现为逐渐加重的头痛嗜睡一侧肢体无力反应迟钝</li><li>头部外伤后如出现上述症状<strong>必须就医</strong>做头颅CT</li></ul><h2>预防胜于急救</h2><ul><li>家居防滑浴室铺防滑垫清除地面杂物和电线</li><li>改善照明卧室到卫生间的通道安装夜灯</li><li>适当锻炼太极拳平衡训练可显著降低跌倒风险</li><li>定期检查视力和药物副作用降压药安眠药等</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 1987, 356, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES018',
'婴幼儿高热惊厥的正确处置',
'高热惊厥是6个月至5岁婴幼儿最常见的中枢神经系统急症看起来非常吓人但掌握正确处理后可以安全度过',
'IMAGE_TEXT',
'CAT007',
'婴幼儿6个月-5岁发热时突发全身或局部抽搐意识丧失',
'TAG018',
'<h2>什么是高热惊厥</h2><ul><li>通常在体温快速升高阶段发生>38</li><li>好发年龄6个月至5岁高峰18-24个月</li><li>家族遗传倾向明显</li><li><strong>绝大多数是良性的</strong>不会导致脑损伤或智力问题</li></ul><h2>发作时的表现</h2><ul><li>全身僵直或抽搐双眼上翻或凝视</li><li>口吐白沫意识丧失</li><li>约持续1-3分钟一般<strong>5分钟内自行停止</strong></li></ul><h2>家长急救步骤</h2><ol><li><strong>保持镇静</strong>记录发作开始时间</li><li><strong>侧卧位</strong>将孩子侧放防止呕吐物/口水呛入气道</li><li><strong>清除周围危险物</strong>硬物尖锐物</li><li><strong>松开衣物</strong>解开衣领和腰带</li><li><strong>不要往嘴里塞任何东西</strong>包括手指毛巾筷子压舌板</li><li><strong>不要强行按压四肢</strong></li><li>抽搐停止后用退热药对乙酰氨基酚/布洛芬按体重计算剂量</li></ol><h2>什么情况必须立即就医</h2><ul><li>抽搐持续<strong>超过5分钟</strong></li><li>抽搐停止后意识未恢复</li><li>反复抽搐</li><li>抽搐后一侧肢体无力Todd麻痹</li><li>首次发作</li><li>抽搐前有头部外伤史</li></ul><h2>是否会复发</h2><ul><li>约1/3患儿会复发</li><li>首次发作年龄越小发热程度越低<38.5就抽搐直系亲属有惊厥史者复发率更高</li><li>多数孩子5-6岁后不再发作</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 2234, 445, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
-- ===================== 灾害事故急救 =====================
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES019',
'火灾现场逃生与烧伤急救',
'火灾死亡中大部分不是烧死而是吸入有毒烟雾窒息了解正确的逃生方法和初期火灾扑救关键时刻能救命',
'IMAGE_TEXT',
'CAT008',
'建筑火灾发生时的逃生自救和初期火灾处置',
'TAG019',
'<h2>火灾致死的主要原因</h2><ul><li>烟雾和有毒气体吸入COHCN等约占火灾死亡人数的<strong>75%</strong></li><li>高温气体吸入导致的气道烧伤</li><li>直接烧伤</li></ul><h2>逃生要诀</h2><h3>如果房间内起火且火势小初期</h3><ul><li>可用灭火器或湿棉被扑灭仅限火势小于垃圾桶大小且你有把握</li><li>电器着火先断电再灭火</li><li>油锅起火盖锅盖不要倒水</li></ul><h3>如果火势蔓延或烟雾较大 立即逃生</h3><ol><li><strong>低姿前进</strong>烟雾和热气向上聚集贴近地面空气相对清洁<strong>湿毛巾捂口鼻</strong>弯腰或匍匐前进</li><li><strong>触摸门把手</strong>开门前用手背试门把手温度烫手说明门外有火<strong>不要开门</strong></li><li><strong>走楼梯不坐电梯</strong></li><li><strong>身上着火</strong>Stop-Drop-Roll用厚重衣物包裹灭火</li></ol><h3>如果被困无法逃离</h3><ul><li>用湿布堵住门缝和通风口</li><li>拨打119报告自己的具体位置楼层房间</li><li>在窗边挥舞鲜艳衣物发出求救信号</li></ul><h2>灭火器使用"提拔我呀"---</h2><ol><li><strong></strong>提起灭火器</li><li><strong></strong>拔掉保险销</li><li><strong></strong>握住喷管前端对准<strong>火焰根部</strong></li><li><strong></strong>压下压把扫射</li></ol><p>站位站在<strong>上风方向</strong>距火源2-3米</p><h2>家庭火灾预防</h2><ul><li>安装烟雾报警器每个卧室+每层至少一个</li><li>制定家庭逃生计划确定集合点</li><li>不超负荷用电不私拉乱接电线</li><li>厨房烹饪不离人楼道勿堆放杂物</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 3234, 567, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES020',
'道路交通事故现场的检伤分类与急救',
'交通事故现场混乱伤者多资源有限了解检伤分类原则和基本急救技术在专业救援到达前做最有效的处置',
'IMAGE_TEXT',
'CAT008',
'道路交通事故尤其是多车相撞多人受伤的复杂事故现场',
'TAG020',
'<h2>现场安全第一</h2><ul><li>将车辆熄火拉手刹</li><li>在来车方向设置警示标志高速路白天150米外夜间250米外</li><li>注意燃油泄漏电线掉落等次生危险</li><li>不要吸烟</li></ul><h2>检伤分类国际通用四色法</h2><table border="1"><tr><th>颜色</th><th>优先级</th><th>标准</th></tr><tr><td>🔴 红色</td><td>第一优先</td><td>有生命危险但可救治气道梗阻张力性气胸大出血</td></tr><tr><td>🟡 黄色</td><td>第二优先</td><td>重伤但可等待骨折无大出血脊柱损伤稳定</td></tr><tr><td>🟢 绿色</td><td>第三优先</td><td>轻伤可步行轻微擦伤软组织挫伤</td></tr><tr><td> 黑色</td><td>最后</td><td>无生命体征或伤势不可救治</td></tr></table><h2>车祸伤员的急救要点</h2><h3>A - 气道管理</h3><ul><li>托下颌开放气道车祸伤员高度怀疑颈椎损伤<strong>不要仰头</strong></li><li>清除口腔血液和异物</li></ul><h3>B - 呼吸评估</h3><ul><li>观察呼吸频率对称性</li><li>张力性气胸呼吸困难+气管偏移+患侧呼吸音消失需紧急穿刺减压</li></ul><h3>C - 循环与止血</h3><ul><li>控制活动性出血</li><li>评估休克皮肤苍白湿冷烦躁不安脉搏细弱加快</li></ul><h3>D - 脊柱保护</h3><ul><li>除非有立即生命危险<strong>不要移动伤员</strong></li><li>如必须移动保持头--躯干轴线不变</li></ul><h2>不要做的事</h2><ul><li><strong> 不要给伤者喝水</strong>可能需紧急手术</li><li><strong> 不要取出插入体内的异物</strong>固定后送医</li><li><strong> 不要将头盔从摩托车手头上摘下</strong>可能加重颈椎损伤</li><li><strong> 不要一个人逞强</strong>分配任务A打120B设置警示C照护伤员</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 1876, 312, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES021',
'地震自救互救"十要点"',
'新疆地处地震带地震风险不容忽视掌握地震中"伏地、遮挡、手抓牢"的避险原则和震后自救互救技能',
'IMAGE_TEXT',
'CAT008',
'地震发生时和震后的自救互救',
'TAG019',
'<h2>地震发生时室内避险</h2><h3>"伏地、遮挡、手抓牢"Drop-Cover-Hold On</h3><ol><li><strong>伏地Drop</strong>立即蹲下降低重心</li><li><strong>遮挡Cover</strong>钻到牢固的桌子下或靠在内墙墙角用双臂/书包/靠垫护住头颈部</li><li><strong>手抓牢Hold On</strong>一只手抓住桌腿等固定物直到晃动停止</li></ol><h3>室内避震"三不"</h3><ul><li><strong>不要站在窗户边</strong>玻璃飞溅</li><li><strong>不要乘坐电梯</strong></li><li><strong>不要躲在吊灯吊扇高大家具下方</strong></li></ul><h2>地震发生时室外避险</h2><ul><li>远离建筑物电线杆广告牌跑到开阔地带</li><li>如果在开车靠边停车避开桥梁高架隧道留在车内</li></ul><h2>震后自救</h2><ul><li>保持镇静不要使用明火可能发生燃气泄漏</li><li>如被埋压<ul><li>清除口鼻灰尘保持呼吸通畅</li><li>用衣物捂住口鼻防止吸入粉尘</li><li><strong>不要大声呼喊</strong>消耗体力和氧气用敲击管道墙壁的方式发出信号</li><li>有规律敲击"三短三长三短"SOS</li></ul></li></ul><h2>震后互救</h2><ol><li>先救近处的容易救的"先易后难"</li><li>救人时注意被埋压者的头部暴露和呼吸道清理</li><li>不可用利器强力刨挖防止二次伤害</li><li>救出后评估伤势并给予基本急救</li></ol><h2>地震应急包建议备好</h2><ul><li>饮用水每人每天4L备3天干粮急救包</li><li>手电筒+备用电池口哨求救用</li><li>防尘口罩保温毯</li><li>重要证件复印件</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 2456, 423, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
INSERT INTO QH_EME_FIR_AID_RES (ID, TITLE, SUMMARY, CONTENT_TYPE, CATEGORY_ID, APPLICABLE_SCENARIO, TAGS, CONTENT, COVER_IMAGE, FILE_URL, EFFECTIVE_TIME, EXPIRY_TIME, AUDIT_STATUS, AUDIT_REJECT_REASON, AUDIT_BY, AUDIT_TIME, VIEW_COUNT, FAVORITE_COUNT, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, DEL_FLAG)
VALUES (
'RES022',
'家庭急救箱的配置与使用指南',
'急救箱是每个家庭和车辆的必备品了解急救箱应该有哪些物品如何存放过期如何处理才能在紧急时刻真正发挥作用',
'IMAGE_TEXT',
'CAT004',
'家庭日常备置急救箱及发生轻微伤情时的处理',
'TAG011',
'<h2>基础急救箱清单</h2><h3>包扎材料</h3><ol><li>医用纱布片无菌各种尺寸x 10片</li><li>弹性绷带5cm8cm各2卷</li><li>三角巾 x 2条</li><li>创可贴各种尺寸x 20片</li><li>医用胶带透气型x 1卷</li></ol><h3>消毒用品</h3><ol><li>碘伏棉签/棉球 x 20支</li><li>75%酒精棉片 x 20片</li><li>一次性手套无粉x 5双</li></ol><h3>工具</h3><ol><li>圆头剪刀 x 1把</li><li>镊子 x 1把</li><li>体温计电子或红外x 1支</li><li>安全别针 x 5个</li><li>一次性冰袋捏破即冷型x 2袋</li></ol><h3>药品需根据家庭成员情况调整</h3><ol><li>退热镇痛药对乙酰氨基酚/布洛芬</li><li>抗过敏药氯雷他定/西替利嗪</li><li>止泻药蒙脱石散/口服补液盐</li><li>烫伤膏</li><li>抗生素软膏莫匹罗星</li><li>个人常备药硝酸甘油哮喘吸入剂等</li></ol><h2>急救箱管理要点</h2><ul><li>存放在<strong>阴凉干燥儿童拿不到但成人方便取用</strong>的地方</li><li><strong>3-6个月</strong>检查一次更换过期物品</li><li>车用急救箱与家用分开</li><li>箱外标注最近医院的地址和电话</li><li>在家人中指定一人负责维护</li></ul><h2>急救包的使用禁忌</h2><ul><li><strong>不要给不明原因腹痛者服用止痛药</strong>可能掩盖阑尾炎等急腹症</li><li><strong>不要使用过期消毒液和药品</strong></li><li><strong>不要共用眼药水</strong></li><li>任何开放性伤口确认破伤风疫苗接种在有效期<5年清洁伤<10年污染伤</li></ul>',
NULL, NULL,
DATE '2026-07-01', DATE '2027-12-31',
11, NULL, '系统管理员', SYSDATE, 5432, 1023, 1,
'admin', SYSDATE, 'admin', SYSDATE, 0
);
COMMIT;
-- =====================================================
-- 验证数据
-- =====================================================
-- 查看各分类及其下属标签
SELECT
c."NAME" AS 分类名称,
LISTAGG(t."NAME", '、') WITHIN GROUP (ORDER BY t."SORT_NO") AS 下属标签
FROM QH_EME_FIR_AID_RES_CATE c
LEFT JOIN QH_EME_FIR_AID_RES_CATE t ON t."PARENT_ID" = c."ID" AND t."TYPE" = 2 AND t."DEL_FLAG" = 0
WHERE c."TYPE" = 1 AND c."DEL_FLAG" = 0
GROUP BY c."ID", c."NAME", c."SORT_NO"
ORDER BY c."SORT_NO";
-- 统计
SELECT '分类' AS 统计项, COUNT(*) AS 数量 FROM QH_EME_FIR_AID_RES_CATE WHERE "TYPE" = 1 AND "DEL_FLAG" = 0
UNION ALL
SELECT '标签', COUNT(*) FROM QH_EME_FIR_AID_RES_CATE WHERE "TYPE" = 2 AND "DEL_FLAG" = 0
UNION ALL
SELECT '资源', COUNT(*) FROM QH_EME_FIR_AID_RES WHERE "DEL_FLAG" = 0;
@@ -55,5 +55,10 @@ public class AddGroupMemberDTO {
* 群成员名称(可选,仅用于IM账号导入,不发送到腾讯IM) * 群成员名称(可选,仅用于IM账号导入,不发送到腾讯IM)
*/ */
private String memberName; private String memberName;
/**
* 群成员头像URL(可选,仅用于IM账号导入,不发送到腾讯IM)
*/
private String memberAvatar;
} }
} }
@@ -339,7 +339,7 @@ public class TXController {
groupList.add(hashMap); groupList.add(hashMap);
}); });
String result = tencentCloudImUtil.creatGroup(Owner_Account, Type, GroupId, conSessionRequestDO.getName() + "_" + DateUtils.getCurrentTimestamp(), groupList); String result = tencentCloudImUtil.creatGroup(Owner_Account, Type, GroupId, "应急求助", groupList);
if (!JSONObject.parseObject(result).get("ErrorCode").equals(0)) { if (!JSONObject.parseObject(result).get("ErrorCode").equals(0)) {
return Result.error("创建群聊失败!"); return Result.error("创建群聊失败!");
} }
@@ -390,7 +390,7 @@ public class TXController {
groupList.add(hashMap); groupList.add(hashMap);
}); });
String result = tencentCloudImUtil.creatGroup(Owner_Account, Type, GroupId, conSessionRequestDO.getName() + "_" + DateUtils.getCurrentTimestamp(), groupList); String result = tencentCloudImUtil.creatGroup(Owner_Account, Type, GroupId, "应急求助", groupList);
if (!JSONObject.parseObject(result).get("ErrorCode").equals(0)) { if (!JSONObject.parseObject(result).get("ErrorCode").equals(0)) {
return Result.error("创建群聊失败!"); return Result.error("创建群聊失败!");
} }
@@ -554,13 +554,16 @@ public class TencentCloudImUtil {
try { try {
// 先导入账号及其名称,确保成员在IM系统中已注册 // 先导入账号及其名称,确保成员在IM系统中已注册
if (dto.getMemberList() != null && !dto.getMemberList().isEmpty()) { if (dto.getMemberList() != null && !dto.getMemberList().isEmpty()) {
// 构建腾讯IM新版 AccountList 格式(含昵称) // 构建腾讯IM新版 AccountList 格式(含昵称和头像
List<JSONObject> accountList = dto.getMemberList().stream().map(member -> { List<JSONObject> accountList = dto.getMemberList().stream().map(member -> {
JSONObject account = new JSONObject(); JSONObject account = new JSONObject();
account.put("UserID", member.getMemberAccount()); account.put("UserID", member.getMemberAccount());
if (StringUtils.isNotEmpty(member.getMemberName())) { if (StringUtils.isNotEmpty(member.getMemberName())) {
account.put("Nick", member.getMemberName()); account.put("Nick", member.getMemberName());
} }
if (StringUtils.isNotEmpty(member.getMemberAvatar())) {
account.put("FaceUrl", member.getMemberAvatar());
}
return account; return account;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
importAccountsWithNames(accountList); importAccountsWithNames(accountList);
@@ -570,11 +573,13 @@ public class TencentCloudImUtil {
String httpsUrl = getHttpsUrl(TencentCloudImApiConstant.GroupManage.ADD_GROUP_MEMBER, random); String httpsUrl = getHttpsUrl(TencentCloudImApiConstant.GroupManage.ADD_GROUP_MEMBER, random);
String jsonString = objectMapper.writeValueAsString(dto); String jsonString = objectMapper.writeValueAsString(dto);
JSONObject jsonObject = JSONObject.parseObject(jsonString); JSONObject jsonObject = JSONObject.parseObject(jsonString);
// 移除 memberName 字段,腾讯IM API 不接受此字段 // 移除内部字段,腾讯IM API 不接受
JSONArray memberList = jsonObject.getJSONArray("MemberList"); JSONArray memberList = jsonObject.getJSONArray("MemberList");
if (memberList != null) { if (memberList != null) {
for (int i = 0; i < memberList.size(); i++) { for (int i = 0; i < memberList.size(); i++) {
memberList.getJSONObject(i).remove("memberName"); JSONObject member = memberList.getJSONObject(i);
member.remove("memberName");
member.remove("memberAvatar");
} }
} }
log.info("腾讯云im添加群成员,请求参数:{}", jsonObject); log.info("腾讯云im添加群成员,请求参数:{}", jsonObject);
@@ -52,4 +52,18 @@ public class AbnormalEvent extends BaseUser {
private Date bindDate; private Date bindDate;
@Schema(title = "重点指标用户(0:非重点指标用户 1:大病异常 2:慢病异常 3:指标异常)") @Schema(title = "重点指标用户(0:非重点指标用户 1:大病异常 2:慢病异常 3:指标异常)")
private List<WatchKeyUser> keyUserList; private List<WatchKeyUser> keyUserList;
/**
* 事件ID(用于告警事件与GPS位置更新关联的唯一标识)
*/
@Excel(name = "事件ID", width = 32, orderNum = "12")
@Schema(title = "事件ID")
private String eventId;
/**
* 定位时间(手表定时上报的GPS定位时间)
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "定位时间", format = "yyyy-MM-dd HH:mm:ss", width = 20, orderNum = "13")
@Schema(title = "定位时间")
private Date locateTime;
} }
@@ -151,6 +151,20 @@ public class WatchMonitorData implements Serializable {
@Excel(name = "部门编码", width = 15) @Excel(name = "部门编码", width = 15)
@Schema(title = "部门编码") @Schema(title = "部门编码")
private java.lang.String orgCode; private java.lang.String orgCode;
/**
* 事件ID(用于告警事件与GPS位置更新关联的唯一标识)
*/
@Excel(name = "事件ID", width = 32)
@Schema(title = "事件ID")
private java.lang.String eventId;
/**
* 定位时间(手表上报的GPS定位时间,定时上报场景使用)
*/
@Excel(name = "定位时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(title = "定位时间")
private java.util.Date locateTime;
@Schema(title = "员工编号") @Schema(title = "员工编号")
@TableField(exist = false) @TableField(exist = false)
@@ -45,4 +45,15 @@ public class WatchNotifyVo implements Serializable {
private Date warnTime; private Date warnTime;
private String gpsErrorMsg; private String gpsErrorMsg;
/**
* 事件ID(用于告警事件与GPS位置更新关联的唯一标识)
*/
private String eventId;
/**
* 定位时间(手表上报的GPS定位时间,定时上报场景使用)
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date locateTime;
} }
@@ -44,6 +44,21 @@ public class WatchApiController {
return watchMonitorDataService.notice(json); return watchMonitorDataService.notice(json);
} }
/**
* 更新告警事件GPS位置信息接口
* 根据 watchNo + eventId 联合定位已有告警数据;
* 仅更新GPS相关字段,不推送大屏与短信;
* 内部会调用高德接口进行GPS84→GCJ02坐标转换与地址反查。
*
* @param json 入参(watchNo、eventId、lon、lat、address、locateTime、gpsErrorMsg
* @return 处理结果
*/
@PostMapping("/updateMonitorGps")
@Operation(summary = "更新告警事件GPS位置信息")
public AjaxJson updateMonitorGps(@RequestBody JSONObject json) {
return watchMonitorDataService.updateMonitorGps(json);
}
@GetMapping("/setData") @GetMapping("/setData")
public AjaxJson setData() { public AjaxJson setData() {
AjaxJson ajaxJson = new AjaxJson(); AjaxJson ajaxJson = new AjaxJson();
@@ -38,6 +38,17 @@ public interface IWatchMonitorDataService extends IService<WatchMonitorData> {
*/ */
AjaxJson notice(JSONObject jsonObject); AjaxJson notice(JSONObject jsonObject);
/**
* 更新告警事件GPS位置信息
* 根据 watchNo + eventId 联合定位已有告警数据;
* 缺失任一定位字段则忽略;已存在GPS信息则忽略;
* 仅更新数据,不推送大屏与短信。
*
* @param jsonObject 入参(含 watchNo、eventId、lon、lat、address、locateTime、gpsErrorMsg 等)
* @return 处理结果
*/
AjaxJson updateMonitorGps(JSONObject jsonObject);
/** /**
* 处理历史数据 orgCode为空的问题 * 处理历史数据 orgCode为空的问题
* @return * @return
@@ -265,6 +265,102 @@ public class WatchMonitorDataServiceImpl extends ServiceImpl<WatchMonitorDataMap
return ajaxJson; return ajaxJson;
} }
/**
* 更新告警事件GPS位置信息
* 根据 watchNo + eventId 联合定位已有告警数据;
* watchNo 或 eventId 任一缺失则忽略;
* 已存在 GPS 信息则忽略本次更新;
* 参考 createMonitorData 进行 GPS84 → GCJ02 坐标转换 + 高德地址反查;
* 仅更新数据,不推送大屏与短信。
*
* @param json 入参(含 watchNo、eventId、lon、lat、address、locateTime、gpsErrorMsg 等)
* @return 处理结果
*/
@Override
public AjaxJson updateMonitorGps(JSONObject json) {
GlobalUtils.setHttpFeignToken();
AjaxJson ajaxJson = new AjaxJson();
logger.info("接收更新告警事件GPS信息=={}", json.toJSONString());
WatchNotifyVo data = json.toJavaObject(WatchNotifyVo.class);
// watchNo 或 eventId 任一缺失则忽略
if (StrUtil.isBlank(data.getWatchNo()) || StrUtil.isBlank(data.getEventId())) {
logger.warn("更新GPS信息缺失关键定位字段,忽略本次请求 watchNo={}, eventId={}", data.getWatchNo(), data.getEventId());
ajaxJson.setSuccess(true);
return ajaxJson;
}
// watchNo + eventId 联合定位已有告警数据
LambdaQueryWrapper<WatchMonitorData> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(WatchMonitorData::getWatchNo, data.getWatchNo())
.eq(WatchMonitorData::getEventId, data.getEventId());
List<WatchMonitorData> existList = this.list(queryWrapper);
if (CollUtil.isEmpty(existList)) {
logger.warn("更新GPS信息失败,未匹配到告警记录 watchNo={}, eventId={}", data.getWatchNo(), data.getEventId());
ajaxJson.setSuccess(true);
return ajaxJson;
}
// 已存在GPS信息则忽略本次更新,避免覆盖已有有效坐标
boolean hasGps = existList.stream().anyMatch(m -> m.getLon() != null && m.getLat() != null);
if (hasGps) {
logger.info("告警记录已有GPS信息,忽略本次更新 watchNo={}, eventId={}", data.getWatchNo(), data.getEventId());
ajaxJson.setSuccess(true);
return ajaxJson;
}
// 计算高德坐标与高德地址(参考 createMonitorData 逻辑)
WatchMonitorData updateEntity = new WatchMonitorData();
updateEntity.setLon(data.getLon());
updateEntity.setLat(data.getLat());
updateEntity.setAddress(data.getAddress());
updateEntity.setGpsErrorMsg(data.getGpsErrorMsg());
updateEntity.setLocateTime(data.getLocateTime());
if (Stream.of(data.getLon(), data.getLat()).allMatch(value -> ObjUtil.isNotEmpty(value) && value != 0)) {
Gps gps = GPS84ToGCJ02(data.getLon(), data.getLat());
if (null != gps) {
// 写入高德坐标
updateEntity.setLonGd(BigDecimal.valueOf(gps.getLongitude()));
updateEntity.setLatGd(BigDecimal.valueOf(gps.getLatitude()));
// 调用高德接口获取地址信息
AmapResultVo amapResultVo = amapService.getFormattedAddress(gps.getLongitude(), gps.getLatitude(), 5000);
if (amapResultVo.isSuccess()) {
updateEntity.setAddressGd(amapResultVo.getAddress());
updateEntity.setAddress(amapResultVo.getAddress());
} else {
String originError = StrUtil.isBlank(updateEntity.getGpsErrorMsg()) ? "" : updateEntity.getGpsErrorMsg() + "";
updateEntity.setGpsErrorMsg(originError + amapResultVo.getErrorMsg());
}
}
}
// 仅更新 GPS 相关字段,不推送大屏、不发短信
boolean updated = this.lambdaUpdate()
.eq(WatchMonitorData::getWatchNo, data.getWatchNo())
.eq(WatchMonitorData::getEventId, data.getEventId())
.set(WatchMonitorData::getLon, updateEntity.getLon())
.set(WatchMonitorData::getLat, updateEntity.getLat())
.set(WatchMonitorData::getAddress, updateEntity.getAddress())
.set(WatchMonitorData::getLonGd, updateEntity.getLonGd())
.set(WatchMonitorData::getLatGd, updateEntity.getLatGd())
.set(WatchMonitorData::getAddressGd, updateEntity.getAddressGd())
.set(WatchMonitorData::getGpsErrorMsg, updateEntity.getGpsErrorMsg())
.set(WatchMonitorData::getLocateTime, updateEntity.getLocateTime())
.update();
if (!updated) {
logger.warn("更新GPS信息失败 watchNo={}, eventId={}", data.getWatchNo(), data.getEventId());
} else {
logger.info("更新GPS信息成功 watchNo={}, eventId={}, 共更新{}条", data.getWatchNo(), data.getEventId(), existList.size());
}
ajaxJson.setSuccess(true);
return ajaxJson;
}
/** /**
* 构建异常数据 * 构建异常数据
* *
@@ -272,13 +368,16 @@ public class WatchMonitorDataServiceImpl extends ServiceImpl<WatchMonitorDataMap
* @return 异常数据 * @return 异常数据
*/ */
private WatchMonitorData createMonitorData(WatchNotifyVo data) { private WatchMonitorData createMonitorData(WatchNotifyVo data) {
log.info("开始构建异常数据 => {}", JSONObject.toJSONString(data)); log.info("开始构建异常数据 => {}", JSONObject.toJSONString(data));
WatchMonitorData monitorDataEntity = new WatchMonitorData(); WatchMonitorData monitorDataEntity = new WatchMonitorData();
monitorDataEntity.setAddress(data.getAddress()); monitorDataEntity.setAddress(data.getAddress());
monitorDataEntity.setWatchNo(data.getWatchNo()); monitorDataEntity.setWatchNo(data.getWatchNo());
monitorDataEntity.setLon(data.getLon()); monitorDataEntity.setLon(data.getLon());
monitorDataEntity.setLat(data.getLat()); monitorDataEntity.setLat(data.getLat());
monitorDataEntity.setLocateTime(data.getLocateTime());
monitorDataEntity.setEventType(data.getEventType()); monitorDataEntity.setEventType(data.getEventType());
monitorDataEntity.setEventId(data.getEventId());
monitorDataEntity.setDataValue(data.getDataValue()); monitorDataEntity.setDataValue(data.getDataValue());
monitorDataEntity.setCreateDate(data.getCreateTime()); monitorDataEntity.setCreateDate(data.getCreateTime());
monitorDataEntity.setWarnTime(data.getWarnTime()); monitorDataEntity.setWarnTime(data.getWarnTime());
@@ -42,6 +42,7 @@ import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.jeecgframework.poi.exception.excel.enums.ExcelExportEnum; import org.jeecgframework.poi.exception.excel.enums.ExcelExportEnum;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -208,7 +209,12 @@ public class WatchUserDataServiceImpl extends ServiceImpl<WatchUserDataMapper, W
watchUserData.setDataDate(bindDateSave); watchUserData.setDataDate(bindDateSave);
watchUserData.setWatchNo(watchNo); watchUserData.setWatchNo(watchNo);
watchUserData.setCreateDate(new Date()); watchUserData.setCreateDate(new Date());
this.save(watchUserData); try {
this.save(watchUserData);
} catch (DuplicateKeyException e) {
//并发上报同一手表同一天数据时,先删后插存在竞态,另一线程已插入相同记录,忽略即可
log.warn("QH_WAT_USER_DATA并发写入冲突,已忽略: watchNo={}, dataDate={}", watchNo, s);
}
} }
// @Override // @Override
@@ -48,7 +48,8 @@ public enum RoleEnum {
MANAGER("manager"), MANAGER("manager"),
MEDICALUSER("medicaluser"), MEDICALUSER("medicaluser"),
MEDICALADMIN("medicaladmin"), MEDICALADMIN("medicaladmin"),
HOS_DOCTOR("hos_doctor"); HOS_DOCTOR("hos_doctor"),
NOTICE_ROLE("notice_role");
/** /**
* 角色名 * 角色名
@@ -2302,7 +2302,7 @@
}, },
"429005": { "429005": {
"4290051": "竹根滩镇", "4290051": "竹根滩镇",
"4290054": "江汉石油管理局", "4290054": "江汉SY管理局",
"42900545": "周矶管理区", "42900545": "周矶管理区",
"429005001": "园林", "429005001": "园林",
"429005002": "杨市", "429005002": "杨市",
+4
View File
@@ -84,6 +84,10 @@
<groupId>com.renkang</groupId> <groupId>com.renkang</groupId>
<artifactId>xj-anyan-api</artifactId> <artifactId>xj-anyan-api</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.renkang</groupId>
<artifactId>health-im-api</artifactId>
</dependency>
</dependencies> </dependencies>
@@ -85,7 +85,7 @@ public class ArchivesUserServiceImpl implements ArchivesUserService {
return null; return null;
} }
if (managedCodes.contains("A01")) { if (managedCodes.contains("A01")) {
return Collections.singletonList("长庆油田"); return Collections.singletonList("分公司");
} }
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
managedCodes.forEach(orgCode -> { managedCodes.forEach(orgCode -> {
@@ -1,6 +1,7 @@
package org.jeecg.modules.system.controller; package org.jeecg.modules.system.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil; import cn.hutool.http.HtmlUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
@@ -11,12 +12,15 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.renkang.im.api.IMHelloApi;
import com.renkang.im.entity.ConSessionRequestDO;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles; import org.apache.shiro.authz.annotation.RequiresRoles;
import org.jeecg.bean.request.ListUser;
import org.jeecg.bean.request.PeoplePsyAssessPlanVO; import org.jeecg.bean.request.PeoplePsyAssessPlanVO;
import org.jeecg.bean.request.PeopleStatisticVO; import org.jeecg.bean.request.PeopleStatisticVO;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
@@ -25,6 +29,7 @@ import org.jeecg.common.aspect.annotation.PermissionData;
import org.jeecg.common.config.TenantContext; import org.jeecg.common.config.TenantContext;
import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.bean.request.ResetPassword; import org.jeecg.common.system.bean.request.ResetPassword;
import org.jeecg.common.system.bean.request.SimpleUser; import org.jeecg.common.system.bean.request.SimpleUser;
import org.jeecg.common.system.bean.response.BaseUser; import org.jeecg.common.system.bean.response.BaseUser;
@@ -32,6 +37,7 @@ import org.jeecg.common.system.bean.response.GroupUser;
import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.LoginUserNew;
import org.jeecg.common.system.vo.SysUserModel; import org.jeecg.common.system.vo.SysUserModel;
import org.jeecg.common.util.*; import org.jeecg.common.util.*;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig; import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
@@ -130,6 +136,10 @@ public class SysUserController {
private ISysUserPostService sysUserPostService; private ISysUserPostService sysUserPostService;
@Autowired @Autowired
private UserCacheManager userCacheManager; private UserCacheManager userCacheManager;
@Autowired
private IMHelloApi imHelloApi;
@Autowired
private ISysBaseAPI sysBaseAPI;
@GetMapping("userRoles") @GetMapping("userRoles")
public Result<?> userRoles(@RequestParam String userId) { public Result<?> userRoles(@RequestParam String userId) {
if (StrUtil.isBlank(userId)) { if (StrUtil.isBlank(userId)) {
@@ -524,6 +534,8 @@ public class SysUserController {
//获取租户ids //获取租户ids
String relTenantIds = jsonObject.getString("relTenantIds"); String relTenantIds = jsonObject.getString("relTenantIds");
sysUserService.editUser(user, roles, departs, relTenantIds); sysUserService.editUser(user, roles, departs, relTenantIds);
// 同步IM个人资料
syncImProfile(user.getId());
result.success("修改成功!"); result.success("修改成功!");
} }
} catch (Exception e) { } catch (Exception e) {
@@ -1711,6 +1723,8 @@ public class SysUserController {
} }
sysUser.setUpdateTime(new Date()); sysUser.setUpdateTime(new Date());
sysUserService.updateById(sysUser); sysUserService.updateById(sysUser);
// 同步IM个人资料
syncImProfile(sysUser.getId());
} }
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
@@ -2335,4 +2349,17 @@ public class SysUserController {
Page<ScopeUserVO> page = new Page<>(pageNo, pageSize); Page<ScopeUserVO> page = new Page<>(pageNo, pageSize);
return Result.ok(sysUserService.scopeUserList(query,page)); return Result.ok(sysUserService.scopeUserList(query,page));
} }
private void syncImProfile(String userId) {
try {
List<LoginUserNew> users = sysBaseAPI.listUserByIds(new ListUser(Collections.singletonList(userId)));
if (CollUtil.isNotEmpty(users)) {
ConSessionRequestDO req = new ConSessionRequestDO();
req.setAccountList(Collections.singletonList(users.get(0)));
imHelloApi.accountReg(req);
}
} catch (Exception e) {
log.error("同步IM个人资料失败, userId: {}", userId, e);
}
}
} }
@@ -189,12 +189,12 @@ public class SysMessageNoticeServiceImpl extends ServiceImpl<SysMessageNoticeMap
LoginUser loginUser = GlobalUtils.getLoginUser(); LoginUser loginUser = GlobalUtils.getLoginUser();
/* /*
* 1.后台接口的消息列表需要做一定数据权限控制需考虑的角色有admin,system,second_manager,third_manager * 1.后台接口的消息列表需要做一定数据权限控制需考虑的角色有admin,system,second_manager,third_manager
* 2.admin,system可查看所有的活动 * 2.admin,system可查看所有的消息通知
* 3.second_manager,third_manager可查看管理单位下的消息列表 * 3.second_manager,third_manager可查看管理单位下的消息列表
*/ */
boolean permissions = false; boolean permissions = false;
List<String> roleCodes = Arrays.asList(Objects.toString(loginUser.getRoleCodes(), "").split(",")); List<String> roleCodes = Arrays.asList(Objects.toString(loginUser.getRoleCodes(), "").split(","));
if (roleCodes.contains(RoleEnum.ADMIN_MANAGER.roleName) || roleCodes.contains(RoleEnum.SYSTEM.roleName) || roleCodes.contains(RoleEnum.WEIGHT_PLAN_ADMIN.roleName)) { if (roleCodes.contains(RoleEnum.ADMIN_MANAGER.roleName) || roleCodes.contains(RoleEnum.SYSTEM.roleName)) {
permissions = true; permissions = true;
} else if (roleCodes.contains(RoleEnum.SECOND_MANAGER.roleName)) { } else if (roleCodes.contains(RoleEnum.SECOND_MANAGER.roleName)) {
if (StrUtil.isNotEmpty(loginUser.getDepartCodes())) { if (StrUtil.isNotEmpty(loginUser.getDepartCodes())) {
@@ -203,8 +203,8 @@ public class SysMessageNoticeServiceImpl extends ServiceImpl<SysMessageNoticeMap
permissions = true; permissions = true;
} }
} }
// 没有权限,返回空结果 // 只查看本人创建的消息
wrapper.eq(!permissions, SysMessageNotice::getId, "-1"); wrapper.eq(!permissions, SysMessageNotice::getCreateBy, loginUser.getUsername());
} }
/** /**
@@ -16,6 +16,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.renkang.consultation.api.ConSessionHelloApi; import com.renkang.consultation.api.ConSessionHelloApi;
import com.renkang.consultation.vo.FamilyNum; import com.renkang.consultation.vo.FamilyNum;
import com.renkang.im.api.IMHelloApi;
import com.renkang.im.entity.ConSessionRequestDO;
import com.renkang.watch.api.WatchApi; import com.renkang.watch.api.WatchApi;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists; import org.apache.commons.compress.utils.Lists;
@@ -24,6 +26,7 @@ import org.jeecg.bean.entity.UserDataRecordBWH;
import org.jeecg.bean.entity.UserDataRecordBmi; import org.jeecg.bean.entity.UserDataRecordBmi;
import org.jeecg.bean.enums.UserDataSourceEnum; import org.jeecg.bean.enums.UserDataSourceEnum;
import org.jeecg.bean.request.HealthMealsWeightQueryVO; import org.jeecg.bean.request.HealthMealsWeightQueryVO;
import org.jeecg.bean.request.ListUser;
import org.jeecg.bean.request.QueryWeightSignUserParam; import org.jeecg.bean.request.QueryWeightSignUserParam;
import org.jeecg.bean.response.*; import org.jeecg.bean.response.*;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
@@ -34,6 +37,7 @@ import org.jeecg.common.export.PoiExportHandler;
import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.util.DictUtil; import org.jeecg.common.system.util.DictUtil;
import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.LoginUserNew;
import org.jeecg.common.system.vo.SysUserModel; import org.jeecg.common.system.vo.SysUserModel;
import org.jeecg.common.util.*; import org.jeecg.common.util.*;
import org.jeecg.config.mybatis.AnalyzeTableManager; import org.jeecg.config.mybatis.AnalyzeTableManager;
@@ -122,6 +126,8 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
@Autowired @Autowired
private ConSessionHelloApi conSessionHelloApi; private ConSessionHelloApi conSessionHelloApi;
@Autowired @Autowired
private IMHelloApi imHelloApi;
@Autowired
private WatchApi watchApi; private WatchApi watchApi;
@Autowired @Autowired
private CommonExportsInfoController commonExportsInfoController; private CommonExportsInfoController commonExportsInfoController;
@@ -993,6 +999,8 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
if (com.xkcoding.http.util.StringUtil.isNotEmpty(orgCode)) { if (com.xkcoding.http.util.StringUtil.isNotEmpty(orgCode)) {
sendUpdateMsgToRedisStream(userEmployee.getId(), orgCode); sendUpdateMsgToRedisStream(userEmployee.getId(), orgCode);
} }
// 同步IM个人资料
syncImProfile(userEmployee.getId());
return Result.ok("编辑成功"); return Result.ok("编辑成功");
} else { } else {
return Result.error("编辑失败"); return Result.error("编辑失败");
@@ -1010,6 +1018,19 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
redisStreamUtil.add(RedisStreamKeyEnum.CHANGE_USER_DEPART, userModel); redisStreamUtil.add(RedisStreamKeyEnum.CHANGE_USER_DEPART, userModel);
} }
private void syncImProfile(String userId) {
try {
List<LoginUserNew> users = sysBaseAPI.listUserByIds(new ListUser(Collections.singletonList(userId)));
if (CollUtil.isNotEmpty(users)) {
ConSessionRequestDO req = new ConSessionRequestDO();
req.setAccountList(Collections.singletonList(users.get(0)));
imHelloApi.accountReg(req);
}
} catch (Exception e) {
log.error("同步IM个人资料失败, userId: {}", userId, e);
}
}
public boolean updateByIdAndUser(UserEmployee userEmployee) { public boolean updateByIdAndUser(UserEmployee userEmployee) {
// 添加账号 电话 身份证号校验 // 添加账号 电话 身份证号校验
/* List<String> checkExistUser = sysBaseAPI.checkExistUser(userEmployee.getId(), userEmployee.getUsername(), userEmployee.getPhone(), userEmployee.getIdCard()); /* List<String> checkExistUser = sysBaseAPI.checkExistUser(userEmployee.getId(), userEmployee.getUsername(), userEmployee.getPhone(), userEmployee.getIdCard());
@@ -19,6 +19,8 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.renkang.im.api.IMHelloApi;
import com.renkang.im.entity.ConSessionRequestDO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
@@ -35,6 +37,7 @@ import org.jeecg.bean.entity.UserDataRecordBmi;
import org.jeecg.bean.enums.UserDataSourceEnum; import org.jeecg.bean.enums.UserDataSourceEnum;
import org.jeecg.bean.request.PeoplePsyAssessPlanVO; import org.jeecg.bean.request.PeoplePsyAssessPlanVO;
import org.jeecg.bean.request.PeopleStatisticVO; import org.jeecg.bean.request.PeopleStatisticVO;
import org.jeecg.bean.request.ListUser;
import org.jeecg.bean.response.BaseEmployeeInfo; import org.jeecg.bean.response.BaseEmployeeInfo;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.common.bean.request.StatAllReq; import org.jeecg.common.bean.request.StatAllReq;
@@ -50,6 +53,7 @@ import org.jeecg.common.desensitization.annotation.SensitiveEncode;
import org.jeecg.common.exception.ExceptionAssertsUtil; import org.jeecg.common.exception.ExceptionAssertsUtil;
import org.jeecg.common.exception.JeecgBootException; import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.export.PoiExportHandler; import org.jeecg.common.export.PoiExportHandler;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.bean.request.ResetPassword; import org.jeecg.common.system.bean.request.ResetPassword;
import org.jeecg.common.system.bean.request.SimpleUser; import org.jeecg.common.system.bean.request.SimpleUser;
import org.jeecg.common.system.bean.request.SysUserInfoDO; import org.jeecg.common.system.bean.request.SysUserInfoDO;
@@ -95,6 +99,7 @@ import org.slf4j.Logger;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
import org.springframework.context.annotation.Lazy;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -197,6 +202,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
private UserDataRecordBWHMapper bwhMapper; private UserDataRecordBWHMapper bwhMapper;
@Autowired @Autowired
private UserDataRecordBmiMapper bmiMapper; private UserDataRecordBmiMapper bmiMapper;
@Autowired
private IMHelloApi imHelloApi;
@Lazy
@Autowired
private ISysBaseAPI sysBaseAPI;
private final GroupUserExportHandler groupUserExportHandler = new GroupUserExportHandler(); private final GroupUserExportHandler groupUserExportHandler = new GroupUserExportHandler();
@@ -1811,6 +1821,21 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
userModel.setId(loginUser.getId()); userModel.setId(loginUser.getId());
userModel.setAvatar(avatar); userModel.setAvatar(avatar);
redisStreamUtil.add(RedisStreamKeyEnum.UPDATE_USER_INFO, RedisConstant.REDIS_STREAM_KEY_FIELD, userModel); redisStreamUtil.add(RedisStreamKeyEnum.UPDATE_USER_INFO, RedisConstant.REDIS_STREAM_KEY_FIELD, userModel);
// 同步IM个人资料
syncImProfile(loginUser.getId());
}
private void syncImProfile(String userId) {
try {
List<LoginUserNew> users = sysBaseAPI.listUserByIds(new ListUser(Collections.singletonList(userId)));
if (CollUtil.isNotEmpty(users)) {
ConSessionRequestDO req = new ConSessionRequestDO();
req.setAccountList(Collections.singletonList(users.get(0)));
imHelloApi.accountReg(req);
}
} catch (Exception e) {
log.error("同步IM个人资料失败, userId: {}", userId, e);
}
} }
@Override @Override