parent
2015f480fc
commit
1ab2112eb6
@ -1,6 +0,0 @@ |
||||
/target/ |
||||
/.idea/ |
||||
*.iml |
||||
.mvn |
||||
mvnw |
||||
*.cmd |
||||
@ -1,20 +0,0 @@ |
||||
<?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"> |
||||
<parent> |
||||
<artifactId>jxc</artifactId> |
||||
<groupId>cn.toesbieya</groupId> |
||||
<version>0.0.1-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>api</artifactId> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>cn.toesbieya</groupId> |
||||
<artifactId>common</artifactId> |
||||
</dependency> |
||||
</dependencies> |
||||
</project> |
||||
@ -1,15 +0,0 @@ |
||||
package cn.toesbieya.jxc.api; |
||||
|
||||
import java.util.List; |
||||
|
||||
public interface FileApi { |
||||
String getToken(); |
||||
|
||||
void delete(String key); |
||||
|
||||
void deleteBatch(String... key); |
||||
|
||||
default void deleteBatch(List<String> key) { |
||||
deleteBatch(key.toArray(new String[0])); |
||||
} |
||||
} |
||||
@ -1,19 +0,0 @@ |
||||
package cn.toesbieya.jxc.api; |
||||
|
||||
import cn.toesbieya.jxc.common.model.entity.RecAttachment; |
||||
import cn.toesbieya.jxc.common.model.entity.RecLoginHistory; |
||||
import cn.toesbieya.jxc.common.model.entity.RecUserAction; |
||||
|
||||
import java.util.List; |
||||
|
||||
public interface RecordApi { |
||||
List<RecAttachment> getAttachmentByPid(String pid); |
||||
|
||||
void handleAttachment(List<RecAttachment> upload, List<String> delete); |
||||
|
||||
void delAttachmentByPid(String pid); |
||||
|
||||
void insertLoginHistory(RecLoginHistory vo); |
||||
|
||||
void insertUserAction(RecUserAction vo); |
||||
} |
||||
@ -1,18 +0,0 @@ |
||||
package cn.toesbieya.jxc.api; |
||||
|
||||
import cn.toesbieya.jxc.common.model.entity.BizStock; |
||||
import cn.toesbieya.jxc.common.model.vo.StockOutboundVo; |
||||
import cn.toesbieya.jxc.common.model.vo.StockSearch; |
||||
import cn.toesbieya.jxc.common.model.vo.StockSearchResult; |
||||
|
||||
import java.util.List; |
||||
|
||||
public interface StockApi { |
||||
List<StockSearchResult> getByCondition(StockSearch vo); |
||||
|
||||
List<BizStock> getDetail(String cids); |
||||
|
||||
void inbound(List<BizStock> list); |
||||
|
||||
void outbound(List<StockOutboundVo> list); |
||||
} |
||||
@ -1,14 +0,0 @@ |
||||
package cn.toesbieya.jxc.api.system; |
||||
|
||||
import cn.toesbieya.jxc.common.model.entity.SysUser; |
||||
import cn.toesbieya.jxc.common.model.vo.DepartmentVo; |
||||
|
||||
import java.util.Set; |
||||
|
||||
public interface DepartmentApi { |
||||
//获取用户的数据范围(部门ID集合),返回null说明无需限制
|
||||
Set<Integer> getUserDataScope(SysUser user); |
||||
|
||||
//获取带有全名的部门
|
||||
DepartmentVo getById(int id); |
||||
} |
||||
@ -1,14 +0,0 @@ |
||||
package cn.toesbieya.jxc.api.system; |
||||
|
||||
import cn.toesbieya.jxc.common.model.entity.SysResource; |
||||
import cn.toesbieya.jxc.common.model.entity.SysRole; |
||||
|
||||
import java.util.List; |
||||
|
||||
public interface ResourceApi { |
||||
//获取已启用的数据接口列表
|
||||
List<SysResource> getEnableApi(); |
||||
|
||||
//获取角色的权限列表,包含admin权限
|
||||
List<SysResource> getResourceByRole(SysRole role); |
||||
} |
||||
@ -1,7 +0,0 @@ |
||||
package cn.toesbieya.jxc.api.system; |
||||
|
||||
import cn.toesbieya.jxc.common.model.entity.SysRole; |
||||
|
||||
public interface RoleApi { |
||||
SysRole getRoleById(Integer roleId); |
||||
} |
||||
@ -1,45 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<parent> |
||||
<artifactId>jxc</artifactId> |
||||
<groupId>cn.toesbieya</groupId> |
||||
<version>0.0.1-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>common</artifactId> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-data-redis</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.apache.commons</groupId> |
||||
<artifactId>commons-pool2</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>javax.servlet</groupId> |
||||
<artifactId>javax.servlet-api</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.google.guava</groupId> |
||||
<artifactId>guava</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.yaml</groupId> |
||||
<artifactId>snakeyaml</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.alibaba</groupId> |
||||
<artifactId>fastjson</artifactId> |
||||
</dependency> |
||||
</dependencies> |
||||
</project> |
||||
@ -1,19 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.config; |
||||
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature; |
||||
import com.alibaba.fastjson.support.config.FastJsonConfig; |
||||
|
||||
public class FastJsonConfigFactory { |
||||
public static FastJsonConfig defaultConfig() { |
||||
FastJsonConfig config = new FastJsonConfig(); |
||||
|
||||
config.setSerializerFeatures( |
||||
SerializerFeature.WriteMapNullValue, // 是否输出值为null的字段
|
||||
SerializerFeature.WriteDateUseDateFormat, |
||||
SerializerFeature.WriteNullListAsEmpty, |
||||
SerializerFeature.DisableCircularReferenceDetect // 禁用循环引用
|
||||
); |
||||
|
||||
return config; |
||||
} |
||||
} |
||||
@ -1,34 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.config; |
||||
|
||||
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.data.redis.connection.RedisConnectionFactory; |
||||
import org.springframework.data.redis.core.RedisTemplate; |
||||
import org.springframework.data.redis.serializer.StringRedisSerializer; |
||||
|
||||
@Configuration |
||||
public class RedisConfig { |
||||
@Bean |
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { |
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); |
||||
redisTemplate.setConnectionFactory(factory); |
||||
|
||||
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); |
||||
fastJsonRedisSerializer.setFastJsonConfig(FastJsonConfigFactory.defaultConfig()); |
||||
|
||||
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); |
||||
|
||||
// 设置值(value)的序列化采用FastJsonRedisSerializer。
|
||||
redisTemplate.setValueSerializer(fastJsonRedisSerializer); |
||||
redisTemplate.setHashValueSerializer(fastJsonRedisSerializer); |
||||
|
||||
// 设置键(key)的序列化采用StringRedisSerializer。
|
||||
redisTemplate.setKeySerializer(stringRedisSerializer); |
||||
redisTemplate.setHashKeySerializer(stringRedisSerializer); |
||||
|
||||
redisTemplate.setDefaultSerializer(fastJsonRedisSerializer); |
||||
redisTemplate.afterPropertiesSet(); |
||||
return redisTemplate; |
||||
} |
||||
} |
||||
@ -1,12 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.constant; |
||||
|
||||
public interface DocConstant { |
||||
//更新单据ID时的redis锁的键
|
||||
String UPDATE_DOC_LOCK_KEY = "UPDATE_DOC"; |
||||
|
||||
//单据ID的redis缓存的键
|
||||
String DOC_TYPE_REDIS_KEY = "DOC_ID"; |
||||
|
||||
//单据类型
|
||||
String[] DOC_TYPE = {"CGDD", "CGRK", "CGTH", "XSDD", "XSCK", "XSTH"}; |
||||
} |
||||
@ -1,18 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.constant; |
||||
|
||||
public interface SessionConstant { |
||||
//session过期时间,单位秒
|
||||
long EXPIRE = 3600 * 8; |
||||
|
||||
//存储用户信息的键的前缀
|
||||
String REDIS_NAMESPACE = "sessions:"; |
||||
|
||||
//key过期事件的前缀
|
||||
String REDIS_EXPIRE_TOPIC_PREFIX = "__keyspace@0__:"; |
||||
|
||||
//http headers中token的字段名
|
||||
String TOKEN_KEY = "X-Token"; |
||||
|
||||
//区别无活动用户的时间间隔,单位秒
|
||||
long NO_ACTION_INTERVAL = 1800; |
||||
} |
||||
@ -1,23 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.constant; |
||||
|
||||
public interface SocketConstant { |
||||
//web-socket服务端订阅的redis主题名称
|
||||
String REDIS_EVENT_TOPIC_SEND = "socket-event-send"; |
||||
|
||||
//指定用户
|
||||
int REDIS_EVENT_SPECIFIC = 0; |
||||
//广播
|
||||
int REDIS_EVENT_BROADCAST = 1; |
||||
//登出
|
||||
int REDIS_EVENT_LOGOUT = 2; |
||||
|
||||
//存放于redis中的在线用户的ID集合的键
|
||||
String REDIS_ONLINE_USER = "socket:online-user"; |
||||
//存放于redis中的离线用户的离线时间的键
|
||||
String REDIS_OFFLINE_USER = "socket:offline-user"; |
||||
|
||||
//登出事件
|
||||
String EVENT_LOGOUT = "logout"; |
||||
//新消息事件
|
||||
String EVENT_NEW_MESSAGE = "new-message"; |
||||
} |
||||
@ -1,15 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.enumeration; |
||||
|
||||
public enum DataScopeEnum { |
||||
ALL(1), SELF(2), SPECIFIC(3); |
||||
|
||||
private final int code; |
||||
|
||||
DataScopeEnum(int code) { |
||||
this.code = code; |
||||
} |
||||
|
||||
public int getCode() { |
||||
return code; |
||||
} |
||||
} |
||||
@ -1,15 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.enumeration; |
||||
|
||||
public enum GeneralStatusEnum { |
||||
DISABLED(0), ENABLED(1); |
||||
|
||||
private final int code; |
||||
|
||||
GeneralStatusEnum(int code) { |
||||
this.code = code; |
||||
} |
||||
|
||||
public int getCode() { |
||||
return code; |
||||
} |
||||
} |
||||
@ -1,15 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.enumeration; |
||||
|
||||
public enum ResourceTypeEnum { |
||||
ROOT(0), FOLDER(1), LEAF(2), API(3); |
||||
|
||||
private final int code; |
||||
|
||||
ResourceTypeEnum(int code) { |
||||
this.code = code; |
||||
} |
||||
|
||||
public int getCode() { |
||||
return code; |
||||
} |
||||
} |
||||
@ -1,7 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.exception; |
||||
|
||||
public class JsonResultException extends RuntimeException { |
||||
public JsonResultException(String message) { |
||||
super(message); |
||||
} |
||||
} |
||||
@ -1,19 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
public class BizDoc implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private String id; |
||||
private Integer cid; |
||||
private String cname; |
||||
private Long ctime; |
||||
private Integer vid; |
||||
private String vname; |
||||
private Long vtime; |
||||
private Integer status; |
||||
private String remark; |
||||
} |
||||
@ -1,25 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BizDocHistory implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private String pid; |
||||
private Integer type; |
||||
private Integer uid; |
||||
private String uname; |
||||
private Integer statusBefore; |
||||
private Integer statusAfter; |
||||
private Long time; |
||||
private String info; |
||||
} |
||||
@ -1,16 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
import java.math.BigDecimal; |
||||
|
||||
@Data |
||||
public class BizDocSub implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private String pid; |
||||
private Integer cid; |
||||
private String cname; |
||||
private BigDecimal num; |
||||
} |
||||
@ -1,12 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.ToString; |
||||
|
||||
@Data |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class BizPurchaseInbound extends BizDoc { |
||||
private String pid; |
||||
} |
||||
@ -1,12 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.ToString; |
||||
|
||||
@Data |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class BizPurchaseInboundSub extends BizDocSub { |
||||
|
||||
} |
||||
@ -1,20 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.NoArgsConstructor; |
||||
import lombok.ToString; |
||||
|
||||
import java.math.BigDecimal; |
||||
|
||||
@Data |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
@NoArgsConstructor |
||||
public class BizPurchaseOrder extends BizDoc { |
||||
private Integer sid; |
||||
private String sname; |
||||
private Integer finish; |
||||
private Long ftime; |
||||
private BigDecimal total; |
||||
} |
||||
@ -1,15 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.ToString; |
||||
|
||||
import java.math.BigDecimal; |
||||
|
||||
@Data |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class BizPurchaseOrderSub extends BizDocSub { |
||||
private BigDecimal price; |
||||
private BigDecimal remainNum; |
||||
} |
||||
@ -1,19 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.NoArgsConstructor; |
||||
import lombok.ToString; |
||||
|
||||
import java.math.BigDecimal; |
||||
|
||||
@Data |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class BizSellOrder extends BizDoc { |
||||
private Integer customerId; |
||||
private String customerName; |
||||
private Integer finish; |
||||
private Long ftime; |
||||
private BigDecimal total; |
||||
} |
||||
@ -1,15 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.ToString; |
||||
|
||||
import java.math.BigDecimal; |
||||
|
||||
@Data |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class BizSellOrderSub extends BizDocSub { |
||||
private BigDecimal price; |
||||
private BigDecimal remainNum; |
||||
} |
||||
@ -1,13 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.NoArgsConstructor; |
||||
import lombok.ToString; |
||||
|
||||
@Data |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class BizSellOutbound extends BizDoc { |
||||
private String pid; |
||||
} |
||||
@ -1,12 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.ToString; |
||||
|
||||
@Data |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class BizSellOutboundSub extends BizDocSub { |
||||
private Integer sid; |
||||
} |
||||
@ -1,25 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
import java.math.BigDecimal; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class BizStock implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private Integer cid; |
||||
private String cname; |
||||
private BigDecimal num; |
||||
private BigDecimal price; |
||||
private Long ctime; |
||||
private String cgrkid; |
||||
private String cgddid; |
||||
} |
||||
@ -1,26 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
public class Msg implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private String title; |
||||
private String content; |
||||
private Integer type; |
||||
private Integer cid; |
||||
private String cname; |
||||
private Long ctime; |
||||
private Integer pid; |
||||
private String pname; |
||||
private Long ptime; |
||||
private Integer wid; |
||||
private String wname; |
||||
private Long wtime; |
||||
private Integer status; |
||||
private boolean broadcast = false; |
||||
private String recipient; |
||||
} |
||||
@ -1,14 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
public class MsgState implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private Integer mid; |
||||
private Integer uid; |
||||
private Long time; |
||||
} |
||||
@ -1,23 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class RecAttachment implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private String pid; |
||||
private String name; |
||||
private Long time; |
||||
private Integer sort; |
||||
private String url; |
||||
private Long size; |
||||
} |
||||
@ -1,23 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class RecLoginHistory implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Long id; |
||||
private Integer uid; |
||||
private String uname; |
||||
private String ip; |
||||
private String address; |
||||
private boolean login = false; |
||||
private Long time; |
||||
} |
||||
@ -1,25 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class RecUserAction implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Long id; |
||||
private Integer uid; |
||||
private String uname; |
||||
private String url; |
||||
private String ip; |
||||
private Long time; |
||||
private String action; |
||||
private String error; |
||||
private boolean success = false; |
||||
} |
||||
@ -1,14 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
public class StatFinishOrder implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private Integer purchase; |
||||
private Integer sell; |
||||
private Long time; |
||||
} |
||||
@ -1,13 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.ToString; |
||||
|
||||
@Data |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class StatProfitGoods extends StatProfitTotal { |
||||
private Integer cid; |
||||
private String cname; |
||||
} |
||||
@ -1,16 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
import java.math.BigDecimal; |
||||
|
||||
@Data |
||||
public class StatProfitTotal implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private BigDecimal purchase; |
||||
private BigDecimal sell; |
||||
private BigDecimal profit; |
||||
private Long time; |
||||
} |
||||
@ -1,15 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
public class SysCategory implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private Integer pid; |
||||
private String name; |
||||
private boolean leaf = false; |
||||
private Long ctime; |
||||
} |
||||
@ -1,19 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
public class SysCustomer implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private String name; |
||||
private String address; |
||||
private String linkman; |
||||
private String linkphone; |
||||
private String region; |
||||
private boolean enable = false; |
||||
private Long ctime; |
||||
private String remark; |
||||
} |
||||
@ -1,14 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
public class SysDepartment implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private Integer pid; |
||||
private String name; |
||||
private boolean enable = false; |
||||
} |
||||
@ -1,15 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
public class SysRegion implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private String id; |
||||
private String pid; |
||||
private String name; |
||||
private String fullname; |
||||
private int level; |
||||
} |
||||
@ -1,19 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
public class SysResource implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private Integer pid; |
||||
private Integer type; |
||||
private String name; |
||||
private String path; |
||||
private String component; |
||||
private String meta; |
||||
private boolean admin = false; |
||||
private boolean enable = true; |
||||
} |
||||
@ -1,20 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import cn.toesbieya.jxc.common.enumeration.DataScopeEnum; |
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
public class SysRole implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private String name; |
||||
private Integer cid; |
||||
private String cname; |
||||
private Long ctime; |
||||
private boolean enable = false; |
||||
private int scope = DataScopeEnum.ALL.getCode(); |
||||
private String departmentId; |
||||
private String resourceId; |
||||
} |
||||
@ -1,19 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
public class SysSupplier implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private String name; |
||||
private String address; |
||||
private String linkman; |
||||
private String linkphone; |
||||
private String region; |
||||
private boolean enable = false; |
||||
private Long ctime; |
||||
private String remark; |
||||
} |
||||
@ -1,20 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
public class SysUser implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private String loginName; |
||||
private String nickName; |
||||
private String pwd; |
||||
private Integer role; |
||||
private String avatar; |
||||
private Long ctime; |
||||
private boolean admin = false; |
||||
private boolean enable = false; |
||||
private Integer dept; |
||||
} |
||||
@ -1,9 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.vo; |
||||
|
||||
import lombok.Data; |
||||
|
||||
@Data |
||||
public class BaseSearch { |
||||
private Integer page; |
||||
private Integer pageSize; |
||||
} |
||||
@ -1,20 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.vo; |
||||
|
||||
import cn.toesbieya.jxc.common.model.entity.SysDepartment; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.NoArgsConstructor; |
||||
import lombok.ToString; |
||||
import org.springframework.beans.BeanUtils; |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class DepartmentVo extends SysDepartment { |
||||
String fullname; |
||||
|
||||
public DepartmentVo(SysDepartment parent) { |
||||
BeanUtils.copyProperties(parent, this); |
||||
} |
||||
} |
||||
@ -1,83 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.vo; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
@Builder |
||||
public class R implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
//返回码,200表示成功,其他表示失败
|
||||
private int status; |
||||
|
||||
//返回的信息
|
||||
private String msg; |
||||
|
||||
//返回的数据
|
||||
private Object data; |
||||
|
||||
public R(int status) { |
||||
this.status = status; |
||||
} |
||||
|
||||
public R(int status, String msg) { |
||||
this.status = status; |
||||
this.msg = msg; |
||||
} |
||||
|
||||
public R(int status, Object data) { |
||||
this.status = status; |
||||
this.data = data; |
||||
} |
||||
|
||||
public static R success() { |
||||
return new R(200); |
||||
} |
||||
|
||||
public static R success(String msg) { |
||||
return new R(200, msg); |
||||
} |
||||
|
||||
public static R success(Object data) { |
||||
return new R(200, data); |
||||
} |
||||
|
||||
public static R success(String msg, Object data) { |
||||
return new R(200, msg, data); |
||||
} |
||||
|
||||
public static R fail(String msg) { |
||||
return new R(500, msg); |
||||
} |
||||
|
||||
public static R notfound() { |
||||
return new R(404, "请求地址不存在"); |
||||
} |
||||
|
||||
public static R requireLogin() { |
||||
return new R(401, "请登录后重试"); |
||||
} |
||||
|
||||
public static R noPermission() { |
||||
return new R(403, "没有权限进行该操作"); |
||||
} |
||||
|
||||
public static R overload() { |
||||
return new R(503, "当前请求的人数过多,请稍后重试"); |
||||
} |
||||
|
||||
public static R tooManyRequest() { |
||||
return new R(429, "操作过于频繁,请稍后重试"); |
||||
} |
||||
|
||||
public boolean isSuccess() { |
||||
return this.status == 200; |
||||
} |
||||
} |
||||
@ -1,20 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.vo; |
||||
|
||||
import cn.toesbieya.jxc.common.model.entity.SysResource; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.NoArgsConstructor; |
||||
import lombok.ToString; |
||||
import org.springframework.beans.BeanUtils; |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class ResourceVo extends SysResource { |
||||
private String fullname; |
||||
|
||||
public ResourceVo(SysResource parent) { |
||||
BeanUtils.copyProperties(parent, this); |
||||
} |
||||
} |
||||
@ -1,21 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.vo; |
||||
|
||||
import cn.toesbieya.jxc.common.constant.SocketConstant; |
||||
import lombok.Data; |
||||
|
||||
import java.util.List; |
||||
|
||||
@Data |
||||
public class SocketEventVo { |
||||
//事件类型
|
||||
private int type = SocketConstant.REDIS_EVENT_SPECIFIC; |
||||
|
||||
//事件名称
|
||||
private String event; |
||||
|
||||
//发送对象的id集合
|
||||
private List<Integer> to; |
||||
|
||||
//数据包
|
||||
private Object data; |
||||
} |
||||
@ -1,16 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.vo; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class SocketOfflineVo { |
||||
//用户ID
|
||||
private Integer uid; |
||||
|
||||
//断开时间
|
||||
private Long time; |
||||
} |
||||
@ -1,17 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.vo; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.io.Serializable; |
||||
import java.math.BigDecimal; |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class StockOutboundVo implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer id; |
||||
private BigDecimal num; |
||||
} |
||||
@ -1,20 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.vo; |
||||
|
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.ToString; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Data |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class StockSearch extends BaseSearch implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private String ids; |
||||
private String cids; |
||||
private Long startTime; |
||||
private Long endTime; |
||||
private String cgddids; |
||||
private String cgrkids; |
||||
} |
||||
@ -1,15 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.vo; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
import java.math.BigDecimal; |
||||
|
||||
@Data |
||||
public class StockSearchResult implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
private Integer cid; |
||||
private String cname; |
||||
private BigDecimal totalNum; |
||||
private BigDecimal totalPrice; |
||||
} |
||||
@ -1,27 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.model.vo; |
||||
|
||||
import cn.toesbieya.jxc.common.model.entity.SysUser; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.NoArgsConstructor; |
||||
import lombok.ToString; |
||||
import org.springframework.beans.BeanUtils; |
||||
|
||||
import java.util.Set; |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class UserVo extends SysUser { |
||||
private String token; |
||||
private String roleName; |
||||
private String deptName; |
||||
private boolean online = false; |
||||
private Set<Integer> departmentIds; |
||||
private Set<Integer> resourceIds; |
||||
|
||||
public UserVo(SysUser parent) { |
||||
BeanUtils.copyProperties(parent, this); |
||||
} |
||||
} |
||||
@ -1,53 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.util; |
||||
|
||||
import java.time.Instant; |
||||
import java.time.LocalDateTime; |
||||
import java.time.ZoneId; |
||||
import java.time.format.DateTimeFormatter; |
||||
import java.util.Calendar; |
||||
import java.util.Date; |
||||
|
||||
public class DateUtil { |
||||
public static final DateTimeFormatter defaultFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
||||
|
||||
public static String dateFormat() { |
||||
return dateFormat(null, null); |
||||
} |
||||
|
||||
public static String dateFormat(Long time) { |
||||
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()); |
||||
return dateFormat(localDateTime, null); |
||||
} |
||||
|
||||
public static String dateFormat(LocalDateTime time) { |
||||
return dateFormat(time, null); |
||||
} |
||||
|
||||
public static String dateFormat(DateTimeFormatter formatter) { |
||||
return dateFormat(null, formatter); |
||||
} |
||||
|
||||
public static String dateFormat(LocalDateTime time, DateTimeFormatter formatter) { |
||||
LocalDateTime t = time == null ? LocalDateTime.now() : time; |
||||
DateTimeFormatter f = formatter == null ? defaultFormatter : formatter; |
||||
return t.format(f); |
||||
} |
||||
|
||||
//获取今日零点的时间戳
|
||||
public static long getTimestampNow() { |
||||
long currentTimestamps = System.currentTimeMillis(); |
||||
return currentTimestamps - (currentTimestamps + 60 * 60 * 8 * 1000) % (60 * 60 * 24 * 1000); |
||||
} |
||||
|
||||
//获取n天前零点的时间戳
|
||||
public static long getTimestampBeforeNow(int before) { |
||||
Calendar cal = Calendar.getInstance(); |
||||
cal.setTime(new Date()); |
||||
cal.add(Calendar.DATE, -before); |
||||
cal.set(Calendar.HOUR_OF_DAY, 0); |
||||
cal.set(Calendar.MINUTE, 0); |
||||
cal.set(Calendar.SECOND, 0); |
||||
cal.set(Calendar.MILLISECOND, 0); |
||||
return cal.getTime().getTime(); |
||||
} |
||||
} |
||||
@ -1,176 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.util; |
||||
|
||||
import com.google.common.io.ByteStreams; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.core.io.ClassPathResource; |
||||
import org.springframework.data.redis.core.*; |
||||
import org.springframework.data.redis.core.script.DefaultRedisScript; |
||||
import org.springframework.data.redis.core.script.RedisScript; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.io.Closeable; |
||||
import java.io.IOException; |
||||
import java.util.*; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
@Component |
||||
@Slf4j |
||||
public class RedisUtil { |
||||
private static String INCREMENT_AND_EXPIRE_SCRIPT; |
||||
private static RedisTemplate<String, Object> redisTemplate; |
||||
private static StringRedisTemplate stringRedisTemplate; |
||||
|
||||
static { |
||||
try { |
||||
INCREMENT_AND_EXPIRE_SCRIPT = new String(ByteStreams.toByteArray(new ClassPathResource("/script/increase_and_expire.lua").getInputStream())); |
||||
} |
||||
catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
@Autowired |
||||
public RedisUtil(RedisTemplate<String, Object> redisTemplate, StringRedisTemplate stringRedisTemplate) { |
||||
RedisUtil.redisTemplate = redisTemplate; |
||||
RedisUtil.stringRedisTemplate = stringRedisTemplate; |
||||
} |
||||
|
||||
public static Set<String> keys(String match) { |
||||
return redisTemplate.execute((RedisCallback<Set<String>>) connection -> { |
||||
Set<String> result = new HashSet<>(); |
||||
|
||||
Cursor<byte[]> cursor = |
||||
connection.scan( |
||||
new ScanOptions |
||||
.ScanOptionsBuilder() |
||||
.match(match) |
||||
.count(2000) |
||||
.build() |
||||
); |
||||
|
||||
while (cursor.hasNext()) { |
||||
result.add(new String(cursor.next())); |
||||
} |
||||
|
||||
return result; |
||||
}); |
||||
} |
||||
|
||||
public static boolean exist(String key) { |
||||
Boolean result = redisTemplate.hasKey(key); |
||||
return result != null && result; |
||||
} |
||||
|
||||
public static void del(String... keys) { |
||||
redisTemplate.delete(Arrays.asList(keys)); |
||||
} |
||||
|
||||
public static long incrAndExpire(String key, int time) { |
||||
RedisScript<Long> redisScript = new DefaultRedisScript<>(INCREMENT_AND_EXPIRE_SCRIPT, Long.class); |
||||
|
||||
Long result = redisTemplate.execute(redisScript, Collections.singletonList(key), time); |
||||
|
||||
return result == null ? 0 : result; |
||||
} |
||||
|
||||
public static Object get(String key) { |
||||
return redisTemplate.opsForValue().get(key); |
||||
} |
||||
|
||||
public static void set(String key, Object value) { |
||||
redisTemplate.opsForValue().set(key, value); |
||||
} |
||||
|
||||
public static void set(String key, Object value, long expire) { |
||||
redisTemplate.opsForValue().set(key, value, expire, TimeUnit.SECONDS); |
||||
} |
||||
|
||||
public static Object hget(String key, String field) { |
||||
return redisTemplate.opsForHash().get(key, field); |
||||
} |
||||
|
||||
public static Map<Object, Object> hgetAll(String key) { |
||||
return redisTemplate.opsForHash().entries(key); |
||||
} |
||||
|
||||
public static void hset(String key, String field, Object value) { |
||||
redisTemplate.opsForHash().put(key, field, value); |
||||
} |
||||
|
||||
public static void hdel(String key, Object... fields) { |
||||
redisTemplate.opsForHash().delete(key, fields); |
||||
} |
||||
|
||||
public static List<Object> hmget(String key, String... field) { |
||||
return redisTemplate.opsForHash().multiGet(key, Arrays.asList(field)); |
||||
} |
||||
|
||||
public static void hmset(String key, Map<String, Object> map) { |
||||
redisTemplate.opsForHash().putAll(key, map); |
||||
} |
||||
|
||||
public static long sadd(String key, Object... members) { |
||||
Long result = redisTemplate.opsForSet().add(key, members); |
||||
return result == null ? 0 : result; |
||||
} |
||||
|
||||
public static void srem(String key, Object... members) { |
||||
redisTemplate.opsForSet().remove(key, members); |
||||
} |
||||
|
||||
public static long scard(String key) { |
||||
Long result = redisTemplate.opsForSet().size(key); |
||||
return result == null ? 0 : result; |
||||
} |
||||
|
||||
public static Set<Object> smembers(String key) { |
||||
Set<Object> result = redisTemplate.opsForSet().members(key); |
||||
return result == null ? Collections.emptySet() : result; |
||||
} |
||||
|
||||
public static <T> T execute(RedisScript<T> script, List<String> keys, Object... args) { |
||||
return redisTemplate.execute(script, keys, args); |
||||
} |
||||
|
||||
public static RedisTemplate<String, Object> getRedisTemplate() { |
||||
return redisTemplate; |
||||
} |
||||
|
||||
public static StringRedisTemplate getStringRedisTemplate() { |
||||
return stringRedisTemplate; |
||||
} |
||||
|
||||
public static class Locker implements Closeable { |
||||
private final String key; |
||||
private final String value; |
||||
private final long expire; |
||||
|
||||
public Locker(String key) { |
||||
this.key = "lock:" + key; |
||||
this.value = String.valueOf(System.currentTimeMillis()); |
||||
this.expire = 300; |
||||
} |
||||
|
||||
@Override |
||||
public void close() { |
||||
this.unlock(); |
||||
} |
||||
|
||||
public boolean lock() { |
||||
String LOCK_LUA_SCRIPT = "return redis.call('set',KEYS[1],ARGV[1],'EX',ARGV[2],'NX')"; |
||||
RedisScript<Boolean> redisScript = new DefaultRedisScript<>(LOCK_LUA_SCRIPT, Boolean.class); |
||||
Boolean result = redisTemplate.execute(redisScript, Collections.singletonList(key), value, expire); |
||||
return result != null; |
||||
} |
||||
|
||||
public void unlock() { |
||||
String UNLOCK_LUA_SCRIPT = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return false end"; |
||||
RedisScript<Boolean> redisScript = new DefaultRedisScript<>(UNLOCK_LUA_SCRIPT, Boolean.class); |
||||
Boolean result = redisTemplate.execute(redisScript, Collections.singletonList(key), value); |
||||
if (result == null || !result) { |
||||
log.error("redis锁释放失败,key:{},value:{}", key, value); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -1,57 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.util; |
||||
|
||||
import cn.toesbieya.jxc.common.model.entity.SysUser; |
||||
import cn.toesbieya.jxc.common.model.vo.UserVo; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import cn.toesbieya.jxc.common.constant.SessionConstant; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
|
||||
public class SessionUtil { |
||||
//token中的连接符
|
||||
private static final String tokenSeparator = "-*-"; |
||||
|
||||
public static void remove(String token) { |
||||
if (StringUtils.isEmpty(token)) return; |
||||
|
||||
RedisUtil.del(SessionConstant.REDIS_NAMESPACE + token); |
||||
} |
||||
|
||||
public static void save(UserVo user) { |
||||
String token = user.getToken(); |
||||
|
||||
if (StringUtils.isEmpty(token)) return; |
||||
|
||||
RedisUtil.set(SessionConstant.REDIS_NAMESPACE + token, user, SessionConstant.EXPIRE); |
||||
} |
||||
|
||||
public static UserVo get(String token) { |
||||
if (StringUtils.isEmpty(token)) return null; |
||||
|
||||
JSONObject o = (JSONObject) RedisUtil.get(SessionConstant.REDIS_NAMESPACE + token); |
||||
|
||||
if (o == null) return null; |
||||
|
||||
return JSONObject.toJavaObject(o, UserVo.class); |
||||
} |
||||
|
||||
public static UserVo get(HttpServletRequest request) { |
||||
String token = request.getHeader(SessionConstant.TOKEN_KEY); |
||||
return get(token); |
||||
} |
||||
|
||||
public static String generateToken(SysUser user) { |
||||
return user.getId() + tokenSeparator + Util.UUID(); |
||||
} |
||||
|
||||
public static Integer getUidFromToken(String token) { |
||||
if (StringUtils.isEmpty(token)) { |
||||
return null; |
||||
} |
||||
|
||||
String[] arr = token.split(tokenSeparator); |
||||
|
||||
return arr.length > 1 ? Integer.valueOf(arr[0]) : null; |
||||
} |
||||
} |
||||
@ -1,29 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.util; |
||||
|
||||
import org.springframework.expression.EvaluationContext; |
||||
import org.springframework.expression.ExpressionParser; |
||||
import org.springframework.expression.spel.standard.SpelExpressionParser; |
||||
import org.springframework.expression.spel.support.StandardEvaluationContext; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
public class SpringUtil { |
||||
private static final ExpressionParser parser = new SpelExpressionParser(); |
||||
|
||||
/** |
||||
* el表达式解析 |
||||
* |
||||
* @param el 表达式 |
||||
* @param names 参数名称数组 |
||||
* @param args 参数数组 |
||||
*/ |
||||
public static Object spell(String el, String[] names, Object[] args) { |
||||
if (StringUtils.isEmpty(el)) { |
||||
return null; |
||||
} |
||||
EvaluationContext context = new StandardEvaluationContext(); |
||||
for (int i = 0; i < args.length; i++) { |
||||
context.setVariable(names[i], args[i]); |
||||
} |
||||
return parser.parseExpression(el).getValue(context); |
||||
} |
||||
} |
||||
@ -1,72 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.util; |
||||
|
||||
import org.springframework.util.StringUtils; |
||||
|
||||
import java.io.PrintWriter; |
||||
import java.io.StringWriter; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.Arrays; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.UUID; |
||||
import java.util.function.Predicate; |
||||
import java.util.regex.Pattern; |
||||
import java.util.stream.Collectors; |
||||
|
||||
public class Util { |
||||
public static String UUID() { |
||||
return UUID.randomUUID().toString(); |
||||
} |
||||
|
||||
public static List<Integer> str2List(String string) { |
||||
if (StringUtils.isEmpty(string)) { |
||||
return Collections.emptyList(); |
||||
} |
||||
return Arrays.stream(string.split(",")) |
||||
.map(i -> Integer.parseInt(i.trim())) |
||||
.collect(Collectors.toList()); |
||||
} |
||||
|
||||
public static String str2Hex(String s) { |
||||
byte[] baKeyword = new byte[s.length() / 2]; |
||||
for (int i = 0; i < baKeyword.length; i++) { |
||||
baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16)); |
||||
} |
||||
return new String(baKeyword, StandardCharsets.ISO_8859_1); |
||||
} |
||||
|
||||
public static boolean isInteger(String str) { |
||||
Pattern pattern = Pattern.compile("^[-+]?[\\d]*$"); |
||||
return pattern.matcher(str).matches(); |
||||
} |
||||
|
||||
public static String exception2Str(Exception e) { |
||||
StringWriter stringWriter = new StringWriter(); |
||||
PrintWriter printWriter = new PrintWriter(stringWriter); |
||||
e.printStackTrace(printWriter); |
||||
printWriter.close(); |
||||
return stringWriter.toString(); |
||||
} |
||||
|
||||
public static <T> T find(Iterable<T> list, Predicate<T> predicate) { |
||||
for (T t : list) { |
||||
if (predicate.test(t)) return t; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static <T> int findIndex(Iterable<T> list, Predicate<T> predicate) { |
||||
int i = -1; |
||||
if (list == null) return i; |
||||
for (T t : list) { |
||||
i++; |
||||
if (predicate.test(t)) return i; |
||||
} |
||||
return -1; |
||||
} |
||||
|
||||
public static <T> boolean some(Iterable<T> list, Predicate<T> predicate) { |
||||
int index = findIndex(list, predicate); |
||||
return index > -1; |
||||
} |
||||
} |
||||
@ -1,36 +0,0 @@ |
||||
package cn.toesbieya.jxc.common.util; |
||||
|
||||
import cn.toesbieya.jxc.common.model.vo.SocketEventVo; |
||||
import cn.toesbieya.jxc.common.constant.SocketConstant; |
||||
|
||||
import java.util.List; |
||||
import java.util.Set; |
||||
import java.util.stream.Collectors; |
||||
|
||||
public class WebSocketUtil { |
||||
//获取在线用户的总数
|
||||
public static long getOnlineUserNum() { |
||||
return RedisUtil.scard(SocketConstant.REDIS_ONLINE_USER); |
||||
} |
||||
|
||||
//获取所有在线用户的id集合
|
||||
public static Set<Integer> getOnlineUserIds() { |
||||
Set<Object> result = RedisUtil.smembers(SocketConstant.REDIS_ONLINE_USER); |
||||
|
||||
return result.stream().map(e -> (Integer) e).collect(Collectors.toSet()); |
||||
} |
||||
|
||||
//发送消息
|
||||
public static void sendEvent(SocketEventVo vo) { |
||||
RedisUtil.getRedisTemplate().convertAndSend(SocketConstant.REDIS_EVENT_TOPIC_SEND, vo); |
||||
} |
||||
|
||||
//登出
|
||||
public static void sendLogoutEvent(List<Integer> to, String msg) { |
||||
SocketEventVo vo = new SocketEventVo(); |
||||
vo.setEvent(SocketConstant.EVENT_LOGOUT); |
||||
vo.setTo(to); |
||||
vo.setData(msg); |
||||
sendEvent(vo); |
||||
} |
||||
} |
||||
@ -1,6 +0,0 @@ |
||||
local current |
||||
current = redis.call("incr", KEYS[1]) |
||||
if tonumber(current) == 1 then |
||||
redis.call("expire", KEYS[1], ARGV[1]) |
||||
end |
||||
return current |
||||
@ -1,42 +0,0 @@ |
||||
<?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"> |
||||
<parent> |
||||
<artifactId>jxc</artifactId> |
||||
<groupId>cn.toesbieya</groupId> |
||||
<version>0.0.1-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>gateway</artifactId> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>cn.toesbieya</groupId> |
||||
<artifactId>common</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>cn.toesbieya</groupId> |
||||
<artifactId>api</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springframework.cloud</groupId> |
||||
<artifactId>spring-cloud-starter-gateway</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.alibaba.cloud</groupId> |
||||
<artifactId>spring-cloud-starter-dubbo</artifactId> |
||||
</dependency> |
||||
|
||||
<!--<dependency> |
||||
<groupId>com.alibaba.csp</groupId> |
||||
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId> |
||||
</dependency>--> |
||||
</dependencies> |
||||
</project> |
||||
@ -1,13 +0,0 @@ |
||||
package cn.toesbieya.jxc.gateway; |
||||
|
||||
import org.springframework.boot.SpringApplication; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; |
||||
|
||||
@SpringBootApplication(scanBasePackages = "cn.toesbieya.jxc") |
||||
@EnableDiscoveryClient |
||||
public class GatewayApplication { |
||||
public static void main(String[] args) { |
||||
SpringApplication.run(GatewayApplication.class, args); |
||||
} |
||||
} |
||||
@ -1,19 +0,0 @@ |
||||
package cn.toesbieya.jxc.gateway.config; |
||||
|
||||
import lombok.Data; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
|
||||
@Component |
||||
@ConfigurationProperties("spring.cloud.gateway") |
||||
@Data |
||||
public class GatewayConfig { |
||||
private Set<String> whitelist = new HashSet<>(); |
||||
|
||||
private String dataId = "jxc-gateway.yml"; |
||||
|
||||
private String group = "DEFAULT_GROUP"; |
||||
} |
||||
@ -1,14 +0,0 @@ |
||||
package cn.toesbieya.jxc.gateway.config; |
||||
|
||||
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import reactor.core.publisher.Mono; |
||||
|
||||
@Configuration |
||||
public class RateConfig { |
||||
@Bean |
||||
public KeyResolver urlKeyResolver() { |
||||
return exchange -> Mono.just(exchange.getRequest().getPath().value()); |
||||
} |
||||
} |
||||
@ -1,66 +0,0 @@ |
||||
package cn.toesbieya.jxc.gateway.config; |
||||
|
||||
import cn.toesbieya.jxc.api.system.ResourceApi; |
||||
import cn.toesbieya.jxc.common.model.entity.SysResource; |
||||
import cn.toesbieya.jxc.common.model.vo.UserVo; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.apache.dubbo.config.annotation.Reference; |
||||
import org.springframework.boot.CommandLineRunner; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.time.Instant; |
||||
import java.time.temporal.ChronoUnit; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
@Component |
||||
@Slf4j |
||||
public class ResourceConfig implements CommandLineRunner { |
||||
private final static ConcurrentHashMap<String, SysResource> urlMap = new ConcurrentHashMap<>(256); |
||||
private final static ConcurrentHashMap<String, SysResource> adminUrlMap = new ConcurrentHashMap<>(16); |
||||
@Reference |
||||
private ResourceApi resourceApi; |
||||
|
||||
public static boolean authority(UserVo user, String url) { |
||||
boolean isAdmin = user.isAdmin(); |
||||
SysResource r = adminUrlMap.get(url); |
||||
|
||||
//访问admin权限的资源时,需要用户是admin并且该权限已启用
|
||||
if (r != null) { |
||||
return r.isEnable() && isAdmin; |
||||
} |
||||
|
||||
if (isAdmin) return true; |
||||
|
||||
r = urlMap.get(url); |
||||
|
||||
//权限表中无记录的资源放行
|
||||
if (r == null) return true; |
||||
|
||||
//未启用时拦截
|
||||
if (!r.isEnable()) return false; |
||||
|
||||
//根据用户权限判断
|
||||
Set<Integer> ids = user.getResourceIds(); |
||||
return ids != null && ids.contains(r.getId()); |
||||
} |
||||
|
||||
@Override |
||||
public void run(String... args) { |
||||
Instant start = Instant.now(); |
||||
|
||||
List<SysResource> resources = resourceApi.getEnableApi(); |
||||
|
||||
for (SysResource p : resources) { |
||||
String path = p.getPath(); |
||||
if (p.isAdmin()) { |
||||
adminUrlMap.put(path, p); |
||||
} |
||||
else urlMap.put(path, p); |
||||
} |
||||
|
||||
Instant end = Instant.now(); |
||||
log.info("权限资源加载完成,耗时:{}毫秒", ChronoUnit.MILLIS.between(start, end)); |
||||
} |
||||
} |
||||
@ -1,138 +0,0 @@ |
||||
package cn.toesbieya.jxc.gateway.config; |
||||
|
||||
import cn.toesbieya.jxc.gateway.filter.SecurityFilter; |
||||
import com.alibaba.nacos.api.NacosFactory; |
||||
import com.alibaba.nacos.api.PropertyKeyConst; |
||||
import com.alibaba.nacos.api.config.ConfigService; |
||||
import com.alibaba.nacos.api.config.listener.Listener; |
||||
import com.alibaba.nacos.api.exception.NacosException; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.beans.factory.annotation.Value; |
||||
import org.springframework.cloud.gateway.event.RefreshRoutesEvent; |
||||
import org.springframework.cloud.gateway.filter.FilterDefinition; |
||||
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition; |
||||
import org.springframework.cloud.gateway.route.RouteDefinition; |
||||
import org.springframework.cloud.gateway.route.RouteDefinitionWriter; |
||||
import org.springframework.context.ApplicationEventPublisher; |
||||
import org.springframework.context.ApplicationEventPublisherAware; |
||||
import org.springframework.stereotype.Component; |
||||
import org.yaml.snakeyaml.Yaml; |
||||
import reactor.core.publisher.Mono; |
||||
|
||||
import javax.annotation.PostConstruct; |
||||
import java.net.URI; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Properties; |
||||
import java.util.concurrent.Executor; |
||||
import java.util.stream.Collectors; |
||||
|
||||
@Component |
||||
@Slf4j |
||||
public class RouteConfig implements ApplicationEventPublisherAware { |
||||
@Value("${spring.cloud.nacos.config.server-addr}") |
||||
private String NACOS_SERVER_ADDR; |
||||
|
||||
private GatewayConfig config; |
||||
|
||||
private RouteDefinitionWriter writer; |
||||
|
||||
private ApplicationEventPublisher publisher; |
||||
|
||||
@PostConstruct |
||||
public void addListener() throws NacosException { |
||||
Properties properties = new Properties(); |
||||
properties.put(PropertyKeyConst.SERVER_ADDR, NACOS_SERVER_ADDR); |
||||
ConfigService configService = NacosFactory.createConfigService(properties); |
||||
|
||||
configService.addListener(config.getDataId(), config.getGroup(), new Listener() { |
||||
@Override |
||||
public Executor getExecutor() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
@SuppressWarnings("unchecked") |
||||
public void receiveConfigInfo(String configInfo) { |
||||
Yaml yaml = new Yaml(); |
||||
Map<String, Object> config = yaml.load(configInfo); |
||||
config = (Map<String, Object>) config.get("spring"); |
||||
config = (Map<String, Object>) config.get("cloud"); |
||||
config = (Map<String, Object>) config.get("gateway"); |
||||
|
||||
SecurityFilter.updateWhitelist((List<String>) config.get("whitelist")); |
||||
|
||||
List<Map<String, Object>> routes = (List<Map<String, Object>>) config.get("routes"); |
||||
|
||||
if (routes == null) return; |
||||
|
||||
List<RouteDefinition> list = |
||||
routes |
||||
.stream() |
||||
.map(map -> { |
||||
RouteDefinition route = new RouteDefinition(); |
||||
|
||||
route.setId((String) map.get("id")); |
||||
|
||||
route.setUri(URI.create((String) map.get("uri"))); |
||||
|
||||
List<String> predicates = (List<String>) map.get("predicates"); |
||||
|
||||
if (predicates != null) { |
||||
route.setPredicates( |
||||
predicates |
||||
.stream() |
||||
.map(PredicateDefinition::new) |
||||
.collect(Collectors.toList()) |
||||
); |
||||
} |
||||
|
||||
List<String> filters = (List<String>) map.get("filters"); |
||||
|
||||
if (filters != null) { |
||||
route.setFilters( |
||||
filters |
||||
.stream() |
||||
.map(FilterDefinition::new) |
||||
.collect(Collectors.toList()) |
||||
); |
||||
} |
||||
|
||||
return route; |
||||
}) |
||||
.collect(Collectors.toList()); |
||||
|
||||
update(list); |
||||
|
||||
//SentinelFilter.registerRules(list);
|
||||
} |
||||
}); |
||||
} |
||||
|
||||
private void update(List<RouteDefinition> routes) { |
||||
if (routes == null) return; |
||||
|
||||
routes.forEach(route -> { |
||||
this.writer.delete(Mono.just(route.getId())); |
||||
writer.save(Mono.just(route)).subscribe(); |
||||
}); |
||||
|
||||
this.publisher.publishEvent(new RefreshRoutesEvent(this)); |
||||
} |
||||
|
||||
@Override |
||||
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { |
||||
this.publisher = publisher; |
||||
} |
||||
|
||||
@Autowired |
||||
public void setWriter(RouteDefinitionWriter writer) { |
||||
this.writer = writer; |
||||
} |
||||
|
||||
@Autowired |
||||
public void setGatewayProperties(GatewayConfig config) { |
||||
this.config = config; |
||||
} |
||||
} |
||||
@ -1,13 +0,0 @@ |
||||
package cn.toesbieya.jxc.gateway.controller; |
||||
|
||||
import cn.toesbieya.jxc.common.model.vo.R; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.ResponseBody; |
||||
|
||||
public class FallbackController { |
||||
@RequestMapping("fallback") |
||||
@ResponseBody |
||||
public R fallback() { |
||||
return R.fail("服务异常"); |
||||
} |
||||
} |
||||
@ -1,107 +0,0 @@ |
||||
package cn.toesbieya.jxc.gateway.filter; |
||||
|
||||
import cn.toesbieya.jxc.common.model.vo.R; |
||||
import cn.toesbieya.jxc.common.model.vo.UserVo; |
||||
import cn.toesbieya.jxc.gateway.config.GatewayConfig; |
||||
import cn.toesbieya.jxc.gateway.config.ResourceConfig; |
||||
import com.alibaba.fastjson.JSON; |
||||
import cn.toesbieya.jxc.common.constant.SessionConstant; |
||||
import cn.toesbieya.jxc.common.util.SessionUtil; |
||||
import cn.toesbieya.jxc.common.util.Util; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.cloud.gateway.filter.GlobalFilter; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.core.annotation.Order; |
||||
import org.springframework.core.io.buffer.DataBuffer; |
||||
import org.springframework.http.HttpStatus; |
||||
import org.springframework.http.server.PathContainer; |
||||
import org.springframework.http.server.reactive.ServerHttpResponse; |
||||
import org.springframework.stereotype.Component; |
||||
import org.springframework.web.util.pattern.PathPattern; |
||||
import org.springframework.web.util.pattern.PathPatternParser; |
||||
import reactor.core.publisher.Mono; |
||||
|
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.ArrayList; |
||||
import java.util.Collection; |
||||
import java.util.List; |
||||
import java.util.stream.Collectors; |
||||
|
||||
import static org.springframework.http.server.PathContainer.parsePath; |
||||
|
||||
@Component |
||||
@Slf4j |
||||
public class SecurityFilter { |
||||
private GatewayConfig gatewayConfig; |
||||
|
||||
private static final PathPatternParser pathPatternParser = new PathPatternParser(); |
||||
|
||||
private static List<PathPattern> whitelistPatterns = new ArrayList<>(); |
||||
|
||||
@Bean |
||||
@Order(-1) |
||||
public GlobalFilter globalFilter() { |
||||
updateWhitelist(gatewayConfig.getWhitelist()); |
||||
|
||||
return ((exchange, chain) -> { |
||||
String requestUrl = exchange.getRequest().getURI().getPath(); |
||||
|
||||
PathContainer path = parsePath(requestUrl); |
||||
|
||||
//放行白名单内的url
|
||||
if (Util.some(whitelistPatterns, pattern -> pattern.matches(path))) { |
||||
return chain.filter(exchange); |
||||
} |
||||
|
||||
ServerHttpResponse response = exchange.getResponse(); |
||||
|
||||
String token = exchange.getRequest().getHeaders().getFirst(SessionConstant.TOKEN_KEY); |
||||
|
||||
UserVo user = SessionUtil.get(token); |
||||
|
||||
//未登录
|
||||
if (user == null) { |
||||
return responseJSON(response, R.requireLogin()); |
||||
} |
||||
|
||||
//没有权限
|
||||
if (!ResourceConfig.authority(user, requestUrl)) { |
||||
log.warn("权限拦截,访问路径:{},用户:{}", requestUrl, user.getNickName()); |
||||
return responseJSON(response, R.noPermission()); |
||||
} |
||||
|
||||
return chain.filter(exchange); |
||||
}); |
||||
} |
||||
|
||||
private Mono<Void> responseJSON(ServerHttpResponse response, R result) { |
||||
byte[] bytes = JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8); |
||||
|
||||
DataBuffer buffer = response.bufferFactory().wrap(bytes); |
||||
|
||||
response.setStatusCode(HttpStatus.OK); |
||||
|
||||
response.getHeaders().add("Content-Type", "application/json; charset=utf-8"); |
||||
|
||||
return response.writeWith(Mono.just(buffer)); |
||||
} |
||||
|
||||
public static void updateWhitelist(Collection<String> list) { |
||||
if (list == null) { |
||||
whitelistPatterns = new ArrayList<>(); |
||||
return; |
||||
} |
||||
|
||||
whitelistPatterns = |
||||
list |
||||
.stream() |
||||
.map(pathPatternParser::parse) |
||||
.collect(Collectors.toList()); |
||||
} |
||||
|
||||
@Autowired |
||||
public void setGatewayProperties(GatewayConfig gatewayConfig) { |
||||
this.gatewayConfig = gatewayConfig; |
||||
} |
||||
} |
||||
@ -1,68 +0,0 @@ |
||||
package cn.toesbieya.jxc.gateway.filter; |
||||
|
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
@Configuration |
||||
public class SentinelFilter { |
||||
/*private GatewayProperties gatewayProperties; |
||||
|
||||
private final List<ViewResolver> viewResolvers; |
||||
private final ServerCodecConfigurer serverCodecConfigurer; |
||||
|
||||
public SentinelFilter(ObjectProvider<List<ViewResolver>> viewResolversProvider, |
||||
ServerCodecConfigurer serverCodecConfigurer) { |
||||
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList); |
||||
this.serverCodecConfigurer = serverCodecConfigurer; |
||||
} |
||||
|
||||
@Bean |
||||
@Order(Ordered.HIGHEST_PRECEDENCE) |
||||
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() { |
||||
return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer); |
||||
} |
||||
|
||||
@Bean |
||||
@Order(Ordered.HIGHEST_PRECEDENCE) |
||||
public GlobalFilter sentinelGatewayFilter() { |
||||
return new SentinelGatewayFilter(); |
||||
} |
||||
|
||||
@PostConstruct |
||||
public void init() { |
||||
registerRules(gatewayProperties.getRoutes()); |
||||
|
||||
GatewayCallbackManager.setBlockHandler( |
||||
(exchange, t) -> |
||||
ServerResponse |
||||
.status(HttpStatus.OK) |
||||
.contentType(MediaType.APPLICATION_JSON_UTF8) |
||||
.body(fromObject(R.tooManyRequest())) |
||||
); |
||||
} |
||||
|
||||
public static void registerRules(List<RouteDefinition> routes) { |
||||
Set<GatewayFlowRule> rules = new HashSet<>(); |
||||
|
||||
routes.forEach(route -> { |
||||
String id = route.getId(); |
||||
|
||||
rules.add(new GatewayFlowRule(id).setCount(100)); |
||||
|
||||
rules.add( |
||||
new GatewayFlowRule(id) |
||||
.setCount(1) |
||||
.setParamItem( |
||||
new GatewayParamFlowItem() |
||||
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_CLIENT_IP) |
||||
) |
||||
); |
||||
}); |
||||
|
||||
GatewayRuleManager.register2Property(new DynamicSentinelProperty<>(rules)); |
||||
} |
||||
|
||||
@Autowired |
||||
public void setGatewayProperties(GatewayProperties gatewayProperties) { |
||||
this.gatewayProperties = gatewayProperties; |
||||
}*/ |
||||
} |
||||
@ -1,20 +0,0 @@ |
||||
spring: |
||||
application: |
||||
name: jxc-gateway |
||||
|
||||
cloud: |
||||
nacos: |
||||
config: |
||||
server-addr: 127.0.0.1:8848 |
||||
shared-configs: |
||||
- data-id: jxc-common-redis.yml |
||||
file-extension: yml |
||||
|
||||
discovery: |
||||
server-addr: 127.0.0.1:8848 |
||||
|
||||
dubbo: |
||||
registry: |
||||
address: nacos://127.0.0.1:8848 |
||||
cloud: |
||||
subscribed-services: jxc-web-system |
||||
@ -1,24 +0,0 @@ |
||||
spring: |
||||
datasource: |
||||
driver-class-name: com.mysql.cj.jdbc.Driver |
||||
url: jdbc:mysql://localhost:3306/repo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true |
||||
username: |
||||
password: |
||||
|
||||
mybatis-plus: |
||||
mapper-locations: |
||||
- classpath*:/mapper/**/*.xml |
||||
configuration: |
||||
local-cache-scope: STATEMENT |
||||
cache-enabled: false |
||||
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl |
||||
global-config: |
||||
banner: false |
||||
db-config: |
||||
id-type: NONE |
||||
|
||||
pagehelper: |
||||
helperDialect: mysql |
||||
reasonable: true |
||||
supportMethodsArguments: true |
||||
params: count=countSql |
||||
@ -1,12 +0,0 @@ |
||||
spring: |
||||
redis: |
||||
host: localhost |
||||
port: 6379 |
||||
password: |
||||
timeout: 3000 |
||||
lettuce: |
||||
pool: |
||||
max-idle: 500 |
||||
min-idle: 50 |
||||
max-active: 2000 |
||||
max-wait: 1000 |
||||
@ -1,66 +0,0 @@ |
||||
server: |
||||
port: 8081 |
||||
|
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
discovery: |
||||
locator: |
||||
enabled: true |
||||
lowerCaseServiceId: true |
||||
|
||||
default-filters: |
||||
- name: RequestRateLimiter |
||||
args: |
||||
redis-rate-limiter.replenishRate: 10 # 每秒处理多少个请求 |
||||
redis-rate-limiter.burstCapacity: 20 # 一秒钟内完成的最大请求数 |
||||
key-resolver: #{@urlKeyResolver} |
||||
|
||||
routes: |
||||
- id: jxc-web-account |
||||
uri: lb://jxc-web-account |
||||
predicates: |
||||
- Path=/account/** |
||||
|
||||
- id: jxc-web-doc |
||||
uri: lb://jxc-web-doc |
||||
predicates: |
||||
- Path=/doc/** |
||||
|
||||
- id: jxc-web-file |
||||
uri: lb://jxc-web-file |
||||
predicates: |
||||
- Path=/file/** |
||||
|
||||
- id: jxc-web-message |
||||
uri: lb://jxc-web-message |
||||
predicates: |
||||
- Path=/message/** |
||||
|
||||
- id: jxc-web-record |
||||
uri: lb://jxc-web-record |
||||
predicates: |
||||
- Path=/record/** |
||||
|
||||
- id: jxc-web-statistic |
||||
uri: lb://jxc-web-statistic |
||||
predicates: |
||||
- Path=/statistic/** |
||||
|
||||
- id: jxc-web-stock |
||||
uri: lb://jxc-web-stock |
||||
predicates: |
||||
- Path=/stock/** |
||||
|
||||
- id: jxc-web-system |
||||
uri: lb://jxc-web-system |
||||
predicates: |
||||
- Path=/system/** |
||||
|
||||
whitelist: |
||||
- /test/** |
||||
- /account/login |
||||
- /account/logout |
||||
- /account/register |
||||
- /account/checkLoginName |
||||
- /account/checkNickName |
||||
@ -1,2 +0,0 @@ |
||||
server: |
||||
port: 8000 |
||||
@ -1,4 +0,0 @@ |
||||
server: |
||||
port: 8001 |
||||
servlet: |
||||
context-path: /doc |
||||
@ -1,11 +0,0 @@ |
||||
server: |
||||
port: 8002 |
||||
|
||||
qiniu: |
||||
access-key: |
||||
secret-key: |
||||
bucket: |
||||
#七牛的临时上传凭证的有效期,单位秒 |
||||
token-expires: 3600 |
||||
#七牛的临时上传凭证的redis键名 |
||||
redis-cache-key: qiniu-token |
||||
@ -1,4 +0,0 @@ |
||||
server: |
||||
port: 8003 |
||||
servlet: |
||||
context-path: /message |
||||
@ -1,2 +0,0 @@ |
||||
server: |
||||
port: 8004 |
||||
@ -1,2 +0,0 @@ |
||||
server: |
||||
port: 8005 |
||||
@ -1,2 +0,0 @@ |
||||
server: |
||||
port: 8006 |
||||
@ -1,4 +0,0 @@ |
||||
server: |
||||
port: 8007 |
||||
servlet: |
||||
context-path: /system |
||||
@ -1,6 +0,0 @@ |
||||
socket: |
||||
#hostname: 172.24.52.184 |
||||
hostname: localhost |
||||
port: 12580 |
||||
max-frame-payload-length: 1048576 |
||||
max-http-content-length: 1048576 |
||||
@ -1,151 +0,0 @@ |
||||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<parent> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-parent</artifactId> |
||||
<version>2.2.7.RELEASE</version> |
||||
<relativePath/> <!-- lookup parent from repository --> |
||||
</parent> |
||||
<packaging>pom</packaging> |
||||
<modules> |
||||
<module>common</module> |
||||
<module>gateway</module> |
||||
<module>web</module> |
||||
<module>websocket</module> |
||||
<module>schedule</module> |
||||
<module>api</module> |
||||
</modules> |
||||
|
||||
<groupId>cn.toesbieya</groupId> |
||||
<artifactId>jxc</artifactId> |
||||
<version>0.0.1-SNAPSHOT</version> |
||||
<name>jxc</name> |
||||
|
||||
<properties> |
||||
<java.version>1.8</java.version> |
||||
<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version> |
||||
<spring-cloud.version>Hoxton.SR3</spring-cloud.version> |
||||
<mybatis-plus.version>3.3.2</mybatis-plus.version> |
||||
<pagehelper.version>1.2.12</pagehelper.version> |
||||
<socketio.version>1.7.18</socketio.version> |
||||
<guava.version>29.0-jre</guava.version> |
||||
<fastjson.version>1.2.60</fastjson.version> |
||||
<qiniu.version>[7.2.0, 7.2.99]</qiniu.version> |
||||
<easyexcel.version>2.2.5</easyexcel.version> |
||||
</properties> |
||||
|
||||
<dependencies> |
||||
<!--nacos--> |
||||
<dependency> |
||||
<groupId>com.alibaba.cloud</groupId> |
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.alibaba.cloud</groupId> |
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> |
||||
</dependency> |
||||
|
||||
<!--lombok--> |
||||
<dependency> |
||||
<groupId>org.projectlombok</groupId> |
||||
<artifactId>lombok</artifactId> |
||||
</dependency> |
||||
</dependencies> |
||||
|
||||
<dependencyManagement> |
||||
<dependencies> |
||||
<!--基础模块--> |
||||
<dependency> |
||||
<groupId>cn.toesbieya</groupId> |
||||
<artifactId>common</artifactId> |
||||
<version>${project.version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>cn.toesbieya</groupId> |
||||
<artifactId>web-common</artifactId> |
||||
<version>${project.version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>cn.toesbieya</groupId> |
||||
<artifactId>api</artifactId> |
||||
<version>${project.version}</version> |
||||
</dependency> |
||||
|
||||
<!--<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-dependencies</artifactId> |
||||
<version>${spring-boot.version}</version> |
||||
<type>pom</type> |
||||
<scope>import</scope> |
||||
</dependency>--> |
||||
|
||||
<!--SpringCloud--> |
||||
<dependency> |
||||
<groupId>org.springframework.cloud</groupId> |
||||
<artifactId>spring-cloud-dependencies</artifactId> |
||||
<version>${spring-cloud.version}</version> |
||||
<type>pom</type> |
||||
<scope>import</scope> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.alibaba.cloud</groupId> |
||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId> |
||||
<version>${spring-cloud-alibaba.version}</version> |
||||
<type>pom</type> |
||||
<scope>import</scope> |
||||
</dependency> |
||||
|
||||
<!--mybatis--> |
||||
<dependency> |
||||
<groupId>com.baomidou</groupId> |
||||
<artifactId>mybatis-plus-boot-starter</artifactId> |
||||
<version>${mybatis-plus.version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.github.pagehelper</groupId> |
||||
<artifactId>pagehelper-spring-boot-starter</artifactId> |
||||
<version>${pagehelper.version}</version> |
||||
</dependency> |
||||
|
||||
<!--websocket--> |
||||
<dependency> |
||||
<groupId>com.corundumstudio.socketio</groupId> |
||||
<artifactId>netty-socketio</artifactId> |
||||
<version>${socketio.version}</version> |
||||
</dependency> |
||||
|
||||
<!--工具类--> |
||||
<dependency> |
||||
<groupId>com.alibaba</groupId> |
||||
<artifactId>easyexcel</artifactId> |
||||
<version>${easyexcel.version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.qiniu</groupId> |
||||
<artifactId>qiniu-java-sdk</artifactId> |
||||
<version>${qiniu.version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.google.guava</groupId> |
||||
<artifactId>guava</artifactId> |
||||
<version>${guava.version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.alibaba</groupId> |
||||
<artifactId>fastjson</artifactId> |
||||
<version>${fastjson.version}</version> |
||||
</dependency> |
||||
</dependencies> |
||||
</dependencyManagement> |
||||
|
||||
<build> |
||||
<plugins> |
||||
<plugin> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-maven-plugin</artifactId> |
||||
</plugin> |
||||
</plugins> |
||||
</build> |
||||
</project> |
||||
@ -1,34 +0,0 @@ |
||||
<?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"> |
||||
<parent> |
||||
<artifactId>jxc</artifactId> |
||||
<groupId>cn.toesbieya</groupId> |
||||
<version>0.0.1-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>shedule</artifactId> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>cn.toesbieya</groupId> |
||||
<artifactId>common</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>mysql</groupId> |
||||
<artifactId>mysql-connector-java</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.baomidou</groupId> |
||||
<artifactId>mybatis-plus-boot-starter</artifactId> |
||||
</dependency> |
||||
</dependencies> |
||||
</project> |
||||
@ -1,16 +0,0 @@ |
||||
package cn.toesbieya.jxc.schedule; |
||||
|
||||
import org.mybatis.spring.annotation.MapperScan; |
||||
import org.springframework.boot.WebApplicationType; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.boot.builder.SpringApplicationBuilder; |
||||
|
||||
@SpringBootApplication(scanBasePackages = "cn.toesbieya.jxc") |
||||
@MapperScan("cn.toesbieya.jxc.schedule.mapper") |
||||
public class ScheduleApplication { |
||||
public static void main(String[] args) { |
||||
new SpringApplicationBuilder(ScheduleApplication.class) |
||||
.web(WebApplicationType.NONE) |
||||
.run(args); |
||||
} |
||||
} |
||||
@ -1,45 +0,0 @@ |
||||
package cn.toesbieya.jxc.schedule.config; |
||||
|
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.scheduling.annotation.AsyncConfigurer; |
||||
import org.springframework.scheduling.annotation.EnableAsync; |
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
||||
|
||||
import java.util.concurrent.Executor; |
||||
import java.util.concurrent.ThreadPoolExecutor; |
||||
|
||||
@Configuration |
||||
@EnableAsync |
||||
@Slf4j |
||||
public class ExecutorConfig implements AsyncConfigurer { |
||||
|
||||
@Override |
||||
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { |
||||
return (ex, method, params) -> { |
||||
log.error("异步线程执行失败。方法:[{}],异常信息[{}] : ", method, ex.getMessage(), ex); |
||||
}; |
||||
} |
||||
|
||||
//定时任务线程池
|
||||
@Bean |
||||
public Executor scheduledExecutor() { |
||||
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); |
||||
//核心线程数
|
||||
threadPoolTaskExecutor.setCorePoolSize(3); |
||||
//是否回收空闲线程
|
||||
threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true); |
||||
//最大线程数
|
||||
threadPoolTaskExecutor.setMaxPoolSize(5); |
||||
//配置等待队列大小
|
||||
threadPoolTaskExecutor.setQueueCapacity(2); |
||||
//配置线程池前缀
|
||||
threadPoolTaskExecutor.setThreadNamePrefix("scheduled-"); |
||||
//拒绝策略
|
||||
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy()); |
||||
threadPoolTaskExecutor.initialize(); |
||||
return threadPoolTaskExecutor; |
||||
} |
||||
} |
||||
@ -1,33 +0,0 @@ |
||||
package cn.toesbieya.jxc.schedule.mapper; |
||||
|
||||
import cn.toesbieya.jxc.common.model.entity.StatFinishOrder; |
||||
import cn.toesbieya.jxc.common.model.entity.StatProfitGoods; |
||||
import cn.toesbieya.jxc.common.model.entity.StatProfitTotal; |
||||
import org.apache.ibatis.annotations.Param; |
||||
|
||||
import java.math.BigDecimal; |
||||
import java.util.List; |
||||
|
||||
public interface StatisticMapper { |
||||
boolean checkDailyFinishOrderExist(@Param("time") long time); |
||||
|
||||
boolean checkDailyProfitExist(@Param("time") long time); |
||||
|
||||
int insertFinishOrder(StatFinishOrder param); |
||||
|
||||
int insertProfitTotal(StatProfitTotal param); |
||||
|
||||
int insertProfitGoodsBatch(@Param("list") List<StatProfitGoods> list); |
||||
|
||||
BigDecimal getPurchaseOrderDailyTotalPurchasePrice(@Param("start") Long start, @Param("end") Long end); |
||||
|
||||
List<StatProfitGoods> getPurchaseOrderDailyProfitGoods(@Param("start") long start, @Param("end") long end); |
||||
|
||||
Integer getPurchaseOrderLastDayFinishOrderNum(); |
||||
|
||||
BigDecimal getSellOrderDailyTotalPurchasePrice(@Param("start") Long start, @Param("end") Long end); |
||||
|
||||
List<StatProfitGoods> getSellOrderDailyProfitGoods(@Param("start") long start, @Param("end") long end); |
||||
|
||||
Integer getSellOrderLastDayFinishOrderNum(); |
||||
} |
||||
@ -1,106 +0,0 @@ |
||||
package cn.toesbieya.jxc.schedule.task; |
||||
|
||||
import cn.toesbieya.jxc.common.constant.DocConstant; |
||||
import cn.toesbieya.jxc.common.util.DateUtil; |
||||
import cn.toesbieya.jxc.common.util.RedisUtil; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.boot.CommandLineRunner; |
||||
import org.springframework.context.annotation.DependsOn; |
||||
import org.springframework.scheduling.annotation.Async; |
||||
import org.springframework.scheduling.annotation.Scheduled; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.time.Instant; |
||||
import java.time.temporal.ChronoUnit; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
@Component |
||||
@Slf4j |
||||
@DependsOn("redisUtil") |
||||
public class DocTask implements CommandLineRunner { |
||||
@Override |
||||
public void run(String... args) { |
||||
template("初始化单据ID", 0); |
||||
} |
||||
|
||||
//每天零点重置单据ID的值
|
||||
@Async("scheduledExecutor") |
||||
@Scheduled(cron = "1 0 0 */1 * ?") |
||||
public void autoRefreshDocId() { |
||||
template("定时更新单据ID", 1); |
||||
} |
||||
|
||||
//启动时初始化单据ID
|
||||
private void initDocId() { |
||||
String[] fields = new String[DocConstant.DOC_TYPE.length + 1]; |
||||
fields[0] = "date"; |
||||
System.arraycopy(DocConstant.DOC_TYPE, 0, fields, 1, fields.length - 1); |
||||
|
||||
List<Object> result = RedisUtil.hmget(DocConstant.DOC_TYPE_REDIS_KEY, fields); |
||||
|
||||
long now = DateUtil.getTimestampNow(); |
||||
|
||||
//日期不是今天时,更新全部
|
||||
Object firstItem = result.get(0); |
||||
if (null == firstItem || now != (long) firstItem) { |
||||
updateAllDoc(now); |
||||
log.info("更新【{}】种单据ID成功", DocConstant.DOC_TYPE.length); |
||||
return; |
||||
} |
||||
|
||||
//判断是否有新增的单据类型,有则更新
|
||||
int updateNum = 0; |
||||
Map<String, Object> update = new HashMap<>(); |
||||
int resultSize = result.size(); |
||||
|
||||
for (int i = 1; i < resultSize; i++) { |
||||
if (result.get(i) == null) { |
||||
updateNum++; |
||||
update.put(DocConstant.DOC_TYPE[i - 1], 1); |
||||
} |
||||
} |
||||
|
||||
if (updateNum > 0) { |
||||
RedisUtil.hmset(DocConstant.DOC_TYPE_REDIS_KEY, update); |
||||
log.info("更新增加的单据【{}】种", updateNum); |
||||
} |
||||
} |
||||
|
||||
//每种单据的值置为1
|
||||
private void updateAllDoc(long now) { |
||||
Map<String, Object> map = new HashMap<>(); |
||||
map.put("date", now); |
||||
for (String v : DocConstant.DOC_TYPE) { |
||||
map.put(v, 1); |
||||
} |
||||
RedisUtil.hmset(DocConstant.DOC_TYPE_REDIS_KEY, map); |
||||
} |
||||
|
||||
//模板
|
||||
private void template(String action, int type) { |
||||
Instant start = Instant.now(); |
||||
|
||||
String lockKey = DocConstant.UPDATE_DOC_LOCK_KEY; |
||||
|
||||
try (RedisUtil.Locker locker = new RedisUtil.Locker(lockKey)) { |
||||
if (!locker.lock()) { |
||||
log.error("{}失败,获取锁【{}】失败", action, lockKey); |
||||
return; |
||||
} |
||||
|
||||
if (type == 0) { |
||||
initDocId(); |
||||
} |
||||
else { |
||||
updateAllDoc(DateUtil.getTimestampNow()); |
||||
} |
||||
|
||||
log.info("{}成功,耗时:{}毫秒", action, ChronoUnit.MILLIS.between(start, Instant.now())); |
||||
} |
||||
catch (Exception e) { |
||||
log.error("{}失败", action, e); |
||||
} |
||||
} |
||||
} |
||||
@ -1,63 +0,0 @@ |
||||
package cn.toesbieya.jxc.schedule.task; |
||||
|
||||
import cn.toesbieya.jxc.common.constant.SessionConstant; |
||||
import cn.toesbieya.jxc.common.constant.SocketConstant; |
||||
import cn.toesbieya.jxc.common.model.vo.SocketOfflineVo; |
||||
import cn.toesbieya.jxc.common.util.RedisUtil; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.boot.CommandLineRunner; |
||||
import org.springframework.context.annotation.DependsOn; |
||||
import org.springframework.scheduling.annotation.Async; |
||||
import org.springframework.scheduling.annotation.Scheduled; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
@Component |
||||
@Slf4j |
||||
@DependsOn("redisUtil") |
||||
public class SessionTask implements CommandLineRunner { |
||||
@Override |
||||
public void run(String... args) { |
||||
cleanSession(); |
||||
} |
||||
|
||||
@Async("scheduledExecutor") |
||||
@Scheduled(cron = "0 */10 * * * ?") |
||||
public void autoCleanSession() { |
||||
cleanSession(); |
||||
} |
||||
|
||||
//清理session中未活动的用户
|
||||
private void cleanSession() { |
||||
try { |
||||
long now = System.currentTimeMillis(); |
||||
|
||||
//获取所有用户session
|
||||
Set<String> sessionKeys = RedisUtil.keys(SessionConstant.REDIS_NAMESPACE + "*"); |
||||
|
||||
//获取离线情况 (k:sessionKey,v:SocketOfflineVo)
|
||||
Map<Object, Object> offlineMap = RedisUtil.hgetAll(SocketConstant.REDIS_OFFLINE_USER); |
||||
|
||||
//移除无活动时间超出限定的用户
|
||||
sessionKeys.forEach(sessionKey -> { |
||||
Object obj = offlineMap.get(sessionKey); |
||||
if (obj != null) { |
||||
SocketOfflineVo offlineVo = ((JSONObject) obj).toJavaObject(SocketOfflineVo.class); |
||||
if (now > offlineVo.getTime() + SessionConstant.NO_ACTION_INTERVAL) { |
||||
//删除session
|
||||
RedisUtil.del(sessionKey); |
||||
|
||||
//删除离线表信息
|
||||
RedisUtil.hdel(SocketConstant.REDIS_OFFLINE_USER, sessionKey); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
catch (Exception e) { |
||||
log.error("清理session失败", e); |
||||
} |
||||
} |
||||
} |
||||
@ -1,116 +0,0 @@ |
||||
package cn.toesbieya.jxc.schedule.task; |
||||
|
||||
import cn.toesbieya.jxc.common.model.entity.StatFinishOrder; |
||||
import cn.toesbieya.jxc.common.model.entity.StatProfitGoods; |
||||
import cn.toesbieya.jxc.common.model.entity.StatProfitTotal; |
||||
import cn.toesbieya.jxc.common.util.DateUtil; |
||||
import cn.toesbieya.jxc.schedule.mapper.StatisticMapper; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.boot.CommandLineRunner; |
||||
import org.springframework.scheduling.annotation.Async; |
||||
import org.springframework.scheduling.annotation.Scheduled; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import javax.annotation.Resource; |
||||
import java.math.BigDecimal; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
@Component |
||||
@Slf4j |
||||
public class StatisticTask implements CommandLineRunner { |
||||
@Resource |
||||
private StatisticMapper mapper; |
||||
|
||||
@Override |
||||
public void run(String... args) throws Exception { |
||||
autoStat(); |
||||
} |
||||
|
||||
//每天零点统计信息
|
||||
@Async("scheduledExecutor") |
||||
@Scheduled(cron = "1 0 0 */1 * ?") |
||||
public void autoStat() { |
||||
log.info("开始统计信息..."); |
||||
|
||||
long lastDay = DateUtil.getTimestampBeforeNow(1); |
||||
long today = DateUtil.getTimestampNow(); |
||||
|
||||
//检查是否已统计过昨日已完成的订单数
|
||||
if (!mapper.checkDailyFinishOrderExist(lastDay)) { |
||||
Integer lastDayPurchaseOrderFinish = mapper.getPurchaseOrderLastDayFinishOrderNum(); |
||||
Integer lastDaySellOrderFinish = mapper.getSellOrderLastDayFinishOrderNum(); |
||||
|
||||
StatFinishOrder param = new StatFinishOrder(); |
||||
param.setPurchase(lastDayPurchaseOrderFinish); |
||||
param.setSell(lastDaySellOrderFinish); |
||||
param.setTime(lastDay); |
||||
|
||||
mapper.insertFinishOrder(param); |
||||
} |
||||
|
||||
//检查是否已统计过昨日的采购额、销售额、毛利
|
||||
if (!mapper.checkDailyProfitExist(lastDay)) { |
||||
//昨日各个商品的采购额、销售额
|
||||
List<StatProfitGoods> purchaseProfitGoods = mapper.getPurchaseOrderDailyProfitGoods(lastDay, today); |
||||
List<StatProfitGoods> sellProfitGoods = mapper.getSellOrderDailyProfitGoods(lastDay, today); |
||||
|
||||
//昨日的采购总额、销售总额
|
||||
BigDecimal totalPurchase = new BigDecimal(0); |
||||
BigDecimal totalSell = new BigDecimal(0); |
||||
|
||||
//根据商品分类计算
|
||||
Map<Integer, StatProfitGoods> map = new HashMap<>(sellProfitGoods.size()); |
||||
|
||||
for (StatProfitGoods p : sellProfitGoods) { |
||||
map.put(p.getCid(), p); |
||||
} |
||||
|
||||
for (StatProfitGoods p : purchaseProfitGoods) { |
||||
p.setTime(lastDay); |
||||
Integer cid = p.getCid(); |
||||
BigDecimal purchase = p.getPurchase(); |
||||
totalPurchase = totalPurchase.add(purchase); |
||||
StatProfitGoods s = map.get(cid); |
||||
|
||||
if (s != null) { |
||||
BigDecimal sell = s.getSell(); |
||||
totalSell = totalSell.add(sell); |
||||
p.setSell(sell); |
||||
p.setProfit(sell.subtract(purchase)); |
||||
map.remove(cid); |
||||
} |
||||
else { |
||||
p.setSell(new BigDecimal(0)); |
||||
p.setProfit(p.getSell().subtract(purchase)); |
||||
} |
||||
} |
||||
|
||||
for (StatProfitGoods s : map.values()) { |
||||
s.setTime(lastDay); |
||||
s.setPurchase(new BigDecimal(0)); |
||||
BigDecimal sell = s.getSell(); |
||||
s.setProfit(sell); |
||||
totalSell = totalSell.add(sell); |
||||
purchaseProfitGoods.add(s); |
||||
} |
||||
|
||||
BigDecimal totalProfit = totalSell.subtract(totalPurchase); |
||||
|
||||
StatProfitTotal statProfitTotal = new StatProfitTotal(); |
||||
statProfitTotal.setPurchase(totalPurchase); |
||||
statProfitTotal.setSell(totalSell); |
||||
statProfitTotal.setProfit(totalProfit); |
||||
statProfitTotal.setTime(lastDay); |
||||
|
||||
mapper.insertProfitTotal(statProfitTotal); |
||||
|
||||
if (!purchaseProfitGoods.isEmpty()) { |
||||
mapper.insertProfitGoodsBatch(purchaseProfitGoods); |
||||
} |
||||
} |
||||
|
||||
log.info("结束统计信息..."); |
||||
} |
||||
} |
||||
@ -1,14 +0,0 @@ |
||||
spring: |
||||
application: |
||||
name: jxc-schedule |
||||
|
||||
cloud: |
||||
nacos: |
||||
config: |
||||
server-addr: 127.0.0.1:8848 |
||||
file-extension: yml |
||||
shared-configs: |
||||
- data-id: jxc-common-database.yml |
||||
- data-id: jxc-common-redis.yml |
||||
discovery: |
||||
server-addr: 127.0.0.1:8848 |
||||
@ -1,100 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
<mapper namespace="cn.toesbieya.jxc.schedule.mapper.StatisticMapper"> |
||||
<select id="checkDailyFinishOrderExist" resultType="java.lang.Boolean"> |
||||
select count(0) |
||||
from stat_finish_order |
||||
where time = #{time} |
||||
</select> |
||||
|
||||
<select id="checkDailyProfitExist" resultType="java.lang.Boolean"> |
||||
select count(0) |
||||
from stat_profit_total |
||||
where time = #{time} |
||||
</select> |
||||
|
||||
<insert id="insertFinishOrder" parameterType="cn.toesbieya.jxc.common.model.entity.StatFinishOrder"> |
||||
insert into stat_finish_order (purchase, sell, time) |
||||
values (#{purchase}, #{sell}, #{time}) |
||||
</insert> |
||||
|
||||
<insert id="insertProfitTotal" parameterType="cn.toesbieya.jxc.common.model.entity.StatProfitTotal"> |
||||
insert into stat_profit_total (purchase, sell, profit, time) |
||||
values (#{purchase}, #{sell}, #{profit}, #{time}) |
||||
</insert> |
||||
|
||||
<insert id="insertProfitGoodsBatch" keyColumn="id" keyProperty="id" |
||||
parameterType="cn.toesbieya.jxc.common.model.entity.StatProfitGoods" |
||||
useGeneratedKeys="true"> |
||||
insert into stat_profit_goods |
||||
(cid, purchase, sell, profit, time) |
||||
values |
||||
<foreach collection="list" item="item" separator=","> |
||||
(#{item.cid}, #{item.purchase}, #{item.sell}, #{item.profit}, #{item.time}) |
||||
</foreach> |
||||
</insert> |
||||
|
||||
<select id="getPurchaseOrderDailyTotalPurchasePrice" resultType="java.math.BigDecimal"> |
||||
select ifnull(sum(total), 0) total |
||||
from biz_purchase_order |
||||
where status = 2 |
||||
<if test="start != null"> |
||||
and vtime <![CDATA[ >= ]]> #{start} |
||||
</if> |
||||
<if test="end != null"> |
||||
and vtime <![CDATA[ <= ]]> #{end} |
||||
</if> |
||||
</select> |
||||
|
||||
<select id="getPurchaseOrderLastDayFinishOrderNum" resultType="java.lang.Integer"> |
||||
select count(0) |
||||
from biz_purchase_order |
||||
where status = 2 |
||||
and finish = 2 |
||||
and ftime between unix_timestamp(cast(sysdate() as date) - interval 1 day) * 1000 and unix_timestamp(cast(sysdate() as date)) * 1000 |
||||
</select> |
||||
|
||||
<select id="getPurchaseOrderDailyProfitGoods" resultType="cn.toesbieya.jxc.common.model.entity.StatProfitGoods"> |
||||
select t1.*, |
||||
t2.name cname |
||||
from (select a.cid, |
||||
ifnull(sum(a.num * a.price), 0) purchase |
||||
from biz_purchase_order_sub a |
||||
join biz_purchase_order b on a.pid = b.id |
||||
where b.vtime between #{start} and #{end} |
||||
group by a.cid) t1 |
||||
join sys_category t2 on t1.cid = t2.id |
||||
</select> |
||||
|
||||
<select id="getSellOrderDailyTotalPurchasePrice" resultType="java.math.BigDecimal"> |
||||
select ifnull(sum(total), 0) total |
||||
from biz_sell_order |
||||
where status = 2 |
||||
<if test="start != null"> |
||||
and vtime <![CDATA[ >= ]]> #{start} |
||||
</if> |
||||
<if test="end != null"> |
||||
and vtime <![CDATA[ <= ]]> #{end} |
||||
</if> |
||||
</select> |
||||
|
||||
<select id="getSellOrderLastDayFinishOrderNum" resultType="java.lang.Integer"> |
||||
select count(0) |
||||
from biz_sell_order |
||||
where status = 2 |
||||
and finish = 2 |
||||
and ftime between unix_timestamp(cast(sysdate() as date) - interval 1 day) * 1000 and unix_timestamp(cast(sysdate() as date)) * 1000 |
||||
</select> |
||||
|
||||
<select id="getSellOrderDailyProfitGoods" resultType="cn.toesbieya.jxc.common.model.entity.StatProfitGoods"> |
||||
select t1.*, |
||||
t2.name cname |
||||
from (select a.cid, |
||||
ifnull(sum(a.num * a.price), 0) sell |
||||
from biz_sell_order_sub a |
||||
join biz_sell_order b on a.pid = b.id |
||||
where b.vtime between #{start} and #{end} |
||||
group by a.cid) t1 |
||||
join sys_category t2 on t1.cid = t2.id |
||||
</select> |
||||
</mapper> |
||||
@ -1,20 +0,0 @@ |
||||
<?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"> |
||||
<parent> |
||||
<artifactId>web</artifactId> |
||||
<groupId>cn.toesbieya</groupId> |
||||
<version>0.0.1-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>file</artifactId> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>com.qiniu</groupId> |
||||
<artifactId>qiniu-java-sdk</artifactId> |
||||
</dependency> |
||||
</dependencies> |
||||
</project> |
||||
@ -1,11 +0,0 @@ |
||||
package cn.toesbieya.jxc.file; |
||||
|
||||
import org.springframework.boot.SpringApplication; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
|
||||
@SpringBootApplication(scanBasePackages = "cn.toesbieya.jxc") |
||||
public class FileApplication { |
||||
public static void main(String[] args) { |
||||
SpringApplication.run(FileApplication.class, args); |
||||
} |
||||
} |
||||
@ -1,16 +0,0 @@ |
||||
package cn.toesbieya.jxc.file.config; |
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.annotation.DependsOn; |
||||
|
||||
@Configuration |
||||
@EnableConfigurationProperties(QiniuProperty.class) |
||||
@DependsOn("redisUtil") |
||||
public class QiniuConfig { |
||||
@Bean |
||||
public QiniuTemplate qiniuTemplate(QiniuProperty property) { |
||||
return new QiniuTemplate(property); |
||||
} |
||||
} |
||||
@ -1,45 +0,0 @@ |
||||
package cn.toesbieya.jxc.file.config; |
||||
|
||||
import com.qiniu.storage.Region; |
||||
import lombok.Data; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
import org.springframework.cloud.context.config.annotation.RefreshScope; |
||||
|
||||
@Data |
||||
@ConfigurationProperties("qiniu") |
||||
@RefreshScope |
||||
public class QiniuProperty { |
||||
private String accessKey; |
||||
|
||||
private String secretKey; |
||||
|
||||
private String bucket; |
||||
|
||||
//机房区域,默认为自动
|
||||
private QiniuRegion region = QiniuRegion.auto; |
||||
|
||||
//临时上传凭证的有效期,单位秒
|
||||
private Integer tokenExpire = 3600; |
||||
|
||||
//临时上传凭证的redis键名
|
||||
private String redisCacheKey = "qiniu-token"; |
||||
|
||||
enum QiniuRegion { |
||||
auto(Region.autoRegion()), |
||||
huadong(Region.huadong()), |
||||
huabei(Region.huabei()), |
||||
huanan(Region.huanan()), |
||||
beimei(Region.beimei()), |
||||
xinjiapo(Region.xinjiapo()); |
||||
|
||||
private final Region region; |
||||
|
||||
QiniuRegion(Region region) { |
||||
this.region = region; |
||||
} |
||||
|
||||
public Region getRegion() { |
||||
return this.region; |
||||
} |
||||
} |
||||
} |
||||
@ -1,54 +0,0 @@ |
||||
package cn.toesbieya.jxc.file.config; |
||||
|
||||
import cn.toesbieya.jxc.common.util.RedisUtil; |
||||
import com.qiniu.common.QiniuException; |
||||
import com.qiniu.storage.BucketManager; |
||||
import com.qiniu.storage.Configuration; |
||||
import com.qiniu.util.Auth; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
@Slf4j |
||||
public class QiniuTemplate { |
||||
private final QiniuProperty property; |
||||
private final Auth auth; |
||||
private final BucketManager bucketManager; |
||||
|
||||
public QiniuTemplate(QiniuProperty property) { |
||||
this.property = property; |
||||
this.auth = Auth.create(property.getAccessKey(), property.getSecretKey()); |
||||
this.bucketManager = new BucketManager(this.auth, new Configuration(property.getRegion().getRegion())); |
||||
} |
||||
|
||||
public String getToken() { |
||||
String key = property.getRedisCacheKey(); |
||||
|
||||
String token = (String) RedisUtil.get(key); |
||||
|
||||
if (token == null) { |
||||
token = auth.uploadToken(property.getBucket()); |
||||
RedisUtil.set(key, token, property.getTokenExpire()); |
||||
} |
||||
|
||||
return token; |
||||
} |
||||
|
||||
public void delete(String key) { |
||||
try { |
||||
bucketManager.delete(property.getBucket(), key); |
||||
} |
||||
catch (QiniuException e) { |
||||
log.info("七牛云删除单个文件失败,{}", e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
public void deleteBatch(String... key) { |
||||
BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations(); |
||||
batchOperations.addDeleteOp(property.getBucket(), key); |
||||
try { |
||||
bucketManager.batch(batchOperations); |
||||
} |
||||
catch (QiniuException e) { |
||||
log.info("七牛云批量删除文件失败,{}", e.getMessage()); |
||||
} |
||||
} |
||||
} |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue