init:米东项目初始化

This commit is contained in:
Yuan
2025-07-23 09:55:50 +08:00
commit 6b49fbfaca
355 changed files with 392953 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
package com.saye.hospitalgd.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @author thuang
* @version 1.0
* @description: TODO
* @date 2021/9/17 16:40
*/
@Configuration
public class ApplicationConfig {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}

View File

@@ -0,0 +1,50 @@
package com.saye.hospitalgd.config;
import com.saye.hospitalgd.model.ServiceParams;
import com.saye.hospitalgd.model.StatusDefine;
import com.saye.hospitalgd.service.system.ServiceParamsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
@Component
public class LoadStatusDefine implements ApplicationRunner {
@Autowired
private ServiceParamsService serviceParamsService;
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("/************************************开始加载系统默认参数*************************************************/");
StatusDefine sd = new StatusDefine();
List<ServiceParams> paramsList = this.serviceParamsService.selectServiceParams(new HashMap<String, String>());
for (int i = 0; i < paramsList.size(); i++) {
ServiceParams param = paramsList.get(i);
String paramName = param.getParamCode();
Field declaredField = null;
try {
declaredField = sd.getClass().getDeclaredField(paramName);
} catch (Exception e) {
//e.printStackTrace();
}
if (declaredField != null) {
declaredField.setAccessible(true);
declaredField.set(sd, param.getParamVal());
}
}
System.out.println("/************************************加载系统默认参数完成*************************************************/");
}
}

View File

