登录接口和同步接口修改

This commit is contained in:
jiangs 2026-06-17 17:49:03 +08:00
parent 8031411716
commit 39fd22454d
19 changed files with 343 additions and 34 deletions

7
.idea/MarsCodeWorkspaceAppSettings.xml generated Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="com.codeverse.userSettings.MarscodeWorkspaceAppSettingsState">
<option name="chatAppRouterInfo" value="chat-session" />
<option name="progress" value="1.0" />
</component>
</project>

View File

@ -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;

View File

@ -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;

View File

@ -38,6 +38,7 @@ public class BloodExtInterfaceService implements ExtSystemInterface {
@Override
public Result syncUser() {
//同步用户
XkOperatorInfo xkOperatorInfo = new XkOperatorInfo();
List<XkOperatorInfo> 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;
}
}

View File

@ -6,10 +6,11 @@
select * from xk_patient_info
<where>
<if test="beinhos_id != null and beinhos_id != ''">and beinhos_id = #{beinhos_id}</if>
<if test="hos_id != null and hos_id != ''">and hos_id = #{hos_id}</if>
</where>
</select>
<select id="queryOne" resultType="com.czblood.bus.pojo.XkPatientInfo">
select * from xk_patient_info where beinhos_id = #{beinhos_id}
select * from xk_patient_info where beinhos_id = #{beinhos_id} and hos_id = #{hos_id}
</select>
<insert id="insertXkPatientInfo">
@ -77,6 +78,6 @@
<delete id="deleteXkPatientInfo">
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}
</delete>
</mapper>

View File

@ -13,7 +13,7 @@
<select id="queryOne" resultType="com.czblood.bus.pojo.XkTransfuseApplyBefore">
select * from xk_transfuse_apply_before where bill_no = #{bill_no}
select * from xk_transfuse_apply_before where bill_no = #{bill_no} and hos_id = #{hos_id}
</select>
<insert id="insertXkTransfuseApplyBefore">
@ -80,6 +80,7 @@
<if test="cruor != null and cruor != ''">cruor = #{cruor},</if>
<if test="bqgy != null and bqgy != ''">bqgy = #{bqgy},</if>
<if test="bill_status != null and bill_status != ''">bill_status = #{bill_status},</if>
<if test="hos_id != null and hos_id != ''">hos_id = #{hos_id},</if>
bill_no = #{bill_no}
</set>
where bill_no = #{bill_no}

View File

@ -8,10 +8,11 @@
<if test="bill_no != null and bill_no != ''">and bill_no = #{bill_no}</if>
<if test="beinhos_id != null and beinhos_id != ''">and beinhos_id = #{beinhos_id}</if>
<if test="assess_bill_no != null and assess_bill_no != ''">and assess_bill_no = #{assess_bill_no}</if>
<if test="hos_id != null and hos_id != ''">and hos_id = #{hos_id}</if>
</where>
</select>
<select id="queryOne" resultType="com.czblood.bus.pojo.XkTransfuseApply">
select * from xk_transfuse_apply where bill_no = #{bill_no}
select * from xk_transfuse_apply where bill_no = #{bill_no} and hos_id = #{hos_id}
</select>
</mapper>

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<String, Object> 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<String, Object> originalMap = (Map<String, Object>) 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) {
}
}

View File

@ -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())

View File

@ -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
* <p>
* 获取优先级:
* 1. 手动通过 {@link #setHosId(String)} 放入 ThreadLocal 的值
* 2. HTTP 请求 header 中的 "hos_id"
* 3. 当前登录用户 sysLoginParam 中的 loginYLJG
* </p>
*/
public class HosIdHolder {
private static final ThreadLocal<String> 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();
}
}

View File

@ -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();
}
}
}

View File

@ -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);
//管理员不判断

View File

@ -25,7 +25,7 @@
<result property="vshisuser" column="vshisuser" />
<result property="vshisuser1" column="vshisuser1" />
<result property="vshisuser2" column="vshisuser2" />
<result property="yljg" column="yljg" />
<result property="hos_id" column="hos_id" />
<result property="sn" column="sn" />
<result property="snid" column="snid" />
<result property="signCert" column="signCert" />

View File

@ -26,7 +26,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="vshisuser" column="vshisuser" />
<result property="vshisuser1" column="vshisuser1" />
<result property="vshisuser2" column="vshisuser2" />
<result property="yljg" column="yljg" />
<result property="hos_id" column="hos_id" />
<result property="sn" column="sn" />
<result property="snid" column="snid" />
<result property="signCert" column="signCert" />
@ -55,7 +55,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<sql id="selectUserVo">
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"
<select id="queryUserList" resultMap="SysUserResult">
select * from sys_user where del_flag = '0'
<if test="userName != null and userName != ''">and user_name = #{userName}</if>
<if test="yljg != null and yljg != ''">and yljg = #{yljg}</if>
<if test="hos_id != null and hos_id != ''">and hos_id = #{hos_id}</if>
</select>
<select id="checkUserNameUnique" parameterType="String" resultMap="SysUserResult">
@ -169,7 +169,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="status != null and status != ''">status,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
<if test="remark != null and remark != ''">remark,</if>
<if test="yljg != null and yljg != ''">yljg,</if>
<if test="hos_id != null and hos_id != ''">hos_id,</if>
create_time
)values(
<if test="deptId != null and deptId != ''">#{deptId},</if>
@ -183,7 +183,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="status != null and status != ''">#{status},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="remark != null and remark != ''">#{remark},</if>
<if test="yljg != null and yljg != ''">#{yljg},</if>
<if test="hos_id != null and hos_id != ''">#{hos_id},</if>
getdate()
)
</insert>
@ -203,7 +203,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="loginDate != null">login_date = #{loginDate},</if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="yljg != null and yljg != ''">yljg = #{yljg},</if>
<if test="hos_id != null and hos_id != ''">hos_id = #{hos_id},</if>
update_time = getdate()
</set>
where user_id = #{userId}

View File

@ -24,10 +24,12 @@ if not exists(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'xk_c
end
go
if not exists(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'sys_user' AND COLUMN_NAME = 'yljg')
if not exists(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'sys_user' AND COLUMN_NAME = 'hos_id')
begin
alter table sys_user add yljg varchar(10);
update sys_user set yljg = '602' where user_name = 'admin'
alter table sys_user add hos_id varchar(10);
end
begin
update sys_user set hos_id = '602' where user_name = 'admin'
end
go
@ -339,4 +341,11 @@ IF NOT EXISTS (SELECT 1 FROM sys.key_constraints WHERE name = 'PK_xk_hos_info' A
BEGIN
ALTER TABLE xk_hos_info ADD CONSTRAINT PK_xk_hos_info PRIMARY KEY CLUSTERED (hospital_code);
END
GO
IF NOT EXISTS (SELECT 1 FROM sys.key_constraints WHERE name = 'UQ_sys_user_user_name' AND type = 'UQ')
BEGIN
ALTER TABLE sys_user ADD CONSTRAINT UQ_sys_user_user_name UNIQUE(user_name);
END
GO