19 changed files with 832 additions and 9 deletions
@ -0,0 +1,87 @@ |
|||
package com.acupuncture.web.controller.web; |
|||
|
|||
import com.acupuncture.common.constant.Constants; |
|||
import com.acupuncture.common.core.domain.AjaxResult; |
|||
import com.acupuncture.common.core.domain.entity.SysUser; |
|||
import com.acupuncture.common.core.domain.model.LoginBody; |
|||
import com.acupuncture.common.core.domain.model.LoginUser; |
|||
import com.acupuncture.common.utils.SecurityUtils; |
|||
import com.acupuncture.framework.web.service.SysPermissionService; |
|||
import com.acupuncture.framework.web.service.TokenService; |
|||
import com.acupuncture.framework.web.service.WebDmsLoginService; |
|||
import io.swagger.annotations.Api; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import javax.annotation.Resource; |
|||
import java.util.Set; |
|||
|
|||
/** |
|||
* @Author zzc |
|||
* @Package com.acupuncture.web.controller.web |
|||
* @Date 2025/2/10 10:44 |
|||
* @description: |
|||
*/ |
|||
@Slf4j |
|||
@Api(tags = "填报端登录") |
|||
@RestController |
|||
@RequestMapping("/web") |
|||
public class DmsLoginController { |
|||
|
|||
@Resource |
|||
private WebDmsLoginService webDmsLoginService; |
|||
@Resource |
|||
private SysPermissionService permissionService; |
|||
|
|||
@Resource |
|||
private TokenService tokenService; |
|||
|
|||
|
|||
/** |
|||
* 登录方法 |
|||
* |
|||
* @param loginBody 登录信息 |
|||
* @return 结果 |
|||
*/ |
|||
@PostMapping("/login") |
|||
public AjaxResult login(@RequestBody LoginBody loginBody) |
|||
{ |
|||
AjaxResult ajax = AjaxResult.success(); |
|||
// 生成令牌
|
|||
String token = webDmsLoginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), |
|||
loginBody.getUuid()); |
|||
ajax.put(Constants.TOKEN, token); |
|||
return ajax; |
|||
} |
|||
|
|||
/** |
|||
* 获取用户信息 |
|||
* |
|||
* @return 用户信息 |
|||
*/ |
|||
@GetMapping("getInfo") |
|||
public AjaxResult getInfo() |
|||
{ |
|||
LoginUser loginUser = SecurityUtils.getLoginUser(); |
|||
SysUser user = loginUser.getUser(); |
|||
// 角色集合
|
|||
Set<String> roles = permissionService.getRolePermission(user); |
|||
// 权限集合
|
|||
Set<String> permissions = permissionService.getMenuPermission(user); |
|||
if (!loginUser.getPermissions().equals(permissions)) |
|||
{ |
|||
loginUser.setPermissions(permissions); |
|||
tokenService.refreshToken(loginUser); |
|||
} |
|||
AjaxResult ajax = AjaxResult.success(); |
|||
ajax.put("user", user); |
|||
ajax.put("roles", roles); |
|||
ajax.put("permissions", permissions); |
|||
ajax.put("tenantId", loginUser.getTenantId()); |
|||
ajax.put("scoreId", loginUser.getScoreId()); |
|||
|
|||
return ajax; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,45 @@ |
|||
package com.acupuncture.framework.security.provider; |
|||
|
|||
import com.acupuncture.framework.security.token.DmsUserAuthenticationToken; |
|||
import com.acupuncture.framework.web.service.UserDetailsServiceImpl; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.security.authentication.AuthenticationProvider; |
|||
import org.springframework.security.core.Authentication; |
|||
import org.springframework.security.core.AuthenticationException; |
|||
import org.springframework.security.core.userdetails.UserDetails; |
|||
|
|||
import javax.annotation.Resource; |
|||
import java.util.Collections; |
|||
|
|||
/** |
|||
* @Author zzc |
|||
* @Package com.acupuncture.framework.security.provider |
|||
* @Date 2025/2/10 9:41 |
|||
* @description: |
|||
*/ |
|||
public class DmsUserAuthenticationProvider implements AuthenticationProvider { |
|||
/** |
|||
* 用户输入用户名密码,匹配主库dms_user租户用户表,根据dms_user表中tenant_id租户ID字段匹配dms_tenant租户表中的id, |
|||
* 如租户用户正常,且租户正常、数据源正常,则创建返回token,token中存用户信息、组织信息、数据源信息; 数据源找不到或错误,则异常 |
|||
*/ |
|||
|
|||
@Resource |
|||
private UserDetailsServiceImpl userDetailsService; |
|||
|
|||
@Override |
|||
public Authentication authenticate(Authentication authentication) throws AuthenticationException { |
|||
String username = (String) authentication.getPrincipal(); |
|||
String password = (String) authentication.getCredentials(); |
|||
//通过openId获取用户
|
|||
UserDetails userDetails = userDetailsService.loadDmsUserByUsername(username); |
|||
//返回用户信息
|
|||
DmsUserAuthenticationToken result = new DmsUserAuthenticationToken(userDetails, Collections.emptyList()); |
|||
result.setDetails(authentication.getDetails()); |
|||
return result; |
|||
} |
|||
|
|||
@Override |
|||
public boolean supports(Class<?> authentication) { |
|||
return (DmsUserAuthenticationToken.class.isAssignableFrom(authentication)); |
|||
} |
|||
} |
@ -0,0 +1,71 @@ |
|||
package com.acupuncture.framework.security.token; |
|||
|
|||
import org.springframework.security.authentication.AbstractAuthenticationToken; |
|||
import org.springframework.security.core.GrantedAuthority; |
|||
import org.springframework.security.core.SpringSecurityCoreVersion; |
|||
|
|||
import java.util.Collection; |
|||
|
|||
/** |
|||
* @author zhangsan |
|||
* @date 2022-08-11 21:15 |
|||
* @description TODO |
|||
*/ |
|||
public class DmsUserAuthenticationToken extends AbstractAuthenticationToken { |
|||
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; |
|||
|
|||
private final Object principal; |
|||
private String credentials; |
|||
|
|||
/** |
|||
* 准备登录时调用 |
|||
* 此构造函数用来初始化未授信凭据. |
|||
* |
|||
* @param principal |
|||
* @param credentials |
|||
*/ |
|||
public DmsUserAuthenticationToken(Object principal, String credentials) { |
|||
super(null); |
|||
this.principal = principal; |
|||
this.credentials = credentials; |
|||
setAuthenticated(false); |
|||
} |
|||
|
|||
/** |
|||
* 登录成功时调用 |
|||
* 此构函数用来初始化已授信凭据. |
|||
* @param principal |
|||
* @param authorities |
|||
*/ |
|||
public DmsUserAuthenticationToken(Object principal, Collection<? extends GrantedAuthority> authorities) { |
|||
super(authorities); |
|||
this.principal = principal; |
|||
this.credentials = null; |
|||
super.setAuthenticated(true); |
|||
} |
|||
|
|||
@Override |
|||
public Object getPrincipal() { |
|||
return principal; |
|||
} |
|||
|
|||
@Override |
|||
public Object getCredentials() { |
|||
return credentials; |
|||
} |
|||
|
|||
@Override |
|||
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { |
|||
if (isAuthenticated) { |
|||
throw new IllegalArgumentException( |
|||
"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); |
|||
} |
|||
super.setAuthenticated(false); |
|||
} |
|||
|
|||
@Override |
|||
public void eraseCredentials() { |
|||
super.eraseCredentials(); |
|||
credentials = null; |
|||
} |
|||
} |
@ -0,0 +1,227 @@ |
|||
package com.acupuncture.framework.web.service; |
|||
|
|||
import com.acupuncture.common.constant.CacheConstants; |
|||
import com.acupuncture.common.constant.Constants; |
|||
import com.acupuncture.common.constant.UserConstants; |
|||
import com.acupuncture.common.core.domain.entity.SysUser; |
|||
import com.acupuncture.common.core.domain.model.LoginUser; |
|||
import com.acupuncture.common.core.redis.RedisCache; |
|||
import com.acupuncture.common.exception.ServiceException; |
|||
import com.acupuncture.common.exception.user.*; |
|||
import com.acupuncture.common.utils.DateUtils; |
|||
import com.acupuncture.common.utils.MessageUtils; |
|||
import com.acupuncture.common.utils.StringUtils; |
|||
import com.acupuncture.common.utils.ip.IpUtils; |
|||
import com.acupuncture.framework.manager.AsyncManager; |
|||
import com.acupuncture.framework.manager.factory.AsyncFactory; |
|||
import com.acupuncture.framework.security.context.AuthenticationContextHolder; |
|||
import com.acupuncture.framework.security.token.DmsUserAuthenticationToken; |
|||
import com.acupuncture.system.service.ISysConfigService; |
|||
import com.acupuncture.system.service.ISysUserService; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.security.authentication.AuthenticationManager; |
|||
import org.springframework.security.authentication.BadCredentialsException; |
|||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
|||
import org.springframework.security.core.Authentication; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import javax.annotation.Resource; |
|||
|
|||
/** |
|||
* 登录校验方法 |
|||
* |
|||
* @author acupuncture |
|||
*/ |
|||
@Component |
|||
public class WebDmsLoginService |
|||
{ |
|||
@Autowired |
|||
private TokenService tokenService; |
|||
|
|||
@Resource |
|||
private AuthenticationManager authenticationManager; |
|||
|
|||
@Autowired |
|||
private RedisCache redisCache; |
|||
|
|||
@Autowired |
|||
private ISysUserService userService; |
|||
|
|||
@Autowired |
|||
private ISysConfigService configService; |
|||
|
|||
/** |
|||
* 登录验证 |
|||
* |
|||
* @param username 用户名 |
|||
* @param password 密码 |
|||
* @param code 验证码 |
|||
* @param uuid 唯一标识 |
|||
* @return 结果 |
|||
*/ |
|||
public String login(String username, String password, String code, String uuid) |
|||
{ |
|||
// 验证码校验
|
|||
// validateCaptcha(username, code, uuid);
|
|||
// 登录前置校验
|
|||
loginPreCheck(username, password); |
|||
// 用户验证
|
|||
Authentication authentication = null; |
|||
try |
|||
{ |
|||
DmsUserAuthenticationToken authenticationToken = new DmsUserAuthenticationToken(username, password); |
|||
AuthenticationContextHolder.setContext(authenticationToken); |
|||
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
|
|||
authentication = authenticationManager.authenticate(authenticationToken); |
|||
} |
|||
catch (Exception e) |
|||
{ |
|||
if (e instanceof BadCredentialsException) |
|||
{ |
|||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); |
|||
throw new UserPasswordNotMatchException(); |
|||
} |
|||
else |
|||
{ |
|||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage())); |
|||
throw new ServiceException(e.getMessage()); |
|||
} |
|||
} |
|||
finally |
|||
{ |
|||
AuthenticationContextHolder.clearContext(); |
|||
} |
|||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); |
|||
LoginUser loginUser = (LoginUser) authentication.getPrincipal(); |
|||
recordLoginInfo(loginUser.getUserId()); |
|||
// 生成token
|
|||
return tokenService.createToken(loginUser); |
|||
} |
|||
|
|||
/** |
|||
* 登录验证 |
|||
* |
|||
* @param username 用户名 |
|||
* @param password 密码 |
|||
* @param code 验证码 |
|||
* @param uuid 唯一标识 |
|||
* @return 结果 |
|||
*/ |
|||
public String dmsLogin(String username, String password, String code, String uuid) |
|||
{ |
|||
// 验证码校验
|
|||
validateCaptcha(username, code, uuid); |
|||
// 登录前置校验
|
|||
loginPreCheck(username, password); |
|||
// 用户验证
|
|||
Authentication authentication = null; |
|||
try |
|||
{ |
|||
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); |
|||
AuthenticationContextHolder.setContext(authenticationToken); |
|||
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
|
|||
authentication = authenticationManager.authenticate(authenticationToken); |
|||
} |
|||
catch (Exception e) |
|||
{ |
|||
if (e instanceof BadCredentialsException) |
|||
{ |
|||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); |
|||
throw new UserPasswordNotMatchException(); |
|||
} |
|||
else |
|||
{ |
|||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage())); |
|||
throw new ServiceException(e.getMessage()); |
|||
} |
|||
} |
|||
finally |
|||
{ |
|||
AuthenticationContextHolder.clearContext(); |
|||
} |
|||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); |
|||
LoginUser loginUser = (LoginUser) authentication.getPrincipal(); |
|||
recordLoginInfo(loginUser.getUserId()); |
|||
// 生成token
|
|||
return tokenService.createToken(loginUser); |
|||
} |
|||
|
|||
/** |
|||
* 校验验证码 |
|||
* |
|||
* @param username 用户名 |
|||
* @param code 验证码 |
|||
* @param uuid 唯一标识 |
|||
* @return 结果 |
|||
*/ |
|||
public void validateCaptcha(String username, String code, String uuid) |
|||
{ |
|||
boolean captchaEnabled = configService.selectCaptchaEnabled(); |
|||
if (captchaEnabled) |
|||
{ |
|||
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); |
|||
String captcha = redisCache.getCacheObject(verifyKey); |
|||
if (captcha == null) |
|||
{ |
|||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"))); |
|||
throw new CaptchaExpireException(); |
|||
} |
|||
redisCache.deleteObject(verifyKey); |
|||
if (!code.equalsIgnoreCase(captcha)) |
|||
{ |
|||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); |
|||
throw new CaptchaException(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 登录前置校验 |
|||
* @param username 用户名 |
|||
* @param password 用户密码 |
|||
*/ |
|||
public void loginPreCheck(String username, String password) |
|||
{ |
|||
// 用户名或密码为空 错误
|
|||
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) |
|||
{ |
|||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); |
|||
throw new UserNotExistsException(); |
|||
} |
|||
// 密码如果不在指定范围内 错误
|
|||
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH |
|||
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH) |
|||
{ |
|||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); |
|||
throw new UserPasswordNotMatchException(); |
|||
} |
|||
// 用户名不在指定范围内 错误
|
|||
if (username.length() < UserConstants.USERNAME_MIN_LENGTH |
|||
|| username.length() > UserConstants.USERNAME_MAX_LENGTH) |
|||
{ |
|||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); |
|||
throw new UserPasswordNotMatchException(); |
|||
} |
|||
// IP黑名单校验
|
|||
String blackStr = configService.selectConfigByKey("sys.login.blackIPList"); |
|||
if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) |
|||
{ |
|||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked"))); |
|||
throw new BlackListException(); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 记录登录信息 |
|||
* |
|||
* @param userId 用户ID |
|||
*/ |
|||
public void recordLoginInfo(Long userId) |
|||
{ |
|||
SysUser sysUser = new SysUser(); |
|||
sysUser.setUserId(userId); |
|||
sysUser.setLoginIp(IpUtils.getIpAddr()); |
|||
sysUser.setLoginDate(DateUtils.getNowDate()); |
|||
userService.updateUserProfile(sysUser); |
|||
} |
|||
} |
@ -0,0 +1,76 @@ |
|||
package com.acupuncture.system.domain.vo; |
|||
|
|||
import com.acupuncture.system.domain.po.DmsUser; |
|||
import com.acupuncture.system.domain.po.UmsDataSource; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Data; |
|||
|
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* @Author zzc |
|||
* @Package com.acupuncture.system.domain.vo |
|||
* @Date 2025/2/10 9:56 |
|||
* @description: |
|||
*/ |
|||
|
|||
public class DmsLoginUserVo { |
|||
|
|||
@Data |
|||
public static class DmsUserVo { |
|||
private Integer id; |
|||
|
|||
private Long tenantId; |
|||
|
|||
private String userName; |
|||
|
|||
private String password; |
|||
|
|||
private String nickName; |
|||
|
|||
private String email; |
|||
|
|||
private String phonenumber; |
|||
|
|||
private String sex; |
|||
|
|||
private String status; |
|||
} |
|||
|
|||
@Data |
|||
public static class DataScoreVo { |
|||
|
|||
@ApiModelProperty("") |
|||
private Long tenantId; |
|||
@ApiModelProperty("") |
|||
private Long dmsUserId; |
|||
@ApiModelProperty("") |
|||
private String dmsUsername; |
|||
@ApiModelProperty("") |
|||
private String dmsUserNickName; |
|||
@ApiModelProperty("") |
|||
private Long scoreId; |
|||
@ApiModelProperty("") |
|||
private String dataSourceKey; |
|||
@ApiModelProperty("") |
|||
private Long hospitalId; |
|||
@ApiModelProperty("") |
|||
private String url; |
|||
@ApiModelProperty("") |
|||
private String username; |
|||
@ApiModelProperty("") |
|||
private String password; |
|||
@ApiModelProperty("") |
|||
private String createBy; |
|||
@ApiModelProperty("") |
|||
private Date createTime; |
|||
@ApiModelProperty("") |
|||
private String updateBy; |
|||
@ApiModelProperty("") |
|||
private Date updateTime; |
|||
@ApiModelProperty("") |
|||
private String delFlag; |
|||
@ApiModelProperty("") |
|||
private String status; |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
package com.acupuncture.system.persist.dao; |
|||
|
|||
import com.acupuncture.common.annotation.DataSource; |
|||
import com.acupuncture.common.enums.DataSourceType; |
|||
import com.acupuncture.system.domain.vo.DmsLoginUserVo; |
|||
import org.apache.ibatis.annotations.Param; |
|||
|
|||
/** |
|||
* @Author zzc |
|||
* @Package com.acupuncture.system.persist.dao |
|||
* @Date 2025/2/10 9:48 |
|||
* @description: |
|||
*/ |
|||
public interface DmsUserDao { |
|||
|
|||
/** |
|||
* 通过用户名查询用户 |
|||
* |
|||
* @param userName 用户名 |
|||
* @return 用户对象信息 |
|||
*/ |
|||
@DataSource(DataSourceType.MASTER) |
|||
DmsLoginUserVo.DmsUserVo selectUserByUserName(@Param("userName") String userName); |
|||
|
|||
/** |
|||
* 根据用户名查询主库用户租户及数据源信息 |
|||
* @param userName |
|||
* @return |
|||
*/ |
|||
@DataSource(DataSourceType.MASTER) |
|||
DmsLoginUserVo.DataScoreVo queryLoginUserDataScore(@Param("userName") String userName); |
|||
|
|||
} |
@ -0,0 +1,22 @@ |
|||
package com.acupuncture.system.service; |
|||
|
|||
import com.acupuncture.common.core.domain.entity.SysUser; |
|||
import com.acupuncture.system.domain.po.DmsUser; |
|||
import com.acupuncture.system.domain.vo.DmsLoginUserVo; |
|||
|
|||
/** |
|||
* @Author zzc |
|||
* @Package com.acupuncture.system.service |
|||
* @Date 2025/2/10 9:29 |
|||
* @description: |
|||
*/ |
|||
public interface DmsLoginService { |
|||
|
|||
/** |
|||
* 通过用户名查询用户 |
|||
* |
|||
* @param userName 用户名 |
|||
* @return 用户对象信息 |
|||
*/ |
|||
public DmsLoginUserVo.DataScoreVo selectUserByUserName(String userName); |
|||
} |
@ -0,0 +1,27 @@ |
|||
package com.acupuncture.system.service.impl; |
|||
|
|||
import com.acupuncture.system.domain.po.DmsUser; |
|||
import com.acupuncture.system.domain.vo.DmsLoginUserVo; |
|||
import com.acupuncture.system.persist.dao.DmsUserDao; |
|||
import com.acupuncture.system.service.DmsLoginService; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import javax.annotation.Resource; |
|||
|
|||
/** |
|||
* @Author zzc |
|||
* @Package com.acupuncture.system.service |
|||
* @Date 2025/2/10 9:29 |
|||
* @description: |
|||
*/ |
|||
@Service |
|||
public class DmsLoginServiceImpl implements DmsLoginService { |
|||
|
|||
@Resource |
|||
private DmsUserDao dmsUserDao; |
|||
|
|||
@Override |
|||
public DmsLoginUserVo.DataScoreVo selectUserByUserName(String userName) { |
|||
return dmsUserDao.queryLoginUserDataScore(userName); |
|||
} |
|||
} |
@ -0,0 +1,53 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|||
<mapper namespace="com.acupuncture.system.persist.dao.DmsUserDao"> |
|||
|
|||
<select id="selectUserByUserName" resultType="com.acupuncture.system.domain.vo.DmsLoginUserVo$DmsUserVo"> |
|||
select |
|||
id, |
|||
tenant_id as tenantId, |
|||
user_name as userName, |
|||
password, |
|||
nick_name as nickName, |
|||
email, |
|||
phonenumber, |
|||
sex, |
|||
status |
|||
from |
|||
dms_user |
|||
where |
|||
user_name = #{userName} |
|||
</select> |
|||
|
|||
<select id="queryLoginUserDataScore" resultType="com.acupuncture.system.domain.vo.DmsLoginUserVo$DataScoreVo"> |
|||
select |
|||
d.id as dmsUserId, |
|||
d.user_name as dmsUsername, |
|||
d.nick_name as dmsUserNickName, |
|||
s.id as scoreId, |
|||
s.data_source_key as dataSourceKey, |
|||
s.hospital_id as hospitalId, |
|||
s.url, |
|||
s.username, |
|||
s.password, |
|||
t.id as tenantId, |
|||
d.del_flag as delFlag |
|||
from |
|||
dms_user d |
|||
left join |
|||
dms_tenant t |
|||
on |
|||
d.tenant_id = t.id |
|||
left join |
|||
ums_data_source s |
|||
on |
|||
d.tenant_id = t.id |
|||
<where> |
|||
<if test="userName != null and userName != ''"> |
|||
and d.user_name = #{userName} |
|||
</if> |
|||
and s.del_flag = 0 |
|||
and t.del_flag = 0 |
|||
</where> |
|||
</select> |
|||
</mapper> |
Loading…
Reference in new issue