@@ -0,0 +1,79 @@
package com.saye.hospitalgd.config;
import com.saye.hospitalgd.commons.date.DateDUtil;
import com.saye.hospitalgd.commons.string.StringDUtil;
import com.saye.hospitalgd.model.Users;
import com.saye.hospitalgd.service.system.UsersService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
public class MyShiroRealm extends AuthorizingRealm {
@Autowired
private UsersService usersService;
/*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
//获取用户的输入的账号.
UsernamePasswordToken up = (UsernamePasswordToken)token;
String username = String.valueOf(up.getUsername());
String password = String.valueOf(up.getPassword());
List<Users> list = usersService.searchByName(username);
if(list.isEmpty()){
return null;
}
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();
Users user = list.get(0);
//判断账户是否锁定
String lockTime = user.getLockTime();
String currentTime = DateDUtil.getTheCurrentTime();
if(lockTime.compareTo(currentTime) == 1) {
throw new ExcessiveAttemptsException();
}
//连续输入错误超过6次锁定10分钟
String truePassword = user.getPassword();
String encryptPassword = new Md5Hash(password,"hospitalgd",2).toString();
if(!truePassword.equals(encryptPassword)) {
String num = StringDUtil.changeNullToEmpty(session.getAttribute(username));
int failNum = Integer.valueOf(num.equals("")?"0":num);
session.setAttribute(username, ++failNum);
if(failNum>6) {
lockTime = DateDUtil.getPlusMinutes("yyyy-MM-dd HH:mm:ss", currentTime, 10);
this.usersService.modifyLockTime(username, lockTime);
throw new ExcessiveAttemptsException();
}
}
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
user,
truePassword,
ByteSource.Util.bytes("hospitalgd"),
getName() //realm name
);
return authenticationInfo;
}
public static void main(String[] args) {
String result = new Md5Hash("1234Saye","hospitalgd",2).toString();
System.out.println(result);
System.out.println(result.length());
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 配置权限
return null;
}
}

View File

@@ -0,0 +1,98 @@
package com.saye.hospitalgd.config;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
System.out.println("ShiroConfiguration.shirFilter()");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//过滤器
Map<String, Filter> filterMap = new LinkedHashMap<>();
filterMap.put("authc", new com.saye.hospitalgd.config.ShiroFilter());
shiroFilterFactoryBean.setFilters(filterMap);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
//配置所有请求都走shiroFilter
filterChainDefinitionMap.put("/receiveData/**", "anon");
filterChainDefinitionMap.put("/**", "authc");
//如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/toLogin");
//登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
* 凭证匹配器
* 由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
*
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));
return hashedCredentialsMatcher;
}
@Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return myShiroRealm;
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
/**
* 开启shiro aop注解支持.
* 使用代理方式;所以需要开启代码支持;
*
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean(name = "simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
mappings.setProperty("UnauthorizedException", "403");
r.setExceptionMappings(mappings); // None by default
r.setDefaultErrorView("error"); // No default
r.setExceptionAttribute("ex"); // Default is "exception"
//r.setWarnLogCategory("example.MvcLogger"); // No default
return r;
}
}

View File

@@ -0,0 +1,88 @@
package com.saye.hospitalgd.config;
import com.saye.hospitalgd.commons.string.StringDUtil;
import com.saye.hospitalgd.mapper.system.MenuMapper;
import com.saye.hospitalgd.model.Users;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class ShiroFilter extends AuthorizationFilter{
private MenuMapper menuMapper;
static List<String> list= null;
static {
list = new ArrayList<String>();
list.add("/getCode");
list.add("/toLogin");
list.add("/login");
list.add("/logout");
list.add("/favicon.ico");
list.add("/image/sgl.png");
list.add("/js/common.js");
}
@Override
protected boolean isAccessAllowed(ServletRequest srequest, ServletResponse sresponse, Object mappedValue)
throws Exception {
// TODO Auto-generated method stub
return false;
}
@Override
protected boolean onAccessDenied(ServletRequest srequest, ServletResponse sresponse) throws IOException {
if(menuMapper == null) {
ServletContext context = srequest.getServletContext();
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context);
if(ctx != null) {
menuMapper= (MenuMapper ) ctx.getBean("menuMapper");
}
}
HttpServletRequest request = (HttpServletRequest) srequest;
HttpServletResponse response = (HttpServletResponse) sresponse;
String url = request.getRequestURI();
System.out.println("this is MyFilter,url :"+url);
if(!list.contains(url) && url.indexOf("/layui/")==-1 && url.indexOf("/showFile/")==-1) {
Users user = (Users)SecurityUtils.getSubject().getPrincipal();
String requestType = StringDUtil.changeNullToEmpty(request.getHeader("X-Requested-With"));
if(user == null) {
if(!"".equals(requestType) && requestType.equalsIgnoreCase("XMLHttpRequest")) {
response.setHeader("sessionstatus", "timeout");
response.sendError(403, "session timeout.");
}else{
response.sendRedirect("/toLogin");
}
}else {
//判断用户是否有此菜单权限
HashMap<Object,Object> map = new HashMap<Object,Object>();
map.put("userid", user.getUserId());
map.put("url", url);
List<HashMap<Object,Object>> menuList = this.menuMapper.findMenuByUrl(map);
if(!menuList.isEmpty()) {
String menu_id = StringDUtil.changeNullToEmpty(menuList.get(0).get("MENU_ID"));
map.put("menu_id", menu_id);
List<HashMap<Object,Object>> roleList = this.menuMapper.findRoleByUserAndMenu(map);
if(roleList.isEmpty()) {
response.sendRedirect("/toNoAuthority");
}
}
}
}
return true;
}
}

View File

@@ -0,0 +1,58 @@
package com.saye.hospitalgd.config;
import org.apache.ibatis.executor.result.ResultMapException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Description: 实体类数据返回时将null转成"" <result column="name" property="name" jdbcType="VARCHAR" typeHandler="com.saye.hospitalgd.config.StringTypeHandler"/>
* @author dqzhang
* @created 2021年3月10日 下午3:29:00
*/
@MappedTypes({String.class})
@MappedJdbcTypes(JdbcType.VARCHAR)
public class StringTypeHandler extends BaseTypeHandler<String> {
@Override
public String getResult(ResultSet rs, String columnName) {
String result;
try {
result = getNullableResult(rs, columnName);
} catch (Exception e) {
throw new ResultMapException("Error attempting to get column '" + columnName + "' from result set. Cause: " + e, e);
}
return result;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
throws SQLException {
ps.setString(i, parameter);
}
@Override
public String getNullableResult(ResultSet rs, String columnName)
throws SQLException {
return rs.getString(columnName) == null? "" : rs.getString(columnName);
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
return rs.getString(columnIndex) == null? "" : rs.getString(columnIndex);
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
return cs.getString(columnIndex) == null? "" : cs.getString(columnIndex);
}
}

View File

@@ -0,0 +1,39 @@
package com.saye.hospitalgd.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @author thuang
* @version 1.0
* @description: Swagger配置用来生成接口查看页面
* @date 2021/10/13 8:41
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("对账平台接口文档")
.description("对账系统前后端接口说明")
.version("1.0")
.build();
}
}

View File

@@ -0,0 +1,28 @@
package com.saye.hospitalgd.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
/**
* Description: 配置虚拟路径
* @author dqzhang
* @created 2019年11月19日 下午3:26:06
*/
@Configuration
public class VirtualPathConfig extends WebMvcConfigurationSupport{
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
//这样会在项目当前盘符下创建saye文件夹
registry.addResourceHandler("/showFile/**").addResourceLocations("file:/saye/");
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
/*swagger 404静态资源配置*/
registry.addResourceHandler("/swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
super.addResourceHandlers(registry);
}
}

View File

@@ -0,0 +1,58 @@
package com.saye.hospitalgd.config;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
@Component
public class XssFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest)request;
HttpSession session = httpRequest.getSession(false);
String requestURI = httpRequest.getRequestURI();
if("/login".equals(requestURI)){
if ( session != null && !session.isNew() ) {
//首先将原session中的数据转移至一临时map中
Map<String,Object> tempMap = new HashMap();
Enumeration<String> sessionNames = session.getAttributeNames();
while(sessionNames.hasMoreElements()){
String sessionName = sessionNames.nextElement();
tempMap.put(sessionName, session.getAttribute(sessionName));
}
//注销原session为的是重置sessionId
session.invalidate();
//将临时map中的数据转移至新session
session = httpRequest.getSession();
for(Map.Entry<String, Object> entry : tempMap.entrySet()){
session.setAttribute(entry.getKey(), entry.getValue());
}
}
}
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
filterChain.doFilter(xssRequest, response);
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) {
}
}

View File

@@ -0,0 +1,131 @@
package com.saye.hospitalgd.config;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.file.IOUtils;
import com.saye.hospitalgd.commons.string.StringDUtil;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper{
HttpServletRequest orgRequest = null;
private static final Whitelist whitelist = Whitelist.basicWithImages();
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
orgRequest = request;
}
@Override
public ServletInputStream getInputStream() throws IOException {
ServletInputStream stream = null;
try {
stream = orgRequest.getInputStream();
String requestBody = IOUtils.toString(stream, "utf-8");
requestBody = Jsoup.clean(requestBody,whitelist);
JSONObject resultJson = JSONObject.parseObject(requestBody);
byte[] array = resultJson.toString().getBytes("utf-8");
if (array == null) {
array = new byte[0];
}
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(array);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() {
return byteArrayInputStream.read();
}
};
} catch (IOException e) {
e.printStackTrace();
}
return super.getInputStream();
}
/**
* 覆盖getParameter方法将参数名和参数值都做xss过滤.
* 如果需要获得原始的值则通过super.getParameterValues(name)来获取
* getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
*/
@Override
public String getParameter(String name) {
if (("content".equals(name) || name.endsWith("WithHtml"))) {
return super.getParameter(name);
}
name = Jsoup.clean(name,whitelist);
String value = super.getParameter(name);
if (StringDUtil.isNotBlank(value)) {
value = Jsoup.clean(value,whitelist);
}
return value;
}
@Override
public String[] getParameterValues(String name) {
String[] arr = super.getParameterValues(name);
if (arr != null) {
for (int i = 0; i < arr.length; i++) {
arr[i] = Jsoup.clean(arr[i],whitelist);
}
}
return arr;
}
/**
* 覆盖getHeader方法将参数名和参数值都做xss过滤。<br/>
* 如果需要获得原始的值则通过super.getHeaders(name)来获取<br/>
* getHeaderNames 也可能需要覆盖
*/
@Override
public String getHeader(String name) {
name = Jsoup.clean(name,whitelist);
String value = super.getHeader(name);
if (StringDUtil.isNotBlank(value)) {
value = Jsoup.clean(value,whitelist);
}
return value;
}
/**
* 获取最原始的request
*
* @return
*/
public HttpServletRequest getOrgRequest() {
return orgRequest;
}
/**
* 获取最原始的request的静态方法
*
* @return
*/
public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
if (req instanceof XssHttpServletRequestWrapper) {
return ((XssHttpServletRequestWrapper) req).getOrgRequest();
}
return req;
}
}

View File

@@ -0,0 +1,23 @@
package com.saye.hospitalgd.config.dataSourceConfig;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.wrapper.MapWrapper;
import java.util.Map;
/**
* @author thuang
* @version 1.0
* @description: 用来将查询结果的key全转为大写
* @date 2021/5/8 10:05
*/
public class MapKeyUpperWrapper extends MapWrapper {
public MapKeyUpperWrapper(MetaObject metaObject, Map<String, Object> map) {
super(metaObject, map);
}
@Override
public String findProperty(String name, boolean useCamelCaseMapping) {
return name==null?"":name.toUpperCase() ;
}
}

View File

@@ -0,0 +1,26 @@
package com.saye.hospitalgd.config.dataSourceConfig;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.wrapper.ObjectWrapper;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import java.util.Map;
/**
* @author thuang
* @version 1.0
* @description: 重写工厂类使用自定义的MapKeyUpperWrapper
* @date 2021/5/8 10:08
*/
public class MapWrapperFactory implements ObjectWrapperFactory {
@Override
public boolean hasWrapperFor(Object object) {
return object != null && object instanceof Map;
}
@Override
public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) {
return new MapKeyUpperWrapper(metaObject, (Map) object);
}
}

View File

@@ -0,0 +1,25 @@
package com.saye.hospitalgd.config.dataSourceConfig;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
/**
* @author thuang
* @version 1.0
* @description: 自定义Convert 转换类 springboot只认ObjectWrapperFactory 自定义的那名字不认
* @date 2021/5/8 10:27
*/
@Component
@ConfigurationPropertiesBinding
public class ObjectWrapperFactoryConverter implements Converter<String, ObjectWrapperFactory> {
@Override
public ObjectWrapperFactory convert(String source) {
try {
return (ObjectWrapperFactory) Class.forName(source).newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}