diff --git a/.idea/MarsCodeWorkspaceAppSettings.xml b/.idea/MarsCodeWorkspaceAppSettings.xml new file mode 100644 index 0000000..b26fdc6 --- /dev/null +++ b/.idea/MarsCodeWorkspaceAppSettings.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/blood_bus/src/main/java/com/czblood/bus/mapper/XkTransfuseApplyBeforeMapper.java b/blood_bus/src/main/java/com/czblood/bus/mapper/XkTransfuseApplyBeforeMapper.java index f75cbf7..cac1b39 100644 --- a/blood_bus/src/main/java/com/czblood/bus/mapper/XkTransfuseApplyBeforeMapper.java +++ b/blood_bus/src/main/java/com/czblood/bus/mapper/XkTransfuseApplyBeforeMapper.java @@ -1,6 +1,7 @@ package com.czblood.bus.mapper; import com.czblood.bus.pojo.XkTransfuseApplyBefore; +import org.apache.ibatis.annotations.Param; import java.util.List; diff --git a/blood_bus/src/main/java/com/czblood/bus/pojo/XkPatientInfo.java b/blood_bus/src/main/java/com/czblood/bus/pojo/XkPatientInfo.java index b984a2e..642dad1 100644 --- a/blood_bus/src/main/java/com/czblood/bus/pojo/XkPatientInfo.java +++ b/blood_bus/src/main/java/com/czblood/bus/pojo/XkPatientInfo.java @@ -45,7 +45,7 @@ public class XkPatientInfo { private String gestation_history; @ApiModelProperty("分娩史") private String parturition_history; - @ApiModelProperty("配型史") + @ApiModelProperty("移植配型史") private String match_history; @ApiModelProperty("器官移植史") private String transplant_history; diff --git a/blood_bus/src/main/java/com/czblood/bus/system/BloodExtInterfaceService.java b/blood_bus/src/main/java/com/czblood/bus/system/BloodExtInterfaceService.java index 38d848e..ec07a82 100644 --- a/blood_bus/src/main/java/com/czblood/bus/system/BloodExtInterfaceService.java +++ b/blood_bus/src/main/java/com/czblood/bus/system/BloodExtInterfaceService.java @@ -38,6 +38,7 @@ public class BloodExtInterfaceService implements ExtSystemInterface { @Override public Result syncUser() { + //同步用户 XkOperatorInfo xkOperatorInfo = new XkOperatorInfo(); List xkOperatorInfoList = xkOperatorInfoMapper.queryList(xkOperatorInfo); int j = 0; @@ -56,7 +57,7 @@ public class BloodExtInterfaceService implements ExtSystemInterface { sysUser.setStatus("0"); sysUser.setCreateBy("admin"); sysUser.setVshisuser(operatorInfo.getVshiscode()); - sysUser.setYljg("602"); //以前老的输血系统没有医疗机构的概念,所以这里先给个之前的默认值 + sysUser.setHos_id("602"); //以前老的输血系统没有医疗机构的概念,所以这里先给个之前的默认值 sysUser.setDelFlag("0"); userMapper.insertUser(sysUser); j++; @@ -80,4 +81,12 @@ public class BloodExtInterfaceService implements ExtSystemInterface { xkHosInfo.setSfby("Y"); return xkHosInfoMapper.queryList(xkHosInfo); } + + /** + * 同步科室 + * @return + */ + public Result syncDept(){ + return null; + } } diff --git a/blood_bus/src/main/resources/mapper/XkPatientInfoMapper.xml b/blood_bus/src/main/resources/mapper/XkPatientInfoMapper.xml index b48e233..102d32a 100644 --- a/blood_bus/src/main/resources/mapper/XkPatientInfoMapper.xml +++ b/blood_bus/src/main/resources/mapper/XkPatientInfoMapper.xml @@ -6,10 +6,11 @@ select * from xk_patient_info and beinhos_id = #{beinhos_id} + and hos_id = #{hos_id} @@ -77,6 +78,6 @@ - delete from xk_patient_info where beinhos_id = #{beinhos_id} + delete from xk_patient_info where beinhos_id = #{beinhos_id} and hos_id = #{hos_id} \ No newline at end of file diff --git a/blood_bus/src/main/resources/mapper/XkTransfuseApplyBeforeMapper.xml b/blood_bus/src/main/resources/mapper/XkTransfuseApplyBeforeMapper.xml index 8fe935f..818df64 100644 --- a/blood_bus/src/main/resources/mapper/XkTransfuseApplyBeforeMapper.xml +++ b/blood_bus/src/main/resources/mapper/XkTransfuseApplyBeforeMapper.xml @@ -13,7 +13,7 @@ @@ -80,6 +80,7 @@ cruor = #{cruor}, bqgy = #{bqgy}, bill_status = #{bill_status}, + hos_id = #{hos_id}, bill_no = #{bill_no} where bill_no = #{bill_no} diff --git a/blood_bus/src/main/resources/mapper/XkTransfuseApplyMapper.xml b/blood_bus/src/main/resources/mapper/XkTransfuseApplyMapper.xml index 0a5a1ea..cc925d6 100644 --- a/blood_bus/src/main/resources/mapper/XkTransfuseApplyMapper.xml +++ b/blood_bus/src/main/resources/mapper/XkTransfuseApplyMapper.xml @@ -8,10 +8,11 @@ and bill_no = #{bill_no} and beinhos_id = #{beinhos_id} and assess_bill_no = #{assess_bill_no} + and hos_id = #{hos_id} \ No newline at end of file diff --git a/blood_bus_doctor/src/main/java/com/czblood/busDoctor/controller/TransfuseApplyController.java b/blood_bus_doctor/src/main/java/com/czblood/busDoctor/controller/TransfuseApplyController.java index 8ab9f78..b1114de 100644 --- a/blood_bus_doctor/src/main/java/com/czblood/busDoctor/controller/TransfuseApplyController.java +++ b/blood_bus_doctor/src/main/java/com/czblood/busDoctor/controller/TransfuseApplyController.java @@ -1,5 +1,6 @@ package com.czblood.busDoctor.controller; +import com.czblood.bus.pojo.XkTransfuseApply; import com.czblood.busDoctor.service.TransfuseApplyService; import com.czblood.common.core.domain.Result; import io.swagger.annotations.Api; @@ -27,8 +28,8 @@ public class TransfuseApplyController { @ApiOperation("查询申请单列表") @GetMapping("/queryList") - public Result queryList(){ - return null; + public Result queryList(XkTransfuseApply xkTransfuseApply){ + return transfuseApplyService.queryList(xkTransfuseApply); } diff --git a/blood_bus_doctor/src/main/java/com/czblood/busDoctor/service/TransfuseApplyService.java b/blood_bus_doctor/src/main/java/com/czblood/busDoctor/service/TransfuseApplyService.java index 7bf6f1e..df020d4 100644 --- a/blood_bus_doctor/src/main/java/com/czblood/busDoctor/service/TransfuseApplyService.java +++ b/blood_bus_doctor/src/main/java/com/czblood/busDoctor/service/TransfuseApplyService.java @@ -1,7 +1,10 @@ package com.czblood.busDoctor.service; +import com.czblood.bus.pojo.XkTransfuseApply; import com.czblood.common.core.domain.Result; public interface TransfuseApplyService { Result getPatInfo(String beinhosId); + + Result queryList(XkTransfuseApply xkTransfuseApply); } diff --git a/blood_bus_doctor/src/main/java/com/czblood/busDoctor/service/impl/TransfuseApplyServiceImpl.java b/blood_bus_doctor/src/main/java/com/czblood/busDoctor/service/impl/TransfuseApplyServiceImpl.java index 7e231b7..52b35f6 100644 --- a/blood_bus_doctor/src/main/java/com/czblood/busDoctor/service/impl/TransfuseApplyServiceImpl.java +++ b/blood_bus_doctor/src/main/java/com/czblood/busDoctor/service/impl/TransfuseApplyServiceImpl.java @@ -1,5 +1,6 @@ package com.czblood.busDoctor.service.impl; +import com.czblood.bus.pojo.XkTransfuseApply; import com.czblood.busDoctor.service.TransfuseApplyService; import com.czblood.common.core.domain.Result; import lombok.extern.slf4j.Slf4j; @@ -15,4 +16,9 @@ public class TransfuseApplyServiceImpl implements TransfuseApplyService { public Result getPatInfo(String beinhosId) { return null; } + + @Override + public Result queryList(XkTransfuseApply xkTransfuseApply) { + return null; + } } diff --git a/blood_common/src/main/java/com/czblood/common/config/mybatis/HosIdInjectingSqlSource.java b/blood_common/src/main/java/com/czblood/common/config/mybatis/HosIdInjectingSqlSource.java new file mode 100644 index 0000000..2e2e955 --- /dev/null +++ b/blood_common/src/main/java/com/czblood/common/config/mybatis/HosIdInjectingSqlSource.java @@ -0,0 +1,44 @@ +package com.czblood.common.config.mybatis; + +import com.czblood.common.utils.HosIdHolder; +import org.apache.ibatis.builder.StaticSqlSource; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.SqlSource; + +/** + * 包装 MyBatis 的 SqlSource,在每次 getBoundSql 时自动把 hos_id 注入 additionalParameters。 + * + * 原理:MyBatis 的 createCacheKey 和 ParameterHandler.setParameters 在读取参数时, + * 都会先检查 boundSql.hasAdditionalParameter(propertyName)。只要 hos_id 在 additionalParameters 中, + * 就不会去原始参数对象(如 ParamMap)中查找,从而绕过 ParamMap 的严格 key 检查。 + */ +public class HosIdInjectingSqlSource implements SqlSource { + + private static final String PARAM_NAME = "hos_id"; + private final SqlSource delegate; + + public HosIdInjectingSqlSource(SqlSource delegate) { + this.delegate = delegate; + } + + @Override + public BoundSql getBoundSql(Object parameterObject) { + // 1. 先让 MyBatis 正常生成 BoundSql + BoundSql boundSql = delegate.getBoundSql(parameterObject); + + // 2. 自动注入 hos_id 到 additionalParameters + String hosId = HosIdHolder.getHosId(); + if (hosId != null && !hosId.isEmpty() && !boundSql.hasAdditionalParameter(PARAM_NAME)) { + boundSql.setAdditionalParameter(PARAM_NAME, hosId); + } + + return boundSql; + } + + /** + * 获取被包装的原始 SqlSource(用于调试/去重)。 + */ + public SqlSource getDelegate() { + return delegate; + } +} \ No newline at end of file diff --git a/blood_common/src/main/java/com/czblood/common/config/mybatis/HosIdInterceptor.java b/blood_common/src/main/java/com/czblood/common/config/mybatis/HosIdInterceptor.java new file mode 100644 index 0000000..b85c03a --- /dev/null +++ b/blood_common/src/main/java/com/czblood/common/config/mybatis/HosIdInterceptor.java @@ -0,0 +1,114 @@ +package com.czblood.common.config.mybatis; + +import com.czblood.common.utils.HosIdHolder; +import org.apache.ibatis.cache.CacheKey; +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.executor.parameter.ParameterHandler; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlSource; +import org.apache.ibatis.plugin.*; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.reflection.SystemMetaObject; +import org.apache.ibatis.session.ResultHandler; +import org.apache.ibatis.session.RowBounds; + +import java.sql.PreparedStatement; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * 自动注入 hos_id 参数的 MyBatis 拦截器。 + * 在 Mapper XML 中直接写 #{hos_id} 即可,无需在方法参数中传入。 + * + * 获取 hos_id 的逻辑在 HosIdHolder.getHosId() 中维护。 + */ +@Intercepts({ + @Signature(type = Executor.class, method = "update", + args = {MappedStatement.class, Object.class}), + @Signature(type = Executor.class, method = "query", + args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}), + @Signature(type = Executor.class, method = "query", + args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, + CacheKey.class, BoundSql.class}) +}) +public class HosIdInterceptor implements Interceptor { + + private static final String PARAM_NAME = "hos_id"; + + @Override + public Object intercept(Invocation invocation) throws Throwable { + Object[] args = invocation.getArgs(); + MappedStatement ms = (MappedStatement) args[0]; + Object parameter = args[1]; + + String hosId = HosIdHolder.getHosId(); + if (hosId == null) { + // 取不到 hos_id,跳过注入 + return invocation.proceed(); + } + + Object newParameter = injectIntoParameter(parameter, hosId); + args[1] = newParameter; + + // 对于 6 参数的 query 重载(BoundSql 已存在),需要额外处理 additionalParameter + if (args.length == 6 && args[5] instanceof BoundSql) { + BoundSql boundSql = (BoundSql) args[5]; + // 向 BoundSql 中添加 hos_id,作为参数解析的后备 + boundSql.setAdditionalParameter(PARAM_NAME, hosId); + } + + return invocation.proceed(); + } + + /** + * 把 hos_id 注入到参数对象中。 + * + * 核心策略:无论参数是什么类型,都构建一个新的 HashMap 包装, + * 这样可以彻底避开 MyBatis ParamMap 的严格检查。 + */ + @SuppressWarnings("unchecked") + private Object injectIntoParameter(Object parameter, String hosId) { + Map newMap = new HashMap<>(); + + if (parameter == null) { + // 无参数 -> 只放 hos_id + newMap.put(PARAM_NAME, hosId); + return newMap; + } + + if (parameter instanceof Map) { + // 参数是 Map(包括 MyBatis 的 ParamMap)-> 复制全部条目 + hos_id + Map originalMap = (Map) parameter; + newMap.putAll(originalMap); + // 用户手动传的值优先(已存在则不覆盖) + newMap.putIfAbsent(PARAM_NAME, hosId); + return newMap; + } + + // 参数是 POJO -> 通过 MetaObject 读取所有可读字段 + hos_id + MetaObject metaObject = SystemMetaObject.forObject(parameter); + for (String name : metaObject.getGetterNames()) { + if ("class".equals(name)) continue; + try { + newMap.put(name, metaObject.getValue(name)); + } catch (Exception ignored) { + // 某些 getter 可能不可读,跳过即可 + } + } + newMap.putIfAbsent(PARAM_NAME, hosId); + // 同时把原 POJO 也放进去,作为 fallback + newMap.put("_pojo", parameter); + return newMap; + } + + @Override + public Object plugin(Object target) { + return Plugin.wrap(target, this); + } + + @Override + public void setProperties(Properties properties) { + } +} \ No newline at end of file diff --git a/blood_common/src/main/java/com/czblood/common/core/domain/entity/SysUser.java b/blood_common/src/main/java/com/czblood/common/core/domain/entity/SysUser.java index 660034d..99a15d5 100644 --- a/blood_common/src/main/java/com/czblood/common/core/domain/entity/SysUser.java +++ b/blood_common/src/main/java/com/czblood/common/core/domain/entity/SysUser.java @@ -101,7 +101,7 @@ public class SysUser extends BaseEntity private String vshisuser; private String vshisuser1; private String vshisuser2; - private String yljg; + private String hos_id; private String sn; private String snid; private String signCert; @@ -140,14 +140,6 @@ public class SysUser extends BaseEntity this.vshisuser2 = vshisuser2; } - public String getYljg() { - return yljg; - } - - public void setYljg(String yljg) { - this.yljg = yljg; - } - public String getSn() { return sn; } @@ -185,6 +177,14 @@ public class SysUser extends BaseEntity } + public String getHos_id() { + return hos_id; + } + + public void setHos_id(String hos_id) { + this.hos_id = hos_id; + } + public SysUser(Long userId) { this.userId = userId; @@ -413,7 +413,7 @@ public class SysUser extends BaseEntity .append("vshisuser",getVshisuser()) .append("vshisuser1",getVshisuser1()) .append("vshisuser2",getVshisuser1()) - .append("yljg",getYljg()) + .append("hos_id",getHos_id()) .append("sn",getSn()) .append("snid",getSnid()) .append("signCert",getSignCert()) diff --git a/blood_common/src/main/java/com/czblood/common/utils/HosIdHolder.java b/blood_common/src/main/java/com/czblood/common/utils/HosIdHolder.java new file mode 100644 index 0000000..a348222 --- /dev/null +++ b/blood_common/src/main/java/com/czblood/common/utils/HosIdHolder.java @@ -0,0 +1,73 @@ +package com.czblood.common.utils; + +import com.czblood.common.core.domain.entity.SysLoginParam; +import com.czblood.common.core.domain.model.LoginUser; + +import javax.servlet.http.HttpServletRequest; + +/** + * 持有当前请求的 hos_id + *

+ * 获取优先级: + * 1. 手动通过 {@link #setHosId(String)} 放入 ThreadLocal 的值 + * 2. HTTP 请求 header 中的 "hos_id" + * 3. 当前登录用户 sysLoginParam 中的 loginYLJG + *

+ */ +public class HosIdHolder { + + private static final ThreadLocal HOS_ID_HOLDER = new ThreadLocal<>(); + + /** + * 获取当前 hos_id + */ + public static String getHosId() { + // 1. 优先取手动设置的值 + String hosId = HOS_ID_HOLDER.get(); + if (hosId != null && !hosId.isEmpty()) { + return hosId; + } + + // 2. 从 HTTP 请求 header 中取 + try { + HttpServletRequest request = ServletUtils.getRequest(); + if (request != null) { + String headerHosId = request.getHeader("hos_id"); + if (headerHosId != null && !headerHosId.isEmpty()) { + return headerHosId; + } + // 兼容可能的其他命名,比如 X-Hos-Id + String headerHosId2 = request.getHeader("x-hos-id"); + if (headerHosId2 != null && !headerHosId2.isEmpty()) { + return headerHosId2; + } + } + } catch (Exception ignored) { + // 非 web 环境(如定时任务、MQ 消费等)拿不到 request,忽略即可 + } + + // 3. 从登录用户的 sysLoginParam.loginYLJG 取 + try { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser != null) { + SysLoginParam loginParam = loginUser.getSysLoginParam(); + if (loginParam != null && loginParam.getLoginYLJG() != null + && !loginParam.getLoginYLJG().isEmpty()) { + return loginParam.getLoginYLJG(); + } + } + } catch (Exception ignored) { + // 未登录或获取失败,返回 null 即可(拦截器中为 null 时不注入) + } + + return null; + } + + public static void setHosId(String hosId) { + HOS_ID_HOLDER.set(hosId); + } + + public static void clear() { + HOS_ID_HOLDER.remove(); + } +} \ No newline at end of file diff --git a/blood_system/src/main/java/com/czblood/system/config/MyBatisConfig.java b/blood_system/src/main/java/com/czblood/system/config/MyBatisConfig.java index c013fee..7c55164 100644 --- a/blood_system/src/main/java/com/czblood/system/config/MyBatisConfig.java +++ b/blood_system/src/main/java/com/czblood/system/config/MyBatisConfig.java @@ -1,7 +1,10 @@ package com.czblood.system.config; +import com.czblood.common.config.mybatis.HosIdInjectingSqlSource; import com.czblood.common.utils.StringUtils; import org.apache.ibatis.io.VFS; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.boot.autoconfigure.SpringBootVFS; @@ -20,10 +23,8 @@ import org.springframework.util.ClassUtils; import javax.sql.DataSource; import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; +import java.lang.reflect.Field; +import java.util.*; /** * Mybatis支持*匹配扫描包 @@ -105,6 +106,44 @@ public class MyBatisConfig { sessionFactory.setTypeAliasesPackage(typeAliasesPackage); sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ","))); sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation)); - return sessionFactory.getObject(); + + SqlSessionFactory sqlSessionFactory = sessionFactory.getObject(); + + // ↓↓↓ 核心:把所有 MappedStatement 的 SqlSource 包一层,自动注入 hos_id + injectHosIdSqlSource(sqlSessionFactory); + + return sqlSessionFactory; + } + + /** + * 遍历 Configuration 中所有 MappedStatement,用 HosIdInjectingSqlSource 包装其 sqlSource。 + * 通过反射修改 MappedStatement 私有字段 sqlSource。 + */ + private void injectHosIdSqlSource(SqlSessionFactory sqlSessionFactory) { + try { + org.apache.ibatis.session.Configuration configuration = sqlSessionFactory.getConfiguration(); + + // 反射获取 MappedStatement.sqlSource 字段 + Field sqlSourceField = MappedStatement.class.getDeclaredField("sqlSource"); + sqlSourceField.setAccessible(true); + + // 注意:getMappedStatements() 返回的 Collection 里不全是 MappedStatement, + // 还可能包含 StrictMap.Ambiguity(MyBatis 内部用来标记 statement id 有歧义的对象), + // 必须用 Object 接收并做 instanceof 判断。 + Collection statements = configuration.getMappedStatements(); + for (Object obj : statements) { + if (!(obj instanceof MappedStatement)) continue; // 跳过 StrictMap.Ambiguity + MappedStatement ms = (MappedStatement) obj; + + SqlSource original = ms.getSqlSource(); + if (original == null) continue; + if (original instanceof HosIdInjectingSqlSource) continue; // 避免重复包装 + + sqlSourceField.set(ms, new HosIdInjectingSqlSource(original)); + } + } catch (Exception e) { + System.err.println("[HosId] 自动注入 hos_id 失败: " + e.getMessage()); + e.printStackTrace(); + } } } \ No newline at end of file diff --git a/blood_system/src/main/java/com/czblood/system/web/service/SysLoginService.java b/blood_system/src/main/java/com/czblood/system/web/service/SysLoginService.java index e63ba65..89dab68 100644 --- a/blood_system/src/main/java/com/czblood/system/web/service/SysLoginService.java +++ b/blood_system/src/main/java/com/czblood/system/web/service/SysLoginService.java @@ -231,7 +231,7 @@ public class SysLoginService { //判断用户名是否在登录的医疗机构中 SysUser sysUser1 = new SysUser(); sysUser1.setUserName(username); - sysUser1.setYljg(loginParam.getLoginYLJG()); + sysUser1.setHos_id(loginParam.getLoginYLJG()); SysUser sysUser = userService.queryUserList(sysUser1); //管理员不判断 diff --git a/blood_system/src/main/resources/mapper/system/SysUserCommMapper.xml b/blood_system/src/main/resources/mapper/system/SysUserCommMapper.xml index 5d5fd0e..152164f 100644 --- a/blood_system/src/main/resources/mapper/system/SysUserCommMapper.xml +++ b/blood_system/src/main/resources/mapper/system/SysUserCommMapper.xml @@ -25,7 +25,7 @@ - + diff --git a/blood_system/src/main/resources/mapper/system/SysUserMapper.xml b/blood_system/src/main/resources/mapper/system/SysUserMapper.xml index 6b21855..c13f141 100644 --- a/blood_system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/blood_system/src/main/resources/mapper/system/SysUserMapper.xml @@ -26,7 +26,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + @@ -55,7 +55,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, - u.yljg, + u.hos_id, d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status, r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status from sys_user u @@ -141,7 +141,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"