Commit 215b5b68 authored by liu_cheng_jiu's avatar liu_cheng_jiu

init

parent 90339c0c
*.iml
target
/.idea
/storage/
/logfile/
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/server-admin-api" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/server-all" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/server-all/src/main/java/cn" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/server-core" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/server-db" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/server-wx-api" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-devtools:2.0.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.0.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.0.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.0.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.0.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.0.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter:2.0.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.0.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.10.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apache.logging.log4j:log4j-api:2.10.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.slf4j:jul-to-slf4j:1.7.25" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.yaml:snakeyaml:1.19" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.0.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.0.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.9.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:2.15.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy:1.7.11" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.7.11" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.0.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.0.8.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.0.8.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.5.1" level="project" />
</component>
</module>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="IGNORE_DEPRECATED" value="false" />
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="date" />
</inspection_tool>
</profile>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/engine-class-work.iml" filepath="$PROJECT_DIR$/.idea/engine-class-work.iml" />
<module fileurl="file://$PROJECT_DIR$/server-admin-api/server-admin-api.iml" filepath="$PROJECT_DIR$/server-admin-api/server-admin-api.iml" />
<module fileurl="file://$PROJECT_DIR$/server-all/server-all.iml" filepath="$PROJECT_DIR$/server-all/server-all.iml" />
<module fileurl="file://$PROJECT_DIR$/server-core/server-core.iml" filepath="$PROJECT_DIR$/server-core/server-core.iml" />
<module fileurl="file://$PROJECT_DIR$/server-db/server-db.iml" filepath="$PROJECT_DIR$/server-db/server-db.iml" />
<module fileurl="file://$PROJECT_DIR$/server-wx-api/server-wx-api.iml" filepath="$PROJECT_DIR$/server-wx-api/server-wx-api.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.exploring.engine</groupId>
<artifactId>server</artifactId>
<version>0.1.0</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven.test.skip>true</maven.test.skip>
</properties>
<modules>
<module>server-core</module>
<module>server-db</module>
<module>server-wx-api</module>
<module>server-admin-api</module>
<module>server-all</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.exploring.engine</groupId>
<artifactId>server-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.exploring.engine</groupId>
<artifactId>server-db</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.exploring.engine</groupId>
<artifactId>server-wx-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.exploring.engine</groupId>
<artifactId>server-admin-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.exploring.engine</groupId>
<artifactId>server-all</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Spring Boot Mybatis 依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- Spring Boot pagehelper 依赖 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.0</version>
</dependency>
<!-- MySQL 连接驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.github.qcloudsms</groupId>
<artifactId>qcloudsms</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.4.4</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>[7.2.0, 7.2.99]</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 热部署模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- 测试模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>server-admin-api</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>cn.exploring.engine</groupId>
<artifactId>server</artifactId>
<version>0.1.0</version>
</parent>
<dependencies>
<dependency>
<groupId>cn.exploring.engine</groupId>
<artifactId>server-core</artifactId>
</dependency>
<dependency>
<groupId>cn.exploring.engine</groupId>
<artifactId>server-db</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package cn.exploring.engine.server.admin;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication(scanBasePackages = {"cn.exploring.engine.server.db", "cn.exploring.engine.server.core", "cn.exploring.engine.server.admin"})
@MapperScan("cn.exploring.engine.server.db.dao")
@EnableTransactionManagement
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
package cn.exploring.engine.server.admin.annotation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresPermissionsDesc {
String[] menu();
String button();
}
package cn.exploring.engine.server.admin.config;
import cn.exploring.engine.server.admin.shiro.AdminAuthorizingRealm;
import cn.exploring.engine.server.admin.shiro.AdminWebSessionManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
@Bean
public Realm realm() {
return new AdminAuthorizingRealm();
}
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
filterChainDefinitionMap.put("/admin/auth/login", "anon");
filterChainDefinitionMap.put("/admin/auth/401", "anon");
filterChainDefinitionMap.put("/admin/auth/index", "anon");
filterChainDefinitionMap.put("/admin/auth/403", "anon");
// filterChainDefinitionMap.put("/admin/lessonInfo/**", "anon");
filterChainDefinitionMap.put("/admin/**", "authc");
shiroFilterFactoryBean.setLoginUrl("/admin/auth/401");
shiroFilterFactoryBean.setSuccessUrl("/admin/auth/index");
shiroFilterFactoryBean.setUnauthorizedUrl("/admin/auth/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public SessionManager sessionManager() {
AdminWebSessionManager mySessionManager = new AdminWebSessionManager();
return mySessionManager;
}
@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm());
securityManager.setSessionManager(sessionManager());
return securityManager;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public static DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
creator.setProxyTargetClass(true);
return creator;
}
}
package cn.exploring.engine.server.admin.config;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.AuthorizationException;
import cn.exploring.engine.server.core.util.ResponseUtil;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
@Order( value = Ordered.HIGHEST_PRECEDENCE )
public class ShiroExceptionHandler {
@ExceptionHandler(AuthenticationException.class)
@ResponseBody
public Object unauthenticatedHandler(AuthenticationException e) {
e.printStackTrace();
return ResponseUtil.unlogin();
}
@ExceptionHandler(AuthorizationException.class)
@ResponseBody
public Object unauthorizedHandler(AuthorizationException e) {
e.printStackTrace();
return ResponseUtil.unauthz();
}
}
package cn.exploring.engine.server.admin.shiro;
import cn.exploring.engine.server.core.util.bcrypt.BCryptPasswordEncoder;
import cn.exploring.engine.server.db.domain.AdminAdmin;
import cn.exploring.engine.server.db.service.AdminAdminService;
import cn.exploring.engine.server.db.service.AdminPermissionService;
import cn.exploring.engine.server.db.service.AdminRoleService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Set;
public class AdminAuthorizingRealm extends AuthorizingRealm {
private static final Logger log = LoggerFactory.getLogger(AdminAuthorizingRealm.class);
@Autowired
private AdminAdminService adminService;
@Autowired
private AdminRoleService roleService;
@Autowired
private AdminPermissionService permissionService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
if (principals == null) {
throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
}
AdminAdmin admin = (AdminAdmin) getAvailablePrincipal(principals);
Integer[] roleIds = admin.getRoleIds();
Set<String> roles = roleService.queryByIds(roleIds);
Set<String> permissions = permissionService.queryByRoleIds(roleIds);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setRoles(roles);
info.setStringPermissions(permissions);
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
String password=new String(upToken.getPassword());
if (StringUtils.isEmpty(username)) {
throw new AccountException("用户名不能为空");
}
if (StringUtils.isEmpty(password)) {
throw new AccountException("密码不能为空");
}
List<AdminAdmin> adminList = adminService.findAdmin(username);
Assert.state(adminList.size() < 2, "同一个用户名存在两个账户");
if (adminList.size() == 0) {
throw new UnknownAccountException("找不到用户("+username+")的帐号信息");
}
AdminAdmin admin = adminList.get(0);
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
if (!encoder.matches(password, admin.getPassword())) {
throw new UnknownAccountException("找不到用户("+username+")的帐号信息");
}
return new SimpleAuthenticationInfo(admin,password,getName());
}
}
package cn.exploring.engine.server.admin.shiro;
import com.alibaba.druid.util.StringUtils;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.Serializable;
public class AdminWebSessionManager extends DefaultWebSessionManager {
public static final String LOGIN_TOKEN_KEY = "X-EmbaCourse-Admin-Token";
private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";
@Override
protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
String id = WebUtils.toHttp(request).getHeader(LOGIN_TOKEN_KEY);
if (!StringUtils.isEmpty(id)) {
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
return id;
} else {
return super.getSessionId(request, response);
}
}
}
package cn.exploring.engine.server.admin.util;
public class AdminResponseCode {
public static final Integer ADMIN_INVALID_NAME = 601;
public static final Integer ADMIN_INVALID_PASSWORD = 602;
public static final Integer ADMIN_NAME_EXIST = 602;
public static final Integer ADMIN_ALTER_NOT_ALLOWED = 603;
public static final Integer ADMIN_DELETE_NOT_ALLOWED = 604;
public static final Integer ADMIN_INVALID_ACCOUNT = 605;
public static final Integer GOODS_UPDATE_NOT_ALLOWED = 610;
public static final Integer GOODS_NAME_EXIST = 611;
public static final Integer GOODS_PRICE_ERROR = 612;
public static final Integer GOODS_USE_SCROES_ERROR = 612;
public static final Integer GOODS_SEND_SCORES_ERROR = 613;
public static final Integer GOODS_ONE_SCORES_MINUS_MONEY_ERROR = 614;
public static final Integer ORDER_CONFIRM_NOT_ALLOWED = 620;
public static final Integer ORDER_REFUND_FAILED = 621;
public static final Integer ORDER_REPLY_EXIST = 622;
public static final Integer USER_INVALID_NAME = 630;
public static final Integer USER_INVALID_PASSWORD = 631;
public static final Integer USER_INVALID_MOBILE = 632;
public static final Integer USER_NAME_EXIST = 633;
public static final Integer USER_MOBILE_EXIST = 634;
public static final Integer ROLE_NAME_EXIST = 640;
public static final Integer ROLE_SUPER_SUPERMISSION = 641;
public static final Integer USER_SCORES_ERROR = 635;
}
package cn.exploring.engine.server.admin.util;
import java.util.List;
public class CatVo {
private Integer value = null;
private String label = null;
private List children = null;
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public List getChildren() {
return children;
}
public void setChildren(List children) {
this.children = children;
}
}
package cn.exploring.engine.server.admin.util;
import org.apache.poi.hssf.usermodel.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
public class ExcelHelper {
public static void xlsxExcel2007(List<?> xlsx,HttpServletResponse response){
if(xlsx != null && xlsx.size()==0){
return;
}
// 创建Excel文档
// XSSFWorkbook hwb = new XSSFWorkbook();
HSSFWorkbook hwb = new HSSFWorkbook();
//通过反射,获取对象的字段
Field[] fields = xlsx.get(0).getClass().getDeclaredFields();
String[] names = new String[fields.length];
for(int i = 0;i<fields.length;i++){
names[i]=fields[i].getName();
}
// sheet 对应一个工作页
HSSFSheet sheet = hwb.createSheet("pldrxkxxmb");
sheet.setDefaultColumnWidth(21);//设置单元格宽度
HSSFRow firstrow = sheet.createRow(0); // 下标为0的行开始
HSSFCell[] firstcell = new HSSFCell[fields.length];
for (int j = 0; j < fields.length; j++) {
firstcell[j] = firstrow.createCell(j);
firstcell[j].setCellValue(new HSSFRichTextString(names[j]));
}
for (int i = 0; i < xlsx.size(); i++) {
// 创建一行
HSSFRow row = sheet.createRow(i + 1);
// 得到要插入的每一条记录
Object obj = xlsx.get(i);
Field[] field = obj.getClass().getDeclaredFields();
for (int j = 0; j < field.length; j++) {
String name = field[j].getName();
String type = field[j].getGenericType().toString();
if("int".equals(type)){
type = "class java.lang.Integer";
}
if("short".equals(type)){
type = "class java.lang.Short";
}
if("double".equals(type)){
type = "class java.lang.Double";
}
if("long".equals(type)){
type = "class java.lang.Long";
}
field[j].setAccessible(true);
// System.out.println("=========="+name);
String n = name.substring(0, 1).toUpperCase();
name = n+name.substring(1);
// System.out.println("=========="+name);
// 在一行内循环
try {
Method m;
if(type.equals("class java.lang.String")){
// m = ReflectionUtils.getDeclaredMethod(obj, "get"+name, null);
m = obj.getClass().getDeclaredMethod("get"+name);
m.setAccessible(true);
String value = (String)m.invoke(obj);
System.out.println("get"+name+"---"+value);
HSSFCell fd = row.createCell(j);
if(value != null){
fd.setCellValue(value);
}
}
if(type.equals("class java.lang.Long")){
m = obj.getClass().getDeclaredMethod("get"+name);
m.setAccessible(true);
Long value = (Long)m.invoke(obj);
// System.out.println("get"+name+"---"+value);
HSSFCell fd = row.createCell(j);
if(value != null){
fd.setCellValue(value);
}
}
if(type.equals("class java.lang.Integer")){
m = obj.getClass().getDeclaredMethod("get"+name);
m.setAccessible(true);
Integer value = (Integer)m.invoke(obj);
// System.out.println("get"+name+"---"+value);
HSSFCell fd = row.createCell(j);
if(value != null){
fd.setCellValue(value);
}
}
if (type.equals("class java.lang.Short"))
{
m = obj.getClass().getDeclaredMethod("get" + name);
m.setAccessible(true);
Short value = (Short) m.invoke(obj);
// System.out.println("get"+name+"---"+value);
HSSFCell fd = row.createCell(j);
if(value != null){
fd.setCellValue(value);
}
}
if (type.equals("class java.lang.Double"))
{
m = obj.getClass().getDeclaredMethod("get" + name);
m.setAccessible(true);
Double value = (Double) m.invoke(obj);
// System.out.println("get"+name+"---"+value);
HSSFCell fd = row.createCell(j);
if(value != null){
fd.setCellValue(value);
}
}
if (type.equals("class java.lang.Boolean"))
{
m = obj.getClass().getDeclaredMethod("get" + name);
m.setAccessible(true);
Boolean value = (Boolean) m.invoke(obj);
//System.out.println("get"+name+"---"+value);
HSSFCell fd = row.createCell(j);
fd.setCellValue(value);
}
if (type.equals("class java.util.Date"))
{
m = obj.getClass().getDeclaredMethod("get" + name);
m.setAccessible(true);
Date value = (Date) m.invoke(obj);
// System.out.println("get"+name+"---"+TimeUtil.date2String(value,TimeUtil.OTHER_PATTERN));
HSSFCell fd = row.createCell(j);
if(value != null){
fd.setCellValue(TimeUtil.date2String(value,TimeUtil.OTHER_PATTERN));
}
}
// System.out.println(" ------ ------ ----- ");
} catch (Exception e) {
System.out.println("抛异常:"+name);
e.printStackTrace();
}
}
}
// 创建文件输出流,准备输出电子表格
// OutputStream out = new FileOutputStream("D:/pldrxkxxmb.xls");
// hwb.write(out);
// out.close();
try {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String now = format.format(new Date());
//xlsx.get(0).getClass().getSimpleName()+"_"+
String exportFileName = new Date().getTime()+".xls";//导出文件名
// 表示以附件的形式把文件发送到客户端
response.setHeader("Content-Disposition", "attachment;filename=" + new String((exportFileName).getBytes(), StandardCharsets.ISO_8859_1));//设定输出文件头
response.setContentType("application/vnd.ms-excel;charset=UTF-8");// 定义输出类型
// 通过response的输出流把工作薄的流发送浏览器形成文件
OutputStream outStream;
outStream = response.getOutputStream();
hwb.write(outStream);
outStream.flush();
outStream.close();
hwb.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("数据库导出成功");
}
}
/*
package cn.exploring.engine.server.admin.util;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.MultipartConfigElement;
import java.io.File;
@Configuration
public class MutipartUploadUtil {
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
String location = "/upload/shopping";
File tmpFile = new File(location);
if (!tmpFile.exists()) {
tmpFile.mkdirs();
}
factory.setLocation(location);
return factory.createMultipartConfig();
}
}
*/
package cn.exploring.engine.server.admin.util;
import java.util.List;
public class PermVo {
private String id;
private String label;
private String api;
private List<PermVo> children;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public void setApi(String api) {
this.api = api;
}
public String getApi() {
return api;
}
public List<PermVo> getChildren() {
return children;
}
public void setChildren(List<PermVo> children) {
this.children = children;
}
}
package cn.exploring.engine.server.admin.util;
import cn.exploring.engine.server.admin.annotation.RequiresPermissionsDesc;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.RequestMapping;
public class Permission {
private RequiresPermissions requiresPermissions;
private RequiresPermissionsDesc requiresPermissionsDesc;
private String api;
public RequiresPermissions getRequiresPermissions() {
return requiresPermissions;
}
public RequiresPermissionsDesc getRequiresPermissionsDesc() {
return requiresPermissionsDesc;
}
public void setRequiresPermissions(RequiresPermissions requiresPermissions) {
this.requiresPermissions = requiresPermissions;
}
public void setRequiresPermissionsDesc(RequiresPermissionsDesc requiresPermissionsDesc) {
this.requiresPermissionsDesc = requiresPermissionsDesc;
}
public String getApi() {
return api;
}
public void setApi(String api) {
this.api = api;
}
}
package cn.exploring.engine.server.admin.util;
import cn.exploring.engine.server.admin.annotation.RequiresPermissionsDesc;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.lang.reflect.Method;
import java.util.*;
public class PermissionUtil {
public static List<PermVo> listPermVo(List<Permission> permissions) {
List<PermVo> root = new ArrayList<>();
for (Permission permission : permissions) {
RequiresPermissions requiresPermissions = permission.getRequiresPermissions();
RequiresPermissionsDesc requiresPermissionsDesc = permission.getRequiresPermissionsDesc();
String api = permission.getApi();
String[] menus = requiresPermissionsDesc.menu();
if (menus.length != 2) {
throw new RuntimeException("目前只支持两级菜单");
}
String menu1 = menus[0];
PermVo perm1 = null;
for (PermVo permVo : root) {
if (permVo.getLabel().equals(menu1)) {
perm1 = permVo;
break;
}
}
if (perm1 == null) {
perm1 = new PermVo();
perm1.setId(menu1);
perm1.setLabel(menu1);
perm1.setChildren(new ArrayList<>());
root.add(perm1);
}
String menu2 = menus[1];
PermVo perm2 = null;
for (PermVo permVo : perm1.getChildren()) {
if (permVo.getLabel().equals(menu2)) {
perm2 = permVo;
break;
}
}
if (perm2 == null) {
perm2 = new PermVo();
perm2.setId(menu2);
perm2.setLabel(menu2);
perm2.setChildren(new ArrayList<>());
perm1.getChildren().add(perm2);
}
String button = requiresPermissionsDesc.button();
PermVo leftPerm = null;
for (PermVo permVo : perm2.getChildren()) {
if (permVo.getLabel().equals(button)) {
leftPerm = permVo;
break;
}
}
if (leftPerm == null) {
leftPerm = new PermVo();
leftPerm.setId(requiresPermissions.value()[0]);
leftPerm.setLabel(requiresPermissionsDesc.button());
leftPerm.setApi(api);
perm2.getChildren().add(leftPerm);
}
else{
System.out.println("------------------- " + leftPerm);
// TODO
// 目前限制Controller里面每个方法的RequiresPermissionsDesc注解是唯一的
// 如果允许相同,可能会造成内部权限不一致。
throw new RuntimeException("权限已经存在,不能添加新权限");
}
}
return root;
}
public static List<Permission> listPermission(ApplicationContext context, String basicPackage) {
Map<String, Object> map = context.getBeansWithAnnotation(Controller.class);
List<Permission> permissions = new ArrayList<>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
Object bean = entry.getValue();
if (!StringUtils.contains(ClassUtils.getPackageName(bean.getClass()), basicPackage)) {
continue;
}
Class<?> clz = bean.getClass();
Class controllerClz = clz.getSuperclass();
RequestMapping clazzRequestMapping = AnnotationUtils.findAnnotation(controllerClz, RequestMapping.class);
List<Method> methods = MethodUtils.getMethodsListWithAnnotation(controllerClz, RequiresPermissions.class);
for (Method method : methods) {
RequiresPermissions requiresPermissions = AnnotationUtils.getAnnotation(method, RequiresPermissions.class);
RequiresPermissionsDesc requiresPermissionsDesc = AnnotationUtils.getAnnotation(method, RequiresPermissionsDesc.class);
if (requiresPermissions == null || requiresPermissionsDesc == null) {
continue;
}
String api = "";
if (clazzRequestMapping != null) {
api = clazzRequestMapping.value()[0];
}
PostMapping postMapping = AnnotationUtils.getAnnotation(method, PostMapping.class);
if (postMapping != null) {
api = "POST " + api + postMapping.value()[0];
Permission permission = new Permission();
permission.setRequiresPermissions(requiresPermissions);
permission.setRequiresPermissionsDesc(requiresPermissionsDesc);
permission.setApi(api);
permissions.add(permission);
continue;
}
GetMapping getMapping = AnnotationUtils.getAnnotation(method, GetMapping.class);
if (getMapping != null) {
api = "GET " + api + getMapping.value()[0];
Permission permission = new Permission();
permission.setRequiresPermissions(requiresPermissions);
permission.setRequiresPermissionsDesc(requiresPermissionsDesc);
permission.setApi(api);
permissions.add(permission);
continue;
}
// TODO
// 这里只支持GetMapping注解或者PostMapping注解,应该进一步提供灵活性
throw new RuntimeException("目前权限管理应该在method的前面使用GetMapping注解或者PostMapping注解");
}
}
return permissions;
}
public static Set<String> listPermissionString(List<Permission> permissions) {
Set<String> permissionsString = new HashSet<>();
for(Permission permission : permissions){
permissionsString.add(permission.getRequiresPermissions().value()[0]);
}
return permissionsString;
}
}
package cn.exploring.engine.server.admin.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class StatVo {
private String[] columns = new String[0];
private List<Map> rows = new ArrayList<>();
public String[] getColumns() {
return columns;
}
public void setColumns(String[] columns) {
this.columns = columns;
}
public List<Map> getRows() {
return rows;
}
public void setRows(List<Map> rows) {
this.rows = rows;
}
public void add(Map... r) {
rows.addAll(Arrays.asList(r));
}
}
package cn.exploring.engine.server.admin.util;
import org.apache.commons.lang3.StringUtils;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class TimeUtil {
public static String NORMAL_PATTERN = "MM/dd/yyyy";
public static String OTHER_PATTERN = "yyyy-MM-dd HH:mm:ss";
public static String convertMillisecondToStr(Long milliSecond, String pattern) {
if (milliSecond == null) {
return "";
}
Date date = new Date(milliSecond);
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.format(date);
}
public static Date convertM2D(Long mill) {
if (mill == null) {
return null;
}
return new Date(mill);
}
public static Long getZeroMill() {
Date date = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime().getTime();
}
public static String getCurrentTime() {
Date date = new Date();
DateFormat format = new SimpleDateFormat(OTHER_PATTERN);
String time = format.format(date);
return time;
}
public static Date addDate(Date d, Integer day) {
Calendar fromCal = Calendar.getInstance();
fromCal.setTime(d);
fromCal.add(Calendar.DATE, day);
return fromCal.getTime();
}
/**
* 获取周一
*
* @param d
* 当前时间
* @param num
* 推迟的周数,0本周,-1上周一,1下周一,依次类推
* @return
* @Author: zongyannan
* @Date: 2015年11月10日
*/
public static Date getMonday(Date d, Integer num) {
Calendar fromCal = Calendar.getInstance();
fromCal.add(Calendar.DATE, num * 7);
// 想周几,这里就传几Calendar.MONDAY(TUESDAY...)
fromCal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
return fromCal.getTime();
}
/**
* 给定日期增加 指定月份
*
* @param sourceDate
* @param addMonth
* @return
* @Author: wangxingfei
* @Date: 2015年5月30日
*/
public static Date addMonth(Date sourceDate, Integer addMonth) {
Calendar fromCal = Calendar.getInstance();
fromCal.setTime(sourceDate);
fromCal.add(Calendar.MONTH, addMonth);
return fromCal.getTime();
}
public static boolean isOverdue(Date date) {
return date.getTime() <= new Date().getTime();
}
/**
* 获取 date1 减去 date2 的 分钟数
*
* @param date1
* @param date2
* @return
* @Author: wangxingfei
* @Date: 2015年5月23日
*/
public static Long sub2Min(Date date1, Date date2) {
if (date1 == null || date2 == null)
return 0L;
return (date1.getTime() - date2.getTime()) / 1000 / 60;
}
/**
* 获取 date1 减去 date2 的 天数
*
* @param date1
* @param date2
* @return
* @Author: wangxingfei
* @Date: 2015年6月24日
*/
public static Integer sub2Date(Date date1, Date date2) {
if (date1 == null || date2 == null)
return 0;
return (int) ((date1.getTime() - date2.getTime()) / 1000 / 60 / 60 / 24);
}
public static void main(String[] args) throws ParseException {
System.out.println(getLongTime());
}
/**
* 获取 起始日期和结束日期中的所有日期
*
* @param startDate
* 起始日期 2015-05-23
* @param endDate
* 结束日期 2015-05-25
* @return 2015-05-23,2015-05-24,2015-05-25
* @Author: wangxingfei
* @Date: 2015年5月23日
*/
public static List<String> getSpaceDates(String startDate, String endDate) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
long start = string2Date(startDate).getTime();
long end = string2Date(endDate).getTime();
List<String> list = new ArrayList<String>();
while (start <= end) {
Date time = new Date(start);
list.add(sdf.format(time));
start += 1000 * 60 * 60 * 24;// 加一天
}
return list;
}
/**
* date转字符串
*
* @param date
* @return yyyy-MM-dd
* @Author: wangxingfei
* @Date: 2015年5月23日
*/
public static String date2String(Date date) {
if (date == null)
return null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(date);
}
/**
* date转字符串
*
* @param date
* @return yyyy-MM-dd
* @Author: wangxingfei
* @Date: 2015年5月23日
*/
public static String date2String(Date date, String pattern) {
if (date == null)
return null;
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.format(date);
}
/**
* 字符串转date
*
* @param str
* yyyy-MM-dd
* @return
* @Author: wangxingfei
* @Date: 2015年5月23日
*/
public static Date string2Date(String str) {
return string2Date(str, "yyyy-MM-dd");
}
/**
* 字符串转date
*
* @param str
* 字符串
* @param format
* 格式化
* @return
* @Author: wangxingfei
* @Date: 2015年6月26日
*/
public static Date string2Date(String str, String format) {
if (str == null)
return null;
SimpleDateFormat sdf = new SimpleDateFormat(format);
try {
return sdf.parse(str);
} catch (ParseException e) {
}
return null;
}
/**
* 获取 当前日期 是周几
*
* @param date
* @return 周日:1,周一:2
* @Author: wangxingfei
* @Date: 2015年5月23日
*/
public static int getDayOfWeek(Date date) {
if (date == null)
return 0;
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.DAY_OF_WEEK);
}
/**
* 获取没有时分秒的 当前年月日
*
* @return
* @Author: wangxingfei
* @Date: 2015年5月23日
*/
public static Date getZeroTimeDate() {
return getZeroTimeDate(new Date());
}
/**
* 将日期转换为 没有时分秒的日期
*
* @return
* @Author: wangxingfei
* @Date: 2015年5月23日
*/
public static Date getZeroTimeDate(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
public static long getLongTime(){
Date now = new Date();
return now.getTime();
}
public static boolean isSameDay(Date day1, Date day2) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String ds1 = sdf.format(day1);
String ds2 = sdf.format(day2);
return ds1.equals(ds2);
}
public static String timeLongToString(long secondValue) {
long day = 0;
long hour = 0;
long min = 0;
long second = 0;
long temp1 = secondValue % (60 * 60 * 24); // 计算小时
long temp2 = temp1 % (60 * 60); // 计算分
long temp3 = temp2 % 60; // 计算秒
day = secondValue / (60 * 60 * 24);
hour = temp1 / 60 / 60;
min = temp2 / 60;
String backStr = "";
if (day > 0) {
backStr = backStr + day + "天";
}
if (hour > 0) {
backStr = backStr + hour + "小时";
}
if (day <= 0) {
if (min > 0) {
backStr = backStr + min + "分";
}
if (StringUtils.isBlank(backStr)) {
if (temp3 > 0) {
backStr = backStr + temp3 + "秒";
}
}
}
if (StringUtils.isBlank(backStr)) {
backStr = "0秒";
}
return backStr;
}
public static String timeLongToStringSecond(long value) {// 传入的是毫秒
long second = value / 1000;
if (second / 60 == 0 && second % 60 == 0) {
return "0秒";
} else if (second / 60 == 0) {
return (second % 60) + "秒";
} else if (second % 60 == 0) {
return (second / 60) + "分钟";
} else {
return (second / 60) + "分钟" + (second % 60) + "秒";
}
}
public static String intToTime(int time){
String num=String.valueOf(time/60);
String ss = String.valueOf(time%60);
if(num.length()==1 && ss.length()==1){
return "0"+num+":0"+ss+"";
}else if(num.length()==1 && ss.length()>1){
return "0"+num+":"+ss+"";
}else if(num.length()>0 && ss.length()==1){
return num+":0"+ss+"";
}else if(num.length()>0 && ss.length()>0){
return num+":"+ss+"";
}
return "00:00";
}
}
package cn.exploring.engine.server.admin.web;
import cn.exploring.engine.server.admin.annotation.RequiresPermissionsDesc;
import cn.exploring.engine.server.core.util.ResponseUtil;
import cn.exploring.engine.server.core.util.bcrypt.BCryptPasswordEncoder;
import cn.exploring.engine.server.core.validator.Order;
import cn.exploring.engine.server.core.validator.Sort;
import cn.exploring.engine.server.db.domain.AdminAdmin;
import cn.exploring.engine.server.db.service.AdminAdminService;
import cn.exploring.engine.server.db.util.RegexUtil;
import com.github.pagehelper.PageInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static cn.exploring.engine.server.admin.util.AdminResponseCode.*;
@RestController
@RequestMapping("/admin/admin")
@Validated
public class AdminAdminController {
private final Log logger = LogFactory.getLog(AdminAdminController.class);
@Autowired
private AdminAdminService adminService;
@RequiresPermissions("admin:admin:list")
@RequiresPermissionsDesc(menu={"系统管理" , "管理员管理"}, button="查询")
@GetMapping("/list")
public Object list(String username,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
List<AdminAdmin> adminList = adminService.querySelective(username, page, limit, sort, order);
long total = PageInfo.of(adminList).getTotal();
Map<String, Object> data = new HashMap<>();
data.put("total", total);
data.put("items", adminList);
return ResponseUtil.ok(data);
}
private Object validate(AdminAdmin admin) {
String name = admin.getUsername();
if (StringUtils.isEmpty(name)) {
return ResponseUtil.badArgument();
}
if (!RegexUtil.isUsername(name)) {
return ResponseUtil.fail(ADMIN_INVALID_NAME, "管理员名称不符合规定");
}
String password = admin.getPassword();
if (!StringUtils.isEmpty(password) && password.length() < 6) {
return ResponseUtil.fail(ADMIN_INVALID_PASSWORD, "管理员密码长度不能小于6");
}
return null;
}
@RequiresPermissions("admin:admin:create")
@RequiresPermissionsDesc(menu={"系统管理" , "管理员管理"}, button="添加")
@PostMapping("/create")
public Object create(@RequestBody AdminAdmin admin) {
Object error = validate(admin);
if (error != null) {
return error;
}
String username = admin.getUsername();
List<AdminAdmin> adminList = adminService.findAdmin(username);
if (adminList.size() > 0) {
return ResponseUtil.fail(ADMIN_NAME_EXIST, "管理员已经存在");
}
String rawPassword = admin.getPassword();
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String encodedPassword = encoder.encode(rawPassword);
admin.setPassword(encodedPassword);
adminService.add(admin);
return ResponseUtil.ok(admin);
}
@RequiresPermissions("admin:admin:read")
@RequiresPermissionsDesc(menu={"系统管理" , "管理员管理"}, button="详情")
@GetMapping("/read")
public Object read(@NotNull Integer id) {
AdminAdmin admin = adminService.findById(id);
return ResponseUtil.ok(admin);
}
@RequiresPermissions("admin:admin:update")
@RequiresPermissionsDesc(menu={"系统管理" , "管理员管理"}, button="编辑")
@PostMapping("/update")
public Object update(@RequestBody AdminAdmin admin) {
Object error = validate(admin);
if (error != null) {
return error;
}
Integer anotherAdminId = admin.getId();
if (anotherAdminId == null) {
return ResponseUtil.badArgument();
}
String rawPassword = admin.getPassword();
if (!StringUtils.isEmpty(rawPassword)) {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String encodedPassword = encoder.encode(rawPassword);
admin.setPassword(encodedPassword);
}
if (adminService.updateById(admin) == 0) {
return ResponseUtil.updatedDataFailed();
}
return ResponseUtil.ok(admin);
}
@RequiresPermissions("admin:admin:delete")
@RequiresPermissionsDesc(menu={"系统管理" , "管理员管理"}, button="删除")
@PostMapping("/delete")
public Object delete(@RequestBody AdminAdmin admin) {
Integer anotherAdminId = admin.getId();
if (anotherAdminId == null) {
return ResponseUtil.badArgument();
}
adminService.deleteById(anotherAdminId);
return ResponseUtil.ok();
}
}
package cn.exploring.engine.server.admin.web;
import cn.exploring.engine.server.admin.util.Permission;
import cn.exploring.engine.server.admin.util.PermissionUtil;
import cn.exploring.engine.server.core.util.JacksonUtil;
import cn.exploring.engine.server.core.util.ResponseUtil;
import cn.exploring.engine.server.db.domain.AdminAdmin;
import cn.exploring.engine.server.db.service.AdminAdminService;
import cn.exploring.engine.server.db.service.AdminPermissionService;
import cn.exploring.engine.server.db.service.AdminRoleService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import static cn.exploring.engine.server.admin.util.AdminResponseCode.ADMIN_INVALID_ACCOUNT;
@RestController
@RequestMapping("/admin/auth")
@Validated
public class AdminAuthController {
private final Log logger = LogFactory.getLog(AdminAuthController.class);
@Autowired
private AdminAdminService adminService;
@Autowired
private AdminRoleService roleService;
@Autowired
private AdminPermissionService permissionService;
/*
* { username : value, password : value }
*/
@PostMapping("/login")
public Object login(@RequestBody String body) {
String username = JacksonUtil.parseString(body, "username");
String password = JacksonUtil.parseString(body, "password");
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
return ResponseUtil.badArgument();
}
Subject currentUser = SecurityUtils.getSubject();
try {
currentUser.login(new UsernamePasswordToken(username, password));
} catch (UnknownAccountException uae) {
return ResponseUtil.fail(ADMIN_INVALID_ACCOUNT, "用户帐号或密码不正确");
} catch (LockedAccountException lae) {
return ResponseUtil.fail(ADMIN_INVALID_ACCOUNT, "用户帐号已锁定不可用");
} catch (AuthenticationException ae) {
return ResponseUtil.fail(ADMIN_INVALID_ACCOUNT, ae.getMessage());
}
return ResponseUtil.ok(currentUser.getSession().getId());
}
/*
*
*/
@RequiresAuthentication
@PostMapping("/logout")
public Object login() {
Subject currentUser = SecurityUtils.getSubject();
currentUser.logout();
return ResponseUtil.ok();
}
@RequiresAuthentication
@GetMapping("/info")
public Object info() {
Subject currentUser = SecurityUtils.getSubject();
AdminAdmin admin = (AdminAdmin) currentUser.getPrincipal();
Map<String, Object> data = new HashMap<>();
data.put("name", admin.getUsername());
data.put("avatar", admin.getAvatar());
Integer[] roleIds = admin.getRoleIds();
Set<String> roles = roleService.queryByIds(roleIds);
Set<String> permissions = permissionService.queryByRoleIds(roleIds);
data.put("roles", roles);
// NOTE
// 这里需要转换perms结构,因为对于前端而已API形式的权限更容易理解
data.put("perms", toAPI(permissions));
return ResponseUtil.ok(data);
}
@Autowired
private ApplicationContext context;
private HashMap<String, String> systemPermissionsMap = null;
private Collection<String> toAPI(Set<String> permissions) {
if (systemPermissionsMap == null) {
systemPermissionsMap = new HashMap<>();
final String basicPackage = "cn.exploring.engine.server.admin";
List<Permission> systemPermissions = PermissionUtil.listPermission(context, basicPackage);
for (Permission permission : systemPermissions) {
String perm = permission.getRequiresPermissions().value()[0];
String api = permission.getApi();
systemPermissionsMap.put(perm, api);
}
}
Collection<String> apis = new HashSet<>();
for (String perm : permissions) {
String api = systemPermissionsMap.get(perm);
apis.add(api);
if (perm.equals("*")) {
apis.clear();
apis.add("*");
return apis;
// return systemPermissionsMap.values();
}
}
return apis;
}
@GetMapping("/401")
public Object page401() {
return ResponseUtil.unlogin();
}
@GetMapping("/index")
public Object pageIndex() {
return ResponseUtil.ok();
}
@GetMapping("/403")
public Object page403() {
return ResponseUtil.unauthz();
}
}
package cn.exploring.engine.server.admin.web;
import cn.exploring.engine.server.core.util.ResponseUtil;
import cn.exploring.engine.server.db.service.WxUserService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/admin/dashboard")
@Validated
public class AdminDashbordController {
private final Log logger = LogFactory.getLog(AdminDashbordController.class);
@Autowired
private WxUserService userService;
@GetMapping("")
public Object info() {
int userTotal = userService.count();
Map<String, Integer> data = new HashMap<>();
data.put("userTotal", userTotal);
return ResponseUtil.ok(data);
}
}
package cn.exploring.engine.server.admin.web;
import cn.exploring.engine.server.admin.annotation.RequiresPermissionsDesc;
import cn.exploring.engine.server.core.util.ResponseUtil;
import cn.exploring.engine.server.core.validator.Order;
import cn.exploring.engine.server.core.validator.Sort;
import cn.exploring.engine.server.db.domain.WxSearchHistory;
import cn.exploring.engine.server.db.service.WxSearchHistoryService;
import com.github.pagehelper.PageInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/admin/history")
public class AdminHistoryController {
private final Log logger = LogFactory.getLog(AdminHistoryController.class);
@Autowired
private WxSearchHistoryService searchHistoryService;
@RequiresPermissions("admin:history:list")
@RequiresPermissionsDesc(menu={"会员管理" , "搜索历史"}, button="查询")
@GetMapping("/list")
public Object list(String userId, String keyword,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
List<WxSearchHistory> footprintList = searchHistoryService.querySelective(userId, keyword, page, limit, sort, order);
long total = PageInfo.of(footprintList).getTotal();
Map<String, Object> data = new HashMap<>();
data.put("total", total);
data.put("items", footprintList);
return ResponseUtil.ok(data);
}
}
package cn.exploring.engine.server.admin.web;
import cn.exploring.engine.server.core.util.ResponseUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresGuest;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/admin/index")
public class AdminIndexController {
private final Log logger = LogFactory.getLog(AdminIndexController.class);
@RequestMapping("/index")
public Object index() {
return ResponseUtil.ok("hello world, this is admin service");
}
@RequiresGuest
@RequestMapping("/guest")
public Object guest() {
return ResponseUtil.ok("hello world, this is admin service");
}
@RequiresAuthentication
@RequestMapping("/authn")
public Object authn() {
return ResponseUtil.ok("hello world, this is admin service");
}
@RequiresUser
@RequestMapping("/user")
public Object user() {
return ResponseUtil.ok("hello world, this is admin service");
}
@RequiresRoles("admin")
@RequestMapping("/admin")
public Object admin() {
return ResponseUtil.ok("hello world, this is admin service");
}
@RequiresRoles("admin2")
@RequestMapping("/admin2")
public Object admin2() {
return ResponseUtil.ok("hello world, this is admin service");
}
@GetMapping("/read")
public Object read() {
return ResponseUtil.ok("hello world, this is admin service");
}
@PostMapping("/write")
public Object write() {
return ResponseUtil.ok("hello world, this is admin service");
}
}
package cn.exploring.engine.server.admin.web;
import cn.exploring.engine.server.admin.annotation.RequiresPermissionsDesc;
import cn.exploring.engine.server.core.util.ResponseUtil;
import cn.exploring.engine.server.core.validator.Order;
import cn.exploring.engine.server.core.validator.Sort;
import cn.exploring.engine.server.db.domain.CourseInitTest;
import cn.exploring.engine.server.db.service.InitTestService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/admin/initTest")
@Validated
public class AdminInitTestController {
@Autowired
private InitTestService initTestService;
@RequiresPermissions("admin:initTest:select")
@RequiresPermissionsDesc(menu={"创业基因测试" , "课程介绍视频"}, button="搜索")
@GetMapping("select")
public Object selectInitTest(@RequestParam(required = false) Integer id,
@RequestParam(required = false) Integer titleRank,
@RequestParam(required = false) String title,
@RequestParam(required = false) String topic,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "asc") String order
){
return ResponseUtil.ok(initTestService.selectCourseInitTest(id, titleRank, title, topic, null, page, limit, sort, order));
}
@RequiresPermissions("admin:initTest:add")
@RequiresPermissionsDesc(menu={"创业基因测试" , "课程介绍视频"}, button="添加")
@PostMapping("/add")
public Object addInitTest(@RequestBody CourseInitTest initTest){
String addMessage = initTestService.addInitTest(initTest);
Object backData = "insert Ok".equals(addMessage) ? ResponseUtil.ok(addMessage) : ResponseUtil.fail(403, addMessage);
return backData;
}
@RequiresPermissions("admin:initTest:update")
@RequiresPermissionsDesc(menu={"创业基因测试" , "课程介绍视频"}, button="编辑")
@PostMapping("/update")
public Object updateInitTest(@RequestBody CourseInitTest initTest){
return ResponseUtil.ok(initTestService.updateInitTest(initTest));
}
@RequiresPermissions("admin:initTest:batchDeleted")
@RequiresPermissionsDesc(menu={"创业基因测试" , "课程介绍视频"}, button="批量删除")
@PostMapping("/batchDeleted")
public Object updateInitTest(@RequestBody List<Integer> idList){
return ResponseUtil.ok(initTestService.batchDeletedInitTest(idList));
}
}
package cn.exploring.engine.server.admin.web;
import cn.exploring.engine.server.admin.annotation.RequiresPermissionsDesc;
import cn.exploring.engine.server.core.util.ResponseUtil;
import cn.exploring.engine.server.core.validator.Order;
import cn.exploring.engine.server.core.validator.Sort;
import cn.exploring.engine.server.db.domain.LessonInfo;
import cn.exploring.engine.server.db.service.LessonInfoService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/admin/lessonInfo")
@Validated
public class AdminLessonInfoController {
@Autowired
private LessonInfoService lessonInfoService;
@RequiresPermissions("admin:lessonInfo:select")
@RequiresPermissionsDesc(menu={"1系课程视频" , "1系课程视频"}, button="搜索")
@GetMapping("/select")
public Object selectLessonInfo(@RequestParam(required = false) Integer id,
@RequestParam(required = false) Integer chapters,
@RequestParam(required = false) String chaptersName,
@RequestParam(required = false) Integer session,
@RequestParam(required = false) String sessionName,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "asc") String order
){
return ResponseUtil.ok(lessonInfoService.selectLessonInfo(id, chapters, chaptersName, session, sessionName, page, limit, sort, order));
}
@RequiresPermissions("admin:initTest:add")
@RequiresPermissionsDesc(menu={"1系课程视频" , "1系课程视频"}, button="添加")
@PostMapping("/add")
public Object addLessonInfo(@RequestBody LessonInfo lessonInfo){
String addMessage = lessonInfoService.addLessonInfo(lessonInfo);
Object backData = "insert Ok".equals(addMessage) ? ResponseUtil.ok(addMessage) : ResponseUtil.fail(403, addMessage);
return backData;
}
@RequiresPermissions("admin:initTest:update")
@RequiresPermissionsDesc(menu={"1系课程视频" , "1系课程视频"}, button="编辑")
@PostMapping("/update")
public Object updateLessonInfo(@RequestBody LessonInfo lessonInfo){
return ResponseUtil.ok(lessonInfoService.updateLessonInfo(lessonInfo));
}
@RequiresPermissions("admin:initTest:batchDeleted")
@RequiresPermissionsDesc(menu={"1系课程视频" , "1系课程视频"}, button="批量删除")
@PostMapping("/batchDeleted")
public Object batchUpdateLessonInfo(@RequestBody List<Integer> lessonInfoIdList){
return ResponseUtil.ok(lessonInfoService.batchDeletedLessonInfo(lessonInfoIdList));
}
@GetMapping("selectLessonChaptersInfo")
public Object selectLessonChaptersInfo() {
return ResponseUtil.ok(lessonInfoService.getAllChaptersInfo());
}
}
package cn.exploring.engine.server.admin.web;
import cn.exploring.engine.server.admin.annotation.RequiresPermissionsDesc;
import cn.exploring.engine.server.core.validator.Order;
import cn.exploring.engine.server.core.validator.Sort;
import cn.exploring.engine.server.db.domain.WxSensitiveWords;
import cn.exploring.engine.server.db.service.WxSensitiveWordsService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotNull;
//敏感词汇
@RestController
@RequestMapping("/admin/sensitive/words")
@Validated
public class AdminSensitiveWordsController {
private final Log logger = LogFactory.getLog(AdminSensitiveWordsController.class);
@Autowired
private WxSensitiveWordsService sensitiveWordsService;
//分页查询
@RequiresPermissions("admin:sensitive:words:list")
@RequiresPermissionsDesc(menu={"系统管理" , "敏感词汇管理"}, button="查询")
@GetMapping("/list")
public Object list(WxSensitiveWords object,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
return sensitiveWordsService.list(object, page, limit, sort, order);
}
//根据id查询
@RequiresPermissions("admin:sensitive:words:read")
@RequiresPermissionsDesc(menu={"系统管理" , "敏感词汇管理"}, button="详情")
@GetMapping("/read")
public Object read(@NotNull Integer id) {
return sensitiveWordsService.selectByPrimaryKey(id);
}
//添加
@RequiresPermissions("admin:sensitive:words:create")
@RequiresPermissionsDesc(menu={"系统管理" , "敏感词汇管理"}, button="添加")
@PostMapping("/create")
public Object create(@RequestBody WxSensitiveWords object) {
return sensitiveWordsService.add(object);
}
//修改
@RequiresPermissions("admin:sensitive:words:update")
@RequiresPermissionsDesc(menu={"系统管理" , "敏感词汇管理"}, button="编辑")
@PostMapping("/update")
public Object update(@RequestBody WxSensitiveWords object) {
return sensitiveWordsService.updateById(object) ;
}
//批量删除
@RequiresPermissions("admin:sensitive:words:delete")
@RequiresPermissionsDesc(menu={"系统管理" , "敏感词汇管理"}, button="删除")
@PostMapping("/delete")
public Object delete(@RequestBody Integer[] ids) {
return sensitiveWordsService.deleteByIds(ids);
}
}
package cn.exploring.engine.server.admin.web;
import cn.exploring.engine.server.admin.util.StatVo;
import cn.exploring.engine.server.core.util.ResponseUtil;
import cn.exploring.engine.server.db.service.StatService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/admin/stat")
@Validated
public class AdminStatController {
private final Log logger = LogFactory.getLog(AdminStatController.class);
@Autowired
private StatService statService;
@GetMapping("/user")
public Object statUser() {
List<Map> rows = statService.statUser();
String[] columns = new String[]{"day", "users"};
StatVo statVo = new StatVo();
statVo.setColumns(columns);
statVo.setRows(rows);
return ResponseUtil.ok(statVo);
}
@GetMapping("/order")
public Object statOrder() {
List<Map> rows = statService.statOrder();
String[] columns = new String[]{"day", "orders", "customers", "amount", "pcr"};
StatVo statVo = new StatVo();
statVo.setColumns(columns);
statVo.setRows(rows);
return ResponseUtil.ok(statVo);
}
@GetMapping("/goods")
public Object statGoods() {
List<Map> rows = statService.statGoods();
String[] columns = new String[]{"day", "orders", "products", "amount"};
StatVo statVo = new StatVo();
statVo.setColumns(columns);
statVo.setRows(rows);
return ResponseUtil.ok(statVo);
}
}
package cn.exploring.engine.server.admin.web;
import cn.exploring.engine.server.admin.annotation.RequiresPermissionsDesc;
import cn.exploring.engine.server.core.qcode.QCodeService;
import cn.exploring.engine.server.core.storage.StorageService;
import cn.exploring.engine.server.core.util.FileUploadUtil;
import cn.exploring.engine.server.core.util.ImageUtil;
import cn.exploring.engine.server.core.util.ResponseUtil;
import cn.exploring.engine.server.core.validator.Order;
import cn.exploring.engine.server.core.validator.Sort;
import cn.exploring.engine.server.db.domain.WxStorage;
import cn.exploring.engine.server.db.domain.vo.ShareQrcodeVo;
import cn.exploring.engine.server.db.service.WxStorageService;
import com.github.pagehelper.PageInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/admin/storage")
@Validated
public class AdminStorageController {
private final Log logger = LogFactory.getLog(AdminStorageController.class);
@Autowired
private StorageService storageService;
@Autowired
private WxStorageService wxStorageService;
@Autowired
private QCodeService qCodeService;
@Value("${projectRedis.keyPrefix.share}")
private String projectRedisKeyShare;
@RequiresPermissions("admin:storage:list")
@RequiresPermissionsDesc(menu={"系统管理" , "对象存储"}, button="查询")
@GetMapping("/list")
public Object list(String key, String name,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
List<WxStorage> storageList = wxStorageService.querySelective(key, name, page, limit, sort, order);
long total = PageInfo.of(storageList).getTotal();
Map<String, Object> data = new HashMap<>();
data.put("total", total);
data.put("items", storageList);
return ResponseUtil.ok(data);
}
@RequiresPermissions("admin:storage:create")
@RequiresPermissionsDesc(menu={"系统管理" , "对象存储"}, button="上传")
@PostMapping("/create")
public Object create(@RequestParam("file") MultipartFile file) throws IOException {
String url = ImageUtil.storeSrcAndCompress(storageService, file);
if (url == null) {
return ResponseUtil.badArgumentValue();
}
Map<String, Object> data = new HashMap<>();
data.put("url", url);
return ResponseUtil.ok(data);
}
/**
* 上传本地,不压缩
* @param file
* @return
* @throws IOException
*/
@RequiresPermissions("admin:storage:createAny")
@RequiresPermissionsDesc(menu={"系统管理" , "对象存储"}, button="上传任意格式文件")
@PostMapping("/createAny")
public Object createAny(@RequestParam("file") MultipartFile file) throws IOException {
String url = FileUploadUtil.store(storageService, file);
if (url == null) {
return cn.exploring.engine.server.db.util.ResponseUtil.badArgumentValue();
}
Map<String, Object> data = new HashMap<>();
data.put("url", url);
return cn.exploring.engine.server.db.util.ResponseUtil.ok(data);
}
@RequiresPermissions("admin:storage:read")
@RequiresPermissionsDesc(menu={"系统管理" , "对象存储"}, button="详情")
@PostMapping("/read")
public Object read(@NotNull Integer id) {
WxStorage storageInfo = wxStorageService.findById(id);
if (storageInfo == null) {
return ResponseUtil.badArgumentValue();
}
return ResponseUtil.ok(storageInfo);
}
@RequiresPermissions("admin:storage:update")
@RequiresPermissionsDesc(menu={"系统管理" , "对象存储"}, button="编辑")
@PostMapping("/update")
public Object update(@RequestBody WxStorage storage) {
if (wxStorageService.update(storage) == 0) {
return ResponseUtil.updatedDataFailed();
}
return ResponseUtil.ok(storage);
}
@RequiresPermissions("admin:storage:delete")
@RequiresPermissionsDesc(menu={"系统管理" , "对象存储"}, button="删除")
@PostMapping("/delete")
public Object delete(@RequestBody WxStorage wxStorage) {
String key = wxStorage.getKey();
if (StringUtils.isEmpty(key)) {
return ResponseUtil.badArgument();
}
wxStorageService.deleteByKey(key);
storageService.delete(key);
return ResponseUtil.ok();
}
/**
* 用户分享图片
* @param vo
* @return
*/
@RequiresPermissions("admin:storage:share")
@RequiresPermissionsDesc(menu={"系统管理" , "对象存储"}, button="分享")
@PostMapping("/share")
public Object share(@RequestBody ShareQrcodeVo vo) {
if (vo == null || vo.getId() == null || vo.getUrl() == null) {
return ResponseUtil.badArgument();
}
Integer oid = Integer.parseInt(vo.getId().split("_")[1]);
String result = qCodeService.createShareQrcodeImage(vo.getId(), vo.getUrl(), QCodeService.INVOTE, "url", "name"); // todo
Map<String, Object> data = new HashMap<>();
data.put("url", result);
return ResponseUtil.ok(data);
}
/**
* 访问存储对象
*
* @param key 存储对象key
* @return
*/
@GetMapping("/fetch/{path}/{key:.+}")
public ResponseEntity<Resource> fetch(@PathVariable String path, @PathVariable String key) throws UnsupportedEncodingException {
String filePathAndName = path + "/" + key;
if (filePathAndName == null) {
return ResponseEntity.notFound().build();
}
WxStorage storage = wxStorageService.findByKey(filePathAndName);
if (storage == null) {
return ResponseEntity.notFound().build();
}
String type = storage.getType();
MediaType mediaType = MediaType.parseMediaType(type);
Resource file = storageService.getLocalStorage().loadAsResource(filePathAndName);
if (file == null) {
return ResponseEntity.notFound().build();
}
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Content-Disposition", String.format("attachment; filename=%s", java.net.URLEncoder.encode(key, "UTF-8")));
return ResponseEntity.ok().headers(headers).contentType(mediaType).body(file);
}
@GetMapping("/fetch/{key:.+}")
public ResponseEntity<Resource> fetch(@PathVariable String key) {
if (key == null) {
return ResponseEntity.notFound().build();
}
if (key.contains("../")) {
return ResponseEntity.badRequest().build();
}
WxStorage storage = wxStorageService.findByKey(key);
if (storage == null) {
return ResponseEntity.notFound().build();
}
String type = storage.getType();
MediaType mediaType = MediaType.parseMediaType(type);
Resource file = storageService.getLocalStorage().loadAsResource(key);
if (file == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok().contentType(mediaType).body(file);
}
}
package cn.exploring.engine.server.admin.web;
import cn.exploring.engine.server.admin.annotation.RequiresPermissionsDesc;
import cn.exploring.engine.server.core.util.ResponseUtil;
import cn.exploring.engine.server.core.util.bcrypt.BCryptPasswordEncoder;
import cn.exploring.engine.server.core.validator.Order;
import cn.exploring.engine.server.core.validator.Sort;
import cn.exploring.engine.server.db.domain.WxUser;
import cn.exploring.engine.server.db.service.WxUserService;
import cn.exploring.engine.server.db.util.RegexUtil;
import com.github.pagehelper.PageInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotEmpty;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static cn.exploring.engine.server.admin.util.AdminResponseCode.*;
@RestController
@RequestMapping("/admin/user")
@Validated
public class AdminUserController {
private final Log logger = LogFactory.getLog(AdminUserController.class);
@Autowired
private WxUserService userService;
@RequiresPermissions("admin:user:list")
@RequiresPermissionsDesc(menu={"会员管理" , "会员信息管理"}, button="查询")
@GetMapping("/list")
public Object list(WxUser user,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
List<WxUser> userList = userService.querySelective(user, page, limit, sort, order);
long total = PageInfo.of(userList).getTotal();
Map<String, Object> data = new HashMap<>();
data.put("total", total);
data.put("items", userList);
return ResponseUtil.ok(data);
}
@GetMapping("/username")
public Object username(@NotEmpty String username) {
boolean exist = userService.checkByUsername(username);
if (exist) {
return ResponseUtil.ok("已存在");
}
return ResponseUtil.ok("不存在");
}
private Object validate(WxUser user) {
String username = user.getUsername();
if (StringUtils.isEmpty(user)) {
return ResponseUtil.badArgument();
}
/*if (!RegexUtil.isUsername(username)) {
return ResponseUtil.fail(USER_INVALID_NAME, "用户名不符合规定"); 注释此处的原因是,用户名必须大于6位,名字一般为3个汉字
}*/
String password = user.getPassword();
if (StringUtils.isEmpty(password) || password.length() < 6) {
return ResponseUtil.fail(USER_INVALID_PASSWORD, "用户密码长度不能小于6");
}
String mobile = user.getMobile();
if (StringUtils.isEmpty(mobile)) {
return ResponseUtil.badArgument();
}
if (!RegexUtil.isMobileExact(mobile)) {
return ResponseUtil.fail(USER_INVALID_MOBILE, "用户手机号码格式不正确");
}
return null;
}
@RequiresPermissions("admin:user:create")
@RequiresPermissionsDesc(menu={"会员管理" , "会员信息管理"}, button="添加")
@PostMapping("/create")
public Object create(@RequestBody WxUser user) {
Object error = validate(user);
if (error != null) {
return error;
}
String username = user.getUsername();
String mobile = user.getMobile();
List<WxUser> userList = userService.queryByUsername(username);
if (userList.size() > 0) {
return ResponseUtil.fail(USER_NAME_EXIST, "用户名已注册");
}
userList = userService.queryByMobile(mobile);
if (userList.size() > 0) {
return ResponseUtil.fail(USER_MOBILE_EXIST, "手机号已注册");
}
if (!RegexUtil.isMobileExact(mobile)) {
return ResponseUtil.fail(USER_INVALID_MOBILE, "手机号格式不正确");
}
if(user.getScores() != null && !RegexUtil.isNumeric(String.valueOf(user.getScores()))){
return ResponseUtil.fail(USER_SCORES_ERROR, "积分必须是大于或等于0的整数");
}
String password = user.getPassword();
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String encodedPassword = encoder.encode(password);
user.setPassword(encodedPassword);
userService.add(user);
return ResponseUtil.ok(user);
}
@RequiresPermissions("admin:user:update")
@RequiresPermissionsDesc(menu={"会员管理" , "会员信息管理"}, button="编辑")
@PostMapping("/update")
public Object update(@RequestBody WxUser user) {
Object error = validate(user);
if (error != null) {
return error;
}
// 如果已加密,则不加密,否则加密
String password = user.getPassword();
// System.out.println("*****前端***************:"+password+"***********后端*************:"+userDB.getPassword().trim());
if(password != null && password.trim().length() <= 22){
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String encodedPassword = encoder.encode(password);
user.setPassword(encodedPassword);
}
if(user.getScores() != null && !RegexUtil.isNumeric(String.valueOf(user.getScores()))){
return ResponseUtil.fail(USER_SCORES_ERROR, "积分必须是大于或等于0的整数");
}
if (userService.updateById(user) == 0) {
return ResponseUtil.updatedDataFailed();
}
return ResponseUtil.ok(user);
}
//批量删除
@RequiresPermissions("admin:user:delete")
@RequiresPermissionsDesc(menu={"会员管理" , "会员信息管理"}, button="删除")
@PostMapping("/delete")
public Object delete(@RequestBody Integer[] ids) {
return userService.deleteByIds(ids);
}
}
spring:
profiles:
active: db, core, admin
messages:
encoding: UTF-8
server:
port: 8083
logging:
level:
root: ERROR
org.springframework: ERROR
org.mybatis: ERROR
cn.exploring.engine.server.admin: DEBUG
cn.exploring.engine.server: ERROR
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>server-all</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>cn.exploring.engine</groupId>
<artifactId>server</artifactId>
<version>0.1.0</version>
</parent>
<dependencies>
<dependency>
<groupId>cn.exploring.engine</groupId>
<artifactId>server-core</artifactId>
</dependency>
<dependency>
<groupId>cn.exploring.engine</groupId>
<artifactId>server-db</artifactId>
</dependency>
<dependency>
<groupId>cn.exploring.engine</groupId>
<artifactId>server-wx-api</artifactId>
</dependency>
<dependency>
<groupId>cn.exploring.engine</groupId>
<artifactId>server-admin-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package cn.exploring.engine.server;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.cors.CorsConfiguration;
@SpringBootApplication(scanBasePackages = {"cn.exploring.engine.server"})
@MapperScan("cn.exploring.engine.server.db.dao")
@EnableTransactionManagement
@EnableScheduling
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);//这两句不加不能跨域上传文件,
corsConfiguration.setMaxAge(3600L);//加上去就可以了
return corsConfiguration;
}
}
spring:
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
profiles:
include: dbDev, coreDev, adminDev, wxDev
server:
port: 8181
logging:
level:
root: ERROR
org.springframework: ERROR
org.mybatis: ERROR
cn.exploring.engine.server.db.dao: ERROR
cn.exploring.engine.server.core: ERROR
cn.exploring.engine.server.db: ERROR
cn.exploring.engine.server.admin: ERROR
cn.exploring.engine.server.wx: ERROR
cn.exploring.engine.server: ERROR
# redis相关配置
projectRedis:
keyPrefix:
share: "BI-SHARE-TEST-" # 分享相关
userInfo: "GYH-USER-INFO-TEST-" # 用户信息key前缀
expireDay: 30 # 默认过期时间天数
spring:
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
profiles:
include: dbProd, coreProd, adminProd, wxProd
server:
port: 8181
logging:
level:
root: ERROR
org.springframework: ERROR
org.mybatis: ERROR
cn.exploring.engine.server.core: ERROR
cn.exploring.engine.server.db: ERROR
cn.exploring.engine.server.admin: ERROR
cn.exploring.engine.server.wx: ERROR
cn.exploring.engine.server: ERROR
# redis相关配置
projectRedis:
keyPrefix:
share: "BI-SHARE-" # 分享相关
userInfo: "GYH-USER-INFO-" # 用户信息key前缀
expireDay: 30 # 默认过期时间天数
spring:
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
profiles:
include: dbTest, coreTest, adminTest, wxTest
server:
port: 8181
logging:
level:
root: ERROR
org.springframework: ERROR
org.mybatis: ERROR
cn.exploring.engine.server.core: ERROR
cn.exploring.engine.server.db: ERROR
cn.exploring.engine.server.admin: ERROR
cn.exploring.engine.server.wx: ERROR
cn.exploring.engine.server: ERROR
# redis相关配置
projectRedis:
keyPrefix:
share: "BI-SHARE-" # 分享相关
userInfo: "GYH-USER-INFO-TEST-" # 用户信息key前缀
expireDay: 30 # 默认过期时间天数
spring:
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
profiles:
active: dev
messages:
encoding: UTF-8
servlet:
multipart:
max-file-size: 200Mb
max-request-size: 100MB
server:
port: 8181
logging:
level:
root: ERROR
org.springframework: ERROR
org.mybatis: ERROR
cn.exploring.engine.server.core: ERROR
cn.exploring.engine.server.db: ERROR
cn.exploring.engine.server.admin: ERROR
cn.exploring.engine.server.wx: ERROR
cn.exploring.engine.server: ERROR
mybatis:
configuration:
map-underscore-to-camel-case: true
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>server-core</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>cn.exploring.engine</groupId>
<artifactId>server</artifactId>
<version>0.1.0</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>3.0.114</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
<dependency>
<groupId>com.github.qcloudsms</groupId>
<artifactId>qcloudsms</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>3.3.1</version>
</dependency>
<!--谷歌缓存 缓存在内存中-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.1-jre</version>
</dependency>
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<exclusions>
<exclusion>
<artifactId>commons-lang</artifactId>
<groupId>commons-lang</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
</dependency>
<dependency>
<groupId>cn.exploring.engine</groupId>
<artifactId>server-db</artifactId>
</dependency>
<!-- 邮件模板freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.11</version>
</dependency>
</dependencies>
</project>
package cn.exploring.engine.server.core;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = {"cn.exploring.engine.server.db", "cn.exploring.engine.server.core"})
@MapperScan("cn.exploring.engine.server.db.dao")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
package cn.exploring.engine.server.core.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
@Configuration
@EnableAsync
public class AsyncConfig {
}
package cn.exploring.engine.server.core.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 4 对接口配置跨域设置
return new CorsFilter(source);
}
}
package cn.exploring.engine.server.core.config;
import cn.exploring.engine.server.core.util.ResponseUtil;
import org.hibernate.validator.internal.engine.path.PathImpl;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.Set;
@ControllerAdvice
@Order( value = Ordered.LOWEST_PRECEDENCE )
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
@ResponseBody
public Object badArgumentHandler(HttpServletRequest request, IllegalArgumentException e) {
e.printStackTrace();
printExceptionInfo(request);
return ResponseUtil.badArgumentValue();
}
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
@ResponseBody
public Object badArgumentHandler(HttpServletRequest request, MethodArgumentTypeMismatchException e) {
e.printStackTrace();
printExceptionInfo(request);
return ResponseUtil.badArgumentValue();
}
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseBody
public Object badArgumentHandler(HttpServletRequest request, MissingServletRequestParameterException e) {
e.printStackTrace();
printExceptionInfo(request);
return ResponseUtil.badArgumentValue();
}
@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseBody
public Object badArgumentHandler(HttpServletRequest request, HttpMessageNotReadableException e) {
e.printStackTrace();
printExceptionInfo(request);
return ResponseUtil.badArgumentValue();
}
@ExceptionHandler(ValidationException.class)
@ResponseBody
public Object badArgumentHandler(HttpServletRequest request, ValidationException e) {
e.printStackTrace();
printExceptionInfo(request);
if (e instanceof ConstraintViolationException) {
ConstraintViolationException exs = (ConstraintViolationException) e;
Set<ConstraintViolation<?>> violations = exs.getConstraintViolations();
for (ConstraintViolation<?> item : violations) {
String message = ((PathImpl) item.getPropertyPath()).getLeafNode().getName() + item.getMessage();
return ResponseUtil.fail(402, message);
}
}
return ResponseUtil.badArgumentValue();
}
@ExceptionHandler(Exception.class)
@ResponseBody
public Object seriousHandler(HttpServletRequest request, Exception e) {
e.printStackTrace();
printExceptionInfo(request);
return ResponseUtil.serious();
}
private void printExceptionInfo(HttpServletRequest request) {
System.out.println();
int id = request.hashCode();
System.out.println("========================================== 请求出错啦 sessionId: " + id + " ==========================================");
System.out.println("sessionId: " + id + " ======= 请求方式:" + request.getMethod());
System.out.println("sessionId: " + id + " ======= 请求地址:" + request.getRequestURL().toString());
System.out.println("sessionId: " + id + " ======= 请求参数:" + request.getQueryString());
System.out.println("========================================== 错误打印结束 sessionId: " + id + " ==========================================");
System.out.println();
}
}
package cn.exploring.engine.server.core.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
@Configuration
public class JacksonConfig {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public Jackson2ObjectMapperBuilderCustomizer customJackson() {
return new Jackson2ObjectMapperBuilderCustomizer() {
@Override
public void customize(Jackson2ObjectMapperBuilder builder) {
builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
builder.serializerByType(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
builder.serializerByType(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
builder.deserializerByType(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
builder.deserializerByType(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
builder.serializationInclusion(JsonInclude.Include.NON_NULL);
builder.failOnUnknownProperties(false);
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
};
}
}
package cn.exploring.engine.server.core.config;
import cn.exploring.engine.server.core.notify.NotifyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
//定时任务
@Configuration
@EnableScheduling
public class NotifyScheduleTask {
@Autowired
private NotifyService notifyService;
/**
* 每5分钟统一一次组织总步数
*/
@Scheduled(cron = "0 */30 * * * ?")
private void countOrgAllStep() {
System.out.println("NotifyScheduleTask test!");
}
}
package cn.exploring.engine.server.core.config;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
@Configuration
public class ValidatorConfiguration {
@Bean
public Validator validator() {
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure()
.addProperty("hibernate.validator.fail_fast", "true")
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
return validator;
}
}
package cn.exploring.engine.server.core.config;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.config.WxMaInMemoryConfig;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WxConfig {
@Autowired
private WxProperties properties;
@Bean
public WxMaConfig wxMaConfig() {
WxMaInMemoryConfig config = new WxMaInMemoryConfig();
config.setAppid(properties.getAppId());
config.setSecret(properties.getAppSecret());
return config;
}
@Bean
public WxMaService wxMaService(WxMaConfig maConfig) {
WxMaService service = new WxMaServiceImpl();
service.setWxMaConfig(maConfig);
return service;
}
@Bean
public WxPayConfig wxPayConfig() {
WxPayConfig payConfig = new WxPayConfig();
payConfig.setAppId(properties.getAppId());
payConfig.setMchId(properties.getMchId());
payConfig.setMchKey(properties.getMchKey());
payConfig.setNotifyUrl(properties.getNotifyUrl());
payConfig.setKeyPath(properties.getKeyPath());
payConfig.setTradeType("JSAPI");
payConfig.setSignType("MD5");
return payConfig;
}
@Bean
public WxPayService wxPayService(WxPayConfig payConfig) {
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(payConfig);
return wxPayService;
}
}
package cn.exploring.engine.server.core.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "server.wx")
public class WxProperties {
private String appId;
private String appSecret;
private String mchId;
private String mchKey;
private String notifyUrl;
private String keyPath;
public String getNotifyUrl() {
return notifyUrl;
}
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
public String getMchKey() {
return mchKey;
}
public void setMchKey(String mchKey) {
this.mchKey = mchKey;
}
public String getAppId() {
return this.appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getAppSecret() {
return appSecret;
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
}
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getKeyPath() {
return keyPath;
}
public void setKeyPath(String keyPath) {
this.keyPath = keyPath;
}
}
package cn.exploring.engine.server.core.express;
import cn.exploring.engine.server.core.express.dao.ExpressInfo;
import cn.exploring.engine.server.core.util.HttpUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.exploring.engine.server.core.express.config.ExpressProperties;
import org.springframework.util.Base64Utils;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
/**
* 物流查询服务
*
* 快递鸟即时查询API http://www.kdniao.com/api-track
*/
public class ExpressService {
//请求url
private String ReqURL = "http://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx";
private ExpressProperties properties;
public ExpressProperties getProperties() {
return properties;
}
public void setProperties(ExpressProperties properties) {
this.properties = properties;
}
/**
* 获取物流供应商名
*
* @param vendorCode
* @return
*/
public String getVendorName(String vendorCode) {
for (Map<String, String> item : properties.getVendors()) {
if (item.get("code").equals(vendorCode))
return item.get("name");
}
return null;
}
/**
* 获取物流信息
*
* @param expCode
* @param expNo
* @return
*/
public ExpressInfo getExpressInfo(String expCode, String expNo) {
try {
String result = getOrderTracesByJson(expCode, expNo);
ObjectMapper objMap = new ObjectMapper();
ExpressInfo ei = objMap.readValue(result, ExpressInfo.class);
ei.setShipperName(getVendorName(expCode));
return ei;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Json方式 查询订单物流轨迹
*
* @throws Exception
*/
private String getOrderTracesByJson(String expCode, String expNo) throws Exception {
if (!properties.isEnable()) {
return null;
}
String requestData = "{'OrderCode':'','ShipperCode':'" + expCode + "','LogisticCode':'" + expNo + "'}";
Map<String, String> params = new HashMap<String, String>();
params.put("RequestData", URLEncoder.encode(requestData, "UTF-8"));
params.put("EBusinessID", properties.getAppId());
params.put("RequestType", "1002");
String dataSign = encrypt(requestData, properties.getAppKey(), "UTF-8");
params.put("DataSign", URLEncoder.encode(dataSign, "UTF-8"));
params.put("DataType", "2");
String result = HttpUtil.sendPost(ReqURL, params);
//根据公司业务处理返回的信息......
return result;
}
/**
* MD5加密
*
* @param str 内容
* @param charset 编码方式
* @throws Exception
*/
private String MD5(String str, String charset) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes(charset));
byte[] result = md.digest();
StringBuffer sb = new StringBuffer(32);
for (int i = 0; i < result.length; i++) {
int val = result[i] & 0xff;
if (val <= 0xf) {
sb.append("0");
}
sb.append(Integer.toHexString(val));
}
return sb.toString().toLowerCase();
}
/**
* Sign签名生成
*
* @param content 内容
* @param keyValue Appkey
* @param charset 编码方式
* @return DataSign签名
*/
private String encrypt(String content, String keyValue, String charset) {
if (keyValue != null) {
content = content + keyValue;
}
byte[] src = new byte[0];
try {
src = MD5(content, charset).getBytes(charset);
return Base64Utils.encodeToString(src);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package cn.exploring.engine.server.core.express.config;
import cn.exploring.engine.server.core.express.ExpressService;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(ExpressProperties.class)
public class ExpressAutoConfiguration {
private final ExpressProperties properties;
public ExpressAutoConfiguration(ExpressProperties properties) {
this.properties = properties;
}
@Bean
public ExpressService expressService() {
ExpressService expressService = new ExpressService();
expressService.setProperties(properties);
return expressService;
}
}
package cn.exploring.engine.server.core.express.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ConfigurationProperties(prefix = "server.express")
public class ExpressProperties {
private boolean enable;
private String appId;
private String appKey;
private List<Map<String, String>> vendors = new ArrayList<>();
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public List<Map<String, String>> getVendors() {
return vendors;
}
public void setVendors(List<Map<String, String>> vendors) {
this.vendors = vendors;
}
public String getAppKey() {
return appKey;
}
public void setAppKey(String appKey) {
this.appKey = appKey;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
}
/**
* Copyright 2018 bejson.com
*/
package cn.exploring.engine.server.core.express.dao;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
/**
* Auto-generated: 2018-07-19 22:27:22
*
* @author bejson.com (i@bejson.com)
* @website http://www.bejson.com/java2pojo/
*/
public class ExpressInfo {
@JsonProperty("LogisticCode")
private String LogisticCode;
@JsonProperty("ShipperCode")
private String ShipperCode;
@JsonProperty("Traces")
private List<Traces> Traces;
@JsonProperty("State")
private String State;
@JsonProperty("EBusinessID")
private String EBusinessID;
@JsonProperty("Success")
private boolean Success;
@JsonProperty("Reason")
private String Reason;
private String ShipperName;
public String getLogisticCode() {
return LogisticCode;
}
public void setLogisticCode(String LogisticCode) {
this.LogisticCode = LogisticCode;
}
public String getShipperCode() {
return ShipperCode;
}
public void setShipperCode(String ShipperCode) {
this.ShipperCode = ShipperCode;
}
public List<Traces> getTraces() {
return Traces;
}
public void setTraces(List<Traces> Traces) {
this.Traces = Traces;
}
public String getState() {
return State;
}
public void setState(String State) {
this.State = State;
}
public String getEBusinessID() {
return EBusinessID;
}
public void setEBusinessID(String EBusinessID) {
this.EBusinessID = EBusinessID;
}
public boolean getSuccess() {
return Success;
}
public void setSuccess(boolean Success) {
this.Success = Success;
}
public String getReason() {
return Reason;
}
public void setReason(String Reason) {
this.Reason = Reason;
}
public String getShipperName() {
return ShipperName;
}
public void setShipperName(String shipperName) {
ShipperName = shipperName;
}
@Override
public String toString() {
return "ExpressInfo{" +
"LogisticCode='" + LogisticCode + '\'' +
", ShipperCode='" + ShipperCode + '\'' +
", Traces=" + Traces +
", State='" + State + '\'' +
", EBusinessID='" + EBusinessID + '\'' +
", Success=" + Success +
", Reason=" + Reason +
", ShipperName='" + ShipperName + '\'' +
'}';
}
}
/**
* Copyright 2018 bejson.com
*/
package cn.exploring.engine.server.core.express.dao;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Auto-generated: 2018-07-19 22:27:22
*
* @author bejson.com (i@bejson.com)
* @website http://www.bejson.com/java2pojo/
*/
public class Traces {
@JsonProperty("AcceptStation")
private String AcceptStation;
@JsonProperty("AcceptTime")
private String AcceptTime;
public String getAcceptStation() {
return AcceptStation;
}
public void setAcceptStation(String AcceptStation) {
this.AcceptStation = AcceptStation;
}
public String getAcceptTime() {
return AcceptTime;
}
public void setAcceptTime(String AcceptTime) {
this.AcceptTime = AcceptTime;
}
}
package cn.exploring.engine.server.core.notify;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.HashMap;
/*
* 阿里云短信服务
*/
public class AliyunSmsSender implements SmsSender {
private final Log logger = LogFactory.getLog(AliyunSmsSender.class);
private final String product = "Dysmsapi";
private final String domain = "dysmsapi.aliyuncs.com";
private final String accessKeyId = "ztCPfI257OJL6Fe0";
private final String accessKeySecret = "VpsvKMdzo1Ag05L7bWdhNadfTCfE5H";
private final String signName = "戈十五";
private final String templateCode1 = "SMS_183245262"; // 戈15报名成功-AB组类型通知
private final String templateCode2 = "SMS_183240880"; // 戈15报名成功-志愿者组类型通知
private final String templateCode3 = "SMS_183260898"; // 戈15报名成功-媒体摄影组类型通知
private final String templateCode4 = "SMS_183265503"; // 戈15报名成功-合作伙伴组类型通知
private final HashMap<Integer, String > templateCodeMap = new HashMap<Integer, String>(){{
put(1, templateCode1);
put(2, templateCode2);
put(3, templateCode3);
put(4, templateCode4);
}};
private int subType;
public AliyunSmsSender(int subType) {
this.subType = subType;
}
@Override
public SmsResult send(String phone, String content) {
return null;
}
@Override
public SmsResult sendWithTemplate(String phone, int templateId, String[] params) {
try {
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//组装请求对象-具体描述见控制台-文档部分内容
SendSmsRequest request = new SendSmsRequest();
request.setMethod(MethodType.POST);
//必填:待发送手机号
request.setPhoneNumbers(phone);
//必填:短信签名-可在短信控制台中找到
request.setSignName(signName);
//必填:短信模板-可在短信控制台中找到
String templateCode = templateCodeMap.get(subType);
request.setTemplateCode(templateCode);
request.setTemplateParam("{\"name\":\""+params[0] +"\"}");
//hint 此处可能会抛出异常,注意catch
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public int getSubType() {
return subType;
}
public void setSubType(int subType) {
this.subType = subType;
}
}
package cn.exploring.engine.server.core.notify;
public enum NotifyType {
PAY_SUCCEED("paySucceed"),
SHIP("ship"),
REFUND("refund"),
CAPTCHA("captcha"),
OTHER("other");
private String type;
NotifyType(String type) {
this.type = type;
}
public String getType() {
return this.type;
}
}
package cn.exploring.engine.server.core.notify;
/**
* 发送短信的返回结果
*/
public class SmsResult {
private boolean successful;
private Object result;
/**
* 短信是否发送成功
*
* @return
*/
public boolean isSuccessful() {
return successful;
}
public void setSuccessful(boolean successful) {
this.successful = successful;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
}
package cn.exploring.engine.server.core.notify;
public interface SmsSender {
/**
* 发送短信息
*
* @param phone 接收通知的电话号码
* @param content 短消息内容
*/
SmsResult send(String phone, String content);
/**
* 通过短信模版发送短信息
*
* @param phone 接收通知的电话号码
* @param templateId 通知模板ID
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
*/
SmsResult sendWithTemplate(String phone, int templateId, String[] params);
}
package cn.exploring.engine.server.core.notify;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.github.qcloudsms.httpclient.HTTPException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
/*
* 腾讯云短信服务
*/
public class TencentSmsSender implements SmsSender {
private final Log logger = LogFactory.getLog(TencentSmsSender.class);
private SmsSingleSender sender;
public SmsSingleSender getSender() {
return sender;
}
public void setSender(SmsSingleSender sender) {
this.sender = sender;
}
@Override
public SmsResult send(String phone, String content) {
try {
SmsSingleSenderResult result = sender.send(0, "86", phone, content, "", "");
logger.debug(result);
SmsResult smsResult = new SmsResult();
smsResult.setSuccessful(true);
smsResult.setResult(result);
return smsResult;
} catch (HTTPException | IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public SmsResult sendWithTemplate(String phone, int templateId, String[] params) {
try {
SmsSingleSenderResult result = sender.sendWithParam("86", phone, templateId, params, "", "", "");
logger.debug(result);
SmsResult smsResult = new SmsResult();
smsResult.setSuccessful(true);
smsResult.setResult(result);
return smsResult;
} catch (HTTPException | IOException e) {
e.printStackTrace();
}
return null;
}
}
package cn.exploring.engine.server.core.notify;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateData;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
import cn.exploring.engine.server.db.domain.WxUserFormid;
import cn.exploring.engine.server.db.service.WxUserFormIdService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;
/**
* 微信模版消息通知
*/
public class WxTemplateSender {
private final Log logger = LogFactory.getLog(WxTemplateSender.class);
@Autowired
private WxMaService wxMaService;
@Autowired
private WxUserFormIdService formIdService;
/**
* 发送微信消息(模板消息),不带跳转
*
* @param touser 用户 OpenID
* @param templatId 模板消息ID
* @param parms 详细内容
*/
public void sendWechatMsg(String touser, String templatId, String[] parms) {
sendMsg(touser, templatId, parms, "", "", "");
}
/**
* 发送微信消息(模板消息),带跳转
*
* @param touser 用户 OpenID
* @param templatId 模板消息ID
* @param parms 详细内容
* @param page 跳转页面
*/
public void sendWechatMsg(String touser, String templatId, String[] parms, String page) {
sendMsg(touser, templatId, parms, page, "", "");
}
private void sendMsg(String touser, String templatId, String[] parms, String page, String color, String emphasisKeyword) {
WxUserFormid userFormid = formIdService.queryByOpenId(touser);
if (userFormid == null)
return;
WxMaTemplateMessage msg = new WxMaTemplateMessage();
msg.setTemplateId(templatId);
msg.setToUser(touser);
msg.setFormId(userFormid.getFormid());
msg.setPage(page);
msg.setColor(color);
msg.setEmphasisKeyword(emphasisKeyword);
msg.setData(createMsgData(parms));
try {
wxMaService.getMsgService().sendTemplateMsg(msg);
if (formIdService.updateUserFormId(userFormid) == 0) {
logger.warn("更新数据已失效");
}
} catch (Exception e) {
e.printStackTrace();
}
}
private List<WxMaTemplateData> createMsgData(String[] parms) {
List<WxMaTemplateData> dataList = new ArrayList<WxMaTemplateData>();
for (int i = 1; i <= parms.length; i++) {
dataList.add(new WxMaTemplateData("keyword" + i, parms[i - 1]));
}
return dataList;
}
}
package cn.exploring.engine.server.core.notify.config;
import cn.exploring.engine.server.core.notify.NotifyService;
import cn.exploring.engine.server.core.notify.WxTemplateSender;
import com.github.qcloudsms.SmsSingleSender;
import cn.exploring.engine.server.core.notify.TencentSmsSender;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
@Configuration
@EnableConfigurationProperties(NotifyProperties.class)
public class NotifyAutoConfiguration {
private final NotifyProperties properties;
public NotifyAutoConfiguration(NotifyProperties properties) {
this.properties = properties;
}
@Bean
public NotifyService notifyService() {
NotifyService notifyService = new NotifyService();
NotifyProperties.Mail mailConfig = properties.getMail();
if (mailConfig.isEnable()) {
notifyService.setMailSender(mailSender());
notifyService.setSendFrom(mailConfig.getSendfrom());
notifyService.setSendTo(mailConfig.getSendto());
}
NotifyProperties.Sms smsConfig = properties.getSms();
if (smsConfig.isEnable()) {
notifyService.setSmsSender(tencentSmsSender());
notifyService.setSmsTemplate(smsConfig.getTemplate());
}
NotifyProperties.Wx wxConfig = properties.getWx();
if (wxConfig.isEnable()) {
notifyService.setWxTemplateSender(wxTemplateSender());
notifyService.setWxTemplate(wxConfig.getTemplate());
}
return notifyService;
}
@Bean
public JavaMailSender mailSender() {
NotifyProperties.Mail mailConfig = properties.getMail();
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost(mailConfig.getHost());
mailSender.setUsername(mailConfig.getUsername());
mailSender.setPassword(mailConfig.getPassword());
return mailSender;
}
@Bean
public WxTemplateSender wxTemplateSender() {
WxTemplateSender wxTemplateSender = new WxTemplateSender();
return wxTemplateSender;
}
@Bean
public TencentSmsSender tencentSmsSender() {
NotifyProperties.Sms smsConfig = properties.getSms();
TencentSmsSender smsSender = new TencentSmsSender();
smsSender.setSender(new SmsSingleSender(smsConfig.getAppid(), smsConfig.getAppkey()));
return smsSender;
}
}
package cn.exploring.engine.server.core.notify.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ConfigurationProperties(prefix = "server.notify")
public class NotifyProperties {
private Mail mail;
private Sms sms;
private Wx wx;
public Mail getMail() {
return mail;
}
public void setMail(Mail mail) {
this.mail = mail;
}
public Sms getSms() {
return sms;
}
public void setSms(Sms sms) {
this.sms = sms;
}
public Wx getWx() {
return wx;
}
public void setWx(Wx wx) {
this.wx = wx;
}
public static class Mail {
private boolean enable;
private String host;
private String username;
private String password;
private String sendfrom;
private String sendto;
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSendfrom() {
return sendfrom;
}
public void setSendfrom(String sendfrom) {
this.sendfrom = sendfrom;
}
public String getSendto() {
return sendto;
}
public void setSendto(String sendto) {
this.sendto = sendto;
}
}
public static class Sms {
private boolean enable;
private int appid;
private String appkey;
private List<Map<String, String>> template = new ArrayList<>();
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public int getAppid() {
return appid;
}
public void setAppid(int appid) {
this.appid = appid;
}
public String getAppkey() {
return appkey;
}
public void setAppkey(String appkey) {
this.appkey = appkey;
}
public List<Map<String, String>> getTemplate() {
return template;
}
public void setTemplate(List<Map<String, String>> template) {
this.template = template;
}
}
public static class Wx {
private boolean enable;
private List<Map<String, String>> template = new ArrayList<>();
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public List<Map<String, String>> getTemplate() {
return template;
}
public void setTemplate(List<Map<String, String>> template) {
this.template = template;
}
}
}
package cn.exploring.engine.server.core.qcode;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.exploring.engine.server.core.storage.StorageService;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
@Service
public class QCodeService {
@Autowired
WxMaService wxMaService;
@Autowired
private StorageService storageService;
public static final String INVOTE = "INVOTE"; // 生成邀请码类型的标识
public String createShareQrcodeImage(String id, String url, String type, String pic, String name) {
try {
File file = wxMaService.getQrcodeService().createWxaCodeUnlimit("id," + id, url);
FileInputStream inputStream = new FileInputStream(file);
//savePic(inputStream, organize.getOrgName() + "-" + file.getName());
byte[] imageData = null;
if (!StringUtils.isEmpty(type) && INVOTE.equals(type)) { // 后台生成邀请码
imageData = drawPicture(inputStream, pic, name);
} else { // 生成二维码
imageData = drawPicture(inputStream);
}
//将二维码图片保存
ByteArrayInputStream inputStream2 = new ByteArrayInputStream(imageData);
//存储分享图
String keyName = getKeyName(id, url);
String result = storageService.store(inputStream2, imageData.length, "image/jpeg", keyName, storageService.generateKey(keyName));
return result;
} catch (WxErrorException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
private void savePic(InputStream inputStream, String fileName) {
OutputStream os = null;
try {
String path = "/storage/ewm/";
byte[] bs = new byte[1024];
int len;
File tempFile = new File(path);
if (!tempFile.exists()) {
tempFile.mkdirs();
}
os = new FileOutputStream(tempFile.getPath() + File.separator + fileName);
while ((len = inputStream.read(bs)) != -1) {
os.write(bs, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
os.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private String getKeyName(String id, String url) {
return "QCODE_" + url + "_" + id + ".jpg";
}
/**
* 将二维码图片保存
*
* @param qrCodeImg 二维码图片
* @return
* @throws IOException
*/
private byte[] drawPicture(InputStream qrCodeImg) throws IOException {
BufferedImage qrCodeImage = ImageIO.read(qrCodeImg);
//转jpg
BufferedImage result = new BufferedImage(qrCodeImage.getWidth(), qrCodeImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
result.getGraphics().drawImage(qrCodeImage, 0, 0, null);
ByteArrayOutputStream bs = new ByteArrayOutputStream();
ImageIO.write(result, "jpg", bs);
//最终byte数组
return bs.toByteArray();
}
/**
* 将邀请码保存
*
* @param qrCodeImg 二维码图片
* @return
* @throws IOException
*/
private byte[] drawPicture(InputStream qrCodeImg, String orgUrl, String orgName) throws IOException {
// 底图
ClassPathResource redResource = new ClassPathResource("invote.png");
BufferedImage red = ImageIO.read(redResource.getInputStream());
// 组织头图
URL orgPic = new URL(orgUrl);
BufferedImage orgImage = ImageIO.read(orgPic);
//小程序二维码
BufferedImage qrCodeImage = ImageIO.read(qrCodeImg);
//底层空白 bufferedImage
BufferedImage baseImage = new BufferedImage(red.getWidth(), red.getHeight(), BufferedImage.TYPE_4BYTE_ABGR_PRE);
//画上图片
drawImgInImg(baseImage, red, 0, 0, red.getWidth(), red.getHeight());
//画上组织图片
drawImgInImg(baseImage, orgImage, 131, 0, 210, 210);
//画上小程序二维码
drawImgInImg(baseImage, qrCodeImage, 98, 316, 278, 278);
//写上组织名称
drawTextInImgCenter(baseImage, orgName, 217, new Color(50, 51, 51));
//写上提示
drawTextInImgCenter(baseImage, "用微信扫描二维码即可使用", 701, new Color(126, 124, 126));
//转jpg
BufferedImage result = new BufferedImage(baseImage.getWidth(), baseImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
result.getGraphics().drawImage(baseImage, 0, 0, null);
ByteArrayOutputStream bs = new ByteArrayOutputStream();
ImageIO.write(result, "jpg", bs);
//最终byte数组
return bs.toByteArray();
}
private void drawTextInImgCenter(BufferedImage baseImage, String textToWrite, int y, Color color) {
Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
g2D.setColor(color);
String fontName = "Microsoft YaHei";
Font f = new Font(fontName, Font.PLAIN, 28);
g2D.setFont(f);
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 计算文字长度,计算居中的x点坐标
FontMetrics fm = g2D.getFontMetrics(f);
int textWidth = fm.stringWidth(textToWrite);
int widthX = (baseImage.getWidth() - textWidth) / 2;
// 表示这段文字在图片上的位置(x,y) .第一个是你设置的内容。
g2D.drawString(textToWrite, widthX, y);
// 释放对象
g2D.dispose();
}
private void drawTextInImg(BufferedImage baseImage, String textToWrite, int x, int y) {
Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
g2D.setColor(new Color(126, 124, 126));
//TODO 注意,这里的字体必须安装在服务器上
g2D.setFont(new Font("Microsoft YaHei", Font.PLAIN, 28));
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
System.out.println(2);
g2D.drawString(textToWrite, x, y);
g2D.dispose();
}
private void drawImgInImg(BufferedImage baseImage, BufferedImage imageToWrite, int x, int y, int width, int heigth) {
Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
/*if (tm) { // 透明
baseImage = g2D.getDeviceConfiguration().createCompatibleImage(width, heigth, Transparency.TRANSLUCENT);
g2D.dispose();
g2D = baseImage.createGraphics();
}*/
g2D.drawImage(imageToWrite, x, y, width, heigth, null);
g2D.dispose();
}
}
package cn.exploring.engine.server.core.storage;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.util.stream.Stream;
/**
* @author Yogeek
* @date 2018/7/16 16:10
* @decrpt 阿里云对象存储服务
*/
public class AliyunStorage implements Storage {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
private String dir;
private String domain;
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getAccessKeyId() {
return accessKeyId;
}
public void setAccessKeyId(String accessKeyId) {
this.accessKeyId = accessKeyId;
}
public String getAccessKeySecret() {
return accessKeySecret;
}
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}
public String getBucketName() {
return bucketName;
}
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
/**
* 获取阿里云OSS客户端对象
*
* @return ossClient
*/
private OSSClient getOSSClient() {
return new OSSClient(endpoint, accessKeyId, accessKeySecret);
}
private String getBaseUrl() {
return "https://" + domain + "/" + dir;
// return "https://" + bucketName + "." + endpoint + "/" + dir;
}
/**
* 阿里云OSS对象存储简单上传实现
*/
@Override
public void store(InputStream inputStream, long contentLength, String contentType, String keyName) {
try {
// 简单文件上传, 最大支持 5 GB, 适用于小文件上传, 建议 20M以下的文件使用该接口
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(contentLength);
objectMetadata.setContentType(contentType);
// 对象键(Key)是对象在存储桶中的唯一标识。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, dir + keyName, inputStream, objectMetadata);
PutObjectResult putObjectResult = getOSSClient().putObject(putObjectRequest);
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override
public Stream<Path> loadAll() {
return null;
}
@Override
public Path load(String keyName) {
return null;
}
@Override
public Resource loadAsResource(String keyName) {
try {
URL url = new URL(getBaseUrl() + keyName);
Resource resource = new UrlResource(url);
if (resource.exists() || resource.isReadable()) {
return resource;
} else {
return null;
}
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
}
@Override
public void delete(String keyName) {
try {
getOSSClient().deleteObject(bucketName, keyName);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String generateUrl(String keyName) {
return getBaseUrl() + keyName;
}
}
package cn.exploring.engine.server.core.storage;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.stream.Stream;
/**
* 服务器本地对象存储服务
*/
public class LocalStorage implements Storage {
private String storagePath;
private String address;
private Path rootLocation;
public String getStoragePath() {
return storagePath;
}
public void setStoragePath(String storagePath) {
this.storagePath = storagePath;
this.rootLocation = Paths.get(storagePath);
try {
Files.createDirectories(rootLocation);
} catch (IOException e) {
e.printStackTrace();
}
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public void store(InputStream inputStream, long contentLength, String contentType, String keyName) {
try {
// 路径不存在则新建
Path p = rootLocation.resolve(keyName);
Path tmp = p.getParent();
if (tmp != null) {
Files.createDirectories(tmp);
}
Files.copy(inputStream, p, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
throw new RuntimeException("Failed to store file " + keyName, e);
}
}
@Override
public Stream<Path> loadAll() {
try {
return Files.walk(rootLocation, 1)
.filter(path -> !path.equals(rootLocation))
.map(path -> rootLocation.relativize(path));
} catch (IOException e) {
throw new RuntimeException("Failed to read stored files", e);
}
}
@Override
public Path load(String filename) {
return rootLocation.resolve(filename);
}
@Override
public Resource loadAsResource(String filename) {
try {
Path file = load(filename);
Resource resource = new UrlResource(file.toUri());
if (resource.exists() || resource.isReadable()) {
return resource;
} else {
return null;
}
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
}
@Override
public void delete(String filename) {
Path file = load(filename);
try {
Files.delete(file);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String generateUrl(String keyName) {
String url = address + keyName;
return url;
}
public String generatePath(String keyName) {
String path = rootLocation + "/" + keyName;
return path;
}
}
package cn.exploring.engine.server.core.storage;
import org.springframework.core.io.Resource;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.stream.Stream;
/**
* 对象存储接口
*/
public interface Storage {
/**
* 存储一个文件对象
*
* @param inputStream 文件输入流
* @param contentLength 文件长度
* @param contentType 文件类型
* @param keyName 文件名
*/
void store(InputStream inputStream, long contentLength, String contentType, String keyName);
Stream<Path> loadAll();
Path load(String keyName);
Resource loadAsResource(String keyName);
void delete(String keyName);
String generateUrl(String keyName);
}
package cn.exploring.engine.server.core.util;
import java.util.Random;
public class CharUtil {
public static String getRandomString(Integer num) {
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < num; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
public static String getRandomNum(Integer num) {
String base = "0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < num; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
}
package cn.exploring.engine.server.core.vo.email;
public class G15H5AuthCodeVo {
private String code;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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