Commit 6cfae964 by flyxiaozhu

测试 项目

parents
Showing with 4758 additions and 0 deletions
*.iml
target
/.idea
## 总架构图
![img](doc/spring-cloud.jpg)
---
> 学习博客:http://www.mooooc.com/spring-cloud.html
https://blog.csdn.net/forezp/article/details/70148833
https://windmt.com/2018/04/24/spring-cloud-12-sleuth-zipkin/
### 环境
> spring boot 版本:2.0.6.RELEASE
mvn环境
docker容器
docker-compose
### 启动
- 构建jar包(根目录下)
> mvn clean
mvn compile
mvn package
或者
> mvn clean install
- 构建镜像,启动容器
> docker-compose up -d --build
### 使用
- eureka server
功能:服务注册中心
- spring boot admin
功能:监控应用,查看应用运行信息
> 访问 http://主机:7020
账号:flyxiaozhu
密码:123456
![img](doc/login.png)
![img](doc/applications.png)
![img](doc/wallboard.png)
- config server
功能:配置中心
- server hello
功能:服务提供者
- ribbon/feign server
功能:服务消费者、熔断器、服务端负载均衡
- zuul gateway
功能:路由转发、熔断器、过滤器、客户端负载均衡
api-a 路由转发给 ribbon-server,api-b 路由转发给 feign-server。token 参数必须有,因为自定义了过滤器。
> 访问
http://主机:7070/api-a/hello?token=key
http://主机:7070/api-b/hello?token=key
http://主机:7070/api-b/test?token=key # 可以测试自动刷新配置
http://主机:7070/api-b/test2?token=key # 可以测试 feign 集群
- zipkin 服务链路追踪
> 访问 http://主机:9411
![img](doc/zipkin-1.png)
![img](doc/zipkin-2.png)
![img](doc/zipkin-3.png)
- turbine server
功能:hystrix 监控集群,监控 ribbon/feign server
- hystrix dashboard
功能:hystrix 监控面板
> 访问 http://主机:7060/hystrix
![img](doc/hystrix-1.png)
> 输入 http://主机:7050/turbine.stream
![img](doc/hystrix-2.png)
### 未实现
- zipkin 服务链路和 hystrix 监控使用的是http方式,可改成使用消息中间件 rabbitmq
- zipkin 的数据并未持久化
# 基于哪个镜像
FROM java:8
# 将本地文件夹挂载到当前容器
VOLUME /tmp
ADD ./target/erp-admin-api-1.0-SNAPSHOT.jar erp-admin-api.jar
## 开放端口
#EXPOSE 7020
# 配置容器启动后执行的命令
ENTRYPOINT ["java","-jar","/erp-admin-api.jar"]
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">
<parent>
<artifactId>erp</artifactId>
<groupId>com.maile</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>erp-admin-api</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer>
<mainClass>com.maile.erp.admin.AdminApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<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>
<artifactId>erp-admin-api</artifactId>
<packaging>jar</packaging>
<parent>
<artifactId>erp</artifactId>
<groupId>com.maile</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.maile</groupId>
<artifactId>erp-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--aop依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--显示应用版本信息-->
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.maile.erp.admin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableCaching
@EntityScan(basePackages = {"com.maile.erp"})
@ComponentScan(basePackages = {"com.maile.erp"})
@EnableJpaRepositories(basePackages = {"com.maile.erp"})
@EnableAsync
public class AdminApplication {
public static void main(String[] args) {
SpringApplication.run(AdminApplication.class, args);
}
}
package com.maile.erp.admin.LogSection;
import com.maile.erp.admin.authorize.AdminUserDetails;
import com.maile.erp.core.entities.Permission;
import com.maile.erp.core.entities.SysLog;
import com.maile.erp.core.services.SysLogService;
import com.maile.erp.core.utils.LoggerUtils;
import com.maile.erp.core.utils.MethodType;
import com.maile.erp.core.utils.ObjectMapUtils;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.Session;
import org.hibernate.event.internal.DefaultLoadEventListener;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.*;
import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.persister.entity.EntityPersister;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManagerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
@Component
@Slf4j
public class OperListener extends DefaultLoadEventListener implements PostDeleteEventListener, PostInsertEventListener, PostUpdateEventListener {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Autowired(required = false)
private HttpServletRequest request;
@Autowired(required = false)
private HttpServletResponse response;
@Autowired
private SysLogService sysLogService;
/**
* 注册事件
*/
@PostConstruct
public void registerListeners() {
SessionFactoryImpl sessionFactoryImpl = entityManagerFactory.unwrap(SessionFactoryImpl.class);
EventListenerRegistry eventListenerRegistry = sessionFactoryImpl.getServiceRegistry().getService(EventListenerRegistry.class);
eventListenerRegistry.getEventListenerGroup(EventType.POST_INSERT).appendListener(this);
eventListenerRegistry.getEventListenerGroup(EventType.POST_UPDATE).appendListener(this);
eventListenerRegistry.getEventListenerGroup(EventType.POST_DELETE).appendListener(this);
}
/**
* 监听删除事件
* event
*/
@Override
@Async
public void onPostDelete(PostDeleteEvent event) {
log.debug("数据删除监听");
StringBuffer remark = new StringBuffer();
remark.append("{");// 获得实体名称
for (int i = 0; i < event.getDeletedState().length; i++) {
// 过滤掉创建时间字段
if (event.getPersister().getPropertyNames()[i].equals("createTime")) {
continue;
}
remark.append("\"" + event.getPersister().getPropertyNames()[i] + "\": ");
remark.append("\"" + event.getDeletedState()[i] + "\"");
if (i != event.getDeletedState().length - 1) {
remark.append(",");
}
}
remark.append("}");
saveOperLog(event.getSession(), event.getEntity().getClass().getSimpleName(), event.getId(), remark, MethodType.DELETE.toString());
}
/**
* 监听插入事件
*
* @param event
*/
@Override
@Async
public void onPostInsert(PostInsertEvent event) {
if ((event.getEntity() instanceof SysLog) || (event.getEntity() instanceof Permission)) {// 当对日志表进行插入时,不进行记录
return;
}
log.debug("数据插入监听");
StringBuffer remark = new StringBuffer();
remark.append("{");// 获得实体名称
for (int i = 0; i < event.getState().length; i++) {
// 过滤掉创建时间字段
if (event.getPersister().getPropertyNames()[i].equals("createTime")) {
continue;
}
remark.append("\"" + event.getPersister().getPropertyNames()[i] + "\": ");
remark.append("\"" + event.getState()[i] + "\"");
if (i != event.getState().length - 1) {
remark.append(",");
}
}
remark.append("}");
saveOperLog(event.getSession(), event.getEntity().getClass().getSimpleName(), event.getId(), remark, MethodType.INSERT.toString());
}
/**
* 监听更新事件
*
* @param event
*/
@Override
@Async
public void onPostUpdate(PostUpdateEvent event) {
boolean temp = event.getState().equals(event.getOldState());
// 判断两个对象的内容是否相等
log.debug("数据更新监听");
StringBuffer des = new StringBuffer();//操作描述
des.append("{");// 获得实体名称
String diff = arrayDiff(event.getState(), event.getOldState(), event.getPersister().getPropertyNames());//判断修改了哪些部分,并拼接成字符串
des.append(diff);
des.append("}");
saveOperLog(event.getSession(), event.getEntity().getClass().getSimpleName(), event.getId(), des, MethodType.UPDATE.toString());
}
/**
* 日志的添加
*
* @param session
* @param des
*/
private void saveOperLog(Session session, String targetEntity, Serializable targetId, StringBuffer des, String methodType) {
log.debug("数据:" + des.toString());
// 创建日志实体
SysLog sysLog = new SysLog();
// 用户名
AdminUserDetails details = (AdminUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
sysLog.setUsername(details.getUsername());
// 实体名称
sysLog.setEntity(targetEntity);
// 设置数据ID值
sysLog.setDataId(Long.parseLong(targetId.toString()));
// 设置方法类型
sysLog.setMethodType(methodType);
// 设置请求方式(post|get)
sysLog.setRequestMethod(request.getMethod());
// 设置请求参数
sysLog.setRequestParams(ObjectMapUtils.mapToJson(request.getParameterMap()));
// 设置请求地址
sysLog.setRequestUrl(request.getRequestURI());
// 请求者ip
sysLog.setRequestIp(LoggerUtils.getCliectIp(request));
// 获取请求状态码
String status = String.valueOf(response.getStatus());
// 设置状态码
sysLog.setRequestCode(status);
// 设置数据变化
sysLog.setMethodDescription(des.toString());
//执行将日志写入数据库
sysLogService.save(sysLog);
}
/**
* 数组不同部分转字符串
*
* @param n 成员新值
* @param o 成员原值
* @param names 成员名
* @return
*/
private String arrayDiff(Object[] n, Object[] o, String[] names) {
StringBuffer result = new StringBuffer();
//各参数数组均按序传进来的,按index取值即可
for (int i = 0; i < n.length; i++) {
// 去除createTime字段
if (names[i].equals("createTime")) {
continue;
}
//如不相等,则加入字符串中
if (!String.valueOf(n[i]).equals(String.valueOf(o[i]))) {
result.append("\"" + names[i] + "\"" + ":\"" + o[i] + ">>" + n[i] + "\",");
}
}
if (result.length() > 0) {
return result.substring(0, result.length() - 1);
} else {
return "\"data\":\"内存地址改变,但内容无变化\"";
}
}
@Override
public boolean requiresPostCommitHanding(EntityPersister entityPersister) {
return false;
}
}
package com.maile.erp.admin.Result;
import com.maile.erp.core.entities.GoodsSku;
import com.maile.erp.core.entities.GoodsTag;
import lombok.Data;
import java.util.List;
@Data
public class GoodsResp {
private long id;
private String name;
private String goodsNo;
private int type;
private int status;
private int sales;
private int ruleId;
private long categoryId;
private String thumb;
private int stock;
private List<GoodsTag> tags;
private List<String> pictureList;
private String createTime;
private List<GoodsSku> sku;
private int sellingPrice;
private int examine;
private Boolean isInfiniteStock;
}
package com.maile.erp.admin.Result;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class GoodsShow {
private long id;
private String name;
private String goodsNo;
private long categoryId;
private long type;
private long ruleId;
private long sellingPrice;
private long status;
private List<Long> goodsTags;
private String thumb;
private List<String> slideImages;
private String goodsDetails;
private List<SpecItem> specList;
private List<SpecTags> specTags;
private List<Map<String,String>> specMultiplyData;
}
package com.maile.erp.admin.Result;
import lombok.Data;
@Data
public class Options {
private long key;
private String value;
private Boolean isTop = false;
}
package com.maile.erp.admin.Result;
import lombok.Data;
import java.util.List;
@Data
public class Schema {
private String key;
private String title;
private String dataType;
private String showType;
private List<Options> options;
}
package com.maile.erp.admin.Result;
import lombok.Data;
@Data
public class SpecItem {
private String key;
private String specName;
private String specItem;
}
package com.maile.erp.admin.Result;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class SpecTags {
private String specName;
private List<Map<String,String>> specItem;
}
package com.maile.erp.admin.annotations;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequireLogin {
boolean value() default true;
}
package com.maile.erp.admin.authorize;
import com.maile.erp.core.entities.AdminUser;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
public class AdminUserDetails implements UserDetails {
private AdminUser adminUser;
private Collection<? extends GrantedAuthority> authorities;
public AdminUserDetails(AdminUser adminUser, Collection<? extends GrantedAuthority> authorities) {
this.adminUser = adminUser;
this.authorities = authorities;
}
public AdminUser getAdminUser() {
return adminUser;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return adminUser.getPassword();
}
@Override
public String getUsername() {
return adminUser.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return adminUser.getStatus() == 0;
}
}
package com.maile.erp.admin.authorize;
import com.maile.erp.core.entities.AdminUser;
import com.maile.erp.core.entities.Permission;
import com.maile.erp.core.repositories.AdminUserRepository;
import com.maile.erp.core.repositories.PermissionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Service
public class AdminUserDetailsService implements UserDetailsService {
@Autowired
AdminUserRepository adminUserRepository;
@Autowired
PermissionRepository permissionRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
AdminUser user = adminUserRepository.findAdminUserByUsername(username);
if (user != null) {
List<Permission> permissions = permissionRepository.findByAdminUserId(user.getId());
Set<GrantedAuthority> authorities = new HashSet<>();
for (Permission permission : permissions) {
if (permission != null && permission.getName() != null) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_" + permission.getIdentity());
authorities.add(grantedAuthority);
}
}
return new AdminUserDetails(user, authorities);
} else {
throw new UsernameNotFoundException("admin: " + username + " do not exist!");
}
}
}
package com.maile.erp.admin.authorize;
import com.maile.erp.core.entities.AdminUser;
import com.maile.erp.core.utils.CollectionUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class AuthorizeHelper {
public static AdminUserDetails getUserDetails() {
return (AdminUserDetails) SecurityContextHolder.getContext()
.getAuthentication()
.getPrincipal();
}
public static AdminUser getUser() {
return getUserDetails().getAdminUser();
}
public static Collection<String> getPermissions() {
return getPermissions(null);
}
public static Collection<String> getPermissions(UserDetails userDetails) {
if (userDetails == null) {
userDetails = getUserDetails();
}
List<String> permission = CollectionUtils.map(userDetails.getAuthorities(), o -> o.getAuthority().replaceAll("^ROLE_", ""));
Collections.sort(permission);
return permission;
}
}
package com.maile.erp.admin.authorize;
import com.maile.erp.core.entities.Permission;
import com.maile.erp.core.repositories.PermissionRepository;
import com.maile.erp.core.utils.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Component
public class PermissionManager {
private PermissionRepository permissionRepository;
@Autowired
public void setPermissionRepository(PermissionRepository permissionRepository) {
this.permissionRepository = permissionRepository;
}
private Permission buildDefaultPermission(String identify) {
Permission permission = new Permission();
permission.setIdentity(identify);
permission.setName("未定义权限");
return permission;
}
public void init() {
PermissionScanner scanner = new PermissionScanner("com.maile.erp.admin.controllers");
List<Permission> permissions = permissionRepository.findAll();
Set<String> dbPerms = new HashSet<>(CollectionUtils.map(permissions, Permission::getIdentity));
Set<String> realPerms = scanner.getPermissions();
Set<String> newPerms = new HashSet<>(realPerms);
newPerms.removeAll(dbPerms);
Set<String> discardPerms = new HashSet<>(dbPerms);
discardPerms.removeAll(realPerms);
if (discardPerms.size() > 0) {
System.out.println("============无用的权限============");
System.out.println(discardPerms);
}
if (newPerms.size() > 0) {
System.out.println("============新注册权限============");
System.out.println(newPerms);
}
List<Permission> permissiones = new ArrayList<>();
for (String perm : newPerms) {
permissiones.add(buildDefaultPermission(perm));
}
permissionRepository.saveAll(permissiones);
}
}
package com.maile.erp.admin.authorize;
import com.maile.erp.core.libs.ClassScanner;
import com.maile.erp.core.utils.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PermissionScanner extends ClassScanner {
private String basePackage;
private Set<Class<?>> controllers;
public PermissionScanner(String basePackage) {
this.basePackage = basePackage;
}
public Set<Class<?>> getControllers() {
if (controllers == null) {
controllers = new HashSet<>();
Set<Class<?>> clsList = getClasses(basePackage, true);
if (clsList != null && clsList.size() > 0) {
for (Class<?> cls : clsList) {
if (cls.getAnnotation(Controller.class) != null || cls.getAnnotation(RestController.class) != null) {
controllers.add(cls);
}
}
}
}
return controllers;
}
public Set<String> getPermissions() {
Set<String> permissions = new HashSet<>();
for (Class<?> cls : getControllers()) {
Method[] methods = cls.getMethods();
for (Method method : methods) {
Secured securedAnnotation = method.getAnnotation(Secured.class);
if (securedAnnotation != null) {
String[] value = securedAnnotation.value();
permissions.addAll(CollectionUtils.map(value, o -> o.replaceAll("^ROLE_", "")));
} else {
String expression = "";
PreAuthorize preAuthorizeAnnotation = method.getAnnotation(PreAuthorize.class);
if (preAuthorizeAnnotation != null) {
expression = preAuthorizeAnnotation.value();
}
PostAuthorize postAuthorizeAnnotation = method.getAnnotation(PostAuthorize.class);
if (postAuthorizeAnnotation != null) {
expression = postAuthorizeAnnotation.value();
}
if (!StringUtils.isBlank(expression)) {
Pattern pattern = Pattern.compile("ROLE_\\w+");
Matcher matcher = pattern.matcher(expression);
while (matcher.find()) {
permissions.add(matcher.group().replaceAll("^ROLE_", ""));
}
}
}
}
}
return permissions;
}
}
package com.maile.erp.admin.configurations;
import com.maile.erp.admin.authorize.PermissionManager;
import com.maile.erp.admin.authorize.PermissionScanner;
import com.maile.erp.core.annotations.StockRule;
import com.maile.erp.core.libs.StockFactory;
import com.maile.erp.core.services.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Set;
@Component
public class AppListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
RedisService redisService;
private PermissionManager permissionManager;
@Autowired
void setPermissionManager(PermissionManager permissionManager) {
this.permissionManager = permissionManager;
}
@Override
@SuppressWarnings("unchecked")
public void onApplicationEvent(ContextRefreshedEvent event) {
if (event.getApplicationContext().getParent() == null) {
try {
initAutoDelivery(event);
initPermission();
Set keys = redisService.getRedisTemplate().keys("erp-cache:*");
redisService.getRedisTemplate().delete(keys);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void initAutoDelivery(ContextRefreshedEvent event) throws Exception {
Map<String, Object> beans = event.getApplicationContext().getBeansWithAnnotation(StockRule.class);
StockFactory.init(beans);
}
private void initPermission() {
permissionManager.init();
}
}
package com.maile.erp.admin.configurations;
import com.maile.erp.core.libs.AppException;
import com.maile.erp.core.libs.ErrorCode;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.services.RedisService;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.core.serializer.support.SerializationFailedException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.io.IOException;
import java.io.StreamCorruptedException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;
/**
* Description:
*
* @author johnny.lu
* @version 1.0
* @date 2017/12/30 1:06
* Created with IDEA
*/
@ControllerAdvice
public class WebControllerAdvice {
@Autowired
RedisService redisService;
private static final Logger logger = LoggerFactory.getLogger(WebControllerAdvice.class);
@InitBinder
protected void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
@ExceptionHandler(value = ConstraintViolationException.class)
@ResponseBody
public JSONResult handleResourceNotFoundException(ConstraintViolationException e) {
logger.debug("constraint violation exception", e);
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
StringBuilder strBuilder = new StringBuilder();
for (ConstraintViolation<?> violation : violations) {
String errorMsg = violation.getMessage();
strBuilder.append(errorMsg + "\n");
}
return new JSONResult(ErrorCode.INVALID_PARAM, strBuilder.toString());
}
@ExceptionHandler(value = BindException.class)
@ResponseBody
protected JSONResult handleBindException(BindException ex) throws IOException {
JSONResult result = new JSONResult(ex.getBindingResult());
return result;
}
@ExceptionHandler(value = MissingServletRequestParameterException.class)
@ResponseBody
protected JSONResult handleMissingServletRequestParameter(MissingServletRequestParameterException ex) throws IOException {
JSONResult result = new JSONResult(ErrorCode.INVALID_PARAM, "Miss parameter " + ex.getParameterName() + ".");
return result;
}
@ExceptionHandler(value = MissingPathVariableException.class)
@ResponseBody
protected JSONResult handleMissingPathVariable(MissingPathVariableException ex) throws IOException {
JSONResult result = new JSONResult(ErrorCode.INVALID_PARAM, "Miss path variable " + ex.getVariableName() + ".");
return result;
}
@ExceptionHandler(value = DataIntegrityViolationException.class)
@ResponseBody
protected JSONResult handleDataIntegrityViolationException(DataIntegrityViolationException ex) {
JSONResult result = new JSONResult(ErrorCode.DUPLICATE_KEY, "数据发生重复");
return result;
}
@ExceptionHandler(value = AppException.class)
@ResponseBody
protected JSONResult handleAppException(AppException ex) {
JSONResult result = new JSONResult(ex.getCode(), ex.getMessage());
return result;
}
@ExceptionHandler(value = AccessDeniedException.class)
@ResponseBody
protected JSONResult handleAppAccessDenied(AccessDeniedException ex) {
JSONResult result = new JSONResult(ErrorCode.FORBIDDEN, "你没有权限进行此操作");
return result;
}
@ExceptionHandler(value = SerializationFailedException.class)
@ResponseBody
@SuppressWarnings("unchecked")
protected JSONResult handleSerializationFailedException(SerializationFailedException ex) {
Set keys = redisService.getRedisTemplate().keys("erp-cache:*");
redisService.getRedisTemplate().delete(keys);
JSONResult result = new JSONResult(ErrorCode.UNKNOWN, "系统错误,请稍后再试");
return result;
}
}
package com.maile.erp.admin.configurations;
import com.maile.erp.admin.authorize.AdminUserDetails;
import com.maile.erp.admin.authorize.AdminUserDetailsService;
import com.maile.erp.admin.authorize.AuthorizeHelper;
import com.maile.erp.core.libs.ErrorCode;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.libs.RenderUtils;
import com.maile.erp.core.repositories.AdminUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.DigestUtils;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
AdminUserRepository adminUserRepository;
@Bean
UserDetailsService customUserDetailService() {
return new AdminUserDetailsService();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailService())
.passwordEncoder(new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
return DigestUtils.md5DigestAsHex(charSequence.toString().getBytes());
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return s.equals(DigestUtils.md5DigestAsHex(charSequence.toString().getBytes()));
}
});
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/", "/home", "/dist/**", "**.ico").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginProcessingUrl("/login")
.permitAll()
.successHandler((request, response, auth) -> {
AdminUserDetails userDetails = (AdminUserDetails) auth.getPrincipal();
JSONResult result = new JSONResult()
.put("user", userDetails.getAdminUser())
.put("permission", AuthorizeHelper.getPermissions(userDetails));
RenderUtils.renderJson(response, result);
})
.failureHandler((request, response, exception) -> {
if (exception instanceof BadCredentialsException) {
RenderUtils.renderJson(response, new JSONResult(ErrorCode.BAD_CREDENTIALS, "账号或密码错误"));
} else if (exception instanceof DisabledException) {
RenderUtils.renderJson(response, new JSONResult(ErrorCode.USER_DISABLED, "此账户已被禁用"));
} else {
RenderUtils.renderJson(response, new JSONResult(ErrorCode.UNKNOWN, "未知错误"));
}
})
.and()
.logout()
.logoutSuccessHandler((request, response, auth) -> response.sendRedirect("/"))
.permitAll()
.and()
.exceptionHandling()
.authenticationEntryPoint((request, response, exception) -> {
RenderUtils.renderJson(response, new JSONResult(ErrorCode.NOT_LOGIN, "尚未登录"));
});
}
}
package com.maile.erp.admin.controllers;
import com.maile.erp.admin.authorize.AdminUserDetails;
import com.maile.erp.admin.forms.AfterSaleOperationForm;
import com.maile.erp.core.apievents.AfsOrderEvent;
import com.maile.erp.core.entities.*;
import com.maile.erp.core.libs.*;
import com.maile.erp.core.repositories.*;
import com.maile.erp.core.services.GoodsService;
import com.maile.erp.core.utils.AliyunExpress;
import com.maile.erp.core.utils.BeanUtils;
import com.maile.erp.core.utils.SnUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
@RestController
@Validated
public class AfterSaleController {
@Autowired
GoodsOrderRepository goodsOrderRepository;
@Autowired
GoodsService goodsService;
@Autowired
GoodsOrderDetailRepository goodsOrderDetailRepository;
@Autowired
SnUtils snUtils;
@Autowired
AfterSaleRepository afterSaleRepository;
@Autowired
AfterSalePicturesRepository afterSalePicturesRepository;
@Autowired
AfterSaleDetailRepository afterSaleDetailRepository;
@Autowired
AfterSaleLogRepository afterSaleLogRepository;
@Autowired
ApiEventManager eventManager;
@Autowired
AppRepository appRepository;
@Autowired
AliyunExpress aliyunExpress;
@Secured("ROLE_AFTERSALE_SELECT")
@RequestMapping("/afterSale/select")
public JSONResult getAfterSaleList(HttpServletRequest request, @PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
Page<AfterSale> page = afterSaleRepository.findAll(new SearchSpecification<>(request), pageable);
return new JSONResult(page, pageable.getPageNumber());
}
@Secured("ROLE_AFTERSALE_GET_INFO")
@RequestMapping("/afterSale/getAfterSaleInfo")
@Transactional(rollbackFor = Exception.class)
public JSONResult getAfterSaleInfo(@RequestParam(value = "id") Long afterSaleId) {
AfterSale afterSale = afterSaleRepository.findById(afterSaleId).orElse(null);
if (afterSale == null) {
return new JSONResult(ErrorCode.NO_DATA, "售后ID错误");
}
// 备注图片
List<AfterSalePicture> afterSalePictureList = afterSalePicturesRepository.findByAfterSaleId(afterSale.getId());
afterSale.setAfterSalePictures(afterSalePictureList);
// 订单信息
GoodsOrder goodsOrder = goodsOrderRepository.findByOrderSn(afterSale.getOrderSn());
afterSale.setGoodsOrder(goodsOrder);
// 子订单信息
GoodsOrderDetail goodsOrderDetail = goodsOrderDetailRepository.findById(afterSale.getOrderDetailId()).orElse(null);
afterSale.setGoodsOrderDetail(goodsOrderDetail);
// 售后详情
AfterSaleDetail afterSaleDetail = afterSaleDetailRepository.findByAfterSaleSn(afterSale.getAfterSaleSn());
afterSale.setAfterSaleDetail(afterSaleDetail);
// 操作日志
List<AfterSaleLog> afterSaleLogList = afterSaleLogRepository.findByAfterSaleSn(afterSale.getAfterSaleSn());
afterSale.setAfterSaleLogList(afterSaleLogList);
return new JSONResult().put("afterSale", afterSale);
}
@Secured("ROLE_AFTERSALE_SAVE_OPERATION")
@RequestMapping("/afterSale/saveAfterSaleOperation")
@Transactional(rollbackFor = Exception.class)
public JSONResult saveAfterSaleOperation(@Valid AfterSaleOperationForm form, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return new JSONResult(bindingResult);
}
AfterSale afterSale = afterSaleRepository.findByAfterSaleSn(form.getAfterSaleSn());
if (afterSale == null) {
return new JSONResult(ErrorCode.NO_DATA, "售后编号错误");
}
AfterSaleDetail afterSaleDetail = afterSaleDetailRepository.findByAfterSaleSn(afterSale.getAfterSaleSn());
if(afterSaleDetail == null){
return new JSONResult(ErrorCode.NO_DATA, "售后详情为空");
}
// 判断状态是否存在
Map<Integer, String> afterSaleMap = Constants.AFTER_SALE_MAP();
if (afterSaleMap.get(form.getStatus()) == null) {
return new JSONResult(ErrorCode.INVALID_PARAM, "状态错误");
}
// 获取订单
GoodsOrder goodsOrder = goodsOrderRepository.findByOrderSn(afterSale.getOrderSn());
// 带用户寄回 状态
if (form.getStatus() == Constants.AFTER_SALE_SEND) {
afterSaleDetail.setSellerAddressee(form.getSellerAddressee());
afterSaleDetail.setSellerAddress(form.getSellerAddress());
afterSaleDetail.setSellerPhone(form.getSellerPhone());
afterSaleDetailRepository.save(afterSaleDetail);
}
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 拒绝受理,则保存备注
if (form.getStatus() == Constants.AFTER_SALE_REFUSE) {
afterSale.setRefuseDes(form.getRemark());
sendingEvents(afterSale, form, goodsOrder, AfsOrderEvent.TYPE_REFUSE);
} else {
// 记录受理时间
afterSale.setAcceptTime(df.format(new Date()));
}
// 完成售后
if (form.getStatus() == Constants.AFTER_SALE_COMPLETE) {
// 仅换货
if (afterSale.getType() == Constants.AFTER_TYPE_EXCHANGE_GOODS) {
// 库存,订单信息无需处理
sendingEvents(afterSale, form, goodsOrder, AfsOrderEvent.TYPE_EXCHANGE);
} else if (afterSale.getType() == Constants.AFTER_TYPE_REFUND_GOODS) { //退款退货
sendingEvents(afterSale, form, goodsOrder, AfsOrderEvent.TYPE_RETURN);
} else {
return new JSONResult(ErrorCode.NO_DATA, "售后类型错误");
}
}
// 关闭售后
if (form.getStatus() == Constants.AFTER_SALE_CLOSE) {
afterSale.setCloseTime(df.format(new Date()));
}
// 操作日志
AfterSaleLog afterSaleLog = new AfterSaleLog();
afterSaleLog.setAfterSaleSn(form.getAfterSaleSn());
// 用户名
AdminUserDetails details = (AdminUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
afterSaleLog.setOperator(details.getUsername());
afterSaleLog.setOperDes(afterSaleMap.get(afterSale.getStatus()) + " >> " + afterSaleMap.get(form.getStatus()));
afterSaleLog.setRemark(form.getRemark());
afterSale.setStatus(form.getStatus());
afterSaleLogRepository.save(afterSaleLog);
afterSaleRepository.save(afterSale);
return new JSONResult().put("afterSale", afterSale);
}
// 发送事件
private void sendingEvents(AfterSale afterSale, AfterSaleOperationForm form, GoodsOrder goodsOrder, String type) {
AfsOrderEvent event = new AfsOrderEvent(type);
event.setOutTradeNo(afterSale.getOutTradeNo());
event.setGoodsId(goodsOrder.getId());
event.setSkuId(afterSale.getSkuId());
event.setRefuseAmount(form.getRefuseAmount());
event.setStatus(form.getStatus());
List<App> apps = appRepository.findByStatus(Constants.COMMON_STATUS_NORMAL);
eventManager.postEvent(apps, event);
}
@Secured("ROLE_AFTERSALE_GET_EXPRESS_MESS")
@RequestMapping("/afterSale/getExpressMess")
public JSONResult getExpressMess(@RequestParam(value = "expressSn") String expressSn, @RequestParam(value = "expressCode") String expressCode) {
Object expressTraceInfo = aliyunExpress.getExpressMess(expressSn, expressCode);
return new JSONResult().put("expressTraceInfo", expressTraceInfo);
}
@RequestMapping("/afterSale/changeAfterSaleType")
public JSONResult changeAfterSaleType(@RequestParam(value = "afterSaleId") long afterSaleId, @RequestParam(value = "type") int type) {
AfterSale afterSale = afterSaleRepository.findById(afterSaleId).orElse(null);
if (afterSale == null) {
return new JSONResult(ErrorCode.NO_DATA, "没有该售后");
}
afterSale.setType(type);
afterSaleRepository.save(afterSale);
return new JSONResult().put("afterSale", afterSale);
}
@RequestMapping("/afterSale/getExpressName")
public JSONResult getExpressName(@RequestParam(value = "expressCode") String expressCode) {
String expressName = aliyunExpress.getName(expressCode);
return new JSONResult().put("expressName", expressName);
}
}
package com.maile.erp.admin.controllers;
import com.maile.erp.core.entities.App;
import com.maile.erp.core.libs.ErrorCode;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.libs.SearchSpecification;
import com.maile.erp.core.repositories.AppRepository;
import com.maile.erp.core.services.AppService;
import com.maile.erp.core.utils.BeanUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.annotation.Secured;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
@Validated
public class AppController {
@Autowired
AppRepository appRepository;
@Autowired
AppService appService;
@Secured("ROLE_APP_SELECT")
@RequestMapping("/app/select")
public JSONResult getList(HttpServletRequest request, @PageableDefault Pageable pageable) {
Page<App> page = appRepository.findAll(new SearchSpecification<>(request), pageable);
return new JSONResult(page, pageable.getPageNumber());
}
// @OperationLog(modular = "应用",method = MethodType.UPDATE,serviceclass = AppService.class)
@Secured("ROLE_APP_UPDATE")
@RequestMapping("/app/update")
public JSONResult update(App app, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return new JSONResult(bindingResult);
}
App old = appRepository.findById(app.getId()).orElse(null);
if (old == null) {
return new JSONResult(ErrorCode.NO_DATA, "应用ID错误");
}
BeanUtils.copyProperties(app, old);
appService.update(old);
return new JSONResult().put("count", 1).put("model", old);
}
@Secured("ROLE_APP_INSERT")
@RequestMapping("/app/insert")
public JSONResult add(App app, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return new JSONResult(bindingResult);
}
String key;
do {
key = RandomStringUtils.randomAlphanumeric(16);
} while (appRepository.exitsByKey(key) > 0);
app.setKey(key);
app.setSecret(RandomStringUtils.randomAlphanumeric(32));
appRepository.save(app);
return new JSONResult()
.put("model", app);
}
}
package com.maile.erp.admin.controllers;
import com.maile.erp.admin.Result.GoodsResp;
import com.maile.erp.admin.Result.Options;
import com.maile.erp.admin.Result.Schema;
import com.maile.erp.core.entities.*;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.libs.SearchSpecification;
import com.maile.erp.core.pojos.GoodsTagsPojo;
import com.maile.erp.core.repositories.*;
import com.maile.erp.core.services.GoodsTagService;
import com.maile.erp.core.utils.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@RestController
@Slf4j
public class CustomGoodsController {
@Autowired
GoodsTagRepository goodsTagRepository;
@Autowired
GoodsRepository goodsRepository;
@Autowired
GoodsSkuRepository goodsSkuRepository;
@Autowired
GoodsPictureRepository goodsPictureRepository;
@Autowired
GoodsTagService goodsTagService;
@Autowired
GoodsCategoryRepository goodsCategoryRepository;
@Autowired
AppRepository appRepository;
@RequestMapping("/customGoods/select")
@Secured("ROLE_GOODS_SELECT")
public JSONResult customGoodsList(HttpServletRequest request,
@RequestParam(value = "page", defaultValue = "0") Integer page,
@RequestParam(value = "size", defaultValue = "15") Integer size) {
Sort sort = new Sort(Sort.Direction.DESC, "createTime");
Pageable pageable = PageRequest.of(page, size, sort);
SearchSpecification<Goods> searchSpecification = new SearchSpecification<>(request);
searchSpecification.setFilter("search_eq_tagsId", (list, field, operator, value, root, query, cb) -> {
List<GoodsTagsPojo> pojos = goodsTagRepository.getTagedGoodsByTagsId(Long.parseLong(value));
if (pojos.size() != 0) {
List<Long> tagedGoodsIds = CollectionUtils.map(pojos, GoodsTagsPojo::getGoodsId);
return cb.in(root.get("id")).value(tagedGoodsIds);
}
return cb.equal(root.get("id"), 0);
}
);
searchSpecification.setFilter("search_eq_appId", (list, field, operator, value, root, query, cb) -> {
return cb.in(root.get("customAppId")).value(Long.parseLong(value));
}
);
searchSpecification.setBeforeFilter((list, root, query, cb) ->
list.add(cb.equal(root.get("isCustomGoods"), true))
);
Page<Goods> goodsPage = goodsRepository.findAll(searchSpecification, pageable);
if (goodsPage.getContent().size() == 0) {
return new JSONResult().put("list", new ArrayList<>());
}
List<Long> goodsIds = CollectionUtils.map(goodsPage.getContent(), Goods::getId);
// sku分组
List<GoodsSku> roles = goodsSkuRepository.findByGoodsIdIn(goodsIds);
Map<Long, List<GoodsSku>> skuGroup = CollectionUtils.group(roles, new CollectionUtils.GroupFilter<GoodsSku, Long, GoodsSku>() {
@Override
public Long getKey(GoodsSku source) {
return source.getGoodsId();
}
@Override
public GoodsSku getValue(GoodsSku source) {
return source;
}
});
// 轮播图分组
List<GoodsPicture> roles2 = goodsPictureRepository.findByGoodsIdIn(goodsIds);
Map<Long, List<String>> pictureGroup = CollectionUtils.group(roles2, new CollectionUtils.GroupFilter<GoodsPicture, Long, String>() {
@Override
public Long getKey(GoodsPicture source) {
return source.getGoodsId();
}
@Override
public String getValue(GoodsPicture source) {
return source.getUrl();
}
});
// 标签分组
List<GoodsTag> goodsTagList = goodsTagService.findAll();
List<GoodsTagsPojo> roles3 = goodsTagRepository.getTagedGoodsByGoodsIdIn(goodsIds);
Map<Long, List<GoodsTag>> tagsGroup = CollectionUtils.group(roles3, new CollectionUtils.GroupFilter<GoodsTagsPojo, Long, GoodsTag>() {
@Override
public Long getKey(GoodsTagsPojo source) {
return source.getGoodsId();
}
@Override
public GoodsTag getValue(GoodsTagsPojo source) {
GoodsTag temp = new GoodsTag();
for (GoodsTag goodsTag : goodsTagList) {
if (goodsTag.getId() == source.getTagsId()) {
temp = goodsTag;
}
}
return temp;
}
});
List<GoodsResp> resps = new ArrayList<>();
for (Goods goods : goodsPage.getContent()) {
GoodsResp goodsResp = new GoodsResp();
long goodsId = goods.getId();
goods.setTags(null);// 防止多次查询数据库
BeanUtils.copyProperties(goods, goodsResp);
goodsResp.setPictureList(pictureGroup.get(goodsId));
// sku
goodsResp.setSku(skuGroup.get(goodsId));
// 价格
goodsResp.setSellingPrice(goods.getSellingPrice() / 100);
// 标签
goodsResp.setTags(tagsGroup.get(goodsId));
resps.add(goodsResp);
}
return new JSONResult(goodsPage, pageable.getPageNumber())
.put("list", resps);
}
@RequestMapping("/customGoods/schema")
public JSONResult customGoodsSchema() {
List<Object> querySchema = new ArrayList<>();
// 商品分类
List<Options> optionsList1 = new ArrayList<>();
List<GoodsCategory> goodsCategoryList = goodsCategoryRepository.findAll();
for (GoodsCategory goodsCategory : goodsCategoryList) {
Options options = new Options();
options.setKey(goodsCategory.getId());
options.setValue(goodsCategory.getName());
optionsList1.add(options);
}
Schema goodsCategory = new Schema();
goodsCategory.setKey("search_eq_categoryId");
goodsCategory.setTitle("商品分类");
goodsCategory.setDataType("varchar");
goodsCategory.setShowType("select");
goodsCategory.setOptions(optionsList1);
querySchema.add(goodsCategory);
// 商品标签
List<Options> optionsList2 = new ArrayList<>();
List<GoodsTag> goodsTagList = goodsTagService.findAll();
for (GoodsTag goodsTag : goodsTagList) {
Options options = new Options();
options.setKey(goodsTag.getId());
options.setValue(goodsTag.getTitle());
optionsList2.add(options);
}
Schema goodsTag = new Schema();
goodsTag.setKey("search_eq_tagsId");
goodsTag.setTitle("商品标签");
goodsTag.setDataType("varchar");
goodsTag.setShowType("select");
goodsTag.setOptions(optionsList2);
querySchema.add(goodsTag);
// 应用
List<Options> optionsList3 = new ArrayList<>();
List<App> appList = appRepository.findAll();
for (App app : appList) {
Options options = new Options();
options.setKey(app.getId());
options.setValue(app.getName());
optionsList3.add(options);
}
Schema app = new Schema();
app.setKey("search_eq_appId");
app.setTitle("应用");
app.setDataType("varchar");
app.setShowType("select");
app.setOptions(optionsList3);
querySchema.add(app);
///------///
List<Object> dataSchema = new ArrayList<>();
// 商品分类
Schema goodsCategory2 = new Schema();
goodsCategory2.setKey("categoryId");
goodsCategory2.setTitle("商品分类");
goodsCategory2.setDataType("varchar");
goodsCategory2.setShowType("select");
goodsCategory2.setOptions(optionsList1);
dataSchema.add(goodsCategory2);
// 商品标签
Schema goodsTag2 = new Schema();
goodsTag2.setKey("tagsId");
goodsTag2.setTitle("商品标签");
goodsTag2.setDataType("varchar");
goodsTag2.setShowType("select");
goodsTag2.setOptions(optionsList2);
dataSchema.add(goodsTag2);
return new JSONResult().put("querySchema", querySchema).put("dataSchema", dataSchema);
}
}
\ No newline at end of file
package com.maile.erp.admin.controllers;
import com.maile.erp.core.ExpressCompanyRepository;
import com.maile.erp.core.entities.ExpressCompany;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.libs.SearchSpecification;
import com.maile.erp.core.services.ExpressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
public class ExpressController {
@Autowired
ExpressService expressService;
@Autowired
ExpressCompanyRepository expressCompanyRepository;
@RequestMapping("/express/select")
@Secured("ROLE_EXPRESS_SELECT")
public JSONResult select(HttpServletRequest request, @PageableDefault(sort = {"sort"}, direction = Sort.Direction.ASC) Pageable pageable) {
Page<ExpressCompany> page = expressCompanyRepository.findAll(new SearchSpecification<>(request), pageable);
return new JSONResult(page, pageable.getPageNumber());
}
@RequestMapping("/express/insert")
@Secured("ROLE_EXPRESS_INSERT")
public JSONResult insert(ExpressCompany company) {
expressService.insert(company);
return new JSONResult().put("model", company).put("count", 1);
}
@RequestMapping("/express/update")
@Secured("ROLE_EXPRESS_UPDATE")
public JSONResult update(ExpressCompany company) {
expressService.update(company);
return new JSONResult().put("model", company).put("count", 1);
}
@RequestMapping("/express/delete")
@Secured("ROLE_EXPRESS_DELETE")
public JSONResult delete(@RequestParam("id") Long id) {
expressService.delete(id);
return new JSONResult().put("count", 1);
}
}
package com.maile.erp.admin.controllers;
import com.maile.erp.core.entities.GoodsCategory;
import com.maile.erp.core.libs.ErrorCode;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.repositories.GoodsCategoryRepository;
import com.maile.erp.core.services.GoodsCategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.access.annotation.Secured;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* Created by IntelliJ IDEA.
* User: @Faith
* Date: 2018/7/24
* Time: 下午3:20
*/
@RestController
public class GoodsCategoryController {
@Autowired
GoodsCategoryRepository goodsCategoryRepository;
@Autowired
GoodsCategoryService goodsCategoryService;
@Secured("ROLE_GOODS_CATEGORY_SELECT")
@RequestMapping("/goodsCategory/select")
public JSONResult selectCategory() {
List<Map> cateTree = goodsCategoryService.getFormattedTypes(goodsCategoryService.getTree2());
return new JSONResult().put("list", cateTree).put("total", cateTree.size());
}
@RequestMapping("/goodsCategory/select2")
public JSONResult selectCategoryByLevel() {
List<Map> cateTree = goodsCategoryService.getFormattedTypes(goodsCategoryService.getTree3(2));
return new JSONResult().put("list", cateTree).put("total", cateTree.size());
}
@Secured("ROLE_GOODS_CATEGORY_INSERT")
@PostMapping("/goodsCategory/insert")
public JSONResult add(GoodsCategory goodsCategory, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return new JSONResult(bindingResult);
}
goodsCategoryService.save(goodsCategory);
return new JSONResult().put("model", goodsCategory);
}
@Secured("ROLE_GOODS_CATEGORY_UPDATE")
@PostMapping("/goodsCategory/update")
@CacheEvict(value = "erp-cache:categoryTree", key = "'all'")
public JSONResult update(GoodsCategory goodsCategory, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return new JSONResult(bindingResult);
}
GoodsCategory oldCategory = goodsCategoryRepository.findById(goodsCategory.getId()).orElse(null);
if (oldCategory == null) {
return new JSONResult(ErrorCode.NO_DATA, "商品分类id错误");
}
if (goodsCategoryService.hasRing(goodsCategory)) {
return new JSONResult(ErrorCode.NO_DATA, "分类死循环了,请重新设置");
}
goodsCategoryService.save(goodsCategory);
return new JSONResult().put("count", 1).put("model", goodsCategory);
}
}
package com.maile.erp.admin.controllers;
import com.maile.erp.core.entities.GoodsProvider;
import com.maile.erp.core.entities.GoodsProviderSelect;
import com.maile.erp.core.libs.ErrorCode;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.libs.StockFactory;
import com.maile.erp.core.repositories.GoodsProviderRepository;
import com.maile.erp.core.repositories.GoodsProviderSelectRepository;
import com.maile.erp.core.services.GoodsProviderService;
import com.maile.erp.core.stockrules.IStockRule;
import com.maile.erp.core.utils.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
public class GoodsProviderController {
@Autowired
GoodsProviderSelectRepository goodsProviderSelectRepository;
@Autowired
GoodsProviderRepository goodsProviderRepository;
@Autowired
GoodsProviderService goodsProviderService;
/**
* 供应商列表
*
* @return
*/
@RequestMapping("/goodsProvider/providersKv")
public JSONResult getProviders() {
List<Map> result = new ArrayList<>();
List<GoodsProvider> providers = goodsProviderRepository.findAll();
for (GoodsProvider item : providers) {
String name = item.getName();
if (!StringUtils.isBlank(item.getDescription())) {
name += "(" + item.getDescription() + ")";
}
Map<String, Object> data = new HashMap<>();
data.put("key", item.getIdentify());
data.put("value", name);
result.add(data);
}
return new JSONResult().put("list", result);
}
/**
* 供应商选择列表
*
* @return
*/
@RequestMapping("/goodsProvider/select")
@Secured("ROLE_PROVIDER_SELECT")
public JSONResult getSelect() {
List<GoodsProviderSelect> list = goodsProviderSelectRepository.findAll();
List<GoodsProvider> providers = goodsProviderRepository.findAll();
Map<Long, GoodsProvider> providerMap = CollectionUtils.columnMap(providers, GoodsProvider::getId);
Map<Integer, IStockRule> rulesMap = StockFactory.getRules();
for (GoodsProviderSelect item : list) {
item.setProviderName(providerMap.get(item.getProviderId()).getName());
item.setRuleName(rulesMap.get(item.getStockRuleId()).name());
}
return new JSONResult().put("list", list);
}
/**
* 供应商选择列表
*
* @return
*/
@RequestMapping("/goodsProvider/update")
@Secured("ROLE_PROVIDER_UPDATE")
public JSONResult setSelect(@Valid GoodsProviderSelect select, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return new JSONResult(bindingResult);
}
GoodsProviderSelect old = goodsProviderSelectRepository.findById(select.getId()).orElse(null);
if (old == null) {
return new JSONResult(ErrorCode.NO_DATA, "ID错误");
}
GoodsProvider provider = goodsProviderRepository.findByIdentify(select.getProviderIdentify());
if (provider == null) {
return new JSONResult(ErrorCode.NO_DATA, "供应商ID错误");
}
List<Integer> supportRules = CollectionUtils.parseSplitStr(provider.getSupportRules(), ",", Integer::valueOf);
if (supportRules.indexOf(old.getStockRuleId()) < 0) {
return new JSONResult(ErrorCode.NO_DATA, "该供应商不支持此商品类型");
}
old.setProviderIdentify(select.getProviderIdentify());
old.setProviderId(provider.getId());
//更新缓存
goodsProviderService.updateProviderSelect(old);
List<GoodsProvider> providers = goodsProviderRepository.findAll();
Map<Long, GoodsProvider> providerMap = CollectionUtils.columnMap(providers, GoodsProvider::getId);
Map<Integer, IStockRule> rulesMap = StockFactory.getRules();
old.setRuleName(rulesMap.get(old.getStockRuleId()).name());
old.setProviderName(providerMap.get(old.getProviderId()).getName());
return new JSONResult()
.put("count", 1)
.put("model", old);
}
}
package com.maile.erp.admin.controllers;
import com.maile.erp.core.entities.GoodsTag;
import com.maile.erp.core.libs.ErrorCode;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.services.GoodsTagService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.annotation.Secured;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@Slf4j
public class GoodsTagController {
@Autowired
private GoodsTagService goodsTagService;
@Secured("ROLE_GOODS_TAGS_SELECT")
@RequestMapping("/goodsTag/select")
public JSONResult getList(@PageableDefault Pageable pageable) {
Page<GoodsTag> goodsTagList = goodsTagService.findAll(pageable);
return new JSONResult(goodsTagList, pageable.getPageNumber());
}
@Secured("ROLE_GOODS_TAGS_INSERT")
@PostMapping("/goodsTag/insert")
public JSONResult add(@Valid GoodsTag goodsTag, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return new JSONResult(bindingResult);
}
GoodsTag result = goodsTagService.findByTitle(goodsTag.getTitle());
if (result != null) {
return new JSONResult(ErrorCode.DUPLICATE_KEY, "标签名重复");
}
goodsTagService.save(goodsTag);
return new JSONResult().put("model", goodsTag);
}
@Secured("ROLE_GOODS_TAGS_UPDATE")
@PostMapping("/goodsTag/update")
public JSONResult update(@Valid GoodsTag goodsTag, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return new JSONResult(bindingResult);
}
GoodsTag old = goodsTagService.findById(goodsTag.getId());
if (old == null) {
return new JSONResult(ErrorCode.NO_DATA, "标签ID错误");
}
GoodsTag result = goodsTagService.findByTitle(goodsTag.getTitle());
if (result != null && result.getId() != goodsTag.getId()) {
return new JSONResult(ErrorCode.DUPLICATE_KEY, "标签名重复");
}
BeanUtils.copyProperties(goodsTag, old);
goodsTagService.save(goodsTag);
return new JSONResult().put("count", 1).put("model", old);
}
@Secured("ROLE_GOODS_TAGS_DELETE")
@GetMapping("/goodsTag/delete")
public JSONResult delete(@RequestParam("keys") Long id) {
GoodsTag old = goodsTagService.findById(id);
if (old == null) {
return new JSONResult(ErrorCode.NO_DATA, "标签ID错误");
}
try {
goodsTagService.deleteById(id);
} catch (Exception e) {
log.error("商品标签删除数据失败:" + e.toString());
}
return new JSONResult().put("count", 1).put("model", old);
}
}
package com.maile.erp.admin.controllers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.maile.erp.admin.authorize.AuthorizeHelper;
import com.maile.erp.core.apievents.OrderEvent;
import com.maile.erp.core.entities.*;
import com.maile.erp.core.libs.*;
import com.maile.erp.core.repositories.GoodsOrderDeliveryLogRepository;
import com.maile.erp.core.repositories.GoodsOrderDetailRepository;
import com.maile.erp.core.repositories.GoodsOrderRepository;
import com.maile.erp.core.services.AppService;
import com.maile.erp.core.utils.CollectionUtils;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.io.IOException;
import java.util.*;
@RestController
public class OrderController {
@Autowired
GoodsOrderRepository goodsOrderRepository;
@Autowired
GoodsOrderDetailRepository goodsOrderDetailRepository;
@Autowired
GoodsOrderDeliveryLogRepository goodsOrderDeliveryLogRepository;
@Autowired
ApiEventManager eventManager;
@Autowired
AppService appService;
/**
* 订单列表
*
* @param request
* @param pageable
* @return
*/
@Secured("ROLE_ORDER_SELECT")
@RequestMapping("/order/select")
public JSONResult getOrderList(HttpServletRequest request, @PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
SearchSpecification<GoodsOrder> specification = new SearchSpecification<>(request);
specification.setBeforeFilter((list, root, query, cb) -> list.add(cb.equal(root.get("isCustomGoods"), false)));
Page<GoodsOrder> page = goodsOrderRepository.findAll(specification, pageable);
List<Long> orderIds = CollectionUtils.map(page.getContent(), GoodsOrder::getId);
List<GoodsOrderDetail> details = goodsOrderDetailRepository.findByOrderIdIn(orderIds);
Map<Long, List<GoodsOrderDetail>> detailGroup = CollectionUtils.group(details, new CollectionUtils.GroupFilter<GoodsOrderDetail, Long, GoodsOrderDetail>() {
@Override
public Long getKey(GoodsOrderDetail source) {
return source.getOrderId();
}
@Override
public GoodsOrderDetail getValue(GoodsOrderDetail source) {
return source;
}
});
for (GoodsOrder order : page.getContent()) {
order.setDetails(detailGroup.get(order.getId()));
}
return new JSONResult(page, pageable.getPageNumber());
}
/**
* 自建商品订单列表
*
* @param request
* @param pageable
* @return
*/
@Secured("ROLE_ORDER_SELECT")
@RequestMapping("/customOrder/select")
public JSONResult getCustomOrderList(HttpServletRequest request, @PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
SearchSpecification<GoodsOrder> specification = new SearchSpecification<>(request);
specification.setBeforeFilter((list, root, query, cb) -> list.add(cb.equal(root.get("isCustomGoods"), true)));
Page<GoodsOrder> page = goodsOrderRepository.findAll(specification, pageable);
List<Long> orderIds = CollectionUtils.map(page.getContent(), GoodsOrder::getId);
List<GoodsOrderDetail> details = goodsOrderDetailRepository.findByOrderIdIn(orderIds);
Map<Long, List<GoodsOrderDetail>> detailGroup = CollectionUtils.group(details, new CollectionUtils.GroupFilter<GoodsOrderDetail, Long, GoodsOrderDetail>() {
@Override
public Long getKey(GoodsOrderDetail source) {
return source.getOrderId();
}
@Override
public GoodsOrderDetail getValue(GoodsOrderDetail source) {
return source;
}
});
for (GoodsOrder order : page.getContent()) {
order.setDetails(detailGroup.get(order.getId()));
}
return new JSONResult(page, pageable.getPageNumber());
}
@Secured("ROLE_ORDER_DETAILS")
@RequestMapping("/order/details")
public JSONResult getOrderDetails(@RequestParam long id) {
GoodsOrder order = goodsOrderRepository.findById(id);
if (order == null) {
return new JSONResult(ErrorCode.NO_DATA, "订单ID错误");
}
List<GoodsOrderDetail> details = goodsOrderDetailRepository.findByOrderId(order.getId());
order.setDetails(details);
List<GoodsOrderDeliveryLog> logs = goodsOrderDeliveryLogRepository.findByOrderId(order.getId());
return new JSONResult()
.put("model", order)
.put("logs", logs);
}
/**
* 发货
*
* @return
*/
@RequestMapping("/order/delivery")
@Secured("ROLE_ORDER_DELIVERY")
@SuppressWarnings("unchecked")
@Transactional
public JSONResult delivery(@RequestParam String body) {
try {
Map<String, Object> params = new ObjectMapper().readValue(body, HashMap.class);
GoodsOrder order = goodsOrderRepository.findById(Long.valueOf((Integer) params.get("id"))).orElse(null);
if (order == null) {
return new JSONResult(ErrorCode.NO_DATA, "订单ID错误");
}
List<GoodsOrderDetail> details = goodsOrderDetailRepository.findByOrderId(order.getId());
Map<Long, GoodsOrderDetail> detailMap = CollectionUtils.columnMap(details, GoodsOrderDetail::getId);
List<Map<String, Object>> eventsData = new ArrayList<>();
//更新订单详情
List<Map<String, Object>> changed = (List<Map<String, Object>>) params.get("changed");
for (Map<String, Object> item : changed) {
GoodsOrderDetail detail = detailMap.get(Long.valueOf((Integer) item.get("detailId")));
if (detail == null) {
continue;
}
if (item.get("expressCode").equals("")) {
detail.setExpressCode("");
detail.setExpressNo("");
detail.setDeliveryStatus(Constants.DELIVERY_STATUS_NORMAL);
} else {
detail.setExpressCode((String) item.get("expressCode"));
detail.setExpressNo((String) item.get("expressNo"));
detail.setDeliveryStatus(Constants.DELIVERY_STATUS_SENT);
}
Map<String, Object> eventData = new HashMap<>();
eventData.put("expressCode", detail.getExpressCode());
eventData.put("expressNo", detail.getExpressNo());
eventData.put("goodsId", detail.getGoodsId());
eventData.put("skuId", detail.getSkuId());
eventsData.add(eventData);
goodsOrderDetailRepository.save(detail);
}
AdminUser user = AuthorizeHelper.getUser();
//记录日志
GoodsOrderDeliveryLog log = new GoodsOrderDeliveryLog();
log.setUid(user.getId());
log.setRealname(user.getRealname());
log.setChangedData(body);
log.setOrderId(order.getId());
log.setRemark((String) params.get("remark"));
goodsOrderDeliveryLogRepository.save(log);
int deliverStatus = Constants.DELIVERY_STATUS_NORMAL;
if (CollectionUtils.every(details, o -> o.getDeliveryStatus() == Constants.DELIVERY_STATUS_SENT || o.getDeliveryStatus() == Constants.DELIVERY_STATUS_COMPLETED)) {
deliverStatus = Constants.DELIVERY_STATUS_SENT;
order.setStatus(Constants.ORDER_STATUS_SENT);
goodsOrderRepository.save(order);
}
//发送事件
OrderEvent event = new OrderEvent(OrderEvent.TYPE_DELIVERY);
event.setDeliveryStatus(deliverStatus);
event.setOutTradeNo(order.getOutTradeNo());
event.put("expressInfo", JSONArray.fromObject(eventsData).toString());
App app = appService.findOne(order.getAppId());
eventManager.postEvent(app, event);
List<GoodsOrderDeliveryLog> logs = goodsOrderDeliveryLogRepository.findByOrderId(order.getId());
order.setDetails(details);
return new JSONResult()
.put("model", order)
.put("logs", logs);
} catch (IOException e) {
return new JSONResult(ErrorCode.INVALID_PARAM, "发货数据错误");
}
}
@Secured("ROLE_ORDER_CLOSE")
@RequestMapping("/order/close")
public JSONResult close() {
return new JSONResult();
}
}
package com.maile.erp.admin.controllers;
import com.maile.erp.core.entities.Permission;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.libs.SearchSpecification;
import com.maile.erp.core.repositories.PermissionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@RestController
public class PermissionController {
@Autowired
PermissionRepository permissionRepository;
@RequestMapping("/permission/select")
public JSONResult select(HttpServletRequest request, @PageableDefault Pageable pageable) {
Page<Permission> page = permissionRepository.findAll(new SearchSpecification<>(request), pageable);
return new JSONResult(page, pageable.getPageNumber());
}
@RequestMapping("/permission/all")
public JSONResult all(HttpServletRequest request) {
List<Permission> list = permissionRepository.findAll(new SearchSpecification<>(request));
return new JSONResult().put("list", list);
}
@RequestMapping("/permission/update")
public JSONResult update() {
return new JSONResult().put("gg", "f");
}
}
package com.maile.erp.admin.controllers;
import com.maile.erp.core.entities.Role;
import com.maile.erp.core.entities.RolePermission;
import com.maile.erp.core.libs.ErrorCode;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.libs.SearchSpecification;
import com.maile.erp.core.repositories.RolePermissionRepository;
import com.maile.erp.core.repositories.RoleRepository;
import com.maile.erp.core.utils.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.util.*;
@RestController
public class RoleController {
@Autowired
RoleRepository roleRepository;
@Autowired
RolePermissionRepository rolePermissionRepository;
@Secured("ROLE_ROLE_SELECT")
@RequestMapping("/role/select")
public JSONResult select(HttpServletRequest request, @PageableDefault Pageable pageable) {
Page<Role> page = roleRepository.findAll(new SearchSpecification<>(request), pageable);
List<Long> rolesId = CollectionUtils.map(page.getContent(), Role::getId);
List<RolePermission> permissions = rolePermissionRepository.findByRoleIdIn(rolesId);
Map<Long, List<Long>> perms = CollectionUtils.group(permissions, new CollectionUtils.GroupFilter<RolePermission, Long, Long>() {
@Override
public Long getKey(RolePermission source) {
return source.getRoleId();
}
@Override
public Long getValue(RolePermission source) {
return source.getPermissionId();
}
});
for (Role role : page.getContent()) {
if (perms.containsKey(role.getId())) {
role.setPerms(perms.get(role.getId()));
}
}
return new JSONResult(page, pageable.getPageNumber());
}
@Secured("ROLE_ROLE_INSERT")
@RequestMapping("/role/insert")
public JSONResult insert(@RequestParam("name") String name,
@RequestParam(value = "perms", required = false) List<Long> perms) {
if (roleRepository.findByName(name) != null) {
return new JSONResult(ErrorCode.NO_DATA, "角色名已存在");
}
Role role = new Role();
role.setName(name);
roleRepository.save(role);
if (perms != null && perms.size() > 0) {
putPerms(role.getId(), perms);
}
role.setPerms(perms);
return new JSONResult().put("model", role);
}
@Secured("ROLE_ROLE_UPDATE")
@RequestMapping("/role/update")
@Transactional
public JSONResult update(@RequestParam("id") Long id,
@RequestParam("name") String name,
@RequestParam(value = "perms", required = false) List<Long> perms) {
Role role = roleRepository.findById(id).orElse(null);
if (role == null) {
return new JSONResult(ErrorCode.NO_DATA, "角色ID错误");
}
Role old = roleRepository.findByName(name);
if (old != null && old.getId() != id) {
return new JSONResult(ErrorCode.NO_DATA, "角色名已存在");
}
role.setName(name);
roleRepository.save(role);
rolePermissionRepository.deleteAllByRoleId(role.getId());
if (perms != null && perms.size() > 0) {
putPerms(role.getId(), perms);
}
role.setPerms(perms);
return new JSONResult().put("model", role).put("count", 1);
}
private void putPerms(Long roleId, Collection<Long> perms) {
for (Long permId : perms) {
RolePermission rp = new RolePermission();
rp.setPermissionId(permId);
rp.setRoleId(roleId);
rolePermissionRepository.save(rp);
}
}
}
package com.maile.erp.admin.controllers;
import com.maile.erp.core.libs.ErrorCode;
import com.maile.erp.core.libs.JSONResult;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SiteController {
// @RequestMapping(value = "/")
// public String index() {
// return "this is Index";
// }
}
package com.maile.erp.admin.controllers;
import com.maile.erp.core.entities.SysConfig;
import com.maile.erp.core.libs.ErrorCode;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.libs.SearchSpecification;
import com.maile.erp.core.repositories.SysConfigRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.annotation.Secured;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
public class SysConfigController {
@Autowired
SysConfigRepository sysConfigRepository;
@Secured("ROLE_SYSCONFIG_SELECT")
@RequestMapping("/sysConfig/select")
public JSONResult getSysConfigList(HttpServletRequest request, @PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
SearchSpecification<SysConfig> searchSpecification = new SearchSpecification<>(request);
searchSpecification.setBeforeFilter((list, root, query, cb) ->
list.add(cb.notLike(root.get("configKey"), "%balance_notice%"))
);
Page<SysConfig> page = sysConfigRepository.findAll(searchSpecification, pageable);
return new JSONResult(page, pageable.getPageNumber());
}
@Secured("ROLE_SYSCONFIG_UPDATE")
@RequestMapping("/sysConfig/update")
public JSONResult update(SysConfig sysConfig, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return new JSONResult(bindingResult);
}
SysConfig old = sysConfigRepository.findById(sysConfig.getId()).orElse(null);
if (old == null) {
return new JSONResult(ErrorCode.NO_DATA, "配置ID错误");
}
BeanUtils.copyProperties(sysConfig, old);
sysConfigRepository.save(old);
return new JSONResult().put("count", 1).put("model", old);
}
}
package com.maile.erp.admin.controllers;
import com.maile.erp.core.entities.SysLog;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.libs.SearchSpecification;
import com.maile.erp.core.repositories.SysLogRepository;
import com.maile.erp.core.services.SysLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
public class SysLogController {
@Autowired
SysLogService sysLogService;
@Autowired
SysLogRepository sysLogRepository;
@Autowired
HttpServletRequest request;
@Secured("ROLE_SYSLOG_SELECT")
@RequestMapping("/sysLog/select")
public JSONResult getList(@RequestParam(value = "page", defaultValue = "0") Integer page, @RequestParam(value = "size", defaultValue = "15") Integer size) {
Sort sort = new Sort(Sort.Direction.DESC, "createTime");
Pageable pageable = PageRequest.of(page, size, sort);
Page<SysLog> sysLogPage = sysLogRepository.findAll(new SearchSpecification<>(request), pageable);
return new JSONResult(sysLogPage, pageable.getPageNumber());
}
}
package com.maile.erp.admin.controllers;
import com.maile.erp.admin.authorize.AuthorizeHelper;
import com.maile.erp.core.libs.AppException;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.sdk.HuyiCouponSDK;
import com.maile.erp.core.services.AppService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Autowired
AppService appService;
@Autowired
HuyiCouponSDK huyiCouponSDK;
@RequestMapping(value = "/test/t")
@Secured("ROLE_PROVIDER_QUERY")
public JSONResult test(@RequestParam(defaultValue = "1") Long id) {
return new JSONResult().put("app", appService.findOne(id));
}
}
package com.maile.erp.admin.controllers;
import com.maile.erp.admin.annotations.RequireLogin;
import com.maile.erp.admin.authorize.AdminUserDetails;
import com.maile.erp.admin.authorize.AuthorizeHelper;
import com.maile.erp.core.entities.AdminRole;
import com.maile.erp.core.entities.AdminUser;
import com.maile.erp.core.libs.ErrorCode;
import com.maile.erp.core.libs.JSONResult;
import com.maile.erp.core.libs.SearchSpecification;
import com.maile.erp.core.repositories.AdminRoleRepository;
import com.maile.erp.core.repositories.AdminUserRepository;
import com.maile.erp.core.utils.BeanUtils;
import com.maile.erp.core.utils.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@Slf4j
@RestController
@RequireLogin(false)
public class UserController {
@Autowired
AdminUserRepository adminUserRepository;
@Autowired
AdminRoleRepository adminRoleRepository;
@RequestMapping("/user/getCurrentUser")
public JSONResult getCurrentUser() {
AdminUserDetails userDetails = AuthorizeHelper.getUserDetails();
return new JSONResult()
.put("user", userDetails.getAdminUser())
.put("permission", AuthorizeHelper.getPermissions());
}
@Secured("ROLE_USER_SELECT")
@RequestMapping("/user/select")
public JSONResult getUserList(HttpServletRequest request, @PageableDefault Pageable pageable) {
Page<AdminUser> page = adminUserRepository.findAll(new SearchSpecification<>(request), pageable);
List<Long> userIds = CollectionUtils.map(page.getContent(), AdminUser::getId);
List<AdminRole> roles = adminRoleRepository.findByAdminUserIdIn(userIds);
Map<Long, List<Long>> userIdGroup = CollectionUtils.group(roles, new CollectionUtils.GroupFilter<AdminRole, Long, Long>() {
@Override
public Long getKey(AdminRole source) {
return source.getAdminUserId();
}
@Override
public Long getValue(AdminRole source) {
return source.getRoleId();
}
});
for (AdminUser adminUser : page.getContent()) {
adminUser.setRoleId(userIdGroup.get(adminUser.getId()));
}
return new JSONResult(page, pageable.getPageNumber());
}
@Secured("ROLE_USER_INSERT")
@PostMapping("/user/insert")
public JSONResult addUser(AdminUser adminUser,
@RequestParam(value = "roleId", required = false) List<Long> roleId) {
AdminUser adminUser1 = adminUserRepository.findAdminUserByUsername(StringUtils.trim(adminUser.getUsername()));
if (adminUser1 != null) {
return new JSONResult(ErrorCode.DUPLICATE_KEY, "该用户名已存在");
}
adminUser.setPassword(DigestUtils.md5Hex(adminUser.getTmpPwd()));
adminUserRepository.save(adminUser);
if (roleId != null) {
assigningRoles(adminUser.getId(), roleId);
}
adminUser.setTmpPwd("******");
return new JSONResult().put("model", adminUser);
}
@Transactional
@Secured("ROLE_USER_UPDATE")
@PostMapping("/user/update")
public JSONResult updateUser(AdminUser adminUser,
@RequestParam(value = "roleId", required = false) List<Long> roleId) {
AdminUser user = adminUserRepository.findById(adminUser.getId()).orElse(null);
if (user == null) {
return new JSONResult(ErrorCode.NO_DATA, "该用户不存在");
}
AdminUser user1 = adminUserRepository.findAdminUserByUsername(StringUtils.trim(adminUser.getUsername()));
if (user1 != null && user1.getId() != adminUser.getId()) {
return new JSONResult(ErrorCode.DUPLICATE_KEY, "该用户名已存在");
}
BeanUtils.copyProperties(adminUser, user);
if (!adminUser.getTmpPwd().equals("******")) {
user.setPassword(DigestUtils.md5Hex(adminUser.getTmpPwd()));
}
adminUserRepository.save(user);
adminRoleRepository.deleteByAdminUserId(adminUser.getId());
if (roleId != null) {
assigningRoles(adminUser.getId(), roleId);
}
user.setTmpPwd("******");
return new JSONResult().put("count", 1).put("model", user);
}
private void assigningRoles(Long userId, Collection<Long> roleIds) {
for (Long roleId : roleIds) {
AdminRole ar = new AdminRole();
ar.setAdminUserId(userId);
ar.setRoleId(roleId);
adminRoleRepository.save(ar);
}
}
}
package com.maile.erp.admin.forms;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class AfterSaleOperationForm {
@NotBlank(message = "售后编号不能为空")
private String afterSaleSn;
@NotNull(message = "状态不能为空")
private int status;
private String remark;
private String sellerAddressee;
private String sellerAddress;
private String sellerPhone;
@NotNull(message = "退回用户金额不能为空")
private long refuseAmount;
}
spring.profiles.active=dev
spring.jackson.serialization.indent_output=true
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.datasource.secondary.max-idle=10
spring.datasource.secondary.max-wait=10000
spring.datasource.secondary.min-idle=5
spring.datasource.secondary.initial-size=5
spring.datasource.secondary.validation-query=SELECT 1
spring.datasource.secondary.test-on-borrow=false
spring.datasource.secondary.test-while-idle=true
spring.datasource.secondary.time-between-eviction-runs-millis=18800
server.port=8081
app.sign.enable=false
app.sign.field-name.appid=appid
app.sign.field-name.sign=sign
app.sign.field-name.key=key
app.sign.field-name.time=timestamp
app.sign.field-name.secret=secret
# 图片存储(阿里云oss)
oss.endpoint=http://oss-cn-shenzhen.aliyuncs.com
oss.accessKeyId=1cqRjAjXUR1fCLja
oss.accessKeySecret=lnhcikCdDDEAkKdk244F9Fg2E0r4Dg
oss.bucketName=maile-erp-pic
oss.fileDir=
\ No newline at end of file
spring.datasource.url=jdbc:mysql://rm-wz91sjqol342863x08o.mysql.rds.aliyuncs.com:3306/maile_erp?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useSSL=false
spring.datasource.username=dev
spring.datasource.password=yy10241905@@@
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#设置为create时每次都会重新创建表
#需要初始化数据时用create,会自动加载import.sql
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true
logging.level.com.maile.erp=DEBUG
#以下是actuator配置
#如访问:http://localhost:8080/manager/health
management.security.enabled=false
#设置为端点的url设置前缀
management.context-path=/manager
# Redis
spring.redis.host=120.76.152.62
spring.redis.password=redisYy1024
spring.redis.port=6379
# 连接池最大连接数(使用负值表示没有限制)
#spring.redis.pool.max-active=20
# 连接池最大阻塞等待时间(使用负值表示没有限制)
#spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
#spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
#spring.redis.pool.min-idle=8
# 连接超时时间(毫秒)
#spring.redis.timeout=300
app.redis.prefix=erp
app.http-async.api=http://http-async.mailejifen.com/task/add
app.ding-talk.platform=erp
app.ding-talk.business-group-id=omgdzops
app.ding-talk.technical-group-id=uhxgbovh
app.ding-talk.secret=6713CAA687A8CCDB4E296DD25B1A0105
app.ofpay.coupon.gateway=http://apitest.ofpay.com/order.do
app.ofpay.coupon.key=OFCARD
app.ofpay.coupon.user-id=A08566
app.ofpay.coupon.user-pwd=of111111
app.ihuyi.coupon.gateway=http://f.ihuyi.com/giftcard
app.ihuyi.coupon.app-id=cf_testapi
app.ihuyi.coupon.key=6j3ao593wMNQRz4Zo4ao
#聚合无测试环境,禁止在测试环境拉取卡券
app.juhe.coupon.gateway=http://v.juhe.cn
app.juhe.coupon.key=1
app.juhe.coupon.user=1
app.juhe.coupon.openid=1
#易缴费
app.ejiaofei.gateway=http://api.ejiaofei.net:11140
app.ejiaofei.app-id=13824468659
app.ejiaofei.key=yGitr2pStcE6EM4jRBkKmPAMsfBCE7Ey
app.ejiaofei.secret=DXZYryFryDTnySkrZWwGxNGCnFeECx8d
#百事通
app.baishitong.gateway=http://platform.17bst.com
app.baishitong.app-id=6e6402bce9
app.baishitong.key=sba45Qm2
app.baishitong.trade-pwd=135974
app.baishitong.agt-no=18814135974
app.baishitong.notify-url=http://erp-api.mailejifen.com/callback/baishitongPhoneFee
\ No newline at end of file
spring.datasource.url=jdbc:mysql://rm-wz93714227cfic1ya.mysql.rds.aliyuncs.com:3306/maile_erp?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useSSL=false
spring.datasource.username=maile_erp
spring.datasource.password=cL1iB1aO0cB3fB1i
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#设置为create时每次都会重新创建表
#需要初始化数据时用create,会自动加载import.sql
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=false
logging.level.com.maile.erp=INFO
logging.file=/usr/local/logs/java/admin-api.log
#以下是actuator配置
#如访问:http://localhost:8080/manager/health
management.security.enabled=false
#设置为端点的url设置前缀
management.context-path=/manager
# Redis
spring.redis.host=r-wz9a580da419ab84.redis.rds.aliyuncs.com
spring.redis.password=YyvpcRedis10241905
spring.redis.port=6379
# 连接池最大连接数(使用负值表示没有限制)
#spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
#spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
#spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
#spring.redis.pool.min-idle=1
# 连接超时时间(毫秒)
#spring.redis.timeout=300
app.redis.prefix=erp
app.http-async.api=http://http-async.mailejifen.com/task/add
app.ding-talk.platform=erp
app.ding-talk.business-group-id=omgdzops
app.ding-talk.technical-group-id=uhxgbovh
app.ding-talk.secret=6713CAA687A8CCDB4E296DD25B1A0105
app.ofpay.coupon.gateway=http://api2.ofpay.com/order.do
app.ofpay.coupon.key=uG1$dJ1]bB4+iG4
app.ofpay.coupon.user-id=A1408527
app.ofpay.coupon.user-pwd=Mljf12345678
app.ihuyi.coupon.gateway=http://f.ihuyi.com/giftcard
app.ihuyi.coupon.app-id=89011395
app.ihuyi.coupon.key=8acj19fNigTg94FS6Ds9
#聚合无测试环境,禁止在测试环境拉取卡券
app.juhe.coupon.gateway=http://v.juhe.cn
app.juhe.coupon.key=91d0d4ced85705e7ed38f792030c2c23
app.juhe.coupon.user=riorio
app.juhe.coupon.openid=JH29169946a5b160305ac295af4c079498
#易缴费
app.ejiaofei.gateway=http://api.ejiaofei.net:11140
app.ejiaofei.app-id=13824468659
app.ejiaofei.key=yGitr2pStcE6EM4jRBkKmPAMsfBCE7Ey
app.ejiaofei.secret=DXZYryFryDTnySkrZWwGxNGCnFeECx8d
#百事通
app.baishitong.gateway=http://platform.17bst.com
app.baishitong.app-id=6e6402bce9
app.baishitong.key=sba45Qm2
app.baishitong.trade-pwd=135974
app.baishitong.agt-no=18814135974
app.baishitong.notify-url=http://erp-api.mailejifen.com/callback/baishitongPhoneFee
\ No newline at end of file
#注意这个初始化脚本只用于开发/测试时使用,上生产时手动执行
set foreign_key_checks=0;
set foreign_key_checks=1;
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="1361px" height="609px" viewBox="0 0 1361 609" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
<title>Group 21</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Ant-Design-Pro-3.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="账户密码登录-校验" transform="translate(-79.000000, -82.000000)">
<g id="Group-21" transform="translate(77.000000, 73.000000)">
<g id="Group-18" opacity="0.8" transform="translate(74.901416, 569.699158) rotate(-7.000000) translate(-74.901416, -569.699158) translate(4.901416, 525.199158)">
<ellipse id="Oval-11" fill="#CFDAE6" opacity="0.25" cx="63.5748792" cy="32.468367" rx="21.7830479" ry="21.766008"></ellipse>
<ellipse id="Oval-3" fill="#CFDAE6" opacity="0.599999964" cx="5.98746479" cy="13.8668601" rx="5.2173913" ry="5.21330997"></ellipse>
<path d="M38.1354514,88.3520215 C43.8984227,88.3520215 48.570234,83.6838647 48.570234,77.9254015 C48.570234,72.1669383 43.8984227,67.4987816 38.1354514,67.4987816 C32.3724801,67.4987816 27.7006688,72.1669383 27.7006688,77.9254015 C27.7006688,83.6838647 32.3724801,88.3520215 38.1354514,88.3520215 Z" id="Oval-3-Copy" fill="#CFDAE6" opacity="0.45"></path>
<path d="M64.2775582,33.1704963 L119.185836,16.5654915" id="Path-12" stroke="#CFDAE6" stroke-width="1.73913043" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M42.1431708,26.5002681 L7.71190162,14.5640702" id="Path-16" stroke="#E0B4B7" stroke-width="0.702678964" opacity="0.7" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
<path d="M63.9262187,33.521561 L43.6721326,69.3250951" id="Path-15" stroke="#BACAD9" stroke-width="0.702678964" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
<g id="Group-17" transform="translate(126.850922, 13.543654) rotate(30.000000) translate(-126.850922, -13.543654) translate(117.285705, 4.381889)" fill="#CFDAE6">
<ellipse id="Oval-4" opacity="0.45" cx="9.13482653" cy="9.12768076" rx="9.13482653" ry="9.12768076"></ellipse>
<path d="M18.2696531,18.2553615 C18.2696531,13.2142826 14.1798519,9.12768076 9.13482653,9.12768076 C4.08980114,9.12768076 0,13.2142826 0,18.2553615 L18.2696531,18.2553615 Z" id="Oval-4" transform="translate(9.134827, 13.691521) scale(-1, -1) translate(-9.134827, -13.691521) "></path>
</g>
</g>
<g id="Group-14" transform="translate(216.294700, 123.725600) rotate(-5.000000) translate(-216.294700, -123.725600) translate(106.294700, 35.225600)">
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.25" cx="29.1176471" cy="29.1402439" rx="29.1176471" ry="29.1402439"></ellipse>
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.3" cx="29.1176471" cy="29.1402439" rx="21.5686275" ry="21.5853659"></ellipse>
<ellipse id="Oval-2-Copy" stroke="#CFDAE6" opacity="0.4" cx="179.019608" cy="138.146341" rx="23.7254902" ry="23.7439024"></ellipse>
<ellipse id="Oval-2" fill="#BACAD9" opacity="0.5" cx="29.1176471" cy="29.1402439" rx="10.7843137" ry="10.7926829"></ellipse>
<path d="M29.1176471,39.9329268 L29.1176471,18.347561 C23.1616351,18.347561 18.3333333,23.1796097 18.3333333,29.1402439 C18.3333333,35.1008781 23.1616351,39.9329268 29.1176471,39.9329268 Z" id="Oval-2" fill="#BACAD9"></path>
<g id="Group-9" opacity="0.45" transform="translate(172.000000, 131.000000)" fill="#E6A1A6">
<ellipse id="Oval-2-Copy-2" cx="7.01960784" cy="7.14634146" rx="6.47058824" ry="6.47560976"></ellipse>
<path d="M0.549019608,13.6219512 C4.12262681,13.6219512 7.01960784,10.722722 7.01960784,7.14634146 C7.01960784,3.56996095 4.12262681,0.670731707 0.549019608,0.670731707 L0.549019608,13.6219512 Z" id="Oval-2-Copy-2" transform="translate(3.784314, 7.146341) scale(-1, 1) translate(-3.784314, -7.146341) "></path>
</g>
<ellipse id="Oval-10" fill="#CFDAE6" cx="218.382353" cy="138.685976" rx="1.61764706" ry="1.61890244"></ellipse>
<ellipse id="Oval-10-Copy-2" fill="#E0B4B7" opacity="0.35" cx="179.558824" cy="175.381098" rx="1.61764706" ry="1.61890244"></ellipse>
<ellipse id="Oval-10-Copy" fill="#E0B4B7" opacity="0.35" cx="180.098039" cy="102.530488" rx="2.15686275" ry="2.15853659"></ellipse>
<path d="M28.9985381,29.9671598 L171.151018,132.876024" id="Path-11" stroke="#CFDAE6" opacity="0.8"></path>
</g>
<g id="Group-10" opacity="0.799999952" transform="translate(1054.100635, 36.659317) rotate(-11.000000) translate(-1054.100635, -36.659317) translate(1026.600635, 4.659317)">
<ellipse id="Oval-7" stroke="#CFDAE6" stroke-width="0.941176471" cx="43.8135593" cy="32" rx="11.1864407" ry="11.2941176"></ellipse>
<g id="Group-12" transform="translate(34.596774, 23.111111)" fill="#BACAD9">
<ellipse id="Oval-7" opacity="0.45" cx="9.18534718" cy="8.88888889" rx="8.47457627" ry="8.55614973"></ellipse>
<path d="M9.18534718,17.4450386 C13.8657264,17.4450386 17.6599235,13.6143199 17.6599235,8.88888889 C17.6599235,4.16345787 13.8657264,0.332739156 9.18534718,0.332739156 L9.18534718,17.4450386 Z" id="Oval-7"></path>
</g>
<path d="M34.6597385,24.809694 L5.71666084,4.76878945" id="Path-2" stroke="#CFDAE6" stroke-width="0.941176471"></path>
<ellipse id="Oval" stroke="#CFDAE6" stroke-width="0.941176471" cx="3.26271186" cy="3.29411765" rx="3.26271186" ry="3.29411765"></ellipse>
<ellipse id="Oval-Copy" fill="#F7E1AD" cx="2.79661017" cy="61.1764706" rx="2.79661017" ry="2.82352941"></ellipse>
<path d="M34.6312443,39.2922712 L5.06366663,59.785082" id="Path-10" stroke="#CFDAE6" stroke-width="0.941176471"></path>
</g>
<g id="Group-19" opacity="0.33" transform="translate(1282.537219, 446.502867) rotate(-10.000000) translate(-1282.537219, -446.502867) translate(1142.537219, 327.502867)">
<g id="Group-17" transform="translate(141.333539, 104.502742) rotate(275.000000) translate(-141.333539, -104.502742) translate(129.333539, 92.502742)" fill="#BACAD9">
<circle id="Oval-4" opacity="0.45" cx="11.6666667" cy="11.6666667" r="11.6666667"></circle>
<path d="M23.3333333,23.3333333 C23.3333333,16.8900113 18.1099887,11.6666667 11.6666667,11.6666667 C5.22334459,11.6666667 0,16.8900113 0,23.3333333 L23.3333333,23.3333333 Z" id="Oval-4" transform="translate(11.666667, 17.500000) scale(-1, -1) translate(-11.666667, -17.500000) "></path>
</g>
<circle id="Oval-5-Copy-6" fill="#CFDAE6" cx="201.833333" cy="87.5" r="5.83333333"></circle>
<path d="M143.5,88.8126685 L155.070501,17.6038544" id="Path-17" stroke="#BACAD9" stroke-width="1.16666667"></path>
<path d="M17.5,37.3333333 L127.466252,97.6449735" id="Path-18" stroke="#BACAD9" stroke-width="1.16666667"></path>
<polyline id="Path-19" stroke="#CFDAE6" stroke-width="1.16666667" points="143.902597 120.302281 174.935455 231.571342 38.5 147.510847 126.366941 110.833333"></polyline>
<path d="M159.833333,99.7453842 L195.416667,89.25" id="Path-20" stroke="#E0B4B7" stroke-width="1.16666667" opacity="0.6"></path>
<path d="M205.333333,82.1372105 L238.719406,36.1666667" id="Path-24" stroke="#BACAD9" stroke-width="1.16666667"></path>
<path d="M266.723424,132.231988 L207.083333,90.4166667" id="Path-25" stroke="#CFDAE6" stroke-width="1.16666667"></path>
<circle id="Oval-5" fill="#C1D1E0" cx="156.916667" cy="8.75" r="8.75"></circle>
<circle id="Oval-5-Copy-3" fill="#C1D1E0" cx="39.0833333" cy="148.75" r="5.25"></circle>
<circle id="Oval-5-Copy-2" fill-opacity="0.6" fill="#D1DEED" cx="8.75" cy="33.25" r="8.75"></circle>
<circle id="Oval-5-Copy-4" fill-opacity="0.6" fill="#D1DEED" cx="243.833333" cy="30.3333333" r="5.83333333"></circle>
<circle id="Oval-5-Copy-5" fill="#E0B4B7" cx="175.583333" cy="232.75" r="5.25"></circle>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>
<font id="iconfont" horiz-adv-x="1024" >
<font-face
font-family="iconfont"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="jingxuanshichang" unicode="&#58880;" d="M627.977626 476.225434c119.09417-1.609626 238.185267-3.234714 357.295821-4.859699-4.320563 15.968666-8.659558 31.970099-12.985242 47.956173-94.425395-72.591258-188.872192-145.212314-283.298611-217.802547-9.083187-6.970778-15.551795-17.022669-11.830886-29.056819 35.275878-113.777357 70.511718-227.553587 105.774285-341.313536 12.613837 9.670246 25.217331 19.389645 37.817856 29.076173-98.232218 67.357082-196.461363 134.754099-294.693581 202.115277-6.971085 4.792115-19.035341 4.890419-25.973555 0L208.141824-43.727667c12.618957-9.687654 25.200947-19.373261 37.821952-29.057843 33.73056 114.214298 67.447808 228.459213 101.16311 342.70423 3.554099 11.964518-2.581914 22.152499-11.829862 29.056819-95.382221 71.316275-190.799155 142.631526-286.198784 213.963059-4.321587-16.00041-8.661606-31.986483-12.985242-47.956173 119.059354 3.234714 238.11881 6.450893 357.196595 9.669222 12.030464 0.334643 21.047194 7.725978 24.833638 18.90048 38.34071 112.771379 76.697907 225.542861 115.056026 338.296832l-49.636478 0c39.850189-112.235213 79.714714-224.469402 119.579238-336.723046 11.026534-31.032832 60.796109-17.659187 49.634406 13.689754-39.846093 112.235213-79.728026 224.47145-119.57719 336.723046-8.614502 24.230912-41.238835 24.733286-49.636454 0-38.35607-112.771379-76.713267-225.541837-115.052954-338.295808 8.260506 6.283059 16.522957 12.582605 24.80087 18.884096-119.077786-3.21833-238.137242-6.434509-357.196595-9.668198-27.38176-0.753152-32.77783-33.195008-13.003674-47.974605 95.414886-71.315251 190.831923-142.630502 286.212096-213.945651-3.9552 9.684582-7.874662 19.371213-11.830886 29.055795-33.732608-114.247066-67.446784-228.458189-101.179494-342.70423-6.049997-20.51113 18.950349-42.393498 37.80352-29.072179 97.058406 68.499046 194.083123 136.983859 291.10569 205.485978-15.284736-10.792858-34.48576 7.003546-12.482765-8.079053 11.142246-7.640986 22.268006-15.282074 33.380557-22.919987 33.763328-23.160525 67.547136-46.316851 101.29408-69.476352 49.132954-33.679053 98.231194-67.35913 147.331379-101.074022 18.783539-12.868096 44.272128 8.344064 37.83936 29.087437-35.254374 113.779405-70.532198 227.520922-105.772237 341.297152-3.956224-9.685606-7.909478-19.371213-11.84727-29.054771 94.426419 72.58921 188.871168 145.194906 283.312947 217.800499 19.222528 14.779597 14.782259 47.586816-13.00265 47.956173-119.110554 1.62601-238.202675 3.250995-357.295821 4.860723C594.746368 528.15319 594.798592 476.677734 627.977626 476.225434" horiz-adv-x="1024" />
<glyph glyph-name="chexingluntan" unicode="&#59100;" d="M1320.606897 546.427586C1313.544828 564.082759 1292.358621 578.206897 1271.172414 578.206897l-176.551724 0L1094.62069 684.137931c0 21.186207-14.124138 35.310345-35.310345 35.310345L529.655172 719.448276c-21.186207 0-35.310345-14.124138-35.310345-35.310345l0 0c0-21.186207 14.124138-35.310345 35.310345-35.310345l494.344828 0 0-600.275862L632.055172 48.551724c-14.124138 60.027586-70.62069 105.931034-137.710345 105.931034s-120.055172-45.903448-137.710345-105.931034L282.482759 48.551724l0 317.793103c0 21.186207-14.124138 35.310345-35.310345 35.310345l0 0c-21.186207 0-35.310345-14.124138-35.310345-35.310345l0-353.103448c0-21.186207 14.124138-35.310345 35.310345-35.310345l109.462069 0c14.124138-60.027586 70.62069-105.931034 137.710345-105.931034s120.055172 45.903448 137.710345 105.931034l399.006897 0c14.124138-60.027586 70.62069-105.931034 137.710345-105.931034s120.055172 45.903448 137.710345 105.931034L1377.103448-22.068966c21.186207 0 35.310345 14.124138 35.310345 35.310345l0 229.517241C1412.413793 331.034483 1320.606897 546.427586 1320.606897 546.427586zM494.344828-57.37931c-38.841379 0-70.62069 31.77931-70.62069 70.62069s31.77931 70.62069 70.62069 70.62069 70.62069-31.77931 70.62069-70.62069S533.186207-57.37931 494.344828-57.37931zM1165.241379-57.37931c-38.841379 0-70.62069 31.77931-70.62069 70.62069s31.77931 70.62069 70.62069 70.62069 70.62069-31.77931 70.62069-70.62069S1204.082759-57.37931 1165.241379-57.37931zM1341.793103 48.551724l-38.841379 0c-14.124138 60.027586-70.62069 105.931034-137.710345 105.931034-24.717241 0-49.434483-7.062069-70.62069-17.655172L1094.62069 507.586207l158.896552 0c0 0 24.717241-17.655172 28.248276-35.310345l-63.558621 0c-21.186207 0-35.310345-14.124138-35.310345-35.310345l0-141.241379c0-21.186207 14.124138-35.310345 35.310345-35.310345L1341.793103 260.413793C1341.793103 260.413793 1341.793103 48.551724 1341.793103 48.551724zM0 860.689655c0 21.186207 17.655172 35.310345 35.310345 35.310345l353.103448 0c21.186207 0 35.310345-14.124138 35.310345-35.310345 0-21.186207-17.655172-35.310345-35.310345-35.310345L35.310345 825.37931C14.124138 825.37931 0 839.503448 0 860.689655zM105.931034 684.137931c0 21.186207 14.124138 35.310345 35.310345 35.310345l247.172414 0c21.186207 0 35.310345-14.124138 35.310345-35.310345 0-21.186207-14.124138-35.310345-35.310345-35.310345L141.241379 648.827586C120.055172 648.827586 105.931034 662.951724 105.931034 684.137931zM211.862069 507.586207c0 21.186207 17.655172 35.310345 35.310345 35.310345l141.241379 0c17.655172 0 35.310345-14.124138 35.310345-35.310345 0-21.186207-17.655172-35.310345-35.310345-35.310345L247.172414 472.275862C225.986207 472.275862 211.862069 486.4 211.862069 507.586207z" horiz-adv-x="1413" />
</font>
</defs></svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="1361px" height="609px" viewBox="0 0 1361 609" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
<title>Group 21</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Ant-Design-Pro-3.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="账户密码登录-校验" transform="translate(-79.000000, -82.000000)">
<g id="Group-21" transform="translate(77.000000, 73.000000)">
<g id="Group-18" opacity="0.8" transform="translate(74.901416, 569.699158) rotate(-7.000000) translate(-74.901416, -569.699158) translate(4.901416, 525.199158)">
<ellipse id="Oval-11" fill="#CFDAE6" opacity="0.25" cx="63.5748792" cy="32.468367" rx="21.7830479" ry="21.766008"></ellipse>
<ellipse id="Oval-3" fill="#CFDAE6" opacity="0.599999964" cx="5.98746479" cy="13.8668601" rx="5.2173913" ry="5.21330997"></ellipse>
<path d="M38.1354514,88.3520215 C43.8984227,88.3520215 48.570234,83.6838647 48.570234,77.9254015 C48.570234,72.1669383 43.8984227,67.4987816 38.1354514,67.4987816 C32.3724801,67.4987816 27.7006688,72.1669383 27.7006688,77.9254015 C27.7006688,83.6838647 32.3724801,88.3520215 38.1354514,88.3520215 Z" id="Oval-3-Copy" fill="#CFDAE6" opacity="0.45"></path>
<path d="M64.2775582,33.1704963 L119.185836,16.5654915" id="Path-12" stroke="#CFDAE6" stroke-width="1.73913043" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M42.1431708,26.5002681 L7.71190162,14.5640702" id="Path-16" stroke="#E0B4B7" stroke-width="0.702678964" opacity="0.7" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
<path d="M63.9262187,33.521561 L43.6721326,69.3250951" id="Path-15" stroke="#BACAD9" stroke-width="0.702678964" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
<g id="Group-17" transform="translate(126.850922, 13.543654) rotate(30.000000) translate(-126.850922, -13.543654) translate(117.285705, 4.381889)" fill="#CFDAE6">
<ellipse id="Oval-4" opacity="0.45" cx="9.13482653" cy="9.12768076" rx="9.13482653" ry="9.12768076"></ellipse>
<path d="M18.2696531,18.2553615 C18.2696531,13.2142826 14.1798519,9.12768076 9.13482653,9.12768076 C4.08980114,9.12768076 0,13.2142826 0,18.2553615 L18.2696531,18.2553615 Z" id="Oval-4" transform="translate(9.134827, 13.691521) scale(-1, -1) translate(-9.134827, -13.691521) "></path>
</g>
</g>
<g id="Group-14" transform="translate(216.294700, 123.725600) rotate(-5.000000) translate(-216.294700, -123.725600) translate(106.294700, 35.225600)">
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.25" cx="29.1176471" cy="29.1402439" rx="29.1176471" ry="29.1402439"></ellipse>
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.3" cx="29.1176471" cy="29.1402439" rx="21.5686275" ry="21.5853659"></ellipse>
<ellipse id="Oval-2-Copy" stroke="#CFDAE6" opacity="0.4" cx="179.019608" cy="138.146341" rx="23.7254902" ry="23.7439024"></ellipse>
<ellipse id="Oval-2" fill="#BACAD9" opacity="0.5" cx="29.1176471" cy="29.1402439" rx="10.7843137" ry="10.7926829"></ellipse>
<path d="M29.1176471,39.9329268 L29.1176471,18.347561 C23.1616351,18.347561 18.3333333,23.1796097 18.3333333,29.1402439 C18.3333333,35.1008781 23.1616351,39.9329268 29.1176471,39.9329268 Z" id="Oval-2" fill="#BACAD9"></path>
<g id="Group-9" opacity="0.45" transform="translate(172.000000, 131.000000)" fill="#E6A1A6">
<ellipse id="Oval-2-Copy-2" cx="7.01960784" cy="7.14634146" rx="6.47058824" ry="6.47560976"></ellipse>
<path d="M0.549019608,13.6219512 C4.12262681,13.6219512 7.01960784,10.722722 7.01960784,7.14634146 C7.01960784,3.56996095 4.12262681,0.670731707 0.549019608,0.670731707 L0.549019608,13.6219512 Z" id="Oval-2-Copy-2" transform="translate(3.784314, 7.146341) scale(-1, 1) translate(-3.784314, -7.146341) "></path>
</g>
<ellipse id="Oval-10" fill="#CFDAE6" cx="218.382353" cy="138.685976" rx="1.61764706" ry="1.61890244"></ellipse>
<ellipse id="Oval-10-Copy-2" fill="#E0B4B7" opacity="0.35" cx="179.558824" cy="175.381098" rx="1.61764706" ry="1.61890244"></ellipse>
<ellipse id="Oval-10-Copy" fill="#E0B4B7" opacity="0.35" cx="180.098039" cy="102.530488" rx="2.15686275" ry="2.15853659"></ellipse>
<path d="M28.9985381,29.9671598 L171.151018,132.876024" id="Path-11" stroke="#CFDAE6" opacity="0.8"></path>
</g>
<g id="Group-10" opacity="0.799999952" transform="translate(1054.100635, 36.659317) rotate(-11.000000) translate(-1054.100635, -36.659317) translate(1026.600635, 4.659317)">
<ellipse id="Oval-7" stroke="#CFDAE6" stroke-width="0.941176471" cx="43.8135593" cy="32" rx="11.1864407" ry="11.2941176"></ellipse>
<g id="Group-12" transform="translate(34.596774, 23.111111)" fill="#BACAD9">
<ellipse id="Oval-7" opacity="0.45" cx="9.18534718" cy="8.88888889" rx="8.47457627" ry="8.55614973"></ellipse>
<path d="M9.18534718,17.4450386 C13.8657264,17.4450386 17.6599235,13.6143199 17.6599235,8.88888889 C17.6599235,4.16345787 13.8657264,0.332739156 9.18534718,0.332739156 L9.18534718,17.4450386 Z" id="Oval-7"></path>
</g>
<path d="M34.6597385,24.809694 L5.71666084,4.76878945" id="Path-2" stroke="#CFDAE6" stroke-width="0.941176471"></path>
<ellipse id="Oval" stroke="#CFDAE6" stroke-width="0.941176471" cx="3.26271186" cy="3.29411765" rx="3.26271186" ry="3.29411765"></ellipse>
<ellipse id="Oval-Copy" fill="#F7E1AD" cx="2.79661017" cy="61.1764706" rx="2.79661017" ry="2.82352941"></ellipse>
<path d="M34.6312443,39.2922712 L5.06366663,59.785082" id="Path-10" stroke="#CFDAE6" stroke-width="0.941176471"></path>
</g>
<g id="Group-19" opacity="0.33" transform="translate(1282.537219, 446.502867) rotate(-10.000000) translate(-1282.537219, -446.502867) translate(1142.537219, 327.502867)">
<g id="Group-17" transform="translate(141.333539, 104.502742) rotate(275.000000) translate(-141.333539, -104.502742) translate(129.333539, 92.502742)" fill="#BACAD9">
<circle id="Oval-4" opacity="0.45" cx="11.6666667" cy="11.6666667" r="11.6666667"></circle>
<path d="M23.3333333,23.3333333 C23.3333333,16.8900113 18.1099887,11.6666667 11.6666667,11.6666667 C5.22334459,11.6666667 0,16.8900113 0,23.3333333 L23.3333333,23.3333333 Z" id="Oval-4" transform="translate(11.666667, 17.500000) scale(-1, -1) translate(-11.666667, -17.500000) "></path>
</g>
<circle id="Oval-5-Copy-6" fill="#CFDAE6" cx="201.833333" cy="87.5" r="5.83333333"></circle>
<path d="M143.5,88.8126685 L155.070501,17.6038544" id="Path-17" stroke="#BACAD9" stroke-width="1.16666667"></path>
<path d="M17.5,37.3333333 L127.466252,97.6449735" id="Path-18" stroke="#BACAD9" stroke-width="1.16666667"></path>
<polyline id="Path-19" stroke="#CFDAE6" stroke-width="1.16666667" points="143.902597 120.302281 174.935455 231.571342 38.5 147.510847 126.366941 110.833333"></polyline>
<path d="M159.833333,99.7453842 L195.416667,89.25" id="Path-20" stroke="#E0B4B7" stroke-width="1.16666667" opacity="0.6"></path>
<path d="M205.333333,82.1372105 L238.719406,36.1666667" id="Path-24" stroke="#BACAD9" stroke-width="1.16666667"></path>
<path d="M266.723424,132.231988 L207.083333,90.4166667" id="Path-25" stroke="#CFDAE6" stroke-width="1.16666667"></path>
<circle id="Oval-5" fill="#C1D1E0" cx="156.916667" cy="8.75" r="8.75"></circle>
<circle id="Oval-5-Copy-3" fill="#C1D1E0" cx="39.0833333" cy="148.75" r="5.25"></circle>
<circle id="Oval-5-Copy-2" fill-opacity="0.6" fill="#D1DEED" cx="8.75" cy="33.25" r="8.75"></circle>
<circle id="Oval-5-Copy-4" fill-opacity="0.6" fill="#D1DEED" cx="243.833333" cy="30.3333333" r="5.83333333"></circle>
<circle id="Oval-5-Copy-5" fill="#E0B4B7" cx="175.583333" cy="232.75" r="5.25"></circle>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>
<font id="iconfont" horiz-adv-x="1024" >
<font-face
font-family="iconfont"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="jingxuanshichang" unicode="&#58880;" d="M627.977626 476.225434c119.09417-1.609626 238.185267-3.234714 357.295821-4.859699-4.320563 15.968666-8.659558 31.970099-12.985242 47.956173-94.425395-72.591258-188.872192-145.212314-283.298611-217.802547-9.083187-6.970778-15.551795-17.022669-11.830886-29.056819 35.275878-113.777357 70.511718-227.553587 105.774285-341.313536 12.613837 9.670246 25.217331 19.389645 37.817856 29.076173-98.232218 67.357082-196.461363 134.754099-294.693581 202.115277-6.971085 4.792115-19.035341 4.890419-25.973555 0L208.141824-43.727667c12.618957-9.687654 25.200947-19.373261 37.821952-29.057843 33.73056 114.214298 67.447808 228.459213 101.16311 342.70423 3.554099 11.964518-2.581914 22.152499-11.829862 29.056819-95.382221 71.316275-190.799155 142.631526-286.198784 213.963059-4.321587-16.00041-8.661606-31.986483-12.985242-47.956173 119.059354 3.234714 238.11881 6.450893 357.196595 9.669222 12.030464 0.334643 21.047194 7.725978 24.833638 18.90048 38.34071 112.771379 76.697907 225.542861 115.056026 338.296832l-49.636478 0c39.850189-112.235213 79.714714-224.469402 119.579238-336.723046 11.026534-31.032832 60.796109-17.659187 49.634406 13.689754-39.846093 112.235213-79.728026 224.47145-119.57719 336.723046-8.614502 24.230912-41.238835 24.733286-49.636454 0-38.35607-112.771379-76.713267-225.541837-115.052954-338.295808 8.260506 6.283059 16.522957 12.582605 24.80087 18.884096-119.077786-3.21833-238.137242-6.434509-357.196595-9.668198-27.38176-0.753152-32.77783-33.195008-13.003674-47.974605 95.414886-71.315251 190.831923-142.630502 286.212096-213.945651-3.9552 9.684582-7.874662 19.371213-11.830886 29.055795-33.732608-114.247066-67.446784-228.458189-101.179494-342.70423-6.049997-20.51113 18.950349-42.393498 37.80352-29.072179 97.058406 68.499046 194.083123 136.983859 291.10569 205.485978-15.284736-10.792858-34.48576 7.003546-12.482765-8.079053 11.142246-7.640986 22.268006-15.282074 33.380557-22.919987 33.763328-23.160525 67.547136-46.316851 101.29408-69.476352 49.132954-33.679053 98.231194-67.35913 147.331379-101.074022 18.783539-12.868096 44.272128 8.344064 37.83936 29.087437-35.254374 113.779405-70.532198 227.520922-105.772237 341.297152-3.956224-9.685606-7.909478-19.371213-11.84727-29.054771 94.426419 72.58921 188.871168 145.194906 283.312947 217.800499 19.222528 14.779597 14.782259 47.586816-13.00265 47.956173-119.110554 1.62601-238.202675 3.250995-357.295821 4.860723C594.746368 528.15319 594.798592 476.677734 627.977626 476.225434" horiz-adv-x="1024" />
<glyph glyph-name="chexingluntan" unicode="&#59100;" d="M1320.606897 546.427586C1313.544828 564.082759 1292.358621 578.206897 1271.172414 578.206897l-176.551724 0L1094.62069 684.137931c0 21.186207-14.124138 35.310345-35.310345 35.310345L529.655172 719.448276c-21.186207 0-35.310345-14.124138-35.310345-35.310345l0 0c0-21.186207 14.124138-35.310345 35.310345-35.310345l494.344828 0 0-600.275862L632.055172 48.551724c-14.124138 60.027586-70.62069 105.931034-137.710345 105.931034s-120.055172-45.903448-137.710345-105.931034L282.482759 48.551724l0 317.793103c0 21.186207-14.124138 35.310345-35.310345 35.310345l0 0c-21.186207 0-35.310345-14.124138-35.310345-35.310345l0-353.103448c0-21.186207 14.124138-35.310345 35.310345-35.310345l109.462069 0c14.124138-60.027586 70.62069-105.931034 137.710345-105.931034s120.055172 45.903448 137.710345 105.931034l399.006897 0c14.124138-60.027586 70.62069-105.931034 137.710345-105.931034s120.055172 45.903448 137.710345 105.931034L1377.103448-22.068966c21.186207 0 35.310345 14.124138 35.310345 35.310345l0 229.517241C1412.413793 331.034483 1320.606897 546.427586 1320.606897 546.427586zM494.344828-57.37931c-38.841379 0-70.62069 31.77931-70.62069 70.62069s31.77931 70.62069 70.62069 70.62069 70.62069-31.77931 70.62069-70.62069S533.186207-57.37931 494.344828-57.37931zM1165.241379-57.37931c-38.841379 0-70.62069 31.77931-70.62069 70.62069s31.77931 70.62069 70.62069 70.62069 70.62069-31.77931 70.62069-70.62069S1204.082759-57.37931 1165.241379-57.37931zM1341.793103 48.551724l-38.841379 0c-14.124138 60.027586-70.62069 105.931034-137.710345 105.931034-24.717241 0-49.434483-7.062069-70.62069-17.655172L1094.62069 507.586207l158.896552 0c0 0 24.717241-17.655172 28.248276-35.310345l-63.558621 0c-21.186207 0-35.310345-14.124138-35.310345-35.310345l0-141.241379c0-21.186207 14.124138-35.310345 35.310345-35.310345L1341.793103 260.413793C1341.793103 260.413793 1341.793103 48.551724 1341.793103 48.551724zM0 860.689655c0 21.186207 17.655172 35.310345 35.310345 35.310345l353.103448 0c21.186207 0 35.310345-14.124138 35.310345-35.310345 0-21.186207-17.655172-35.310345-35.310345-35.310345L35.310345 825.37931C14.124138 825.37931 0 839.503448 0 860.689655zM105.931034 684.137931c0 21.186207 14.124138 35.310345 35.310345 35.310345l247.172414 0c21.186207 0 35.310345-14.124138 35.310345-35.310345 0-21.186207-14.124138-35.310345-35.310345-35.310345L141.241379 648.827586C120.055172 648.827586 105.931034 662.951724 105.931034 684.137931zM211.862069 507.586207c0 21.186207 17.655172 35.310345 35.310345 35.310345l141.241379 0c17.655172 0 35.310345-14.124138 35.310345-35.310345 0-21.186207-17.655172-35.310345-35.310345-35.310345L247.172414 472.275862C225.986207 472.275862 211.862069 486.4 211.862069 507.586207z" horiz-adv-x="1413" />
</font>
</defs></svg>
This source diff could not be displayed because it is too large. You can view the blob instead.
{"version":3,"file":"bundle.min.js","sources":["webpack:///bundle.min.js"],"mappings":"AAAA","sourceRoot":""}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{"version":3,"file":"vendor.min.js","sources":["webpack:///vendor.min.js"],"mappings":"AAAA","sourceRoot":""}
\ No newline at end of file
<!DOCTYPE html><html><head><base href="/"><title>麦乐 Erp 系统</title><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"><link rel="shorticon icon" type="image/x-icon" href="/favicon.ico"></head><body><div id="root"></div><script type="text/javascript" src="/dist/vendor.min.js?50a1f135441e6bad4998"></script><script type="text/javascript" src="/dist/bundle.min.js?50a1f135441e6bad4998"></script></body></html>
\ No newline at end of file
# 基于哪个镜像
FROM java:8
# 将本地文件夹挂载到当前容器
VOLUME /tmp
ADD ./target/admin-server-1.0-SNAPSHOT.jar admin-server.jar
## 开放端口
#EXPOSE 7020
# 配置容器启动后执行的命令
ENTRYPOINT ["java","-jar","/admin-server.jar"]
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<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>
<artifactId>admin-server</artifactId>
<packaging>jar</packaging>
<name>admin-server</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.maile</groupId>
<artifactId>erp</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<!--spring-boot-admin 所需依赖-->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
<!--有spring-boot-admin-starter-server依赖,所以不需要该依赖-->
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-actuator</artifactId>-->
<!--</dependency>-->
<!--spring-boot-admin 对 ui 所需依赖-->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
</dependency>
<!--web 组件依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--增加安全控制的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--eureka-client 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--服务上下线邮件通知-->
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-mail</artifactId>-->
<!--</dependency>-->
<!--JMX-bean 管理所需依赖-->
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--显示应用版本信息-->
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.maile.erp.adminserver;
import de.codecentric.boot.admin.server.config.AdminServerProperties;
import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
@SpringBootApplication
@EnableAdminServer // 开启监控功能
@EnableEurekaClient //注册到 Eureka
public class AdminServerApplication {
public static void main(String[] args) {
SpringApplication.run(AdminServerApplication.class, args);
}
@Profile("insecure") // 测试时搭配@ActiveProfiles("insecure")使用 也可以在配置文件中 spring.profiles.active 配置
@Configuration // 表明是个配置类
// @EnableWebSecurity
public static class SecurityPermitAllConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll().and().csrf().disable();
}
}
//
@Profile("secure")
@Configuration
// @EnableWebSecurity // 注解开启Spring Security的功能
public static class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
private final String adminContextPath;
public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
this.adminContextPath = adminServerProperties.getContextPath();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
http.authorizeRequests() //定义哪些URL需要被保护、哪些不需要被保护
.antMatchers(adminContextPath + "/assets/**").permitAll()
.antMatchers(adminContextPath + "/login").permitAll()
.anyRequest().authenticated() // 表示其他的请求都必须要有权限认证
.and()
.formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler)
.and()
.logout().logoutUrl(adminContextPath + "/logout")
.and()
.httpBasic()
.and()
.csrf().disable();
}
}
}
server:
port: 7020
spring:
application:
name: admin-server
# 服务上下线邮箱通知
# mail:
# host: smtp.qq.com
# username: 943569813@qq.com
# password: sdrqyfbpdibkbdia # POP3/SMTP服务 授权码
# properties:
# mail:
# smtp:
# auth: true # 开启用户身份验证
# default-encoding: UTF-8
# port: 465
# boot:
# admin:
# notify:
# mail:
# to: 1647622369@qq.com # 发送给谁
# from: 943569813@qq.com # 谁发出去的
eureka:
client:
service-url:
defaultZone: http://eureka-server-1:7000/eureka/
registry-fetch-interval-seconds: 15 #表示eureka client间隔多久去拉取服务注册信息,默认为30秒
instance:
lease-renewal-interval-in-seconds: 10 # 心跳时间,即服务续约间隔时间(缺省为30s)
lease-expiration-duration-in-seconds: 30 # 发呆时间,即服务续约到期时间(缺省为90s)
metadata-map: # 注册给eureka的时候告诉eureka自己的密码
user.name: ${spring.security.user.name}
user.password: ${spring.security.user.password}
management:
endpoints:
web:
base-path: /actuator
exposure:
include: "*" #暴露所有 endpoints
endpoint:
health:
show-details: always
info:
app:
name: "@project.name@"
description: "@project.description@"
version: "@project.version@"
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<jmxConfigurator/>
</configuration>
\ No newline at end of file
# 基于哪个镜像
FROM java:8
# 将本地文件夹挂载到当前容器
VOLUME /tmp
ADD ./target/config-server-1.0-SNAPSHOT.jar config-server.jar
## 开放端口
#EXPOSE 7010
# 配置容器启动后执行的命令
ENTRYPOINT ["java","-jar","/config-server.jar"]
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<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>
<artifactId>config-server</artifactId>
<packaging>jar</packaging>
<name>config-server</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.maile</groupId>
<artifactId>erp</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<!--config-server 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!--eureka-client 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--web 组件依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--信息总线-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<!--JMX-bean 管理所需依赖-->
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--显示应用版本信息-->
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.maile.erp.configserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
server:
port: 7010
spring:
application:
name: config-server
# git 仓库配置
cloud:
config:
server:
git:
uri: https://github.com/fiyxiaozhu/SpringCloudConfig # 配置git仓库的地址
search-paths: respo # git仓库地址下的相对地址,可以配置多个,用,分割。
username: # git仓库的用户和密码
password:
label: master # 分支
eureka:
client:
service-url:
defaultZone: http://eureka-server-1:7000/eureka/
instance:
lease-renewal-interval-in-seconds: 10 # 心跳时间,即服务续约间隔时间(缺省为30s)
lease-expiration-duration-in-seconds: 30 # 发呆时间,即服务续约到期时间(缺省为90s)
# health-check-url-path: /actuator/health #健康监测相对路径
# instance-id: ${spring.cloud.client.ip-address}:${server.port}
# prefer-ip-address: true #是否显示IP地址
management:
endpoints:
web:
base-path: /actuator
exposure:
include: "*" #暴露所有 endpoints
endpoint:
health:
show-details: always
info:
app:
name: "@project.name@"
description: "@project.description@"
version: "@project.version@"
<?xml version="1.0" encoding="UTF-8"?>
<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>
<artifactId>erp-core</artifactId>
<packaging>jar</packaging>
<parent>
<artifactId>erp</artifactId>
<groupId>com.maile</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-actuator</artifactId>-->
<!--<version>2.0.3.RELEASE</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.apache.directory.studio</groupId>
<artifactId>org.apache.commons.lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!--oss依赖-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.7.0</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--显示应用版本信息-->
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.maile.erp.core;
import com.maile.erp.core.entities.ExpressCompany;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface ExpressCompanyRepository extends JpaRepository<ExpressCompany, Long>, JpaSpecificationExecutor<ExpressCompany> {
ExpressCompany findByCode(String code);
ExpressCompany findByName(String name);
}
package com.maile.erp.core.annotations;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequireSignature {
boolean value() default true;
}
package com.maile.erp.core.annotations;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StockRule {
}
package com.maile.erp.core.apievents;
import lombok.Data;
import java.util.Map;
@Data
public class AfsOrderEvent extends ApiEvent {
public static final String TYPE_RETURN = "return"; // 退款退货
public static final String TYPE_EXCHANGE = "exchange"; // 换货
public static final String TYPE_REFUSE = "refuse"; // 拒绝受理
private String outTradeNo;
private long goodsId;
private long skuId;
private int status;
private long refuseAmount;
public AfsOrderEvent(String type) {
super(type);
apiType = API_TYPE_AFS_ORDER;
}
@SuppressWarnings("unchecked")
public Map<String, Object> toParamMap() {
Map<String, Object> params = super.toParamMap();
params.put("outTradeNo", outTradeNo);
params.put("goodsId", goodsId);
params.put("skuId", skuId);
params.put("status", status);
params.put("refuseAmount", refuseAmount);
return params;
}
}
package com.maile.erp.core.apievents;
import java.util.HashMap;
import java.util.Map;
public abstract class ApiEvent {
public static final int API_TYPE_GOODS_ORDER = 1; //商品订单
public static final int API_TYPE_AFS_ORDER = 2; //售后订单
public static final int API_TYPE_GOODS = 3; //商品事件
protected int apiType; //API类型,不会传到第三方
protected String type; //事件类型
protected Map<String, Object> data = new HashMap<>();
public ApiEvent(){}
public ApiEvent(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Map<String, Object> getData() {
return data;
}
public void setData(Map<String, Object> data) {
this.data = data;
}
public ApiEvent put(String key, Object value) {
data.put(key, value);
return this;
}
public Object get(String key) {
return data.get(key);
}
public int getApiType() {
return apiType;
}
@SuppressWarnings("unchecked")
public Map<String, Object> toParamMap() {
Map<String, Object> result = new HashMap<>();
result.putAll(data);
result.put("type", type);
return result;
}
}
package com.maile.erp.core.apievents;
import lombok.Data;
import java.util.Map;
@Data
public class GoodsEvent extends ApiEvent {
public static final String TYPE_SHELVES = "shelves"; //上架
public static final String TYPE_UNSHELVES = "unshelves"; //下架
public static final int STATUS_SUCCESS = 1;
public static final int STATUS_FAIL = 2;
private Long goodsId;
public GoodsEvent(String type) {
super(type);
apiType = API_TYPE_GOODS;
}
@Override
@SuppressWarnings("unchecked")
public Map<String, Object> toParamMap() {
Map<String, Object> params = super.toParamMap();
params.put("goodsId", goodsId);
return params;
}
}
package com.maile.erp.core.apievents;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
public class OrderEvent extends ApiEvent {
public static final String TYPE_DELIVERY = "delivery";
public static final String TYPE_CLOSE = "close";
public static final String TYPE_CANCEL = "cancel";
private String outTradeNo;
private int deliveryStatus;
public OrderEvent(String type) {
super(type);
apiType = API_TYPE_GOODS_ORDER;
}
@Override
@SuppressWarnings("unchecked")
public Map<String, Object> toParamMap() {
Map<String, Object> params = super.toParamMap();
params.put("outTradeNo", outTradeNo);
params.put("deliveryStatus", deliveryStatus);
return params;
}
}
package com.maile.erp.core.entities;
import lombok.Data;
import javax.persistence.*;
@Data
@Entity
public class AdminRole {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(columnDefinition = "int(11)")
private long id;
@Column(columnDefinition = "int(11)")
private long adminUserId;
@Column(columnDefinition = "int(11)")
private long roleId;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.*;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: @Faith
* Date: 2018/7/24
* Time: 下午2:16
*/
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
@Table(indexes = {
@Index(columnList = "username")
})
public class AdminUser extends BaseEntity {
@Column(name = "`username`", columnDefinition = "varchar(64) not null default '' comment '用户名'")
private String username;
@JsonIgnore
@Column(name = "`password`", columnDefinition = "varchar(32) not null default '' comment '密码'")
private String password;
@Column(name = "`realname`", columnDefinition = "varchar(32) not null default '' comment '真实姓名'")
private String realname;
@Column(columnDefinition = "tinyint(11) not null default 0 comment '状态'")
private int status;
@Transient
private String tmpPwd = "******";
@Transient
private List<Long> roleId;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import javax.persistence.*;
import java.util.List;
@Entity
@Data
@DynamicInsert
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
@Table(indexes = {
@Index(columnList = "createTime"),
@Index(columnList = "status"),
@Index(columnList = "afterSaleSn", unique = true),
@Index(columnList = "orderSn")
})
public class AfterSale extends BaseEntity {
@Column(columnDefinition = "VARCHAR(32) NOT NULL DEFAULT '' COMMENT '订单编号'")
private String orderSn;
@Column(columnDefinition = "VARCHAR(32) NOT NULL DEFAULT '' COMMENT '订单应用编号'")
private String outTradeNo;
@Column(columnDefinition = "varchar(32) NOT NULL DEFAULT '' COMMENT 'SKU ID'")
private long skuId;
@Column(columnDefinition = "INT(11) NOT NULL DEFAULT 0 COMMENT '子订单ID'")
private long orderDetailId;
@Column(columnDefinition = "varchar(32) NOT NULL DEFAULT '' COMMENT '售后编号'")
private String afterSaleSn;
@Column(columnDefinition = "varchar(32) NOT NULL DEFAULT '' COMMENT '收件人'")
private String addressee;
@Column(columnDefinition = "varchar(32) NOT NULL DEFAULT '' COMMENT '手机号码'")
private String phone;
@Column(columnDefinition = "varchar(255) NOT NULL DEFAULT '' COMMENT '商品名称'")
private String goodsName;
@Column(columnDefinition = "tinyint(2) NOT NULL DEFAULT 0 COMMENT '受理状态,0待受理 1待用户寄回 2待商家收货 3完成售后 4拒绝受理 5取消售后 '")
private int status;
@Column(columnDefinition = "datetime DEFAULT NULL COMMENT '关闭时间'")
private String closeTime;
@Column(columnDefinition = "datetime default null comment '受理时间'")
private String acceptTime;
@Column(columnDefinition = "varchar(255) NOT NULL DEFAULT '' COMMENT '拒绝受理描述'")
private String refuseDes;
@Column(columnDefinition = "VARCHAR(255) NOT NULL DEFAULT '' COMMENT '退换货原因'")
private String reason;
@Column(columnDefinition = "VARCHAR(255) NOT NULL DEFAULT '' COMMENT '备注'")
private String remark;
@Column(columnDefinition = "TINYINT(2) NOT NULL DEFAULT 0 COMMENT '类型 0换货 1退货'")
private int type;
@Column(columnDefinition = "int(11) NOT NULL DEFAULT 0 COMMENT '退款总金额'")
private long Amount;
@Transient
private List<AfterSalePicture> afterSalePictures;
@Transient
private GoodsOrder goodsOrder;
@Transient
private GoodsOrderDetail goodsOrderDetail;
@Transient
private AfterSaleDetail afterSaleDetail;
@Transient
private List<AfterSaleLog> afterSaleLogList;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import javax.persistence.Column;
import javax.persistence.Entity;
@Entity
@DynamicInsert
@Data
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
public class AfterSaleDetail extends BaseEntity{
@Column(columnDefinition = "varchar(32) NOT NULL DEFAULT '' COMMENT '售后编号'")
private String afterSaleSn;
@Column(columnDefinition = "varchar(50) NOT NULL DEFAULT '' COMMENT '用户提供的快递单号'")
private String expressNum;
@Column(columnDefinition = "varchar(16) NOT NULL DEFAULT '' COMMENT '快递公司代码'")
private String expressCode;
@Column(columnDefinition = "varchar(32) NOT NULL DEFAULT '' COMMENT '快递公司名称'")
private String expressName;
@Column(columnDefinition = "varchar(32) NOT NULL DEFAULT '' COMMENT '商家收件人'")
private String sellerAddressee;
@Column(columnDefinition = "varchar(32) NOT NULL DEFAULT '' COMMENT '商家收件人手机号'")
private String sellerPhone;
@Column(columnDefinition = "varchar(255) NOT NULL DEFAULT '' COMMENT '商家完整收货地址'")
private String sellerAddress;
@Column(columnDefinition = "varchar(32) NOT NULL DEFAULT '' COMMENT '用户收件人'")
private String userAddressee;
@Column(columnDefinition = "varchar(32) NOT NULL DEFAULT '' COMMENT '用户收件人手机号'")
private String userPhone;
@Column(columnDefinition = "varchar(255) NOT NULL DEFAULT '' COMMENT '用户完整收货地址'")
private String userAddress;
@Column(columnDefinition = "DATETIME COMMENT '用户提供快递单号时间'")
private String provideTime;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import javax.persistence.Column;
import javax.persistence.Entity;
@Entity
@Data
@DynamicInsert
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
public class AfterSaleLog extends BaseEntity{
@Column(columnDefinition = "varchar(32) NOT NULL DEFAULT '' COMMENT '售后编号'")
private String afterSaleSn;
@Column(columnDefinition = "VARCHAR(32) NOT NULL DEFAULT '' COMMENT '操作人'")
private String operator;
@Column(columnDefinition = "VARCHAR(255) NOT NULL DEFAULT 0 COMMENT '操作描述'")
private String operDes;
@Column(columnDefinition = "VARCHAR(255) NOT NULL DEFAULT '' COMMENT '备注'")
private String remark;
}
package com.maile.erp.core.entities;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import javax.persistence.Column;
import javax.persistence.Entity;
@Entity
@Data
@DynamicInsert
public class AfterSalePicture extends BaseEntity{
@Column(columnDefinition = "int(11) NOT NULL DEFAULT '0' COMMENT '售后申请ID'")
private long afterSaleId;
@Column(columnDefinition = "varchar(255) NOT NULL DEFAULT '0' COMMENT '图片地址'")
private String url;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.*;
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
@Table(indexes = {
@Index(columnList = "key")
})
@SecondaryTable(name = "app_callback")
public class App extends BaseEntity {
@Column(columnDefinition = "varchar(32) not null default '' comment '应用名称'")
private String name;
@Column(name = "`desc`", columnDefinition = "varchar(255) not null default '' comment '应用描述'")
private String desc;
@Column(name = "`key`", columnDefinition = "varchar(32) not null default '' comment '应用key'")
private String key;
@Column(columnDefinition = "varchar(32) not null default '' comment '应用secret'")
private String secret;
@Column(columnDefinition = "tinyint(11) not null default 0 comment '状态'")
private int status;
@Column(table = "app_callback", columnDefinition = "varchar(255) not null default '' comment '订单事件接收接口'")
private String callbackOrderEvent = ""; //订单发货、发货失败、收货、关闭、退款等事件
@Column(table = "app_callback", columnDefinition = "varchar(255) not null default '' comment '售后订单事件接收接口'")
private String callbackAfsOrderEvent = ""; //售后通过、拒绝等事件
@Column(table = "app_callback", columnDefinition = "varchar(255) not null default '' comment '售后订单事件接收接口'")
private String callbackGoodsEvent = ""; //售后通过、拒绝等事件
}
package com.maile.erp.core.entities;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
@Data
@MappedSuperclass
class BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(columnDefinition = "int(11)")
private long id;
@Column(columnDefinition = "timestamp default CURRENT_TIMESTAMP comment '创建时间'", insertable = false, updatable = false)
private String createTime;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Column;
import javax.persistence.Entity;
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
public class CouponPurchaseRecord extends BaseEntity {
@Column(columnDefinition = "int(11) not null default 0 comment '商品ID'")
private Long goodsId;
@Column(columnDefinition = "int(11) not null default 0 comment 'SKU ID'")
private Long skuId;
@Column(columnDefinition = "varchar(32) not null default '' comment '批号'")
private String batchNo;
@Column(columnDefinition = "varchar(100) not null default '' comment '第三方订单号'")
private String thirdSn;
@Column(columnDefinition = "varchar(64) not null default '' comment '供应商标识'")
private String providerKey;
@Column(columnDefinition = "varchar(64) not null default '' comment '供应商名称'")
private String providerName;
@Column(columnDefinition = "varchar(64) not null default '' comment '商品key'")
private String providerGoodsKey;
@Column(columnDefinition = "int(11) not null default 0 comment '采购价格'")
private int purchasePrice;
@Column(columnDefinition = "int(11) not null default 0 comment '采购数量'")
private int num;
@Column(columnDefinition = "text comment '请求参数'")
private String params;
@Column(columnDefinition = "text comment '响应结果'")
private String response;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.Table;
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
@Table(indexes = {
@Index(columnList = "goodsId,couponSn", unique = true)
})
public class CouponStock extends BaseEntity {
@Column(columnDefinition = "int(11) not null default 0 comment '商品ID'")
private long goodsId;
@Column(columnDefinition = "int(11) not null default 0 comment 'SKU ID'")
private long skuId;
@Column(columnDefinition = "varchar(180) not null default '' comment '卡号'")
private String couponSn;
@Column(columnDefinition = "varchar(180) not null default '' comment '密码'")
private String couponPwd;
@Column(columnDefinition = "tinyint(2) not null default 0 comment '状态(0未使用,1已锁定,2已使用)'")
private int status;
@Column(columnDefinition = "date default null comment '有效期开始时间'")
private String startTime;
@Column(columnDefinition = "date default null comment '有效期截止时间'")
private String endTime;
@Column(columnDefinition = "varchar(32) default null comment '供应商'")
private String provider;
@Column(columnDefinition = "int(11) not null default 0 comment '采购价格'")
private long purchasePrice;
@Column(columnDefinition = "varchar(100) comment '绑定订单号'")
private String bindOrderSn;
@Column(columnDefinition = "int(11) not null default 0 comment '绑定订单详情ID'")
private long bindOrderDetailId;
@Column(columnDefinition = "tinyint(2) not null default 1 comment '入库方式'")
private int putType;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Column;
import javax.persistence.Entity;
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
public class ExpressCompany extends BaseEntity {
@Column(columnDefinition = "varchar(32) not null default ''comment '快递公司名称'")
private String name;
@Column(columnDefinition = "varchar(32) not null default '' comment '快递公司代码'")
private String code;
@Column(columnDefinition = "tinyint(3) not null default 0 comment '排序'")
private int sort;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.apache.commons.lang.StringUtils;
import org.hibernate.annotations.*;
import org.springframework.boot.json.GsonJsonParser;
import javax.persistence.*;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import java.util.*;
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
@SQLDelete(sql = "update goods set is_deleted = 1 where id = ?")
@Where(clause = "is_deleted = 0")
public class Goods extends BaseEntity {
@Column(columnDefinition = "varchar(255) not null default '' comment '商品名称'")
private String name;
@Column(columnDefinition = "varchar(32) not null default '' comment '商品编号'")
private String goodsNo;
@Column(columnDefinition = "int(11) not null default 0 comment '市场价格'")
private int marketPrice;
@Column(columnDefinition = "int(11) not null default 0 comment '销售价格'")
private int sellingPrice;
@Column(columnDefinition = "tinyint(2) not null default 0 comment '系统类型,1实物,2直充,3卡券'")
private int type;
@Column(columnDefinition = "int(11) not null default 0 comment '发货规则'")
private int ruleId;
@Column(columnDefinition = "int(11) not null default 0 comment '商品分类'")
private long categoryId;
@Column(columnDefinition = "varchar(255) not null default '' comment '缩略图'")
private String thumb;
@Column(columnDefinition = "text comment '商品详情'")
private String detail;
@Column(columnDefinition = "int(11) not null default 0 comment '销量'")
private int sales;
@Column(columnDefinition = "tinyint(2) not null default 0 comment '状态'")
private int status;
@Column(columnDefinition = "tinyint(2) not null default 0 comment '审核状态,0待审核,1审核通过,2审核失败'")
private int examine;
@Column(columnDefinition = "int(11) not null default 0 comment '总库存'")
private int stock;
@Column(columnDefinition = "tinyint(1) not null default 0 comment '是否无限库存'")
private Boolean isInfiniteStock;
@Column(columnDefinition = "tinyint(1) not null default 0 comment '是否含有多SKU'")
private Boolean hasMultiSku;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "goods_tags")
private List<GoodsTag> tags = new ArrayList<>();
@Column(columnDefinition = "tinyint(1) not null default 0 comment '是否自建商品'")
private Boolean isCustomGoods;
@Column(columnDefinition = "int(11) not null default 0 comment '自建商品应用ID'")
private long customAppId;
@Column(columnDefinition = "varchar(255) not null default '' comment '自建商品TAG'")
private String customTag;
@Column(columnDefinition = "varchar(255) not null default '' comment '扩展数据'")
private String extendData;
@JsonIgnore
@Column(columnDefinition = "tinyint(2) not null default 0 comment '是否删除'")
private int isDeleted;
public Goods() {
}
public Goods(Long id, int stock) {
setId(id);
setStock(stock);
}
@Transient
List<GoodsAttrName> attrs;
@Transient
List<GoodsSku> sku;
@Transient
List<GoodsPicture> pictures;
/**
* 获取附加SKU数据
* 没有SKU的时候从goods上读
*
* @param nullableSku
* @return
*/
@JsonIgnore
public Map<String, Object> getSkuAttachData(GoodsSku nullableSku) {
Map<String, Object> result = new HashMap<>();
if (nullableSku == null) {
if (!StringUtils.isBlank(extendData)) {
Map<String, Object> data = new GsonJsonParser().parseMap(extendData);
result.putAll(data);
}
} else {
Map<Long, Long> m = nullableSku.getAttrValueMap();
for (Long attrId : m.keySet()) {
for (GoodsAttrName attr : attrs) {
if (attrId == attr.getId()) {
for (GoodsAttrValue value : attr.getValues()) {
if (value.getId() == m.get(attrId)) {
if (!StringUtils.isBlank(value.getExtendData())) {
Map<String, Object> data = new GsonJsonParser().parseMap(value.getExtendData());
result.putAll(data);
}
}
}
}
}
}
}
return result;
}
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Entity;
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
public class GoodsAppBlock extends BaseEntity {
private long goodsId;
private long appId;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
public class GoodsAttrName extends BaseEntity {
@Column(columnDefinition = "int(11) not null default 0 comment '商品ID'")
private long goodsId;
@Column(columnDefinition = "varchar(32) not null default '' comment '属性名称'")
private String name;
@Column(columnDefinition = "varchar(255) not null default '' comment '扩展表单'")
private String extendForm;
@Transient
private List<GoodsAttrValue> values = new ArrayList<>();
//前端数据匹配规则项用
@Transient
Integer key;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Transient;
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
public class GoodsAttrValue extends BaseEntity {
@Column(columnDefinition = "int(11) not null default 0 comment '属性ID'")
private long attrId;
@Column(columnDefinition = "int(11) not null default 0 comment '商品ID'")
private long goodsId;
@Column(columnDefinition = "varchar(32) not null default '' comment '值'")
private String value;
@Column(columnDefinition = "varchar(255) not null default '' comment '图片地址'")
private String thumb;
@Column(columnDefinition = "int(11) not null default 0 comment '排序'")
private int sort;
@Column(columnDefinition = "tinyint(1) not null default 1 comment '是否使用'")
private Boolean isUsed;
@Column(columnDefinition = "varchar(255) not null default '' comment '扩展数据'")
private String extendData;
//前端数据匹配规则项用
@Transient
Integer key;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Transient;
import java.util.List;
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
public class GoodsCategory extends BaseEntity {
@Column(columnDefinition = "varchar(32) not null default '' comment '分类名称'")
private String name;
@Column(columnDefinition = "int(11) not null default 0 comment '类型'")
private int type;
@Column(columnDefinition = "int(11) not null default 0 comment '父分类ID'")
private long pid;
@Column(columnDefinition = "tinyint(2) not null default 0 comment '状态'")
private int status;
@Column(columnDefinition = "int(11) not null default 1 comment '栏目级别,1 一级栏目'")
private long level;
@Transient
@JsonIgnore
private GoodsCategory parent;
@Transient
private List<GoodsCategory> children;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Column;
import javax.persistence.Entity;
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
public class GoodsExamineLog extends BaseEntity {
@Column(columnDefinition = "int(11) NOT NULL DEFAULT 0 COMMENT '用户ID'")
private long uid;
@Column(columnDefinition = "varchar(32) NOT NULL DEFAULT '' COMMENT '用户姓名'")
private String realname;
@Column(columnDefinition = "int(11) NOT NULL DEFAULT 0 COMMENT '商品ID'")
private long goodsId;
@Column(columnDefinition = "varchar(255) not null default '' comment '商品名称'")
private String goodsName;
@Column(columnDefinition = "tinyint(2) not null default 0 comment '审核状态'")
private int examine;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.*;
import java.util.List;
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
@Table(indexes = {
@Index(columnList = "appId"),
@Index(columnList = "createTime"),
@Index(columnList = "status"),
@Index(columnList = "orderSn", unique = true),
@Index(columnList = "outTradeNo", unique = true)
})
public class GoodsOrder extends BaseEntity {
@Column(columnDefinition = "varchar(32) not null default '' comment '订单编号'")
private String orderSn;
@Column(columnDefinition = "int(11) not null default 0 comment '应用ID'")
private long appId;
@Column(columnDefinition = "tinyint(2) not null default 1 comment '类型'")
private int type;
@Column(columnDefinition = "varchar(32) not null default '' comment '应用订单号'")
private String outTradeNo;
@Column(columnDefinition = "varchar(32) not null default '' comment '应用UID'")
private String appUid;
@Column(name = "`status`", columnDefinition = "tinyint(2) not null default 0 comment '状态'")
private int status;
@Column(columnDefinition = "tinyint(2) not null default 0 comment '发货状态'")
private int deliveryStatus;
/*------------收件信息------------*/
@Column(columnDefinition = "varchar(32) not null default '' comment '手机号码'")
private String phone;
@Column(columnDefinition = "int(11) not null default 0 comment '地区代码'")
private int areaCode;
@Column(columnDefinition = "varchar(255) not null default '' comment '完整收货地址'")
private String address;
@Column(columnDefinition = "varchar(32) not null default '' comment '收件人'")
private String addressee;
/*------------价格信息------------*/
@Column(columnDefinition = "int(11) not null default 0 comment '销售金额'")
private long sellingAmount;
@Column(columnDefinition = "int(11) not null default 0 comment '应付现金(含应付运费)'")
private long payableCashAmount;
@Column(columnDefinition = "int(11) not null default 0 comment '实付现金'")
private long paidCashAmount;
@Column(columnDefinition = "varchar(32) not null default '' comment '现金支付方式'")
private String payCashType;
@Column(columnDefinition = "int(11) not null default 0 comment '应付运费'")
private long carriage;
@Column(columnDefinition = "int(11) not null default 0 comment '是否已支付/退款'")
private int isPaid;
@Column(columnDefinition = "tinyint(1) not null default 0 comment '是否自建商品订单'")
private Boolean isCustomGoods;
/*------------其他------------*/
@Column(columnDefinition = "varchar(255) not null default '' comment '备注'")
private String remark;
@Column(columnDefinition = "datetime default null comment '支付时间'")
private String payTime;
@Column(columnDefinition = "datetime default null comment '完成时间'")
private String completeTime;
@Column(columnDefinition = "datetime default null comment '关闭时间'")
private String closeTime;
@Transient
private List<GoodsOrderDetail> details;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Column;
import javax.persistence.Entity;
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
public class GoodsOrderDeliveryLog extends BaseEntity {
@Column(columnDefinition = "int(11) NOT NULL DEFAULT 0 COMMENT '用户ID'")
private long uid;
@Column(columnDefinition = "varchar(32) NOT NULL DEFAULT '' COMMENT '用户姓名'")
private String realname;
@Column(columnDefinition = "int(11) NOT NULL DEFAULT 0 COMMENT '订单ID'")
private long orderId;
@Column(columnDefinition = "text COMMENT '变更信息'")
private String changedData;
@Column(columnDefinition = "varchar(255) NOT NULL DEFAULT '' COMMENT '变更信息'")
private String remark;
}
package com.maile.erp.core.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.Table;
@Entity
@Data
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
@Table(indexes = {
@Index(columnList = "skuId"),
@Index(columnList = "goodsId")
})
public class GoodsOrderDetail extends BaseEntity {
@Column(columnDefinition = "int(11) not null default 0 comment '订单ID'")
private long orderId;
@Column(columnDefinition = "tinyint(2) not null default 0 comment '订单类型,1实物,2直充,3卡券'")
private int type;
@Column(columnDefinition = "int(11) not null default 0 comment '商品ID'")
private long goodsId;
@Column(columnDefinition = "varchar(255) not null default '' comment '商品名称'")
private String goodsName;
@Column(columnDefinition = "varchar(32) not null default '' comment '商品编号'")
private String goodsNo;
@Column(columnDefinition = "varchar(255) not null default '' comment '商品缩略图'")
private String goodsThumb;
@Column(columnDefinition = "int(11) not null default 0 comment '商品SKU ID'")
private long skuId;
@Column(columnDefinition = "varchar(50) not null default '' comment '规格,即什么尺寸什么颜色'")
private String skuDesc;
@Column(columnDefinition = "int(11) not null default 0 comment '购买数量'")
private int goodsNum;
@Column(columnDefinition = "int(11) not null default 0 comment '销售单价'")
private long sellingPrice;
@Column(columnDefinition = "int(11) not null default 0 comment '销售总金额'")
private long sellingAmount;
@Column(columnDefinition = "tinyint(1) not null default 0 comment '是否自建商品'")
private Boolean isCustomGoods;
@Column(columnDefinition = "varchar(32) not null default '' comment '快递公司代码'")
private String expressCode;
@Column(columnDefinition = "varchar(50) not null default '' comment '快递单号'")
private String expressNo;
@Column(columnDefinition = "tinyint(2) not null default 0 comment '发货状态'")
private int deliveryStatus;
@Column(columnDefinition = "varchar(255) not null default '' comment '卡号'")
private String couponSn;
@Column(columnDefinition = "varchar(255) not null default '' comment '卡密'")
private String couponPwd;
@Column(columnDefinition = "datetime default null comment '发货时间'")
private String deliveryTime;
}
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
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 sign in to comment