Commit 292cd868 by 丁伟峰

Merge remote-tracking branch 'origin/develop' into develop

# Conflicts:
#	project-order/src/main/java/com/dituhui/pea/order/service/impl/OrganizationServiceImpl.java
2 parents d4c3e888 4e50659c
Showing with 503 additions and 1024 deletions
...@@ -76,7 +76,7 @@ public class Location { ...@@ -76,7 +76,7 @@ public class Location {
* @return time in minutes * @return time in minutes
*/ */
public int getPathTimeTo(Location location) { public int getPathTimeTo(Location location) {
return distanceTimeMap.get(location).intValue(); return distanceTimeMap.get(location).intValue()/60;
} }
// ************************************************************************ // ************************************************************************
......
...@@ -74,7 +74,7 @@ public class BatchScheduler { ...@@ -74,7 +74,7 @@ public class BatchScheduler {
LocalTime currentTime = LocalTime.now(); LocalTime currentTime = LocalTime.now();
LocalTime cutoffTime = LocalTime.parse("16:00:00", DateTimeFormatter.ISO_LOCAL_TIME); LocalTime cutoffTime = LocalTime.parse("16:00:00", DateTimeFormatter.ISO_LOCAL_TIME);
if (currentTime.isAfter(cutoffTime)) { if (i==1 && currentTime.isAfter(cutoffTime)) {
log.info("dispatchRun 已过cutoff时间,更新pre状态为confirm----- group:{}, day:{}", groupId, currDay); log.info("dispatchRun 已过cutoff时间,更新pre状态为confirm----- group:{}, day:{}", groupId, currDay);
DispatchBatch dispatchBatch = batchService.queryBatchInfoByDay(groupId, currDay); DispatchBatch dispatchBatch = batchService.queryBatchInfoByDay(groupId, currDay);
if (null == dispatchBatch.getBatchNo()) { if (null == dispatchBatch.getBatchNo()) {
......
...@@ -42,7 +42,6 @@ class SolveServiceTest { ...@@ -42,7 +42,6 @@ class SolveServiceTest {
String groupId = "gsuzhou"; String groupId = "gsuzhou";
String day = "2023-07-11"; String day = "2023-07-11";
private SolverManager<DispatchSolution, UUID> solverManager; private SolverManager<DispatchSolution, UUID> solverManager;
private Solver<DispatchSolution> solver; private Solver<DispatchSolution> solver;
......
...@@ -50,6 +50,11 @@ ...@@ -50,6 +50,11 @@
<artifactId>project-interface</artifactId> <artifactId>project-interface</artifactId>
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
......
package com.dituhui.pea.gateway.auth;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import com.dituhui.pea.enums.RedisKeyGroup;
import com.dituhui.pea.enums.StatusCodeEnum;
import com.dituhui.pea.enums.ThirdPartyEnum;
import com.dituhui.pea.exception.BusinessException;
import com.dituhui.pea.gateway.commom.RedisService;
import com.dituhui.pea.pojo.*;
import com.dituhui.pea.user.IUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCrypt;
import java.io.IOException;
import java.util.*;
/**
* 用户登录鉴权认证
*
* @author dk
*/
//@Component
@Slf4j
public class UserAuthService {
@Autowired
private RedisService redisService;
@Autowired
private IUser iUser;
/**
* 获取用户认证token信息, 为了提高效率应该使用缓存
*/
public UserDetails getUserFromToken(UserAuthInfo user) {
UserDetails ud = null;
if (null != user) {
ud = createUser(user.getUserName(), user.getPassword(), new String[]{user.getRole()});
}
return ud;
}
/**
* 对输入参数签名
*
* @param params 参数
* @param secret 密钥
* @return
* @throws IOException
*/
public String signRequest(Map<String, String> params, String secret) {
try {
// 第一步:参数排序
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
for (String key : keys) {
String value = params.get(key);
if (StringUtils.isNotEmpty(key) && !StringUtils.equalsIgnoreCase(key, "sign")
&& StringUtils.isNotEmpty(value)) {
query.append(key).append(value);
}
}
// 第三步:使用MD5/HMAC加密
String sign = DigestUtils.md5Hex(query.toString() + secret);
return sign;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据手机号登录
* @param phone 手机号
* @return token
*/
public String loginByPhone(String phone) {
WebResult<UserInfo> result = iUser.queryUserByPhone(phone);
if (!result.getSuccess() && result.getCode().equals(StatusCodeEnum.USER_DOES_NOT_EXIST.getCode())) {
throw new BusinessException(StatusCodeEnum.USER_DOES_NOT_EXIST);
}
UserInfo userInfo = result.getResult();
UserDetails ud = createUser(userInfo.getAccount(), null, new String[]{"user"});
String token = UUID.randomUUID().toString().replace("-", "");
UserAuthInfo userAuthInfo = new UserAuthInfo(userInfo.getId(), ud.getUsername(),
ud.getPassword(), "user");
// 设置一天后过期
redisService.set(RedisKeyGroup.authToken + ":" + token, userAuthInfo, 24 * 3600L);
return token;
}
public String thirdLogin(ThirdUserInfo thirdUserInfo) {
WebResult<UserInfo> result = iUser.queryUserByThirdParty(thirdUserInfo.getThirdId(),
ThirdPartyEnum.valueOf(thirdUserInfo.getThirdType()));
if (!result.getSuccess() && !result.getCode().equals(StatusCodeEnum.USER_DOES_NOT_EXIST.getCode())) {
return null;
}
UserInfo userInfo = result.getResult();
// 用户不存在就初始化第三方信息
if (ObjectUtil.isEmpty(userInfo)) {
// 微信小程序用户注册,必须手机号不为空才能注册
if (thirdUserInfo.getThirdType().equals(ThirdPartyEnum.WECHAT_MINI_PROGRAM.name())
&& StringUtils.isBlank(thirdUserInfo.getPhone())) {
throw new BusinessException(StatusCodeEnum.USER_DOES_NOT_EXIST);
}
WebResult<UserInfo> trResult = iUser.thirdRegister(thirdUserInfo);
if (!trResult.getSuccess()) {
return null;
}
userInfo = trResult.getResult();
}
UserDetails ud = createUser(userInfo.getAccount(), userInfo.getPassword(), new String[]{"user"});
String token = UUID.randomUUID().toString().replace("-", "");
UserAuthInfo userAuthInfo = new UserAuthInfo(userInfo.getId(), ud.getUsername(),
ud.getPassword(), "user");
// 设置一天后过期
redisService.set(RedisKeyGroup.authToken + ":" + token, userAuthInfo, 24 * 3600L);
return token;
}
/**
* 登录,成功返回token
*
* @param userName
* @param password
* @return
*/
public String login(String userName, String password) {
UserDetails ud = null;
WebResult<UserInfo> userResult = null;
System.out.println("login [" + userName + "][" + password + "]");
try {
userResult = iUser.queryUserByPhone(userName);
} catch (Throwable e) {
// FIXME 代码调整
e.printStackTrace();
}
UserInfo userInfo = userResult.getResult();
log.info("login userInfo queryUserByPhone [" + userInfo + "]");
if (null == userInfo) {
try {
userInfo = iUser.queryUserByAccount(userName).getResult();
} catch (Throwable e) {
e.printStackTrace();
}
}
log.info("login userInfo queryUserByAccount [" + userInfo + "]");
if (null != userInfo) {
try {
if (StringUtils.equalsIgnoreCase(SecureUtil.md5(password), userInfo.getPassword())) {
ud = createUser(userName, password, new String[]{"user"});
} else if (BCrypt.checkpw(password, userInfo.getPassword())) {
ud = createUser(userName, password, new String[]{"user"});
}
} catch (IllegalArgumentException e) {
// 忽略参数版本错误
}
}
if (ud != null) {
String token = UUID.randomUUID().toString().replace("-", "");
UserAuthInfo userAuthInfo = new UserAuthInfo(userInfo.getId(), ud.getUsername(),
ud.getPassword(), "user");
// 设置一天后过期
redisService.set(RedisKeyGroup.authToken.toString() + ":" + token, userAuthInfo, 24 * 3600L);
return token;
} else {
return null;
}
}
/**
* 退出,移除token
*
* @param token token值
*/
public void logout(String token) {
redisService.remove(RedisKeyGroup.authToken.toString() + ":" + token);
}
private UserDetails createUser(String userName, String password, String[] roles) {
return new UserDetails() {
private static final long serialVersionUID = 6905138725952656074L;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
//这是增加了一种名为query的权限,可以使用 @hasAuthority("query") 来判断
SimpleGrantedAuthority authority = new SimpleGrantedAuthority("query");
authorities.add(authority);
//这是增加到xxx角色,可以用hasRole("xxx")来判断;需要注意所有的角色在这里增加时必须以ROLE_前缀,使用时则没有ROLES_前缀
for (String role : roles) {
SimpleGrantedAuthority sga = new SimpleGrantedAuthority("ROLE_" + role);
authorities.add(sga);
}
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return userName;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
};
}
}
...@@ -7,15 +7,24 @@ import org.springframework.data.redis.core.RedisTemplate; ...@@ -7,15 +7,24 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration @Configuration
public class RedisConfig { public class RedisConfig {
@Bean @Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); // ObjectMapper objectMapper = new ObjectMapper();
// objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(),
// ObjectMapper.DefaultTyping.EVERYTHING, JsonTypeInfo.As.PROPERTY);
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory); redisTemplate.setConnectionFactory(connectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer());
return redisTemplate; return redisTemplate;
} }
......
...@@ -5,19 +5,20 @@ import org.springframework.data.redis.core.*; ...@@ -5,19 +5,20 @@ import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.Serializable; import java.io.Serializable;
import java.util.*; import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* redis服务 * redis服务
* *
* @author dk
*/ */
@Component @Component
public class RedisService { public class RedisService {
@Autowired @Autowired
private RedisTemplate redisTemplate; private RedisTemplate<String, String> redisTemplate;
/** /**
* 写入缓存 * 写入缓存
...@@ -26,10 +27,10 @@ public class RedisService { ...@@ -26,10 +27,10 @@ public class RedisService {
* @param value * @param value
* @return * @return
*/ */
public boolean set(final String key, Object value) { public boolean set(final String key, String value) {
boolean result = false; boolean result = false;
try { try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); ValueOperations<String, String> operations = redisTemplate.opsForValue();
operations.set(key, value); operations.set(key, value);
result = true; result = true;
} catch (Exception e) { } catch (Exception e) {
...@@ -45,10 +46,10 @@ public class RedisService { ...@@ -45,10 +46,10 @@ public class RedisService {
* @param value * @param value
* @return * @return
*/ */
public boolean set(final String key, Object value, Long expireTime) { public boolean set(final String key, String value, Long expireTime) {
boolean result = false; boolean result = false;
try { try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); ValueOperations<String, String> operations = redisTemplate.opsForValue();
operations.set(key, value); operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true; result = true;
...@@ -59,166 +60,16 @@ public class RedisService { ...@@ -59,166 +60,16 @@ public class RedisService {
} }
/** /**
* 设置过期时间<br>
* 原始key
*
* @param key
* @param expriedDate
*/
public boolean setExpriedDate(String key, Date expriedDate) {
return redisTemplate.expireAt(key, expriedDate);
}
/**
* 批量删除对应的value
*
* @param keys
*/
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
* 批量删除key
*
* @param pattern
*/
public void removePattern(final String pattern) {
Set<Serializable> keys = redisTemplate.keys(pattern);
if (keys.size() > 0) {
redisTemplate.delete(keys);
}
}
/**
* 删除对应的value
*
* @param key
*/
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
/**
* 判断缓存中是否有对应的value
*
* @param key
* @return
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 读取缓存 * 读取缓存
* *
* @param key * @param key
* @return * @return
*/ */
public Object get(final String key) { public String get(final String key) {
Object result = null; String result = null;
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); ValueOperations<String, String> operations = redisTemplate.opsForValue();
result = operations.get(key); result = operations.get(key);
return result; return result;
} }
/**
* 哈希 添加
*
* @param key
* @param hashKey
* @param value
*/
public void hmSet(String key, Object hashKey, Object value) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
hash.put(key, hashKey, value);
}
/**
* 哈希获取数据
*
* @param key
* @param hashKey
* @return
*/
public Object hmGet(String key, Object hashKey) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.get(key, hashKey);
}
/**
* 列表添加
*
* @param k
* @param v
*/
public void lPush(String k, Object v) {
ListOperations<String, Object> list = redisTemplate.opsForList();
list.rightPush(k, v);
}
/**
* 列表获取
*
* @param k
* @param l
* @param l1
* @return
*/
public List<Object> lRange(String k, long l, long l1) {
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.range(k, l, l1);
}
/**
* 集合添加
*
* @param key
* @param value
*/
public void add(String key, Object value) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
set.add(key, value);
}
/**
* 集合获取
*
* @param key
* @return
*/
public Set<Object> setMembers(String key) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
return set.members(key);
}
/**
* 有序集合添加
*
* @param key
* @param value
* @param scoure
*/
public void zAdd(String key, Object value, double scoure) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.add(key, value, scoure);
}
/**
* 有序集合获取
*
* @param key
* @param scoure
* @param scoure1
* @return
*/
public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.rangeByScore(key, scoure, scoure1);
}
} }
...@@ -15,13 +15,11 @@ import org.springframework.security.core.context.SecurityContextHolder; ...@@ -15,13 +15,11 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import com.dituhui.pea.common.Result;
import com.dituhui.pea.common.ResultEnum;
import com.dituhui.pea.enums.RedisKeyGroup; import com.dituhui.pea.enums.RedisKeyGroup;
import com.dituhui.pea.gateway.commom.RedisService; import com.dituhui.pea.gateway.commom.RedisService;
import com.dituhui.pea.pojo.UserLoginDTO; import com.dituhui.pea.pojo.UserLoginDTO;
import com.dituhui.pea.user.IUser;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
...@@ -34,6 +32,7 @@ public class AuthFilter implements GlobalFilter, Ordered { ...@@ -34,6 +32,7 @@ public class AuthFilter implements GlobalFilter, Ordered {
* 白名单 * 白名单
*/ */
private static final Set<String> authWhiteList = Sets.newHashSet("/pea-user/login", "/pea-user/login/"); private static final Set<String> authWhiteList = Sets.newHashSet("/pea-user/login", "/pea-user/login/");
private static final Gson gson = new Gson();
@Autowired @Autowired
RedisService redisService; RedisService redisService;
...@@ -67,9 +66,9 @@ public class AuthFilter implements GlobalFilter, Ordered { ...@@ -67,9 +66,9 @@ public class AuthFilter implements GlobalFilter, Ordered {
UserLoginDTO userDTO = null; UserLoginDTO userDTO = null;
if (StringUtils.isNotEmpty(authToken)) { if (StringUtils.isNotEmpty(authToken)) {
// 查询token对应的用户 // 查询token对应的用户
Object obj = redisService.get(RedisKeyGroup.authToken + ":" + authToken); String value = redisService.get(RedisKeyGroup.authToken + ":" + authToken);
if (null != obj) { if (null != value) {
userDTO = (UserLoginDTO) obj; userDTO = gson.fromJson(value, UserLoginDTO.class);
} }
} }
if (userDTO == null) { if (userDTO == null) {
......
package com.dituhui.pea.gateway.config;
import brave.Tags;
import brave.Tracer;
import brave.Tracing;
import brave.baggage.BaggageField;
import brave.baggage.BaggagePropagation;
import brave.baggage.BaggagePropagationConfig.SingleBaggageField;
import brave.propagation.B3Propagation;
import com.alibaba.fastjson.JSON;
import com.dituhui.pea.enums.RedisKeyGroup;
import com.dituhui.pea.enums.StatusCodeEnum;
import com.dituhui.pea.exception.BusinessException;
import com.dituhui.pea.gateway.auth.UserAuthService;
import com.dituhui.pea.gateway.commom.RedisService;
import com.dituhui.pea.pojo.UserAuthInfo;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.*;
//@Component
@Slf4j
public class SleuthFilter implements GlobalFilter, Ordered {
@Value("${auth.path:/test/**}")
private String authPath;
/**
* 白名单
*/
private static final String[] AUTH_WHITELIST = new String[]{"/v1/user/getByAccount", "/v1/user/getByPhone", "/v1/user/getByThirdParty",
"/v1/user/register"};
@Autowired
Tracer tracer;
@Autowired
UserAuthService userAuthService;
@Autowired
private RedisService redisService;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String authToken = null;
String url = exchange.getRequest().getPath().toString();
// 下面的代码从Http Header的Authorization中获取token,也可以从其他header,cookie等中获取,看客户端怎么传递token
HttpHeaders headers = exchange.getRequest().getHeaders();
String requestHeader = headers.getFirst("Authorization");
if (requestHeader != null && requestHeader.startsWith("Bearer ")) {
authToken = requestHeader.substring(7);
}
// String ak = exchange.getRequest().getQueryParams().getFirst("ak");
// String requestSign = exchange.getRequest().getQueryParams().getFirst("sign");
if (log.isTraceEnabled()) {
log.trace("token is " + authToken);
}
UserAuthInfo user = null;
if (authToken != null) {
//查询token对应的用户
user = getUserAuthInfoFromToken(authToken);
if (null != user) {
// 写入用户token
doTags("token", authToken);
}
}
if (null == user) {
// 找不到用户登录信息,且在鉴权范围内的请求路径则被拦截
ArrayList<String> authPathList = Lists.newArrayList(authPath.split(","));
authPathList.forEach(path -> {
if (StringUtils.endsWith(path, "**")) {
path = StringUtils.substring(path, 0, path.length() - 2);
}
if (StringUtils.startsWith(url, path)) {
// 白名单过滤
ArrayList<String> authWhiteList = Lists.newArrayList(AUTH_WHITELIST);
if (CollectionUtils.isNotEmpty(authWhiteList)) {
String authWhite = authWhiteList.stream().filter(authWhitePath -> StringUtils.startsWith(url, authWhitePath))
.findFirst().orElse(null);
System.out.println("authWhite: " + authWhite);
if (null == authWhite) {
// 如果没有在白名单内,则抛出鉴权异常
throw new BusinessException(StatusCodeEnum.AUTH_FAILED);
}
} else {
// 抛出鉴权异常
throw new BusinessException(StatusCodeEnum.AUTH_FAILED);
}
}
});
} else {
// 授权和打标签用户信息
authentication(user, exchange);
}
return chain.filter(exchange);
}
/**
* 授权和打标签用户信息
*
* @param user
*/
private void authentication(UserAuthInfo user, ServerWebExchange exchange) {
UserDetails userDetails = this.userAuthService.getUserFromToken(user);
// 把user设置到SecurityContextHolder内,以spring使用
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails,
userDetails.getPassword(), userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
if (StringUtils.isNotEmpty(user.getUserId())) {
// 写入用户id
doTags("userId", user.getUserId());
}
// 客户端IP标签
doTags("clientIp", getRemoteIP(exchange));
// 时间戳标签
String t = exchange.getRequest().getQueryParams().getFirst("t");
if (StringUtils.isEmpty(t)) {
t = String.valueOf(System.currentTimeMillis());
}
doTags("t", t);
doTags("isDebug", exchange.getRequest().getQueryParams().getFirst("isDebug"));
}
/**
* 用户调用参数打标签
*
* @param name 参数名称
* @param value 参数值
*/
private void doTags(String name, String value) {
BaggageField baggageField = BaggageField.create(name);
baggageField.updateValue(value);
Tracing.newBuilder().propagationFactory(BaggagePropagation.newFactoryBuilder(B3Propagation.FACTORY)
.add(SingleBaggageField.remote(baggageField)).build());
Tags.BAGGAGE_FIELD.tag(baggageField, this.tracer.currentSpan());
}
/**
* 客户端ip
*
* @param exchange
* @return
*/
private String getRemoteIP(ServerWebExchange exchange) {
String clientIp = "";
if (StringUtils.isNotEmpty(exchange.getRequest().getHeaders().getFirst("x-forwarded-for"))) {
clientIp = exchange.getRequest().getHeaders().getFirst("x-forwarded-for");
} else if (StringUtils.isNotEmpty(exchange.getRequest().getHeaders().getFirst("X-Forwarded-For"))) {
clientIp = exchange.getRequest().getHeaders().getFirst("X-Forwarded-For");
} else if (StringUtils.isNotEmpty(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress())) {
clientIp = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
}
if ("0:0:0:0:0:0:0:1".equals(clientIp)) {
clientIp = "127.0.0.1";
}
return clientIp;
}
/**
* 获取用户认证信息
*
* @param token
* @return
*/
private UserAuthInfo getUserAuthInfoFromToken(String token) {
if (token == null) {
return null;
}
UserAuthInfo userAuthInfo = (UserAuthInfo) redisService.get(RedisKeyGroup.authToken.toString() + ":" + token);
System.out.println("token: " + token);
System.out.println("userAuthInfo: " + JSON.toJSONString(userAuthInfo));
if (null != userAuthInfo) {
// 设置一天后过期
Date expiredDate = DateUtils.addMinutes(new Date(), 60 * 24);
redisService.setExpriedDate(RedisKeyGroup.authToken.toString() + ":" + token, expiredDate);
}
return userAuthInfo;
}
@Override
public int getOrder() {
return -1;
}
}
package com.dituhui.pea.gateway.controller;
import brave.Tracer;
import com.dituhui.pea.enums.StatusCodeEnum;
import com.dituhui.pea.gateway.auth.UserAuthService;
import com.dituhui.pea.pojo.ThirdUserInfo;
import com.dituhui.pea.pojo.UserInfo;
import com.dituhui.pea.pojo.WebResult;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* 用于管理登录和退出的controller
*
* @author dk
*/
//@RestController
//@RequestMapping("/token")
public class TokenController {
private final static Log log = LogFactory.getLog(TokenController.class);
@Autowired
UserAuthService userAuthService;
@Autowired
private Tracer tracer;
/**
* 登录鉴权
*
* @param user 用户对象
* @return
*/
@PostMapping(value = "/login")
public WebResult login(@RequestBody UserInfo user) {
String userName = user.getAccount();
String password = user.getPassword();
String token = userAuthService.login(userName, password);
String traceId = getTraceId();
if (token == null) {
return WebResult.failed(StatusCodeEnum.COMMON_ACCOUNT_ERROR).setTraceId(traceId);
} else {
return WebResult.ok(token).setTraceId(traceId);
}
}
/**
* 根据手机号登录
* @param user 当前用户
* @return
*/
@PostMapping(value = "/loginByPhone")
public WebResult loginByPhone(@RequestBody UserInfo user) {
String traceId = getTraceId();
if (null == user || StringUtils.isBlank(user.getPhone())) {
return WebResult.failed(StatusCodeEnum.COMMON_PARAM_EMPTY).setTraceId(traceId);
}
String token = userAuthService.loginByPhone(user.getPhone());
return WebResult.ok(token).setTraceId(traceId);
}
/**
* 三方登录鉴权
*
* @param thirdUserInfo 第三方用户对象
* @return
*/
@PostMapping(value = "/thirdLogin")
public WebResult thirdLogin(@RequestBody ThirdUserInfo thirdUserInfo) {
String token = userAuthService.thirdLogin(thirdUserInfo);
String traceId = getTraceId();
if (token == null) {
return WebResult.failed(StatusCodeEnum.COMMON_ACCOUNT_ERROR).setTraceId(traceId);
} else {
return WebResult.ok(token).setTraceId(traceId);
}
}
/**
* 全局日志id
*
* @return
*/
private String getTraceId() {
String traceId = null;
if (null != this.tracer) {
traceId = this.tracer.currentSpan().context().traceIdString();
}
return traceId;
}
/**
* 退出登录
*
* @param authorization
* @return
*/
@RequestMapping(value = "/logout", method = RequestMethod.GET)
public WebResult logout(@RequestHeader(name = "Authorization") String authorization) {
if (authorization != null && authorization.startsWith("Bearer ")) {
String token = authorization.substring(7);
if (log.isTraceEnabled()) {
log.trace("will delete token : " + token);
}
if (StringUtils.isNotEmpty(token)) {
userAuthService.logout(token);
}
}
return WebResult.ok(true).setTraceId(getTraceId());
}
}
package com.dituhui.pea.order;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.dituhui.pea.common.Result;
/**
* 组织结构相关接口
*
*/
@FeignClient(value = "project-order", contextId = "org")
public interface IOrganization {
/**
* 获取指定等级下的所有组织
*
* @param levelType 大区/分部/分站/小组
* @param organizationIds 组织编号
* @return
*/
@RequestMapping(value = "/pea-order/organization/list", method = RequestMethod.GET)
public Result<?> getAllOrganizations(@RequestParam("levelType") String levelType,
@RequestParam("organizationIds") List<String> organizationIds);
}
package com.dituhui.pea.pojo;
import lombok.Data;
@Data
public class OrganizationDTO {
/**
* ID
*/
private String id;
/**
* 名称
*/
private String name;
/**
* 类型
*/
private String type;
private Boolean isActive;
}
...@@ -24,6 +24,7 @@ public class UserLoginDTO { ...@@ -24,6 +24,7 @@ public class UserLoginDTO {
private String token; private String token;
private List<RoleInfo> roles; private List<RoleInfo> roles;
private List<ResourceInfo> resources; private List<ResourceInfo> menus;
private List<OrganizationDTO> auths;
} }
...@@ -86,7 +86,7 @@ public class OrderAssignCheck { ...@@ -86,7 +86,7 @@ public class OrderAssignCheck {
return new Result(false, "没有连续可插入空间(没计算时间)", 0, 0, null, null); return new Result(false, "没有连续可插入空间(没计算时间)", 0, 0, null, null);
} }
log.info("插入位置为第{}单", index); log.info("插入位置为第{}单, 已分配单数(不包含本单):{}", index, orderSegments.size());
// 计算距离 & 时间 // 计算距离 & 时间
if(index == 0 && orderSegments.isEmpty()) { if(index == 0 && orderSegments.isEmpty()) {
// 第一订单为出发地, 没有其他订单 // 第一订单为出发地, 没有其他订单
...@@ -119,7 +119,7 @@ public class OrderAssignCheck { ...@@ -119,7 +119,7 @@ public class OrderAssignCheck {
} }
else if(index == orderSegments.size()) { else if(index == orderSegments.size()) {
// 最后一个订单出发 // 最后一个订单出发
OrderSegment pre = orderSegments.get(index); OrderSegment pre = orderSegments.get(index-1);
Pair p = this.getDistanceAndDuration(pre.getX(), pre.getY(), curX, curY); Pair p = this.getDistanceAndDuration(pre.getX(), pre.getY(), curX, curY);
// 最早可插入位置为技术员上一单出发时间+行程时间 // 最早可插入位置为技术员上一单出发时间+行程时间
int startPos = pre.getEnd() + p.getDuration(); int startPos = pre.getEnd() + p.getDuration();
......
...@@ -43,6 +43,10 @@ public class TimeUtils { ...@@ -43,6 +43,10 @@ public class TimeUtils {
return LocalDate.parse(s, DateTimeFormatter.ofPattern(pattern)); return LocalDate.parse(s, DateTimeFormatter.ofPattern(pattern));
} }
public static final LocalDateTime IsoDateTime2LocalDateTime(String s) {
return LocalDateTime.parse(s, DateTimeFormatter.ofPattern(DATE_TIME_FORMAT));
}
public static final String IsoLocalDate2String(LocalDate localDate) { public static final String IsoLocalDate2String(LocalDate localDate) {
return localDate.format(DateTimeFormatter.ofPattern(DATE_GAP_FORMAT)); return localDate.format(DateTimeFormatter.ofPattern(DATE_GAP_FORMAT));
} }
......
...@@ -16,7 +16,7 @@ public class EngineerTimelineController { ...@@ -16,7 +16,7 @@ public class EngineerTimelineController {
@Autowired @Autowired
private EngineerTimelineService engineerTimelineService; private EngineerTimelineService engineerTimelineService;
@GetMapping("/engineer/work/trace") @GetMapping("/engineer/work/dynamics")
public Result<?> GetEngineerTimeline(@RequestParam String engineerCode, String date) { public Result<?> GetEngineerTimeline(@RequestParam String engineerCode, String date) {
return engineerTimelineService.getEngineerTimelines(engineerCode, date); return engineerTimelineService.getEngineerTimelines(engineerCode, date);
} }
......
...@@ -2,12 +2,17 @@ package com.dituhui.pea.order.controller; ...@@ -2,12 +2,17 @@ package com.dituhui.pea.order.controller;
import com.dituhui.pea.common.BusinessException; import com.dituhui.pea.common.BusinessException;
import com.dituhui.pea.common.Result; import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.common.TimeUtils;
import com.dituhui.pea.order.dto.OrderAssignReq; import com.dituhui.pea.order.dto.OrderAssignReq;
import com.dituhui.pea.order.dto.OrderReschedule;
import com.dituhui.pea.order.dto.OrderRevokeAssign; import com.dituhui.pea.order.dto.OrderRevokeAssign;
import com.dituhui.pea.order.service.OrderAssign; import com.dituhui.pea.order.service.OrderAssign;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
@RestController @RestController
@RequestMapping("/pea-order") @RequestMapping("/pea-order")
public class OrderAssignController { public class OrderAssignController {
...@@ -53,4 +58,18 @@ public class OrderAssignController { ...@@ -53,4 +58,18 @@ public class OrderAssignController {
} }
return res; return res;
} }
@PostMapping("/order/rescheduling")
public Result<?> orderRescheduling(@RequestBody OrderReschedule req){
// 订单改约
Result<?> res = null;
LocalDateTime expectBegin = TimeUtils.IsoDateTime2LocalDateTime(req.getExpectBegin());
LocalDateTime expectEnd = TimeUtils.IsoDateTime2LocalDateTime(req.getExpectEnd());
try{
res = orderAssign.orderReschedule(req.getOrderId(), expectBegin, expectEnd, req.getExpectDesc());
} catch (BusinessException e){
return Result.failed(e.getMessage());
}
return res;
}
} }
package com.dituhui.pea.order.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.dituhui.pea.common.BusinessException;
import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.IOrganization;
import com.dituhui.pea.order.service.OrganizationService;
import com.dituhui.pea.pojo.OrganizationDTO;
/**
* 对外组织结构服务
*
*/
@RestController
public class PublicOrganizationController implements IOrganization {
@Autowired
private OrganizationService organizationService;
@Override
public Result<?> getAllOrganizations(String levelType, List<String> organizationIds) {
if (StringUtils.isEmpty(levelType)) {
return Result.failed("缺少参数levelType");
}
if (CollectionUtils.isEmpty(organizationIds)) {
return Result.failed("缺少参数organizationIds");
}
Result<?> res = null;
try {
List<OrganizationDTO> orgs = organizationService.getAllOrganizations(levelType, organizationIds);
res = Result.success(orgs);
} catch (BusinessException e) {
return Result.failed(e.getMessage());
}
return res;
}
}
...@@ -36,8 +36,9 @@ public class ScheduleController { ...@@ -36,8 +36,9 @@ public class ScheduleController {
public Result<?> getScheduleOverview(@RequestParam long page, @RequestParam long size, @RequestParam String date, public Result<?> getScheduleOverview(@RequestParam long page, @RequestParam long size, @RequestParam String date,
@RequestParam String levelType, @RequestParam("levelValue") List<String> levelIds) { @RequestParam String levelType, @RequestParam("levelValue") List<String> levelIds) {
Result<?> res = null; Result<?> res = null;
LocalDate localDate = TimeUtils.IsoDate2LocalDate(date);
try { try {
res = scheduleService.getScheduleOverview(page, size, date, levelType, levelIds); res = scheduleService.getScheduleOverview(page, size, localDate, levelType, levelIds);
} catch (BusinessException e) { } catch (BusinessException e) {
return Result.failed(e.getMessage()); return Result.failed(e.getMessage());
} }
...@@ -47,8 +48,9 @@ public class ScheduleController { ...@@ -47,8 +48,9 @@ public class ScheduleController {
@GetMapping("/schedule/engineer/overview") @GetMapping("/schedule/engineer/overview")
public Result<?> getScheduleEngineerOverview(@RequestParam String date, @RequestParam String engineerCode) { public Result<?> getScheduleEngineerOverview(@RequestParam String date, @RequestParam String engineerCode) {
Result<?> res = null; Result<?> res = null;
LocalDate localDate = TimeUtils.IsoDate2LocalDate(date);
try { try {
res = scheduleService.getScheduleEngineerOverview(date, engineerCode); res = scheduleService.getScheduleEngineerOverview(localDate, engineerCode);
} catch (BusinessException e) { } catch (BusinessException e) {
return Result.failed(e.getMessage()); return Result.failed(e.getMessage());
} }
......
...@@ -14,4 +14,6 @@ public interface OrgBranchDao extends JpaRepository<OrgBranchEntity, Integer> { ...@@ -14,4 +14,6 @@ public interface OrgBranchDao extends JpaRepository<OrgBranchEntity, Integer> {
List<OrgBranchEntity> findAllByClusterId(String clusterId); List<OrgBranchEntity> findAllByClusterId(String clusterId);
OrgBranchEntity getByBranchId(String branchId); OrgBranchEntity getByBranchId(String branchId);
public List<OrgBranchEntity> findByBranchIdIn(List<String> ids);
} }
package com.dituhui.pea.order.dao; package com.dituhui.pea.order.dao;
import com.dituhui.pea.order.entity.OrgClusterEntity; import com.dituhui.pea.order.entity.OrgClusterEntity;
import java.util.List;
import org.hibernate.annotations.Where; import org.hibernate.annotations.Where;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
...@@ -10,4 +13,6 @@ import org.springframework.stereotype.Repository; ...@@ -10,4 +13,6 @@ import org.springframework.stereotype.Repository;
public interface OrgClusterDao extends JpaRepository <OrgClusterEntity, Integer> { public interface OrgClusterDao extends JpaRepository <OrgClusterEntity, Integer> {
OrgClusterEntity getByClusterId(String clusterId); OrgClusterEntity getByClusterId(String clusterId);
public List<OrgClusterEntity> findByClusterIdIn(List<String> ids);
} }
...@@ -16,4 +16,6 @@ public interface OrgGroupDao extends JpaRepository<OrgGroupEntity, Integer> { ...@@ -16,4 +16,6 @@ public interface OrgGroupDao extends JpaRepository<OrgGroupEntity, Integer> {
List<OrgGroupEntity> findAllByClusterId(String clusterId); List<OrgGroupEntity> findAllByClusterId(String clusterId);
OrgGroupEntity getByGroupId(String groupId); OrgGroupEntity getByGroupId(String groupId);
public List<OrgGroupEntity> findByGroupIdIn(List<String> ids);
} }
package com.dituhui.pea.order.dao; package com.dituhui.pea.order.dao;
import com.dituhui.pea.order.entity.OrgTeamEntity; import com.dituhui.pea.order.entity.OrgTeamEntity;
import org.hibernate.annotations.Where;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
...@@ -36,4 +35,6 @@ public interface OrgTeamDao extends JpaRepository<OrgTeamEntity, Integer> { ...@@ -36,4 +35,6 @@ public interface OrgTeamDao extends JpaRepository<OrgTeamEntity, Integer> {
@Modifying @Modifying
@Query("UPDATE OrgTeamEntity tt SET tt.status = :status WHERE tt.teamId = :teamId") @Query("UPDATE OrgTeamEntity tt SET tt.status = :status WHERE tt.teamId = :teamId")
void updateStatusByTeamId(String teamId, int status); void updateStatusByTeamId(String teamId, int status);
public List<OrgTeamEntity> findByTeamIdIn(List<String> ids);
} }
package com.dituhui.pea.order.dao; package com.dituhui.pea.order.dao;
import com.dituhui.pea.order.entity.WarehouseInfo; import com.dituhui.pea.order.entity.OrgWarehouseInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@Mapper @Mapper
public interface WarehouseInfoMPDao extends BaseMapper<WarehouseInfo> { public interface WarehouseInfoMPDao extends BaseMapper<OrgWarehouseInfo> {
} }
...@@ -3,7 +3,7 @@ package com.dituhui.pea.order.dto; ...@@ -3,7 +3,7 @@ package com.dituhui.pea.order.dto;
import lombok.Data; import lombok.Data;
@Data @Data
public class EnginnerTimelineReq { public class EngineerTimelineReq {
private String enginnerCode; private String engineerCode;
private String date; private String date;
} }
...@@ -5,7 +5,7 @@ import lombok.Data; ...@@ -5,7 +5,7 @@ import lombok.Data;
import java.util.List; import java.util.List;
@Data @Data
public class EnginnerTimelineResp { public class EngineerTimelineResp {
private String engineerCode; private String engineerCode;
private String engineerName; private String engineerName;
......
package com.dituhui.pea.order.dto;
import lombok.Data;
@Data
public class OrderReschedule {
private String orderId;
private String expectBegin;
private String expectEnd;
private String expectDesc;
}
...@@ -3,9 +3,10 @@ package com.dituhui.pea.order.entity; ...@@ -3,9 +3,10 @@ package com.dituhui.pea.order.entity;
import lombok.Data; import lombok.Data;
@Data @Data
public class WarehouseInfo { public class OrgWarehouseInfo {
private Integer warehouseId; private long id;
private String warehouseNname; private String warehouseId;
private String warehouseName;
private String branchId; private String branchId;
private String cityCode; private String cityCode;
private String address; private String address;
......
package com.dituhui.pea.order.enums;
/**
* 组织等级类型
*
*/
public enum OrganizationType {
/**
* 大区
*/
cluster("cluster"),
/**
* 分部
*/
branch("branch"),
/**
* 分站
*/
group("group"),
/**
* 工作队
*/
team("team");
private String value;
private OrganizationType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
package com.dituhui.pea.order.service; package com.dituhui.pea.order.service;
import com.dituhui.pea.common.Result; import com.dituhui.pea.common.Result;
import org.bouncycastle.asn1.cms.TimeStampAndCRL;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
public interface OrderAssign { public interface OrderAssign {
...@@ -11,4 +16,6 @@ public interface OrderAssign { ...@@ -11,4 +16,6 @@ public interface OrderAssign {
Result<?> orderAssign(String orderId, String engineerCode); Result<?> orderAssign(String orderId, String engineerCode);
Result<?> orderRevokeAssign(String orderId); Result<?> orderRevokeAssign(String orderId);
Result<?> orderReschedule(String orderId, LocalDateTime expectBegin, LocalDateTime expectEnd, String expectDesc);
} }
package com.dituhui.pea.order.service; package com.dituhui.pea.order.service;
import com.dituhui.pea.common.Result; import com.dituhui.pea.common.Result;
import com.dituhui.pea.pojo.OrganizationDTO;
import java.util.List; import java.util.List;
...@@ -12,4 +13,6 @@ public interface OrganizationService { ...@@ -12,4 +13,6 @@ public interface OrganizationService {
Result<?> getTeamsByLevel(String levelType, String levelValue); Result<?> getTeamsByLevel(String levelType, String levelValue);
Result<?> getEngineersByLevel(String levelType, String levelValue); Result<?> getEngineersByLevel(String levelType, String levelValue);
public List<OrganizationDTO> getAllOrganizations(String levelType, List<String> organizationIds);
} }
...@@ -9,7 +9,7 @@ public interface ScheduleService { ...@@ -9,7 +9,7 @@ public interface ScheduleService {
Result<?> getScheduleSummary(LocalDate date, String levelType, List<String> levelIds); Result<?> getScheduleSummary(LocalDate date, String levelType, List<String> levelIds);
Result<?> getScheduleOverview(long page, long size, String date, String levelType, List<String> levelIds); Result<?> getScheduleOverview(long page, long size, LocalDate date, String levelType, List<String> levelIds);
Result<?> getScheduleEngineerOverview(String date, String engineerCode); Result<?> getScheduleEngineerOverview(LocalDate date, String engineerCode);
} }
...@@ -3,7 +3,7 @@ package com.dituhui.pea.order.service.impl; ...@@ -3,7 +3,7 @@ package com.dituhui.pea.order.service.impl;
import com.dituhui.pea.common.Result; import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.common.TimeUtils; import com.dituhui.pea.order.common.TimeUtils;
import com.dituhui.pea.order.dao.*; import com.dituhui.pea.order.dao.*;
import com.dituhui.pea.order.dto.EnginnerTimelineResp; import com.dituhui.pea.order.dto.EngineerTimelineResp;
import com.dituhui.pea.order.entity.*; import com.dituhui.pea.order.entity.*;
import com.dituhui.pea.order.service.EngineerTimelineService; import com.dituhui.pea.order.service.EngineerTimelineService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
...@@ -11,8 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -11,8 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.sql.Timestamp; import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
...@@ -39,67 +38,54 @@ public class EngineerTimelineServiceImpl implements EngineerTimelineService { ...@@ -39,67 +38,54 @@ public class EngineerTimelineServiceImpl implements EngineerTimelineService {
@Autowired @Autowired
private OrgGroupMPDao orgGroupMPDao; private OrgGroupMPDao orgGroupMPDao;
@Autowired
private OrderEventMPDao orderEventMPDao;
@Transactional @Transactional
@Override @Override
public Result<?> getEngineerTimelines(String engineerCode, String date){ public Result<?> getEngineerTimelines(String engineerCode, String date){
// 工程师姓名 LocalDate localDate = TimeUtils.IsoDate2LocalDate(date);
String name = this.getEngineerName(engineerCode);
// 工程師信息
EngineerInfo engineerInfo = engineerInfoMPDao.getByEngineerCode(engineerCode);
// 获取工程师已完成的timeline数据
List<EngineerTimeline> timelines = this.engineerTimelines(engineerCode, date);
// 获取工程师date日的订单数据 // 获取工程师date日的订单数据
List<OrderAppointment> orders = this.orderAppointments(engineerCode, date); List<OrderAppointment> orders = orderAppointmentMPDao.selectByEngineerCodeAndDt(engineerCode, localDate);
// 获取工程师已完成的timeline数据
List<String> orderIds = orders.stream().map(OrderAppointment::getOrderId).collect(Collectors.toList());
List<OrderEvent> timelines = this.engineerTimelines(orderIds, date);
// 获取客户地址 // 获取客户地址
List<String> orderIds = new ArrayList<>();
for(OrderAppointment o: orders) {
orderIds.add(o.getOrderId());
}
HashMap<String, String> orderLocations = this.orderRequestsLocation(orderIds); HashMap<String, String> orderLocations = this.orderRequestsLocation(orderIds);
// 获取配送站地址 // 获取配送站地址
String branchId = this.getEngineerBranchId(engineerCode); String branchId = this.getEngineerBranchId(engineerCode);
String warehouseLocation = this.getWarehouseLocation(branchId); String warehouseLocation = this.getWarehouseLocation(branchId);
List<EnginnerTimelineResp.DynamicItem> dynamics = this.packItems(timelines, orders, orderLocations, warehouseLocation); List<EngineerTimelineResp.DynamicItem> dynamics = this.packItems(timelines, orders, orderLocations, warehouseLocation);
EnginnerTimelineResp res = new EnginnerTimelineResp(); EngineerTimelineResp res = new EngineerTimelineResp();
res.setEngineerCode(engineerCode); res.setEngineerCode(engineerCode);
res.setEngineerName(name); res.setEngineerName(engineerInfo.getName());
res.setDynamics(dynamics); res.setDynamics(dynamics);
return Result.success(res); return Result.success(res);
} }
private String getEngineerName(String engineerCode){ private List<OrderEvent> engineerTimelines(List<String> orderIds, String date){
LambdaQueryWrapper<EngineerInfo> lqw = new LambdaQueryWrapper<>();
lqw.eq(EngineerInfo::getEngineerCode, engineerCode);
EngineerInfo e = engineerInfoMPDao.selectOne(lqw);
return e.getName();
}
private List<OrderAppointment> orderAppointments(String engineerCode, String date){
// 获取指派单列表
LambdaQueryWrapper<OrderAppointment> lqw = new LambdaQueryWrapper<>();
lqw.eq(OrderAppointment::getEngineerCode, engineerCode);
lqw.ge(OrderAppointment::getExpectStartTime, date + " 00:00:00");
lqw.le(OrderAppointment::getExpectStartTime, date + " 23:59:59");
return orderAppointmentMPDao.selectList(lqw);
}
private List<EngineerTimeline> engineerTimelines(String engineerCode, String date){
// 获取工程师timeline // 获取工程师timeline
List<String> events = Stream.of("分站取还配件", "已出发", "加单").collect(Collectors.toList()); List<String> events = Stream.of("分站取还配件", "已出发", "加单").collect(Collectors.toList());
LambdaQueryWrapper<EngineerTimeline> lqw = new LambdaQueryWrapper<>(); LambdaQueryWrapper<OrderEvent> lqw = new LambdaQueryWrapper<>();
lqw.eq(EngineerTimeline::getEngineerCode, engineerCode); lqw.in(OrderEvent::getOrderId, orderIds);
lqw.ge(EngineerTimeline::getHappen, date+" 00:00:00"); lqw.ge(OrderEvent::getHappen, date+" 00:00:00");
lqw.le(EngineerTimeline::getHappen, date + " 23:59:59"); lqw.le(OrderEvent::getHappen, date + " 23:59:59");
lqw.in(EngineerTimeline::getEvent, events); lqw.in(OrderEvent::getEvent, events);
return engineerTimelineMPDao.selectList(lqw); return orderEventMPDao.selectList(lqw);
} }
private HashMap<String, String> orderRequestsLocation(List<String> orderIds) { private HashMap<String, String> orderRequestsLocation(List<String> orderIds) {
// 获取客户地址location // 获取客户地址location
HashMap<String, String> map = new HashMap<>(); HashMap<String, String> map = new HashMap<>();
LambdaQueryWrapper<OrderRequest> lqw = new LambdaQueryWrapper<>(); LambdaQueryWrapper<OrderRequest> lqw = new LambdaQueryWrapper<>();
lqw.in(OrderRequest::getOrderId, orderIds); lqw.in(OrderRequest::getOrderId, orderIds);
...@@ -112,9 +98,10 @@ public class EngineerTimelineServiceImpl implements EngineerTimelineService { ...@@ -112,9 +98,10 @@ public class EngineerTimelineServiceImpl implements EngineerTimelineService {
private String getWarehouseLocation(String branchId) { private String getWarehouseLocation(String branchId) {
// 获取配送站location // 获取配送站location
LambdaQueryWrapper<WarehouseInfo> lqw = new LambdaQueryWrapper<>(); LambdaQueryWrapper<OrgWarehouseInfo> lqw = new LambdaQueryWrapper<>();
lqw.eq(WarehouseInfo::getBranchId, branchId); lqw.eq(OrgWarehouseInfo::getBranchId, branchId);
WarehouseInfo w = warehouseInfoMPDao.selectOne(lqw); List<OrgWarehouseInfo> wares = warehouseInfoMPDao.selectList(lqw);
OrgWarehouseInfo w = wares.get(0);
return String.format("%s,%s", w.getX(), w.getY()); return String.format("%s,%s", w.getX(), w.getY());
} }
...@@ -135,15 +122,15 @@ public class EngineerTimelineServiceImpl implements EngineerTimelineService { ...@@ -135,15 +122,15 @@ public class EngineerTimelineServiceImpl implements EngineerTimelineService {
} }
private List<EnginnerTimelineResp.DynamicItem> packItems(List<EngineerTimeline> timelines, List<OrderAppointment> orders, HashMap<String, String> locations, String warehouseLocation) { private List<EngineerTimelineResp.DynamicItem> packItems(List<OrderEvent> timelines, List<OrderAppointment> orders, HashMap<String, String> locations, String warehouseLocation) {
int index = 1; int index = 0;
String order_id, title, type, text, location; String order_id, title, type, text, location;
List<EnginnerTimelineResp.DynamicItem> items = new ArrayList<>(); List<EngineerTimelineResp.DynamicItem> items = new ArrayList<>();
Set<String> s = new HashSet<>(); Set<String> s = new HashSet<>();
for (EngineerTimeline t: timelines){ for (OrderEvent t: timelines){
EnginnerTimelineResp.DynamicItem item = new EnginnerTimelineResp.DynamicItem(); EngineerTimelineResp.DynamicItem item = new EngineerTimelineResp.DynamicItem();
if (t.getEvent().equals("分站取还配件")) { if (t.getEvent().equals("分站取还配件")) {
title = t.getEvent(); title = t.getEvent();
...@@ -180,7 +167,7 @@ public class EngineerTimelineServiceImpl implements EngineerTimelineService { ...@@ -180,7 +167,7 @@ public class EngineerTimelineServiceImpl implements EngineerTimelineService {
continue; continue;
} }
index += 1; index += 1;
EnginnerTimelineResp.DynamicItem item = new EnginnerTimelineResp.DynamicItem(); EngineerTimelineResp.DynamicItem item = new EngineerTimelineResp.DynamicItem();
item.setTitle(String.format("第%d单出发", index)); item.setTitle(String.format("第%d单出发", index));
item.setTime(TimeUtils.IsoTimestamp2DateTime(o.getExpectStartTime())); item.setTime(TimeUtils.IsoTimestamp2DateTime(o.getExpectStartTime()));
item.setStatus(0); item.setStatus(0);
...@@ -190,6 +177,6 @@ public class EngineerTimelineServiceImpl implements EngineerTimelineService { ...@@ -190,6 +177,6 @@ public class EngineerTimelineServiceImpl implements EngineerTimelineService {
items.add(item); items.add(item);
} }
// 根据items的time升序排序 // 根据items的time升序排序
return items.stream().sorted(Comparator.comparing(EnginnerTimelineResp.DynamicItem::getTime)).collect(Collectors.toList()); return items.stream().sorted(Comparator.comparing(EngineerTimelineResp.DynamicItem::getTime)).collect(Collectors.toList());
} }
} }
...@@ -25,6 +25,7 @@ import org.springframework.stereotype.Service; ...@@ -25,6 +25,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
...@@ -212,6 +213,51 @@ public class OrderAssignImpl implements OrderAssign { ...@@ -212,6 +213,51 @@ public class OrderAssignImpl implements OrderAssign {
return Result.success(null); return Result.success(null);
} }
@Override
public Result<?> orderReschedule(String orderId, LocalDateTime expectBegin, LocalDateTime expectEnd, String expectDesc) throws BusinessException{
// 工单改约接口(当前同放回工单池处理)
OrderRequest order = orderRequestMPDao.getByOrderId(orderId);
if (order == null){
throw new BusinessException("订单不存在");
}
if(order.getDt().isEqual(expectBegin.toLocalDate())) {
throw new BusinessException("改约日期不应与之前日期相同");
}
if (LocalDate.now().isAfter(expectBegin.toLocalDate())){
throw new BusinessException("改约日期不能小于今日");
}
// 更新order_request表为未指派
order.setAppointmentStatus("NOT_ASSIGNED");
order.setDt(expectBegin.toLocalDate());
order.setExpectTimeBegin(Timestamp.valueOf(expectBegin));
order.setExpectTimeEnd(Timestamp.valueOf(expectEnd));
order.setExpectTimeDesc(expectDesc);
orderRequestMPDao.updateById(order);
// 更新order_appointment表为未指派
LambdaUpdateWrapper<OrderAppointment> appWrapper = new LambdaUpdateWrapper<>();
appWrapper.set(OrderAppointment::getStatus, "RESCHEDULED")
.eq(OrderAppointment::getOrderId, orderId).eq(OrderAppointment::getDt, order.getDt());
orderAppointmentMPDao.update(null, appWrapper);
// 登记事件
OrderEvent oe = new OrderEvent();
oe.setOrderId(orderId);
oe.setSuborderId("");
oe.setHappen(new Timestamp(System.currentTimeMillis()));
oe.setEvent("已改约");
oe.setOperator("123"); // 操作员ID TODO-用户系统
oe.setOperatorName("测试用户"); // 操作员姓名 TODO-用户系统
oe.setSource("PEA");
oe.setDescription("已改约");
oe.setMemo("");
oe.setCreateTime(new Timestamp(System.currentTimeMillis()));
orderEventMPDao.insert(oe);
return Result.success(null);
}
private List<String> searchEngineerCodes(Integer distance, String key, String recommend){ private List<String> searchEngineerCodes(Integer distance, String key, String recommend){
return null; return null;
} }
......
...@@ -175,4 +175,64 @@ public class OrganizationServiceImpl implements OrganizationService { ...@@ -175,4 +175,64 @@ public class OrganizationServiceImpl implements OrganizationService {
.setTitle(orgClusterEntity.getName()); .setTitle(orgClusterEntity.getName());
} }
@Override
public List<OrganizationDTO> getAllOrganizations(String levelType, List<String> organizationIds) {
log.info("{} {}", levelType, organizationIds);
switch (OrganizationType.valueOf(levelType)) {
case cluster:
List<OrgClusterEntity> clusters = orgClusterDao.findByClusterIdIn(organizationIds);
if (CollectionUtils.isNotEmpty(clusters)) {
return clusters.stream().map(c -> {
OrganizationDTO organizationDTO = new OrganizationDTO();
organizationDTO.setId(c.getClusterId());
organizationDTO.setName(c.getName());
organizationDTO.setType(OrganizationType.cluster.getValue());
return organizationDTO;
}).collect(Collectors.toList());
}
break;
case branch:
List<OrgBranchEntity> branchs = orgBranchDao.findByBranchIdIn(organizationIds);
if (CollectionUtils.isNotEmpty(branchs)) {
return branchs.stream().map(c -> {
OrganizationDTO organizationDTO = new OrganizationDTO();
organizationDTO.setId(c.getBranchId());
organizationDTO.setName(c.getBranchName());
organizationDTO.setType(OrganizationType.branch.getValue());
return organizationDTO;
}
).collect(Collectors.toList());
}
break;
case group:
List<OrgGroupEntity> groups = orgGroupDao.findByGroupIdIn(organizationIds);
if (CollectionUtils.isNotEmpty(groups)) {
return groups.stream().map(c -> {
OrganizationDTO organizationDTO = new OrganizationDTO();
organizationDTO.setId(c.getGroupId());
organizationDTO.setName(c.getGroupName());
organizationDTO.setType(OrganizationType.group.getValue());
return organizationDTO;
}).collect(Collectors.toList());
}
break;
case team:
List<OrgTeamEntity> teams = orgTeamDao.findByTeamIdIn(organizationIds);
if (CollectionUtils.isNotEmpty(teams)) {
return teams.stream().map(c -> {
OrganizationDTO organizationDTO = new OrganizationDTO();
organizationDTO.setId(c.getTeamId());
organizationDTO.setName(c.getTeamName());
organizationDTO.setType(OrganizationType.team.getValue());
return organizationDTO;
}).collect(Collectors.toList());
}
break;
default:
break;
}
return Lists.newArrayList();
}
} }
...@@ -3,9 +3,11 @@ package com.dituhui.pea.order.service.impl; ...@@ -3,9 +3,11 @@ package com.dituhui.pea.order.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dituhui.pea.common.BusinessException; import com.dituhui.pea.common.BusinessException;
import com.dituhui.pea.common.Result; import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.common.ListUtils;
import com.dituhui.pea.order.common.TimeUtils; import com.dituhui.pea.order.common.TimeUtils;
import com.dituhui.pea.order.dao.*; import com.dituhui.pea.order.dao.*;
import com.dituhui.pea.order.dto.*; import com.dituhui.pea.order.dto.*;
...@@ -68,14 +70,17 @@ public class ScheduleServiceImpl implements ScheduleService { ...@@ -68,14 +70,17 @@ public class ScheduleServiceImpl implements ScheduleService {
} }
@Override @Override
public Result<?> getScheduleOverview(long page, long size, String date, String levelType, List<String> levelIds) { public Result<?> getScheduleOverview(long page, long size, LocalDate date, String levelType, List<String> levelIds) {
// 获取team列表 // 获取team列表, 以team排序分页
IPage<OrgTeam> pg = this.queryOrgTeams(page, size, levelType, levelIds); IPage<OrgTeam> pg = this.queryOrgTeams(page, size, levelType, levelIds);
List<OrgTeam> orgTeams = pg.getRecords(); List<OrgTeam> orgTeams = pg.getRecords();
List<ScheduleOverviewResp.Team> teams = new ArrayList<>(); List<ScheduleOverviewResp.Team> teams = new ArrayList<>();
// 获取skill与skill_category的映射
HashMap<String, String> skillMapping = this.getSkillMapping();
// 获取工单列表 // 获取工单列表
for (OrgTeam t : orgTeams) { for (OrgTeam t : orgTeams) {
ScheduleOverviewResp.Team team = new ScheduleOverviewResp.Team(); ScheduleOverviewResp.Team team = new ScheduleOverviewResp.Team();
...@@ -85,11 +90,11 @@ public class ScheduleServiceImpl implements ScheduleService { ...@@ -85,11 +90,11 @@ public class ScheduleServiceImpl implements ScheduleService {
// 获取改team订单列表 // 获取改team订单列表
List<OrderRequest> orders = this.queryOrderRequests(t.getTeamId(), date); List<OrderRequest> orders = this.queryOrderRequests(t.getTeamId(), date);
team.setOrder(this.getTeamOrderSum(orders)); team.setOrder(this.getTeamOrderSum(orders, skillMapping));
// 技术员指派单列表 // 技术员指派单列表
Map<String, List<OrderAppointment>> engineerOrders = new HashMap<>(); Map<String, List<OrderAppointment>> engineerOrders = new HashMap<>();
if (orders != null && !orders.isEmpty()) { if (ListUtils.isNotEmpty(orders)) {
List<String> orderRequestIds = orders.stream().map(OrderRequest::getOrderId).collect(Collectors.toList()); List<String> orderRequestIds = orders.stream().map(OrderRequest::getOrderId).collect(Collectors.toList());
List<OrderAppointment> orderAppointments = this.queryOrderAppointments(orderRequestIds, date); List<OrderAppointment> orderAppointments = this.queryOrderAppointments(orderRequestIds, date);
engineerOrders = orderAppointments.stream().collect(Collectors.groupingBy(OrderAppointment::getEngineerCode)); engineerOrders = orderAppointments.stream().collect(Collectors.groupingBy(OrderAppointment::getEngineerCode));
...@@ -97,9 +102,8 @@ public class ScheduleServiceImpl implements ScheduleService { ...@@ -97,9 +102,8 @@ public class ScheduleServiceImpl implements ScheduleService {
// 获取team技术员列表 // 获取team技术员列表
List<OrgTeamEngineer> teamEngineers = this.queryOrgTeamEngineers(t.getTeamId()); List<OrgTeamEngineer> teamEngineers = this.queryOrgTeamEngineers(t.getTeamId());
List<String> engineerCodes = teamEngineers.stream().map(OrgTeamEngineer::getEngineerCode).collect(Collectors.toList());
// 获取技术员列表 List<EngineerInfo> engineerInfoList = engineerInfoMPDao.selectByEngineerCodes(engineerCodes);
List<EngineerInfo> engineerInfoList = engineerInfoMPDao.selectByGroupId(t.getGroupId());
Map<String, List<EngineerInfo>> engineers = engineerInfoList.stream().collect(Collectors.groupingBy(EngineerInfo::getEngineerCode)); Map<String, List<EngineerInfo>> engineers = engineerInfoList.stream().collect(Collectors.groupingBy(EngineerInfo::getEngineerCode));
List<ScheduleOverviewResp.Item> children = new ArrayList<>(); List<ScheduleOverviewResp.Item> children = new ArrayList<>();
...@@ -107,6 +111,7 @@ public class ScheduleServiceImpl implements ScheduleService { ...@@ -107,6 +111,7 @@ public class ScheduleServiceImpl implements ScheduleService {
ScheduleOverviewResp.Item child = new ScheduleOverviewResp.Item(); ScheduleOverviewResp.Item child = new ScheduleOverviewResp.Item();
//技术员信息
String engineerCode = entry.getKey(); String engineerCode = entry.getKey();
EngineerInfo engineerInfo = entry.getValue().get(0); EngineerInfo engineerInfo = entry.getValue().get(0);
...@@ -122,7 +127,7 @@ public class ScheduleServiceImpl implements ScheduleService { ...@@ -122,7 +127,7 @@ public class ScheduleServiceImpl implements ScheduleService {
child.setName(engineerInfo.getName()); child.setName(engineerInfo.getName());
child.setValue(engineerCode); child.setValue(engineerCode);
child.setLevel("engineer"); child.setLevel("engineer");
child.setOrder(this.getTeamOrderSum(orders2)); child.setOrder(this.getTeamOrderSum(orders2, skillMapping));
child.setOrderDesc(Integer.toString(orders2.size())); child.setOrderDesc(Integer.toString(orders2.size()));
child.setDistanceDesc(""); child.setDistanceDesc("");
...@@ -147,14 +152,14 @@ public class ScheduleServiceImpl implements ScheduleService { ...@@ -147,14 +152,14 @@ public class ScheduleServiceImpl implements ScheduleService {
} }
@Override @Override
public Result<?> getScheduleEngineerOverview(String date, String engineerCode) throws BusinessException { public Result<?> getScheduleEngineerOverview(LocalDate date, String engineerCode) throws BusinessException {
EngineerInfo engineer = engineerInfoMPDao.getByEngineerCode(engineerCode); EngineerInfo engineer = engineerInfoMPDao.getByEngineerCode(engineerCode);
if (engineer == null) { if (engineer == null) {
throw new BusinessException("分销员不存在"); throw new BusinessException("分销员不存在");
} }
List<LabelValueDTO> emptyTips = new ArrayList<>(); List<LabelValueDTO> emptyTips = new ArrayList<>();
List<OrderAppointment> orderAppointments = this.queryOrderAppointmentsByEngineerCode(engineerCode, date); List<OrderAppointment> orderAppointments = orderAppointmentMPDao.selectByEngineerCodeAndDt(engineerCode, date);
List<TimeLineDTO> timelines = new ArrayList<>(); List<TimeLineDTO> timelines = new ArrayList<>();
for (OrderAppointment o : orderAppointments) { for (OrderAppointment o : orderAppointments) {
TimeLineDTO item = new TimeLineDTO(); TimeLineDTO item = new TimeLineDTO();
...@@ -173,7 +178,7 @@ public class ScheduleServiceImpl implements ScheduleService { ...@@ -173,7 +178,7 @@ public class ScheduleServiceImpl implements ScheduleService {
List<LabelValueDTO> dynamics = new ArrayList<>(); List<LabelValueDTO> dynamics = new ArrayList<>();
dynamics.add(new LabelValueDTO("姓名", engineer.getName())); dynamics.add(new LabelValueDTO("姓名", engineer.getName()));
dynamics.add(new LabelValueDTO("日期", date)); dynamics.add(new LabelValueDTO("日期", TimeUtils.IsoLocalDate2String(date)));
dynamics.add(new LabelValueDTO("状态", "上班")); dynamics.add(new LabelValueDTO("状态", "上班"));
dynamics.add(new LabelValueDTO("待服务", Integer.toString(countPending))); dynamics.add(new LabelValueDTO("待服务", Integer.toString(countPending)));
dynamics.add(new LabelValueDTO("服务中", Integer.toString(statusGroup.getOrDefault("STARTED", empty).size()))); dynamics.add(new LabelValueDTO("服务中", Integer.toString(statusGroup.getOrDefault("STARTED", empty).size())));
...@@ -250,46 +255,57 @@ public class ScheduleServiceImpl implements ScheduleService { ...@@ -250,46 +255,57 @@ public class ScheduleServiceImpl implements ScheduleService {
return orgTeamEngineerMPDao.selectList(lqw); return orgTeamEngineerMPDao.selectList(lqw);
} }
private List<OrderRequest> queryOrderRequests(String teamId, String date) { private List<OrderRequest> queryOrderRequests(String teamId, LocalDate date) {
LambdaQueryWrapper<OrderRequest> lqw = new LambdaQueryWrapper<>(); LambdaQueryWrapper<OrderRequest> lqw = new LambdaQueryWrapper<>();
lqw.eq(OrderRequest::getDt, date);
lqw.in(OrderRequest::getOrgTeamId, teamId); lqw.in(OrderRequest::getOrgTeamId, teamId);
lqw.eq(OrderRequest::getAppointmentStatus, "ASSIGNED"); lqw.eq(OrderRequest::getAppointmentStatus, "ASSIGNED");
lqw.ge(OrderRequest::getExpectTimeBegin, TimeUtils.IsoDateTime2Timestamp(String.format("%s 00:00:00", date)));
lqw.le(OrderRequest::getExpectTimeBegin, TimeUtils.IsoDateTime2Timestamp(String.format("%s 23:59:59", date)));
return orderRequestMPDao.selectList(lqw); return orderRequestMPDao.selectList(lqw);
} }
private List<OrderAppointment> queryOrderAppointments(List<String> orderIds, String date) { private List<OrderAppointment> queryOrderAppointments(List<String> orderIds, LocalDate date) {
LambdaQueryWrapper<OrderAppointment> lqw = new LambdaQueryWrapper<>(); LambdaQueryWrapper<OrderAppointment> lqw = new LambdaQueryWrapper<>();
lqw.in(OrderAppointment::getOrderId, orderIds); lqw.in(OrderAppointment::getOrderId, orderIds);
lqw.ge(OrderAppointment::getExpectStartTime, TimeUtils.IsoDateTime2Timestamp(String.format("%s 00:00:00", date))); lqw.eq(OrderAppointment::getDt, date);
lqw.le(OrderAppointment::getExpectEndTime, TimeUtils.IsoDateTime2Timestamp(String.format("%s 23:59:59", date))); lqw.orderByAsc(OrderAppointment::getEngineerCode);
return orderAppointmentMPDao.selectList(lqw); return orderAppointmentMPDao.selectList(lqw);
} }
private List<OrderAppointment> queryOrderAppointmentsByEngineerCode(String engineerCode, String date) { private ScheduleOverviewResp.OrderSum getTeamOrderSum(List<OrderRequest> orders, HashMap<String, String> skillMapping) {
LambdaQueryWrapper<OrderAppointment> lqw = new LambdaQueryWrapper<>(); ScheduleOverviewResp.OrderSum s = new ScheduleOverviewResp.OrderSum();
lqw.in(OrderAppointment::getEngineerCode, engineerCode);
lqw.ge(OrderAppointment::getExpectStartTime, TimeUtils.IsoDateTime2Timestamp(String.format("%s 00:00:00", date)));
lqw.le(OrderAppointment::getExpectEndTime, TimeUtils.IsoDateTime2Timestamp(String.format("%s 23:59:59", date)));
return orderAppointmentMPDao.selectList(lqw);
}
private ScheduleOverviewResp.OrderSum getTeamOrderSum(List<OrderRequest> orders) { List<OrderRequest> emtpy = new ArrayList<>();
ScheduleOverviewResp.OrderSum s = new ScheduleOverviewResp.OrderSum(); HashMap<String, Integer> skillCounter = new HashMap<>();
Map<String, List<OrderRequest>> cc = orders.stream().collect(Collectors.groupingBy(OrderRequest::getSkill)); Map<String, List<OrderRequest>> cc = orders.stream().collect(Collectors.groupingBy(OrderRequest::getSkill));
List<OrderRequest> emtpy = new ArrayList<>(); for(Map.Entry<String, List<OrderRequest>> entry: cc.entrySet()){
String skill = entry.getKey();
Integer count = entry.getValue().size();
String skillCategory = skillMapping.get(skill);
Integer v = skillCounter.getOrDefault(skillCategory, 0);
v += count;
skillCounter.put(skillCategory, v);
}
s.setTotal(orders.size()); s.setTotal(orders.size());
s.setInstallNum(cc.getOrDefault("安装", emtpy).size()); s.setInstallNum(skillCounter.getOrDefault("安装", 0));
s.setFixNum(cc.getOrDefault("维修", emtpy).size()); s.setFixNum(skillCounter.getOrDefault("维修", 0));
s.setDesignNum(cc.getOrDefault("设计", emtpy).size()); s.setDesignNum(skillCounter.getOrDefault("整改", 0));
s.setCleanNum(cc.getOrDefault("清洗", emtpy).size()); s.setCleanNum(skillCounter.getOrDefault("清洁保养", 0));
return s; return s;
} }
private HashMap<String, String> getSkillMapping() {
LambdaQueryWrapper<SkillInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.select(SkillInfo::getSkill, SkillInfo::getSkillCategory)
.groupBy(SkillInfo::getSkill, SkillInfo::getSkillCategory);
List<SkillInfo> skillList = skillInfoMPDao.selectList(queryWrapper);
return skillList.stream().collect(Collectors.toMap(
SkillInfo::getSkill, SkillInfo::getSkillCategory, (oldValue, newValue) -> newValue, HashMap::new));
}
private HashMap<String, Integer> queryCountBySkill(LocalDate date, String levelType, List<String> levelValue) { private HashMap<String, Integer> queryCountBySkill(LocalDate date, String levelType, List<String> levelValue) {
HashMap<String, Integer> map = new HashMap<>(); HashMap<String, Integer> map = new HashMap<>();
......
...@@ -168,7 +168,7 @@ public class WorkbenchServiceImpl implements WorkbenchService { ...@@ -168,7 +168,7 @@ public class WorkbenchServiceImpl implements WorkbenchService {
private List<WorkbenchSummaryResp.ValueDTO> packValueAppointmentMethod(HashMap<String, Long> summary) { private List<WorkbenchSummaryResp.ValueDTO> packValueAppointmentMethod(HashMap<String, Long> summary) {
List<WorkbenchSummaryResp.ValueDTO> items = new ArrayList<>(); List<WorkbenchSummaryResp.ValueDTO> items = new ArrayList<>();
String urlName = "WorkbenchManage"; String urlName = "DispatchBenchManage";
Long manualDealing = summary.getOrDefault("manualDealing", 0L); Long manualDealing = summary.getOrDefault("manualDealing", 0L);
Long manualTotal = summary.getOrDefault("manualTotal", 0L); Long manualTotal = summary.getOrDefault("manualTotal", 0L);
Long autoDealing = summary.getOrDefault("autoDealing", 0L); Long autoDealing = summary.getOrDefault("autoDealing", 0L);
...@@ -192,8 +192,7 @@ public class WorkbenchServiceImpl implements WorkbenchService { ...@@ -192,8 +192,7 @@ public class WorkbenchServiceImpl implements WorkbenchService {
private List<WorkbenchSummaryResp.ValueDTO> packValueOrderStatus(HashMap<String, Long> summary) { private List<WorkbenchSummaryResp.ValueDTO> packValueOrderStatus(HashMap<String, Long> summary) {
List<WorkbenchSummaryResp.ValueDTO> items = new ArrayList<>(); List<WorkbenchSummaryResp.ValueDTO> items = new ArrayList<>();
String urlName = "WorkbenchManage"; String urlName = "DispatchBenchManage";
Long assigned = summary.getOrDefault("ASSIGNED", 0L); Long assigned = summary.getOrDefault("ASSIGNED", 0L);
Long contacted = summary.getOrDefault("CONTACTED", 0L); Long contacted = summary.getOrDefault("CONTACTED", 0L);
Long departed = summary.getOrDefault("DEPARTED", 0L); Long departed = summary.getOrDefault("DEPARTED", 0L);
......
...@@ -107,6 +107,11 @@ ...@@ -107,6 +107,11 @@
<version>2.5.1</version> <version>2.5.1</version>
</dependency> </dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
...@@ -7,8 +7,8 @@ import org.springframework.context.annotation.ComponentScan; ...@@ -7,8 +7,8 @@ import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@SpringBootApplication @SpringBootApplication
@EnableFeignClients
@ComponentScan(basePackages = "com.dituhui.pea") @ComponentScan(basePackages = "com.dituhui.pea")
@EnableFeignClients(basePackages = {"com.dituhui.pea.order"})
@EnableJpaAuditing @EnableJpaAuditing
public class Application { public class Application {
......
...@@ -7,15 +7,24 @@ import org.springframework.data.redis.core.RedisTemplate; ...@@ -7,15 +7,24 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration @Configuration
public class RedisConfig { public class RedisConfig {
@Bean @Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); // ObjectMapper objectMapper = new ObjectMapper();
// objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(),
// ObjectMapper.DefaultTyping.EVERYTHING, JsonTypeInfo.As.PROPERTY);
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory); redisTemplate.setConnectionFactory(connectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer());
return redisTemplate; return redisTemplate;
} }
......
...@@ -13,13 +13,12 @@ import java.util.concurrent.TimeUnit; ...@@ -13,13 +13,12 @@ import java.util.concurrent.TimeUnit;
/** /**
* redis服务 * redis服务
* *
* @author dk
*/ */
@Component @Component
public class RedisService { public class RedisService {
@Autowired @Autowired
private RedisTemplate redisTemplate; private RedisTemplate<String, String> redisTemplate;
/** /**
* 写入缓存 * 写入缓存
...@@ -28,10 +27,10 @@ public class RedisService { ...@@ -28,10 +27,10 @@ public class RedisService {
* @param value * @param value
* @return * @return
*/ */
public boolean set(final String key, Object value) { public boolean set(final String key, String value) {
boolean result = false; boolean result = false;
try { try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); ValueOperations<String, String> operations = redisTemplate.opsForValue();
operations.set(key, value); operations.set(key, value);
result = true; result = true;
} catch (Exception e) { } catch (Exception e) {
...@@ -47,10 +46,10 @@ public class RedisService { ...@@ -47,10 +46,10 @@ public class RedisService {
* @param value * @param value
* @return * @return
*/ */
public boolean set(final String key, Object value, Long expireTime) { public boolean set(final String key, String value, Long expireTime) {
boolean result = false; boolean result = false;
try { try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); ValueOperations<String, String> operations = redisTemplate.opsForValue();
operations.set(key, value); operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true; result = true;
...@@ -61,166 +60,16 @@ public class RedisService { ...@@ -61,166 +60,16 @@ public class RedisService {
} }
/** /**
* 设置过期时间<br>
* 原始key
*
* @param key
* @param expriedDate
*/
public boolean setExpriedDate(String key, Date expriedDate) {
return redisTemplate.expireAt(key, expriedDate);
}
/**
* 批量删除对应的value
*
* @param keys
*/
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
* 批量删除key
*
* @param pattern
*/
public void removePattern(final String pattern) {
Set<Serializable> keys = redisTemplate.keys(pattern);
if (keys.size() > 0) {
redisTemplate.delete(keys);
}
}
/**
* 删除对应的value
*
* @param key
*/
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
/**
* 判断缓存中是否有对应的value
*
* @param key
* @return
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 读取缓存 * 读取缓存
* *
* @param key * @param key
* @return * @return
*/ */
public Object get(final String key) { public String get(final String key) {
Object result = null; String result = null;
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); ValueOperations<String, String> operations = redisTemplate.opsForValue();
result = operations.get(key); result = operations.get(key);
return result; return result;
} }
/**
* 哈希 添加
*
* @param key
* @param hashKey
* @param value
*/
public void hmSet(String key, Object hashKey, Object value) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
hash.put(key, hashKey, value);
}
/**
* 哈希获取数据
*
* @param key
* @param hashKey
* @return
*/
public Object hmGet(String key, Object hashKey) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.get(key, hashKey);
}
/**
* 列表添加
*
* @param k
* @param v
*/
public void lPush(String k, Object v) {
ListOperations<String, Object> list = redisTemplate.opsForList();
list.rightPush(k, v);
}
/**
* 列表获取
*
* @param k
* @param l
* @param l1
* @return
*/
public List<Object> lRange(String k, long l, long l1) {
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.range(k, l, l1);
}
/**
* 集合添加
*
* @param key
* @param value
*/
public void add(String key, Object value) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
set.add(key, value);
}
/**
* 集合获取
*
* @param key
* @return
*/
public Set<Object> setMembers(String key) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
return set.members(key);
}
/**
* 有序集合添加
*
* @param key
* @param value
* @param scoure
*/
public void zAdd(String key, Object value, double scoure) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.add(key, value, scoure);
}
/**
* 有序集合获取
*
* @param key
* @param scoure
* @param scoure1
* @return
*/
public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.rangeByScore(key, scoure, scoure1);
}
} }
...@@ -31,9 +31,6 @@ public class UserController implements IUser { ...@@ -31,9 +31,6 @@ public class UserController implements IUser {
@Autowired @Autowired
private UserService userService; private UserService userService;
@Autowired
private RedisService redisService;
@Override @Override
public Result<?> userLogin(UserLoginParam user) { public Result<?> userLogin(UserLoginParam user) {
return userService.userLogin(user.getAccount(), user.getPassword()); return userService.userLogin(user.getAccount(), user.getPassword());
...@@ -46,21 +43,7 @@ public class UserController implements IUser { ...@@ -46,21 +43,7 @@ public class UserController implements IUser {
@Override @Override
public WebResult<UserInfo> getCurrentUserInfo(String userToken, Boolean needTeamInfo) { public WebResult<UserInfo> getCurrentUserInfo(String userToken, Boolean needTeamInfo) {
UserAuthInfo userInfoCache = getUserAuthInfoFromToken(userToken); return null;
String userId = userInfoCache.getUserId();
UserInfo userInfo = userService.queryUserById(userId);
return WebResult.ok(userInfo);
}
/**
* 获取用户认证信息
*
* @param userToken
* @return
*/
private UserAuthInfo getUserAuthInfoFromToken(String userToken) {
UserAuthInfo userAuthInfo = (UserAuthInfo) redisService.get(RedisKeyGroup.authToken.toString() + ":" + userToken);
return userAuthInfo;
} }
@Override @Override
......
package com.dituhui.pea.user.service; package com.dituhui.pea.user.service;
import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
...@@ -8,18 +9,21 @@ import java.util.stream.Collectors; ...@@ -8,18 +9,21 @@ import java.util.stream.Collectors;
import javax.persistence.criteria.Path; import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.dituhui.pea.common.Result; import com.dituhui.pea.common.Result;
import com.dituhui.pea.common.ResultEnum;
import com.dituhui.pea.enums.RedisKeyGroup; import com.dituhui.pea.enums.RedisKeyGroup;
import com.dituhui.pea.enums.StatusCodeEnum; import com.dituhui.pea.enums.StatusCodeEnum;
import com.dituhui.pea.enums.ThirdPartyEnum; import com.dituhui.pea.enums.ThirdPartyEnum;
import com.dituhui.pea.exception.BusinessException; import com.dituhui.pea.exception.BusinessException;
import com.dituhui.pea.order.IOrganization;
import com.dituhui.pea.pojo.OrganizationDTO;
import com.dituhui.pea.pojo.ResourceInfo; import com.dituhui.pea.pojo.ResourceInfo;
import com.dituhui.pea.pojo.RoleInfo; import com.dituhui.pea.pojo.RoleInfo;
import com.dituhui.pea.pojo.ThirdUserInfo; import com.dituhui.pea.pojo.ThirdUserInfo;
...@@ -40,6 +44,8 @@ import com.dituhui.pea.user.entity.UserRoleEntity; ...@@ -40,6 +44,8 @@ import com.dituhui.pea.user.entity.UserRoleEntity;
import com.dituhui.pea.user.factory.ThirdStrategy; import com.dituhui.pea.user.factory.ThirdStrategy;
import com.dituhui.pea.user.factory.ThirdStrategyFactory; import com.dituhui.pea.user.factory.ThirdStrategyFactory;
import com.dituhui.pea.user.utils.TextHelper; import com.dituhui.pea.user.utils.TextHelper;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
...@@ -61,6 +67,7 @@ public class UserService { ...@@ -61,6 +67,7 @@ public class UserService {
* 失效时间ms * 失效时间ms
*/ */
private static final int LIVE_TIME_MILLIS = 7200000; private static final int LIVE_TIME_MILLIS = 7200000;
private static final Gson gson = new Gson();
@Autowired @Autowired
UserDao userDao; UserDao userDao;
...@@ -83,6 +90,9 @@ public class UserService { ...@@ -83,6 +90,9 @@ public class UserService {
@Autowired @Autowired
ResourceDao resourceDao; ResourceDao resourceDao;
@Autowired
IOrganization organizationService;
public Result<?> userLogin(String account, String password) { public Result<?> userLogin(String account, String password) {
UserEntity user = userDao.findByAccountAndPassword(account, SecureUtil.md5(password)); UserEntity user = userDao.findByAccountAndPassword(account, SecureUtil.md5(password));
log.info("{}/{} login", account, password); log.info("{}/{} login", account, password);
...@@ -93,7 +103,7 @@ public class UserService { ...@@ -93,7 +103,7 @@ public class UserService {
String token = IdUtil.simpleUUID(); String token = IdUtil.simpleUUID();
userDTO.setToken(token); userDTO.setToken(token);
long timestamp = System.currentTimeMillis() + LIVE_TIME_MILLIS; long timestamp = System.currentTimeMillis() + LIVE_TIME_MILLIS;
redisService.set(RedisKeyGroup.authToken + ":" + token, userDTO, timestamp / 1000); redisService.set(RedisKeyGroup.authToken + ":" + token, gson.toJson(userDTO), timestamp / 1000);
return Result.success(userDTO); return Result.success(userDTO);
} else { } else {
return Result.failed("鉴权失败"); return Result.failed("鉴权失败");
...@@ -118,30 +128,54 @@ public class UserService { ...@@ -118,30 +128,54 @@ public class UserService {
List<String> resourceIds = roleResources.stream().map(r -> r.getResourceId()) List<String> resourceIds = roleResources.stream().map(r -> r.getResourceId())
.collect(Collectors.toList()); .collect(Collectors.toList());
List<ResourceEntity> resources = resourceDao.findAllById(resourceIds); List<ResourceEntity> resources = resourceDao.findAllById(resourceIds);
// 子菜单嵌套处理+菜单排序
// 菜单嵌套处理+菜单排序
List<ResourceInfo> levelOne = resources.stream() List<ResourceInfo> levelOne = resources.stream()
.filter(r -> StringUtils.isEmpty(r.getParentId()) && r.getType() == 1) .filter(r -> StringUtils.isEmpty(r.getParentId()) && r.getType() == 1)
.map(r -> BeanUtil.copyProperties(r, ResourceInfo.class)).collect(Collectors.toList()); .map(r -> BeanUtil.copyProperties(r, ResourceInfo.class)).collect(Collectors.toList());
for (ResourceInfo resourceInfo : levelOne) { for (ResourceInfo resourceInfo : levelOne) {
splitExtra(resourceInfo); splitMenuExtra(resourceInfo);
List<ResourceEntity> levelTow = resourceDao.findByParentId(resourceInfo.getId()); List<ResourceEntity> levelTow = resourceDao.findByParentId(resourceInfo.getId());
List<ResourceInfo> levelTowResourceInfo = levelTow.stream().map(r -> { List<ResourceInfo> levelTowResourceInfo = levelTow.stream().map(r -> {
ResourceInfo res = BeanUtil.copyProperties(r, ResourceInfo.class); ResourceInfo res = BeanUtil.copyProperties(r, ResourceInfo.class);
splitExtra(res); splitMenuExtra(res);
return res; return res;
}).sorted(Comparator.comparing(ResourceInfo::getOrder)).collect(Collectors.toList()); }).sorted(Comparator.comparing(ResourceInfo::getOrder)).collect(Collectors.toList());
resourceInfo.setChildren(levelTowResourceInfo); resourceInfo.setChildren(levelTowResourceInfo);
} }
levelOne = levelOne.stream().sorted(Comparator.comparing(ResourceInfo::getOrder)) levelOne = levelOne.stream().sorted(Comparator.comparing(ResourceInfo::getOrder))
.collect(Collectors.toList()); .collect(Collectors.toList());
userDTO.setResources(levelOne); userDTO.setMenus(levelOne);
// 获取组织架构资源
List<OrganizationDTO> allOrgs = resources.stream().filter(r -> r.getType() == 3).map(r -> {
List<OrganizationDTO> orgs = Lists.newArrayList();
String[] temp = r.getExtra().split("\\|");
Result<?> result = organizationService.getAllOrganizations(temp[0],
Arrays.asList(temp[1].split(",")));
if (StringUtils.equals(ResultEnum.SUCCESS.getCode(), result.getCode())) {
orgs = (List<OrganizationDTO>) result.getResult();
}
return orgs;
}).flatMap(a -> a.stream()).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(allOrgs)) {
log.info("allOrgs2: {}", allOrgs.size());
try {
log.info("allOrgs3: {}", allOrgs.get(0).getIsActive());
allOrgs.get(0).setIsActive(true);
} catch (Throwable e) {
e.printStackTrace();
log.error("allOrgs4: {} {}", e.getMessage(), e);
}
}
userDTO.setAuths(allOrgs);
} }
} }
} }
return userDTO; return userDTO;
} }
private void splitExtra(ResourceInfo resourceInfo) { private void splitMenuExtra(ResourceInfo resourceInfo) {
String[] temp = resourceInfo.getExtra().split(","); String[] temp = resourceInfo.getExtra().split(",");
resourceInfo.setCode(temp[0]); resourceInfo.setCode(temp[0]);
resourceInfo.setOrder(Integer.parseInt(temp[1])); resourceInfo.setOrder(Integer.parseInt(temp[1]));
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!