Commit 3f92b2eb authored by gaozhaochen's avatar gaozhaochen

add: 科室信息查询接口

parent 98449130
package cn.sh.stc.sict.cloud.auth.endpoint;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.sh.stc.sict.cloud.common.core.constant.Constant;
import cn.sh.stc.sict.cloud.common.core.constant.PaginationConstants;
import cn.sh.stc.sict.cloud.common.core.constant.RedisCacheConstant;
import cn.sh.stc.sict.cloud.common.core.constant.SecurityConstants;
import cn.sh.stc.sict.cloud.common.core.util.R;
import cn.sh.stc.sict.cloud.common.security.annotation.Inner;
import cn.sh.stc.sict.cloud.common.security.service.SictUser;
import cn.sh.stc.sict.cloud.common.security.util.SysLogUtils;
import cn.sh.stc.sict.cloud.upms.feign.RemoteLogService;
import cn.sh.stc.sict.cloud.upms.model.SysLog;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cn.sh.stc.sict.cloud.common.security.annotation.Inner;
import cn.sh.stc.sict.cloud.common.security.service.SictUser;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
......@@ -45,125 +46,143 @@ import java.util.Map;
@AllArgsConstructor
@RequestMapping("/token")
public class SictTokenEndpoint {
private static final String SICT_OAUTH_ACCESS = SecurityConstants.SICT_PREFIX + SecurityConstants.OAUTH_PREFIX + "auth_to_access:";
private static final String SICT_ACCESS = SecurityConstants.SICT_PREFIX + SecurityConstants.OAUTH_PREFIX + "access:";
private final TokenStore tokenStore;
private final RedisTemplate redisTemplate;
private final CacheManager cacheManager;
private final RemoteLogService remoteLogService;
/**
* 认证页面
*
* @return ModelAndView
*/
@GetMapping("/login")
public ModelAndView require() {
return new ModelAndView("ftl/login");
}
/**
* 退出token
*
* @param authHeader Authorization
*/
@DeleteMapping("/logout")
public R logout(HttpServletRequest request,
@RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authHeader) {
if (StrUtil.isBlank(authHeader)) {
return R.builder()
.code(Constant.BYTE_NO)
.data(Boolean.FALSE)
.msg("退出失败,token 为空").build();
}
String tokenValue = authHeader.replaceAll("(?i)Bearer", "").trim();
OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
if (accessToken == null || StrUtil.isBlank(accessToken.getValue())) {
return new R();
}
OAuth2Authentication auth2Authentication = tokenStore.readAuthentication(accessToken);
String username = auth2Authentication.getName();
SictUser user = (SictUser) cacheManager.getCache(RedisCacheConstant.USER_DETAILS).get(username).get();
cacheManager.getCache(RedisCacheConstant.USER_DETAILS)
.evict(username);
tokenStore.removeAccessToken(accessToken);
SysLog sysLog = SysLogUtils.getSysLog(request, username);
sysLog.setTitle(username + "-用户登出");
sysLog.setParams(user.getName());
sysLog.setServiceId(auth2Authentication.getOAuth2Request().getClientId());
// 保存退出的token
String token = request.getHeader(HttpHeaders.AUTHORIZATION);
sysLog.setParams(token);
remoteLogService.saveLog(sysLog, SecurityConstants.FROM_IN);
log.info("用户:{} 退出成功, token:{} 已注销", username, token);
return new R<>(Boolean.TRUE);
}
/**
* 令牌管理调用
*
* @param token token
* @return
*/
@Inner
@DeleteMapping("/{token}")
public R<Boolean> delToken(@PathVariable("token") String token) {
OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token);
tokenStore.removeAccessToken(oAuth2AccessToken);
return new R<>();
}
/**
* 查询token
*
* @param params 分页参数
* @return
*/
@Inner
@PostMapping("/page")
public R<Page> tokenList(@RequestBody Map<String, Object> params) {
//根据分页参数获取对应数据
String key = String.format("%s", SICT_OAUTH_ACCESS);
List<String> pages = findKeysForPage(key, MapUtil.getInt(params, PaginationConstants.CURRENT)
, MapUtil.getInt(params, PaginationConstants.SIZE));
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
Page result = new Page(MapUtil.getInt(params, PaginationConstants.CURRENT), MapUtil.getInt(params, PaginationConstants.SIZE));
result.setRecords(redisTemplate.opsForValue().multiGet(pages));
result.setTotal(Long.valueOf(redisTemplate.keys(key).size()));
return new R<>(result);
}
private List<String> findKeysForPage(String patternKey, int pageNum, int pageSize) {
ScanOptions options = ScanOptions.scanOptions().match(patternKey).build();
RedisSerializer<String> redisSerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
Cursor cursor = (Cursor) redisTemplate.executeWithStickyConnection(redisConnection -> new ConvertingCursor<>(redisConnection.scan(options), redisSerializer::deserialize));
List<String> result = new ArrayList<>();
int tmpIndex = 0;
int startIndex = (pageNum - 1) * pageSize;
int end = pageNum * pageSize;
assert cursor != null;
while (cursor.hasNext()) {
if (tmpIndex >= startIndex && tmpIndex < end) {
result.add(cursor.next().toString());
tmpIndex++;
continue;
}
if (tmpIndex >= end) {
break;
}
tmpIndex++;
cursor.next();
}
return result;
}
private static final String SICT_OAUTH_ACCESS = SecurityConstants.SICT_PREFIX + SecurityConstants.OAUTH_PREFIX + "auth_to_access:";
private static final String SICT_ACCESS = SecurityConstants.SICT_PREFIX + SecurityConstants.OAUTH_PREFIX + "access:";
private final TokenStore tokenStore;
private final RedisTemplate redisTemplate;
private final CacheManager cacheManager;
private final RemoteLogService remoteLogService;
/**
* 认证页面
*
* @return ModelAndView
*/
@GetMapping("/login")
public ModelAndView require() {
return new ModelAndView("ftl/login");
}
/**
* 退出token
*
* @param authHeader Authorization
*/
@DeleteMapping("/logout")
public R logout(HttpServletRequest request,
@RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authHeader) {
if (StrUtil.isBlank(authHeader)) {
return R.builder()
.code(Constant.BYTE_NO)
.data(Boolean.FALSE)
.msg("退出失败,token 为空").build();
}
String tokenValue = authHeader.replaceAll("(?i)Bearer", "").trim();
OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
if (accessToken == null || StrUtil.isBlank(accessToken.getValue())) {
return new R();
}
OAuth2Authentication auth2Authentication = tokenStore.readAuthentication(accessToken);
String username = auth2Authentication.getName();
SictUser user = (SictUser) cacheManager.getCache(RedisCacheConstant.USER_DETAILS).get(username).get();
cacheManager.getCache(RedisCacheConstant.USER_DETAILS)
.evict(username);
tokenStore.removeAccessToken(accessToken);
SysLog sysLog = SysLogUtils.getSysLog(request, username);
sysLog.setTitle(username + "-用户登出");
sysLog.setParams(user.getName());
sysLog.setServiceId(auth2Authentication.getOAuth2Request().getClientId());
// 保存退出的token
String token = request.getHeader(HttpHeaders.AUTHORIZATION);
sysLog.setParams(token);
remoteLogService.saveLog(sysLog, SecurityConstants.FROM_IN);
log.info("用户:{} 退出成功, token:{} 已注销", username, token);
return new R<>(Boolean.TRUE);
}
/**
* 令牌管理调用
*
* @param token token
* @return
*/
@Inner
@DeleteMapping("/{token}")
public R<Boolean> delToken(@PathVariable("token") String token) {
OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token);
tokenStore.removeAccessToken(oAuth2AccessToken);
return new R<>();
}
/**
* 令牌管理调用
*
* @param token token
* @return
*/
@GetMapping("/check/{token}")
public R<Boolean> isValid(@PathVariable("token") String token) {
String tokenValue = token.replaceAll("(?i)Bearer", "").trim();
OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
if (accessToken == null || StrUtil.isBlank(accessToken.getValue())) {
return new R(false);
}
OAuth2Authentication auth2Authentication = tokenStore.readAuthentication(accessToken);
return new R<>(auth2Authentication.isAuthenticated());
}
/**
* 查询token
*
* @param params 分页参数
* @return
*/
@Inner
@PostMapping("/page")
public R<Page> tokenList(@RequestBody Map<String, Object> params) {
//根据分页参数获取对应数据
String key = String.format("%s", SICT_OAUTH_ACCESS);
List<String> pages = findKeysForPage(key, MapUtil.getInt(params, PaginationConstants.CURRENT)
, MapUtil.getInt(params, PaginationConstants.SIZE));
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
Page result = new Page(MapUtil.getInt(params, PaginationConstants.CURRENT), MapUtil.getInt(params, PaginationConstants.SIZE));
result.setRecords(redisTemplate.opsForValue().multiGet(pages));
result.setTotal(Long.valueOf(redisTemplate.keys(key).size()));
return new R<>(result);
}
private List<String> findKeysForPage(String patternKey, int pageNum, int pageSize) {
ScanOptions options = ScanOptions.scanOptions().match(patternKey).build();
RedisSerializer<String> redisSerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
Cursor cursor = (Cursor) redisTemplate.executeWithStickyConnection(redisConnection -> new ConvertingCursor<>(redisConnection.scan(options), redisSerializer::deserialize));
List<String> result = new ArrayList<>();
int tmpIndex = 0;
int startIndex = (pageNum - 1) * pageSize;
int end = pageNum * pageSize;
assert cursor != null;
while (cursor.hasNext()) {
if (tmpIndex >= startIndex && tmpIndex < end) {
result.add(cursor.next().toString());
tmpIndex++;
continue;
}
if (tmpIndex >= end) {
break;
}
tmpIndex++;
cursor.next();
}
return result;
}
}
......@@ -11,4 +11,6 @@ public interface ServiceNameConstants {
* 认证中心
*/
String UPMS_SERVICE = "cloud-upms-biz";
String AUTH_SERVICE = "cloud-auth";
}
package cn.sh.stc.sict.cloud.common.gateway.feign;
import cn.sh.stc.sict.cloud.common.core.constant.ServiceNameConstants;
import cn.sh.stc.sict.cloud.common.core.util.R;
import cn.sh.stc.sict.cloud.common.gateway.feign.fallback.RemoteAuthFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @Description
* @Author
* @Date
*/
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.AUTH_SERVICE, fallbackFactory = RemoteAuthFallback.class)
//@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.AUTH_SERVICE)
@Service
public interface RemoteAuthService {
/**
* 通过用户名或手机号查询用户
*
* @param username 用户名
* @param from 调用标志
* @return R
*/
@GetMapping("/token/check/{token}")
R<Boolean> isValid(@PathVariable("token") String token);
}
package cn.sh.stc.sict.cloud.common.gateway.feign.fallback;
import cn.sh.stc.sict.cloud.common.core.util.R;
import cn.sh.stc.sict.cloud.common.gateway.feign.RemoteAuthService;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author gao
* @date 2023/09/04 09:51
*/
@Component
@Slf4j
public class RemoteAuthFallback implements FallbackFactory<RemoteAuthService> {
@Override
public RemoteAuthService create(Throwable throwable) {
return new RemoteAuthService() {
@Override
public R<Boolean> isValid(String toke) {
log.info("远程调用失败:权限校验错误");
return null;
}
};
}
}
package cn.sh.stc.sict.cloud.common.gateway.filter;
import cn.hutool.core.util.ObjectUtil;
import cn.sh.stc.sict.cloud.common.core.util.R;
import cn.sh.stc.sict.cloud.common.gateway.feign.RemoteAuthService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
/**
* @author gao
* @date 2023/08/30 10:23
*/
@Slf4j
@Component
@AllArgsConstructor
public class GptServerFilter extends AbstractGatewayFilterFactory {
public final RemoteAuthService remoteAuthService;
public static final String SEC_WEBSOCKET_PROTOCOL = "Sec-WebSocket-Protocol";
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
String token = request.getHeaders().getFirst(SEC_WEBSOCKET_PROTOCOL);
log.info("ws-token{}", token);
// 权限校验
if (checkToken(token)) {
return chain.filter(exchange);
} else {
return Mono.error(new RuntimeException("权限校验失败"));
}
};
}
/**
* 校验token
*
* @param token
* @return
*/
private boolean checkToken(String token) {
// if (StringUtils.isEmpty(token)) {
// return false;
// }
return true;
// R<Boolean> valid = remoteAuthService.isValid(token);
// if (ObjectUtil.isNull(valid) || ObjectUtil.isNull(valid.getData())) {
// return false;
// }
// return valid.getData();
}
}
......@@ -3,6 +3,7 @@ package cn.sh.stc.sict.cloud.gateway;
import cn.sh.stc.sict.cloud.common.dynamic.gateway.annotation.EnableDynamicRoute;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @Description
......@@ -11,6 +12,7 @@ import org.springframework.cloud.client.SpringCloudApplication;
*/
@EnableDynamicRoute
@SpringCloudApplication
@EnableFeignClients(basePackages = {"cn.sh.stc.sict.cloud.common.gateway.feign"})
public class SictGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(SictGatewayApplication.class, args);
......
......@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* 黄浦全科导诊——科室排名(HpgpDepartmentRank)表数据库访问层
......@@ -25,4 +26,6 @@ public interface HpgpDepartmentRankMapper extends BaseMapper<HpgpDepartmentRank>
List<DeptRankVO> getRankByHosAndStandardDept(@Param("hospitalCode") String hospitalCode,
@Param("deptName") String deptName,
@Param("size") int size);
List<Map<String,List<Map<String,String>>>> getStandardDeptDic(@Param("hospitalCode") String hospitalCode);
}
......@@ -17,6 +17,9 @@ import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
public class HpgpDepartmentRank extends Model<HpgpDepartmentRank> {
private Integer id;
@ApiModelProperty(hidden = false, value = "标准科室所属分类")
private String standardDeptCategory;
//标准科室
@ApiModelProperty(hidden = false, value = "标准科室")
private String standardDept;
......
package cn.sh.stc.sict.theme.hpgp.service;
import com.baomidou.mybatisplus.extension.service.IService;
import cn.sh.stc.sict.theme.hpgp.model.HpgpDepartmentRank;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Map;
/**
* 黄浦全科导诊——科室排名(HpgpDepartmentRank)表服务接口
......@@ -18,4 +19,12 @@ public interface HpgpDepartmentRankService extends IService<HpgpDepartmentRank>
HpgpDepartmentRank getByCode(String hospCode, String oneDeptCode, String deptCode);
List<HpgpDepartmentRank> listHotDept();
/**
* 医院标准科室字典
*
* @param hospitalCode 医院编码
* @return
*/
List<Map<String, List<Map<String, String>>>> getStandardDeptDic(String hospitalCode);
}
......@@ -20,6 +20,7 @@ import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* 黄浦全科导诊——科室排名(HpgpDepartmentRank)表服务实现类
......@@ -61,6 +62,11 @@ public class HpgpDepartmentRankServiceImpl extends ServiceImpl<HpgpDepartmentRan
return this.list(wrapper);
}
@Override
public List<Map<String, List<Map<String, String>>>> getStandardDeptDic(String hospitalCode) {
return this.getStandardDeptDic(hospitalCode);
}
@Async
void asyncUpdateRank(HpgpDepartmentRank dept) {
DeptInfo deptInfo = new DeptInfo();
......
......@@ -5,6 +5,7 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.sh.stc.sict.cloud.common.core.constant.Constant;
import cn.sh.stc.sict.cloud.common.core.util.R;
import cn.sh.stc.sict.cloud.common.security.util.SecurityUtils;
import cn.sh.stc.sict.theme.hpgp.model.HpgpDepartmentRank;
import cn.sh.stc.sict.theme.hpgp.service.HpgpBusyIdlePredictionService;
import cn.sh.stc.sict.theme.hpgp.service.HpgpDepartmentRankService;
......@@ -95,4 +96,9 @@ public class HpDeptInfoController extends ApiController {
});
return new R();
}
@GetMapping("/standard-dic")
public R<?> standardDeptDic(@ApiParam("医院编码") @RequestParam(value = "hospitalCode", required = false) String hospitalCode) {
return new R<>().success(hpgpDepartmentRankService.getStandardDeptDic(hospitalCode));
}
}
......@@ -23,4 +23,6 @@ public interface HpDeptInfoService extends IService<HpDeptInfo> {
void asyncUpdate(HpDeptInfo dept);
}
......@@ -3,6 +3,7 @@
<mapper namespace="cn.sh.stc.sict.theme.hpgp.dao.HpgpDepartmentRankMapper">
<resultMap type="cn.sh.stc.sict.theme.hpgp.model.HpgpDepartmentRank" id="HpgpDepartmentRankMap">
<result property="standardDeptCategory" column="standard_dept_category"/>
<result property="standardDept" column="standard_dept"/>
<result property="hospitalCode" column="hospital_code"/>
<result property="hospitalName" column="hospital_name"/>
......@@ -11,7 +12,14 @@
<result property="rankScore" column="rank_score"/>
</resultMap>
<sql id="Base_Column_List"> standard_dept , hospital_code, hospital_name, dept_code, dept_name, rank_score </sql>
<resultMap id="StandardDeptDicMap" type="java.util.LinkedHashMap">
<result property="standardDeptCategory" column="standard_dept_category"/>
<collection property="children" javaType="java.lang.String" ofType="java.util.LinkedHashMap">
<result property="standardDept" column="standard_dept"/>
</collection>
</resultMap>
<sql id="Base_Column_List">standard_dept_category, standard_dept , hospital_code, hospital_name, dept_code, dept_name, rank_score </sql>
<select id="getRankByHosAndStandardDept" resultType="cn.sh.stc.sict.theme.hpgp.vo.DeptRankVO">
select dr.standard_dept standardDept,
......@@ -43,4 +51,19 @@
limit #{size}
</if>
</select>
<select id="getStandardDeptDic" resultType="java.util.LinkedHashMap">
SELECT distinct standard_dept_category,standard_dept
FROM hpgp_department_rank
<where>
delete_flag = 0
AND standard_dept_category IS NOT NULL
AND standard_dept IS NOT NULL
<if test="hospitalCode != null and hospitalCode != ''">
AND hospital_code = #{hospitalCode}
</if>
ORDER BY show_category_sort_idx ASC,
show_standard_dept_sort_idx ASC
</where>
</select>
</mapper>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment