websocket模块解耦

数字计算使用BigDecimal
代码整理
master
toesbieya 6 years ago
parent 9609078727
commit f7366130ea
  1. 28
      java/pom.xml
  2. 12
      java/src/main/java/com/toesbieya/my/annoation/Tx.java
  3. 6
      java/src/main/java/com/toesbieya/my/config/RedisConfig.java
  4. 145
      java/src/main/java/com/toesbieya/my/config/RedisEventListenerConfig.java
  5. 12
      java/src/main/java/com/toesbieya/my/constant/SessionConstant.java
  6. 13
      java/src/main/java/com/toesbieya/my/constant/SocketConstant.java
  7. 14
      java/src/main/java/com/toesbieya/my/controller/AccountController.java
  8. 6
      java/src/main/java/com/toesbieya/my/controller/BizDocumentHistoryController.java
  9. 77
      java/src/main/java/com/toesbieya/my/controller/BizPurchaseInboundController.java
  10. 83
      java/src/main/java/com/toesbieya/my/controller/BizPurchaseOrderController.java
  11. 83
      java/src/main/java/com/toesbieya/my/controller/BizSellOrderController.java
  12. 85
      java/src/main/java/com/toesbieya/my/controller/BizSellOutboundController.java
  13. 14
      java/src/main/java/com/toesbieya/my/controller/BizStockController.java
  14. 1
      java/src/main/java/com/toesbieya/my/controller/FileController.java
  15. 4
      java/src/main/java/com/toesbieya/my/enumeration/DocFinishEnum.java
  16. 4
      java/src/main/java/com/toesbieya/my/enumeration/DocHistoryEnum.java
  17. 4
      java/src/main/java/com/toesbieya/my/enumeration/DocStatusEnum.java
  18. 9
      java/src/main/java/com/toesbieya/my/interceptor/SecurityInterceptor.java
  19. 2
      java/src/main/java/com/toesbieya/my/mapper/BizDocumentHistoryMapper.java
  20. 2
      java/src/main/java/com/toesbieya/my/mapper/BizPurchaseInboundMapper.java
  21. 12
      java/src/main/java/com/toesbieya/my/mapper/BizPurchaseOrderMapper.java
  22. 12
      java/src/main/java/com/toesbieya/my/mapper/BizSellOrderMapper.java
  23. 2
      java/src/main/java/com/toesbieya/my/mapper/BizSellOutboundMapper.java
  24. 13
      java/src/main/java/com/toesbieya/my/mapper/BizStockMapper.java
  25. 17
      java/src/main/java/com/toesbieya/my/mapper/StatisticMapper.java
  26. 4
      java/src/main/java/com/toesbieya/my/model/entity/BizDocumentSub.java
  27. 4
      java/src/main/java/com/toesbieya/my/model/entity/BizPurchaseOrder.java
  28. 6
      java/src/main/java/com/toesbieya/my/model/entity/BizPurchaseOrderSub.java
  29. 4
      java/src/main/java/com/toesbieya/my/model/entity/BizSellOrder.java
  30. 8
      java/src/main/java/com/toesbieya/my/model/entity/BizSellOrderSub.java
  31. 6
      java/src/main/java/com/toesbieya/my/model/entity/BizStock.java
  32. 8
      java/src/main/java/com/toesbieya/my/model/entity/StatProfitTotal.java
  33. 10
      java/src/main/java/com/toesbieya/my/model/vo/IpResultVo.java
  34. 21
      java/src/main/java/com/toesbieya/my/model/vo/SocketEventVo.java
  35. 16
      java/src/main/java/com/toesbieya/my/model/vo/SocketOfflineVo.java
  36. 12
      java/src/main/java/com/toesbieya/my/model/vo/export/StockExport.java
  37. 6
      java/src/main/java/com/toesbieya/my/model/vo/result/StockSearchResult.java
  38. 10
      java/src/main/java/com/toesbieya/my/model/vo/statictis/FourBlockStat.java
  39. 2
      java/src/main/java/com/toesbieya/my/module/PermissionModule.java
  40. 74
      java/src/main/java/com/toesbieya/my/module/WebSocketServer.java
  41. 43
      java/src/main/java/com/toesbieya/my/module/request/RequestModule.java
  42. 56
      java/src/main/java/com/toesbieya/my/schedule/DocumentTask.java
  43. 66
      java/src/main/java/com/toesbieya/my/schedule/SessionTask.java
  44. 116
      java/src/main/java/com/toesbieya/my/schedule/StatisticTask.java
  45. 5
      java/src/main/java/com/toesbieya/my/service/AccountService.java
  46. 6
      java/src/main/java/com/toesbieya/my/service/BizDocumentHistoryService.java
  47. 234
      java/src/main/java/com/toesbieya/my/service/BizPurchaseInboundService.java
  48. 149
      java/src/main/java/com/toesbieya/my/service/BizPurchaseOrderService.java
  49. 149
      java/src/main/java/com/toesbieya/my/service/BizSellOrderService.java
  50. 250
      java/src/main/java/com/toesbieya/my/service/BizSellOutboundService.java
  51. 4
      java/src/main/java/com/toesbieya/my/service/BizStockService.java
  52. 29
      java/src/main/java/com/toesbieya/my/service/MsgService.java
  53. 135
      java/src/main/java/com/toesbieya/my/service/StatisticService.java
  54. 33
      java/src/main/java/com/toesbieya/my/service/SysUserService.java
  55. 4
      java/src/main/java/com/toesbieya/my/utils/DocumentUtil.java
  56. 84
      java/src/main/java/com/toesbieya/my/utils/RedisUtil.java
  57. 22
      java/src/main/java/com/toesbieya/my/utils/SessionUtil.java
  58. 30
      java/src/main/java/com/toesbieya/my/utils/Util.java
  59. 36
      java/src/main/java/com/toesbieya/my/utils/WebSocketUtil.java
  60. 28
      java/src/main/java/com/toesbieya/my/utils/YmlUtil.java
  61. 25
      java/src/main/resources/application.yml
  62. 2
      java/src/main/resources/mapper/BizDocumentHistory.xml
  63. 2
      java/src/main/resources/mapper/BizPurchaseInbound.xml
  64. 27
      java/src/main/resources/mapper/BizPurchaseOrder.xml
  65. 27
      java/src/main/resources/mapper/BizSellOrder.xml
  66. 2
      java/src/main/resources/mapper/BizSellOutbound.xml
  67. 109
      java/src/main/resources/mapper/BizStock.xml
  68. 80
      java/src/main/resources/mapper/Statistic.xml

@ -34,6 +34,11 @@
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
@ -81,6 +86,12 @@
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
@ -110,23 +121,6 @@
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<!--系统监控-->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>${oshi.version}</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>${jna.version}</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>${jna.version}</version>
</dependency>
<!-- 三方工具类 --> <!-- 三方工具类 -->
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>

@ -1,12 +0,0 @@
package com.toesbieya.my.annoation;
import org.springframework.transaction.annotation.Transactional;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Transactional(rollbackFor = Exception.class)
public @interface Tx {
}

@ -10,8 +10,8 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration @Configuration
public class RedisConfig { public class RedisConfig {
@Bean @Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) { public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory); redisTemplate.setConnectionFactory(factory);
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
@ -31,4 +31,4 @@ public class RedisConfig {
redisTemplate.afterPropertiesSet(); redisTemplate.afterPropertiesSet();
return redisTemplate; return redisTemplate;
} }
} }

@ -0,0 +1,145 @@
package com.toesbieya.my.config;
import com.alibaba.fastjson.JSON;
import com.toesbieya.my.constant.SessionConstant;
import com.toesbieya.my.constant.SocketConstant;
import com.toesbieya.my.model.vo.SocketEventVo;
import com.toesbieya.my.module.WebSocketServer;
import com.toesbieya.my.utils.RedisUtil;
import com.toesbieya.my.utils.SessionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import java.util.List;
import java.util.Properties;
@Configuration
@Slf4j
public class RedisEventListenerConfig {
private WebSocketServer server;
@Autowired
public void setSocketServer(WebSocketServer server) {
this.server = server;
}
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory factory) {
modifyRedisEventConfig(factory);
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(factory);
addEventSendListener(container);
addExpireListener(container);
return container;
}
//发送消息的监听器
private void addEventSendListener(RedisMessageListenerContainer container) {
container.addMessageListener(
(message, bytes) -> {
SocketEventVo vo = JSON.parseObject(message.toString(), SocketEventVo.class);
if (vo == null) return;
int type = vo.getType();
String eventName = vo.getEvent();
Object data = vo.getData();
List<Integer> to = vo.getTo();
//登出消息
if (type == SocketConstant.REDIS_EVENT_LOGOUT) {
if (to != null) {
to.forEach(id -> server.logout(id, (String) data));
}
}
//指定用户
else if (type == SocketConstant.REDIS_EVENT_SPECIFIC) {
if (to != null) {
to.forEach(id -> server.sendEvent(eventName, id, data));
}
}
//广播消息
else if (type == SocketConstant.REDIS_EVENT_BROADCAST) {
server.broadcast(eventName, data);
}
},
new ChannelTopic(SocketConstant.REDIS_EVENT_TOPIC_SEND)
);
}
//key过期的监听器
private void addExpireListener(RedisMessageListenerContainer container) {
//监听key过期事件
String expireTopic = SessionConstant.REDIS_EXPIRE_TOPIC_PREFIX + SessionConstant.REDIS_NAMESPACE;
container.addMessageListener(
(message, bytes) -> {
String event = message.toString();
String channel = new String(message.getChannel());
if (!"del".equals(event) && !"expired".equals(event)
|| !channel.startsWith(expireTopic)) {
return;
}
String token = channel.replace(expireTopic, "");
Integer uid = SessionUtil.getUidFromToken(token);
server.logout(uid, "登陆信息过期,请重新登陆");
//删除离线表信息
RedisUtil.hdel(SocketConstant.REDIS_OFFLINE_USER, SessionConstant.REDIS_NAMESPACE + token);
},
new PatternTopic(expireTopic + "*")
);
}
//将redis的notify-keyspace-events配置改为Kgx
private void modifyRedisEventConfig(RedisConnectionFactory factory) {
RedisConnection connection = factory.getConnection();
try {
Properties config = connection.getConfig("notify-keyspace-events");
String notifyOptions =
config == null || config.isEmpty()
? ""
: config.getProperty(config.stringPropertyNames().iterator().next());
String customizedNotifyOptions = notifyOptions;
if (!customizedNotifyOptions.contains("K")) {
customizedNotifyOptions += "K";
}
boolean A = customizedNotifyOptions.contains("A");
if (!(A || customizedNotifyOptions.contains("g"))) {
customizedNotifyOptions += "g";
}
if (!(A || customizedNotifyOptions.contains("x"))) {
customizedNotifyOptions += "x";
}
if (!notifyOptions.equals(customizedNotifyOptions)) {
connection.setConfig("notify-keyspace-events", customizedNotifyOptions);
}
}
finally {
try {
connection.close();
}
catch (Exception ex) {
log.error("Error closing RedisConnection", ex);
}
}
}
}

@ -1,6 +1,18 @@
package com.toesbieya.my.constant; package com.toesbieya.my.constant;
public class SessionConstant { public class SessionConstant {
//session过期时间,单位秒
public static long EXPIRE = 3600 * 8;
//存储用户信息的键的前缀
public static String REDIS_NAMESPACE = "sessions:"; public static String REDIS_NAMESPACE = "sessions:";
//key过期事件的前缀
public static String REDIS_EXPIRE_TOPIC_PREFIX = "__keyspace@0__:";
//http headers中token的字段名
public static String TOKEN_KEY = "X-Token"; public static String TOKEN_KEY = "X-Token";
//区别无活动用户的时间间隔,单位秒
public static long NO_ACTION_INTERVAL = 1800;
} }

@ -1,14 +1,23 @@
package com.toesbieya.my.constant; package com.toesbieya.my.constant;
public class SocketConstant { public class SocketConstant {
public static String REDIS_EVENT_TOPIC_SEND = "socket:event:send"; //web-socket服务端订阅的redis主题名称
public static String REDIS_EVENT_TOPIC_SEND = "socket-event-send";
//指定用户
public static int REDIS_EVENT_SPECIFIC = 0; public static int REDIS_EVENT_SPECIFIC = 0;
//广播
public static int REDIS_EVENT_BROADCAST = 1; public static int REDIS_EVENT_BROADCAST = 1;
//登出
public static int REDIS_EVENT_LOGOUT = 2; public static int REDIS_EVENT_LOGOUT = 2;
public static String REDIS_ONLINE_NUM = "socket:online-num"; //存放于redis中的在线用户的ID集合的键
public static String REDIS_ONLINE_USER = "socket:online-user"; public static String REDIS_ONLINE_USER = "socket:online-user";
//存放于redis中的离线用户的离线时间的键
public static String REDIS_OFFLINE_USER = "socket:offline-user";
//登出事件
public static final String EVENT_LOGOUT = "logout"; public static final String EVENT_LOGOUT = "logout";
//新消息事件
public static final String EVENT_NEW_MESSAGE = "new-message"; public static final String EVENT_NEW_MESSAGE = "new-message";
} }

@ -21,22 +21,22 @@ import java.net.URLDecoder;
@RequestMapping("account") @RequestMapping("account")
public class AccountController { public class AccountController {
@Resource @Resource
private AccountService accountService; private AccountService service;
@PostMapping("login") @PostMapping("login")
public Result login(HttpServletRequest request, @Valid @RequestBody LoginParam param) { public Result login(HttpServletRequest request, @Valid @RequestBody LoginParam param) {
return accountService.login(param, IpUtil.getIp(request)); return service.login(param, IpUtil.getIp(request));
} }
@GetMapping("logout") @GetMapping("logout")
public Result logout(HttpServletRequest request) { public Result logout(HttpServletRequest request) {
UserVo user = SessionUtil.get(); UserVo user = SessionUtil.get();
return accountService.logout(user, IpUtil.getIp(request)); return service.logout(user, IpUtil.getIp(request));
} }
@PostMapping("register") @PostMapping("register")
public Result register(@Valid @RequestBody RegisterParam param) { public Result register(@Valid @RequestBody RegisterParam param) {
return accountService.register(param); return service.register(param);
} }
@PostMapping("updatePwd") @PostMapping("updatePwd")
@ -47,7 +47,7 @@ public class AccountController {
String errMsg = validateUpdatePwdParam(param); String errMsg = validateUpdatePwdParam(param);
if (errMsg != null) return Result.fail(errMsg); if (errMsg != null) return Result.fail(errMsg);
return accountService.updatePwd(param); return service.updatePwd(param);
} }
@GetMapping("updateAvatar") @GetMapping("updateAvatar")
@ -55,7 +55,7 @@ public class AccountController {
if (StringUtils.isEmpty(key)) return Result.fail("参数错误"); if (StringUtils.isEmpty(key)) return Result.fail("参数错误");
UserVo user = SessionUtil.get(); UserVo user = SessionUtil.get();
return accountService.updateAvatar(user, URLDecoder.decode(key, "utf-8")); return service.updateAvatar(user, URLDecoder.decode(key, "utf-8"));
} }
@GetMapping("validate") @GetMapping("validate")
@ -75,7 +75,7 @@ public class AccountController {
return Result.success(); return Result.success();
} }
return Result.success(accountService.checkName(name, id) ? null : "该用户名已存在"); return Result.success(service.checkName(name, id) ? null : "该用户名已存在");
} }
private String validateUpdatePwdParam(PasswordUpdateParam vo) { private String validateUpdatePwdParam(PasswordUpdateParam vo) {

@ -11,15 +11,15 @@ import javax.annotation.Resource;
@RequestMapping("document/history") @RequestMapping("document/history")
public class BizDocumentHistoryController { public class BizDocumentHistoryController {
@Resource @Resource
private BizDocumentHistoryService documentHistoryService; private BizDocumentHistoryService service;
@GetMapping("get") @GetMapping("get")
public Result get(@RequestParam("pid") String pid) { public Result get(@RequestParam("pid") String pid) {
return Result.success(documentHistoryService.getByPid(pid)); return Result.success(service.getByPid(pid));
} }
@PostMapping("search") @PostMapping("search")
public Result search(@RequestBody DocumentHistorySearch vo) { public Result search(@RequestBody DocumentHistorySearch vo) {
return Result.success(documentHistoryService.search(vo)); return Result.success(service.search(vo));
} }
} }

@ -1,6 +1,6 @@
package com.toesbieya.my.controller; package com.toesbieya.my.controller;
import com.toesbieya.my.enumeration.BizDocumentStatusEnum; import com.toesbieya.my.enumeration.DocStatusEnum;
import com.toesbieya.my.model.entity.BizPurchaseInbound; import com.toesbieya.my.model.entity.BizPurchaseInbound;
import com.toesbieya.my.model.entity.BizPurchaseInboundSub; import com.toesbieya.my.model.entity.BizPurchaseInboundSub;
import com.toesbieya.my.model.vo.UserVo; import com.toesbieya.my.model.vo.UserVo;
@ -15,98 +15,99 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
@RestController @RestController
@RequestMapping("purchase/inbound") @RequestMapping("document/purchase/inbound")
public class BizPurchaseInboundController { public class BizPurchaseInboundController {
@Resource @Resource
private BizPurchaseInboundService purchaseInboundService; private BizPurchaseInboundService service;
@GetMapping("getById") @GetMapping("getById")
public Result getById(@RequestParam String id) { public Result getById(@RequestParam String id) {
if (StringUtils.isEmpty(id)) return Result.fail("参数错误"); if (StringUtils.isEmpty(id)) return Result.fail("参数错误");
BizPurchaseInbound inbound = purchaseInboundService.getById(id); BizPurchaseInbound inbound = service.getById(id);
return inbound == null ? Result.fail("获取单据信息失败") : Result.success(inbound); return inbound == null ? Result.fail("获取单据信息失败") : Result.success(inbound);
} }
@GetMapping("getSubById") @GetMapping("getSubById")
public Result getSubById(@RequestParam String id) { public Result getSubById(@RequestParam String id) {
if (StringUtils.isEmpty(id)) return Result.fail("参数错误"); if (StringUtils.isEmpty(id)) return Result.fail("参数错误");
return Result.success(purchaseInboundService.getSubById(id)); return Result.success(service.getSubById(id));
} }
@PostMapping("search") @PostMapping("search")
public Result search(@RequestBody PurchaseInboundSearch vo) { public Result search(@RequestBody PurchaseInboundSearch vo) {
return Result.success(purchaseInboundService.search(vo)); return Result.success(service.search(vo));
} }
@PostMapping("export") @PostMapping("export")
public void export(@RequestBody PurchaseInboundSearch vo, HttpServletResponse response) throws Exception { public void export(@RequestBody PurchaseInboundSearch vo, HttpServletResponse response) throws Exception {
purchaseInboundService.export(vo, response); service.export(vo, response);
} }
@PostMapping("add") @PostMapping("add")
public Result add(@RequestBody BizPurchaseInbound inbound) { public Result add(@RequestBody BizPurchaseInbound vo) {
String errMsg = validateSub(inbound.getData()); String errMsg = validateSub(vo.getData());
if (errMsg != null) return Result.fail(errMsg); if (errMsg != null) return Result.fail(errMsg);
UserVo user = SessionUtil.get(); UserVo user = SessionUtil.get();
inbound.setCid(user.getId()); vo.setCid(user.getId());
inbound.setCname(user.getName()); vo.setCname(user.getName());
inbound.setCtime(System.currentTimeMillis()); vo.setCtime(System.currentTimeMillis());
inbound.setStatus(BizDocumentStatusEnum.DRAFT.getCode()); vo.setStatus(DocStatusEnum.DRAFT.getCode());
return purchaseInboundService.add(inbound); return service.add(vo);
} }
@PostMapping("update") @PostMapping("update")
public Result update(@RequestBody BizPurchaseInbound inbound) { public Result update(@RequestBody BizPurchaseInbound vo) {
String errMsg = validateUpdate(inbound); String errMsg = validateUpdate(vo);
if (errMsg == null) errMsg = validateSub(inbound.getData()); if (errMsg == null) errMsg = validateSub(vo.getData());
if (errMsg != null) return Result.fail(errMsg); if (errMsg != null) return Result.fail(errMsg);
return purchaseInboundService.update(inbound); return service.update(vo);
} }
@PostMapping("commit") @PostMapping("commit")
public Result commit(@RequestBody BizPurchaseInbound inbound) { public Result commit(@RequestBody BizPurchaseInbound vo) {
boolean isFirst = StringUtils.isEmpty(inbound.getId()); boolean isFirst = StringUtils.isEmpty(vo.getId());
String errMsg = validateSub(inbound.getData()); String errMsg = validateSub(vo.getData());
if (!isFirst && errMsg == null) errMsg = validateUpdate(inbound); if (!isFirst && errMsg == null) errMsg = validateUpdate(vo);
if (errMsg != null) return Result.fail(errMsg); if (errMsg != null) return Result.fail(errMsg);
inbound.setStatus(BizDocumentStatusEnum.WAIT_VERIFY.getCode()); vo.setStatus(DocStatusEnum.WAIT_VERIFY.getCode());
if (isFirst) { if (isFirst) {
UserVo user = SessionUtil.get(); UserVo user = SessionUtil.get();
inbound.setCid(user.getId()); vo.setCid(user.getId());
inbound.setCname(user.getName()); vo.setCname(user.getName());
inbound.setCtime(System.currentTimeMillis()); vo.setCtime(System.currentTimeMillis());
} }
return purchaseInboundService.commit(inbound); return service.commit(vo);
} }
@PostMapping("withdraw") @PostMapping("withdraw")
public Result withdraw(@RequestBody DocumentStatusUpdate vo) { public Result withdraw(@RequestBody DocumentStatusUpdate vo) {
return purchaseInboundService.withdraw(vo, SessionUtil.get()); return service.withdraw(vo, SessionUtil.get());
} }
@PostMapping("pass") @PostMapping("pass")
public Result pass(@RequestBody DocumentStatusUpdate vo) { public Result pass(@RequestBody DocumentStatusUpdate vo) {
if (StringUtils.isEmpty(vo.getPid())) return Result.fail("参数错误"); if (StringUtils.isEmpty(vo.getPid())) return Result.fail("参数错误");
return purchaseInboundService.pass(vo, SessionUtil.get()); return service.pass(vo, SessionUtil.get());
} }
@PostMapping("reject") @PostMapping("reject")
public Result reject(@RequestBody DocumentStatusUpdate vo) { public Result reject(@RequestBody DocumentStatusUpdate vo) {
return purchaseInboundService.reject(vo, SessionUtil.get()); return service.reject(vo, SessionUtil.get());
} }
@GetMapping("del") @GetMapping("del")
public Result del(@RequestParam String id) { public Result del(@RequestParam String id) {
if (StringUtils.isEmpty(id)) return Result.fail("参数错误"); if (StringUtils.isEmpty(id)) return Result.fail("参数错误");
return purchaseInboundService.del(id); return service.del(id);
} }
private String validateUpdate(BizPurchaseInbound main) { private String validateUpdate(BizPurchaseInbound main) {
@ -122,11 +123,15 @@ public class BizPurchaseInboundController {
private String validateSub(List<BizPurchaseInboundSub> list) { private String validateSub(List<BizPurchaseInboundSub> list) {
if (CollectionUtils.isEmpty(list)) return "采购入库单必须要有入库列表"; if (CollectionUtils.isEmpty(list)) return "采购入库单必须要有入库列表";
int i = 1; int len = list.size();
for (BizPurchaseInboundSub sub : list) { for (int i = 0; i < len; i++) {
if (sub.getNum() == null || sub.getNum() <= 0) return "第" + i + "个入库商品数量有误"; BizPurchaseInboundSub sub = list.get(i);
if (sub.getCid() == null || StringUtils.isEmpty(sub.getCname())) return "第" + i + "个入库商品数量有误"; if (sub.getNum() == null || sub.getNum().compareTo(BigDecimal.ZERO) <= 0) {
i++; return String.format("第%d个入库商品数量有误", i);
}
if (sub.getCid() == null || StringUtils.isEmpty(sub.getCname())) {
return String.format("第%d个入库商品分类有误", i);
}
} }
return null; return null;
} }

@ -1,6 +1,6 @@
package com.toesbieya.my.controller; package com.toesbieya.my.controller;
import com.toesbieya.my.enumeration.BizDocumentStatusEnum; import com.toesbieya.my.enumeration.DocStatusEnum;
import com.toesbieya.my.model.entity.BizPurchaseOrder; import com.toesbieya.my.model.entity.BizPurchaseOrder;
import com.toesbieya.my.model.entity.BizPurchaseOrderSub; import com.toesbieya.my.model.entity.BizPurchaseOrderSub;
import com.toesbieya.my.model.vo.UserVo; import com.toesbieya.my.model.vo.UserVo;
@ -15,104 +15,105 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
@RestController @RestController
@RequestMapping("purchase/order") @RequestMapping("document/purchase/order")
public class BizPurchaseOrderController { public class BizPurchaseOrderController {
@Resource @Resource
private BizPurchaseOrderService purchaseOrderService; private BizPurchaseOrderService service;
@GetMapping("getById") @GetMapping("getById")
public Result getById(@RequestParam String id) { public Result getById(@RequestParam String id) {
if (StringUtils.isEmpty(id)) return Result.fail("参数错误"); if (StringUtils.isEmpty(id)) return Result.fail("参数错误");
BizPurchaseOrder order = purchaseOrderService.getById(id); BizPurchaseOrder order = service.getById(id);
return order == null ? Result.fail("获取单据信息失败") : Result.success(order); return order == null ? Result.fail("获取单据信息失败") : Result.success(order);
} }
@GetMapping("getSubById") @GetMapping("getSubById")
public Result getSubById(@RequestParam String id) { public Result getSubById(@RequestParam String id) {
if (StringUtils.isEmpty(id)) return Result.fail("参数错误"); if (StringUtils.isEmpty(id)) return Result.fail("参数错误");
return Result.success(purchaseOrderService.getSubById(id)); return Result.success(service.getSubById(id));
} }
@PostMapping("search") @PostMapping("search")
public Result search(@RequestBody PurchaseOrderSearch vo) { public Result search(@RequestBody PurchaseOrderSearch vo) {
return Result.success(purchaseOrderService.search(vo)); return Result.success(service.search(vo));
} }
@PostMapping("export") @PostMapping("export")
public void export(@RequestBody PurchaseOrderSearch vo, HttpServletResponse response) throws Exception { public void export(@RequestBody PurchaseOrderSearch vo, HttpServletResponse response) throws Exception {
purchaseOrderService.export(vo, response); service.export(vo, response);
} }
@PostMapping("add") @PostMapping("add")
public Result add(@RequestBody BizPurchaseOrder order) { public Result add(@RequestBody BizPurchaseOrder vo) {
if (order.getSid() == null if (vo.getSid() == null
|| StringUtils.isEmpty(order.getSname()) || StringUtils.isEmpty(vo.getSname())
|| order.getTotal() == null) { || vo.getTotal() == null) {
return Result.fail("参数错误"); return Result.fail("参数错误");
} }
String errMsg = validateSub(order.getData()); String errMsg = validateSub(vo.getData());
if (errMsg != null) return Result.fail(errMsg); if (errMsg != null) return Result.fail(errMsg);
UserVo user = SessionUtil.get(); UserVo user = SessionUtil.get();
order.setCid(user.getId()); vo.setCid(user.getId());
order.setCname(user.getName()); vo.setCname(user.getName());
order.setCtime(System.currentTimeMillis()); vo.setCtime(System.currentTimeMillis());
order.setStatus(BizDocumentStatusEnum.DRAFT.getCode()); vo.setStatus(DocStatusEnum.DRAFT.getCode());
return purchaseOrderService.add(order); return service.add(vo);
} }
@PostMapping("update") @PostMapping("update")
public Result update(@RequestBody BizPurchaseOrder order) { public Result update(@RequestBody BizPurchaseOrder vo) {
String errMsg = validateUpdate(order); String errMsg = validateUpdate(vo);
if (errMsg == null) errMsg = validateSub(order.getData()); if (errMsg == null) errMsg = validateSub(vo.getData());
if (errMsg != null) return Result.fail(errMsg); if (errMsg != null) return Result.fail(errMsg);
return purchaseOrderService.update(order); return service.update(vo);
} }
@PostMapping("commit") @PostMapping("commit")
public Result commit(@RequestBody BizPurchaseOrder order) { public Result commit(@RequestBody BizPurchaseOrder vo) {
boolean isFirst = StringUtils.isEmpty(order.getId()); boolean isFirst = StringUtils.isEmpty(vo.getId());
String errMsg = validateSub(order.getData()); String errMsg = validateSub(vo.getData());
if (!isFirst && errMsg == null) errMsg = validateUpdate(order); if (!isFirst && errMsg == null) errMsg = validateUpdate(vo);
if (errMsg != null) return Result.fail(errMsg); if (errMsg != null) return Result.fail(errMsg);
order.setStatus(BizDocumentStatusEnum.WAIT_VERIFY.getCode()); vo.setStatus(DocStatusEnum.WAIT_VERIFY.getCode());
if (isFirst) { if (isFirst) {
UserVo user = SessionUtil.get(); UserVo user = SessionUtil.get();
order.setCid(user.getId()); vo.setCid(user.getId());
order.setCname(user.getName()); vo.setCname(user.getName());
order.setCtime(System.currentTimeMillis()); vo.setCtime(System.currentTimeMillis());
} }
return purchaseOrderService.commit(order); return service.commit(vo);
} }
@PostMapping("withdraw") @PostMapping("withdraw")
public Result withdraw(@RequestBody DocumentStatusUpdate vo) { public Result withdraw(@RequestBody DocumentStatusUpdate vo) {
return purchaseOrderService.withdraw(vo, SessionUtil.get()); return service.withdraw(vo, SessionUtil.get());
} }
@PostMapping("pass") @PostMapping("pass")
public Result pass(@RequestBody DocumentStatusUpdate vo) { public Result pass(@RequestBody DocumentStatusUpdate vo) {
return purchaseOrderService.pass(vo, SessionUtil.get()); return service.pass(vo, SessionUtil.get());
} }
@PostMapping("reject") @PostMapping("reject")
public Result reject(@RequestBody DocumentStatusUpdate vo) { public Result reject(@RequestBody DocumentStatusUpdate vo) {
return purchaseOrderService.reject(vo, SessionUtil.get()); return service.reject(vo, SessionUtil.get());
} }
@GetMapping("del") @GetMapping("del")
public Result del(@RequestParam String id) { public Result del(@RequestParam String id) {
if (StringUtils.isEmpty(id)) return Result.fail("参数错误"); if (StringUtils.isEmpty(id)) return Result.fail("参数错误");
return purchaseOrderService.del(id); return service.del(id);
} }
private String validateUpdate(BizPurchaseOrder main) { private String validateUpdate(BizPurchaseOrder main) {
@ -130,11 +131,15 @@ public class BizPurchaseOrderController {
private String validateSub(List<BizPurchaseOrderSub> list) { private String validateSub(List<BizPurchaseOrderSub> list) {
if (CollectionUtils.isEmpty(list)) return "采购订单必须要有采购列表"; if (CollectionUtils.isEmpty(list)) return "采购订单必须要有采购列表";
int i = 1; int len = list.size();
for (BizPurchaseOrderSub sub : list) { for (int i = 0; i < len; i++) {
if (sub.getPrice() == null || sub.getPrice() <= 0) return "第" + i + "个采购商品价格有误"; BizPurchaseOrderSub sub = list.get(i);
if (sub.getNum() == null || sub.getNum() <= 0) return "第" + i + "个采购商品数量有误"; if (sub.getNum() == null || sub.getNum().compareTo(BigDecimal.ZERO) <= 0) {
i++; return String.format("第%d个入库商品数量有误", i);
}
if (sub.getPrice() == null || sub.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
return String.format("第%d个采购商品价格有误", i);
}
} }
return null; return null;
} }

@ -1,6 +1,6 @@
package com.toesbieya.my.controller; package com.toesbieya.my.controller;
import com.toesbieya.my.enumeration.BizDocumentStatusEnum; import com.toesbieya.my.enumeration.DocStatusEnum;
import com.toesbieya.my.model.entity.BizSellOrder; import com.toesbieya.my.model.entity.BizSellOrder;
import com.toesbieya.my.model.entity.BizSellOrderSub; import com.toesbieya.my.model.entity.BizSellOrderSub;
import com.toesbieya.my.model.vo.UserVo; import com.toesbieya.my.model.vo.UserVo;
@ -15,106 +15,107 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
@RestController @RestController
@RequestMapping("sell/order") @RequestMapping("document/sell/order")
public class BizSellOrderController { public class BizSellOrderController {
@Resource @Resource
private BizSellOrderService sellOrderService; private BizSellOrderService service;
@GetMapping("getById") @GetMapping("getById")
public Result getById(@RequestParam String id) { public Result getById(@RequestParam String id) {
if (StringUtils.isEmpty(id)) return Result.fail("参数错误"); if (StringUtils.isEmpty(id)) return Result.fail("参数错误");
BizSellOrder order = sellOrderService.getById(id); BizSellOrder order = service.getById(id);
return order == null ? Result.fail("获取单据信息失败") : Result.success(order); return order == null ? Result.fail("获取单据信息失败") : Result.success(order);
} }
@GetMapping("getSubById") @GetMapping("getSubById")
public Result getSubById(@RequestParam String id) { public Result getSubById(@RequestParam String id) {
if (StringUtils.isEmpty(id)) return Result.fail("参数错误"); if (StringUtils.isEmpty(id)) return Result.fail("参数错误");
return Result.success(sellOrderService.getSubById(id)); return Result.success(service.getSubById(id));
} }
@PostMapping("search") @PostMapping("search")
public Result search(@RequestBody SellOrderSearch vo) { public Result search(@RequestBody SellOrderSearch vo) {
return Result.success(sellOrderService.search(vo)); return Result.success(service.search(vo));
} }
@PostMapping("export") @PostMapping("export")
public void export(@RequestBody SellOrderSearch vo, HttpServletResponse response) throws Exception { public void export(@RequestBody SellOrderSearch vo, HttpServletResponse response) throws Exception {
sellOrderService.export(vo, response); service.export(vo, response);
} }
@PostMapping("add") @PostMapping("add")
public Result add(@RequestBody BizSellOrder order) { public Result add(@RequestBody BizSellOrder vo) {
if (order.getCustomer_id() == null if (vo.getCustomer_id() == null
|| StringUtils.isEmpty(order.getCustomer_name()) || StringUtils.isEmpty(vo.getCustomer_name())
|| order.getTotal() == null) { || vo.getTotal() == null) {
return Result.fail("参数错误"); return Result.fail("参数错误");
} }
String errMsg = validateSub(order.getData()); String errMsg = validateSub(vo.getData());
if (errMsg != null) return Result.fail(errMsg); if (errMsg != null) return Result.fail(errMsg);
UserVo user = SessionUtil.get(); UserVo user = SessionUtil.get();
order.setCid(user.getId()); vo.setCid(user.getId());
order.setCname(user.getName()); vo.setCname(user.getName());
order.setCtime(System.currentTimeMillis()); vo.setCtime(System.currentTimeMillis());
order.setStatus(BizDocumentStatusEnum.DRAFT.getCode()); vo.setStatus(DocStatusEnum.DRAFT.getCode());
return sellOrderService.add(order); return service.add(vo);
} }
@PostMapping("update") @PostMapping("update")
public Result update(@RequestBody BizSellOrder order) { public Result update(@RequestBody BizSellOrder vo) {
String errMsg = validateUpdate(order); String errMsg = validateUpdate(vo);
if (errMsg == null) errMsg = validateSub(order.getData()); if (errMsg == null) errMsg = validateSub(vo.getData());
if (errMsg != null) return Result.fail(errMsg); if (errMsg != null) return Result.fail(errMsg);
return sellOrderService.update(order); return service.update(vo);
} }
@PostMapping("commit") @PostMapping("commit")
public Result commit(@RequestBody BizSellOrder order) { public Result commit(@RequestBody BizSellOrder vo) {
boolean isFirst = StringUtils.isEmpty(order.getId()); boolean isFirst = StringUtils.isEmpty(vo.getId());
String errMsg = validateSub(order.getData()); String errMsg = validateSub(vo.getData());
if (!isFirst && errMsg == null) errMsg = validateUpdate(order); if (!isFirst && errMsg == null) errMsg = validateUpdate(vo);
if (errMsg != null) return Result.fail(errMsg); if (errMsg != null) return Result.fail(errMsg);
order.setStatus(BizDocumentStatusEnum.WAIT_VERIFY.getCode()); vo.setStatus(DocStatusEnum.WAIT_VERIFY.getCode());
if (isFirst) { if (isFirst) {
UserVo user = SessionUtil.get(); UserVo user = SessionUtil.get();
order.setCid(user.getId()); vo.setCid(user.getId());
order.setCname(user.getName()); vo.setCname(user.getName());
order.setCtime(System.currentTimeMillis()); vo.setCtime(System.currentTimeMillis());
} }
return sellOrderService.commit(order); return service.commit(vo);
} }
@PostMapping("withdraw") @PostMapping("withdraw")
public Result withdraw(@RequestBody DocumentStatusUpdate vo) { public Result withdraw(@RequestBody DocumentStatusUpdate vo) {
return sellOrderService.withdraw(vo, SessionUtil.get()); return service.withdraw(vo, SessionUtil.get());
} }
@PostMapping("pass") @PostMapping("pass")
public Result pass(@RequestBody DocumentStatusUpdate vo) { public Result pass(@RequestBody DocumentStatusUpdate vo) {
return sellOrderService.pass(vo, SessionUtil.get()); return service.pass(vo, SessionUtil.get());
} }
@PostMapping("reject") @PostMapping("reject")
public Result reject(@RequestBody DocumentStatusUpdate vo) { public Result reject(@RequestBody DocumentStatusUpdate vo) {
return sellOrderService.reject(vo, SessionUtil.get()); return service.reject(vo, SessionUtil.get());
} }
@GetMapping("del") @GetMapping("del")
public Result del(@RequestParam String id) { public Result del(@RequestParam String id) {
if (StringUtils.isEmpty(id)) return Result.fail("参数错误"); if (StringUtils.isEmpty(id)) return Result.fail("参数错误");
return sellOrderService.del(id); return service.del(id);
} }
private String validateUpdate(BizSellOrder main) { private String validateUpdate(BizSellOrder main) {
@ -132,11 +133,15 @@ public class BizSellOrderController {
private String validateSub(List<BizSellOrderSub> list) { private String validateSub(List<BizSellOrderSub> list) {
if (CollectionUtils.isEmpty(list)) return "销售订单必须要有销售列表"; if (CollectionUtils.isEmpty(list)) return "销售订单必须要有销售列表";
int i = 1; int len = list.size();
for (BizSellOrderSub sub : list) { for (int i = 0; i < len; i++) {
if (sub.getPrice() == null || sub.getPrice() <= 0) return "第" + i + "个销售商品价格有误"; BizSellOrderSub sub = list.get(i);
if (sub.getNum() == null || sub.getNum() <= 0) return "第" + i + "个销售商品数量有误"; if (sub.getNum() == null || sub.getNum().compareTo(BigDecimal.ZERO) <= 0) {
i++; return String.format("第%d个销售商品数量有误", i);
}
if (sub.getPrice() == null || sub.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
return String.format("第%d个销售商品价格有误", i);
}
} }
return null; return null;
} }

@ -1,6 +1,6 @@
package com.toesbieya.my.controller; package com.toesbieya.my.controller;
import com.toesbieya.my.enumeration.BizDocumentStatusEnum; import com.toesbieya.my.enumeration.DocStatusEnum;
import com.toesbieya.my.model.entity.BizSellOutbound; import com.toesbieya.my.model.entity.BizSellOutbound;
import com.toesbieya.my.model.entity.BizSellOutboundSub; import com.toesbieya.my.model.entity.BizSellOutboundSub;
import com.toesbieya.my.model.vo.UserVo; import com.toesbieya.my.model.vo.UserVo;
@ -15,100 +15,101 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
@RestController @RestController
@RequestMapping("sell/outbound") @RequestMapping("document/sell/outbound")
public class BizSellOutboundController { public class BizSellOutboundController {
@Resource @Resource
private BizSellOutboundService sellOutboundService; private BizSellOutboundService service;
@GetMapping("getById") @GetMapping("getById")
public Result getById(@RequestParam String id) { public Result getById(@RequestParam String id) {
if (StringUtils.isEmpty(id)) return Result.fail("参数错误"); if (StringUtils.isEmpty(id)) return Result.fail("参数错误");
BizSellOutbound outbound = sellOutboundService.getById(id); BizSellOutbound outbound = service.getById(id);
return outbound == null ? Result.fail("获取单据信息失败") : Result.success(outbound); return outbound == null ? Result.fail("获取单据信息失败") : Result.success(outbound);
} }
@GetMapping("getSubById") @GetMapping("getSubById")
public Result getSubById(@RequestParam String id) { public Result getSubById(@RequestParam String id) {
if (StringUtils.isEmpty(id)) return Result.fail("参数错误"); if (StringUtils.isEmpty(id)) return Result.fail("参数错误");
return Result.success(sellOutboundService.getSubById(id)); return Result.success(service.getSubById(id));
} }
@PostMapping("search") @PostMapping("search")
public Result search(@RequestBody SellOutboundSearch vo) { public Result search(@RequestBody SellOutboundSearch vo) {
return Result.success(sellOutboundService.search(vo)); return Result.success(service.search(vo));
} }
@PostMapping("export") @PostMapping("export")
public void export(@RequestBody SellOutboundSearch vo, HttpServletResponse response) throws Exception { public void export(@RequestBody SellOutboundSearch vo, HttpServletResponse response) throws Exception {
sellOutboundService.export(vo, response); service.export(vo, response);
} }
@PostMapping("add") @PostMapping("add")
public Result add(@RequestBody BizSellOutbound outbound) { public Result add(@RequestBody BizSellOutbound vo) {
String errMsg = validateSub(outbound.getData()); String errMsg = validateSub(vo.getData());
if (errMsg != null) return Result.fail(errMsg); if (errMsg != null) return Result.fail(errMsg);
UserVo user = SessionUtil.get(); UserVo user = SessionUtil.get();
outbound.setCid(user.getId()); vo.setCid(user.getId());
outbound.setCname(user.getName()); vo.setCname(user.getName());
outbound.setCtime(System.currentTimeMillis()); vo.setCtime(System.currentTimeMillis());
outbound.setStatus(BizDocumentStatusEnum.DRAFT.getCode()); vo.setStatus(DocStatusEnum.DRAFT.getCode());
return sellOutboundService.add(outbound); return service.add(vo);
} }
@PostMapping("update") @PostMapping("update")
public Result update(@RequestBody BizSellOutbound outbound) { public Result update(@RequestBody BizSellOutbound vo) {
String errMsg = validateUpdate(outbound); String errMsg = validateUpdate(vo);
if (errMsg == null) errMsg = validateSub(outbound.getData()); if (errMsg == null) errMsg = validateSub(vo.getData());
if (errMsg != null) return Result.fail(errMsg); if (errMsg != null) return Result.fail(errMsg);
return sellOutboundService.update(outbound); return service.update(vo);
} }
@PostMapping("commit") @PostMapping("commit")
public Result commit(@RequestBody BizSellOutbound outbound) { public Result commit(@RequestBody BizSellOutbound vo) {
boolean isFirst = StringUtils.isEmpty(outbound.getId()); boolean isFirst = StringUtils.isEmpty(vo.getId());
String errMsg = validateSub(outbound.getData()); String errMsg = validateSub(vo.getData());
if (!isFirst && errMsg == null) errMsg = validateUpdate(outbound); if (!isFirst && errMsg == null) errMsg = validateUpdate(vo);
if (errMsg != null) return Result.fail(errMsg); if (errMsg != null) return Result.fail(errMsg);
outbound.setStatus(BizDocumentStatusEnum.WAIT_VERIFY.getCode()); vo.setStatus(DocStatusEnum.WAIT_VERIFY.getCode());
if (isFirst) { if (isFirst) {
UserVo user = SessionUtil.get(); UserVo user = SessionUtil.get();
outbound.setCid(user.getId()); vo.setCid(user.getId());
outbound.setCname(user.getName()); vo.setCname(user.getName());
outbound.setCtime(System.currentTimeMillis()); vo.setCtime(System.currentTimeMillis());
} }
return sellOutboundService.commit(outbound); return service.commit(vo);
} }
@PostMapping("withdraw") @PostMapping("withdraw")
public Result withdraw(@RequestBody DocumentStatusUpdate vo) { public Result withdraw(@RequestBody DocumentStatusUpdate vo) {
return sellOutboundService.withdraw(vo, SessionUtil.get()); return service.withdraw(vo, SessionUtil.get());
} }
@PostMapping("pass") @PostMapping("pass")
public Result pass(@RequestBody DocumentStatusUpdate vo) { public Result pass(@RequestBody DocumentStatusUpdate vo) {
if (StringUtils.isEmpty(vo.getPid())) return Result.fail("参数错误"); if (StringUtils.isEmpty(vo.getPid())) return Result.fail("参数错误");
return sellOutboundService.pass(vo, SessionUtil.get()); return service.pass(vo, SessionUtil.get());
} }
@PostMapping("reject") @PostMapping("reject")
public Result reject(@RequestBody DocumentStatusUpdate vo) { public Result reject(@RequestBody DocumentStatusUpdate vo) {
return sellOutboundService.reject(vo, SessionUtil.get()); return service.reject(vo, SessionUtil.get());
} }
@GetMapping("del") @GetMapping("del")
public Result del(@RequestParam String id) { public Result del(@RequestParam String id) {
if (StringUtils.isEmpty(id)) return Result.fail("参数错误"); if (StringUtils.isEmpty(id)) return Result.fail("参数错误");
return sellOutboundService.del(id); return service.del(id);
} }
private String validateUpdate(BizSellOutbound main) { private String validateUpdate(BizSellOutbound main) {
@ -123,13 +124,21 @@ public class BizSellOutboundController {
} }
private String validateSub(List<BizSellOutboundSub> list) { private String validateSub(List<BizSellOutboundSub> list) {
if (CollectionUtils.isEmpty(list)) return "销售出库单必须要有出库列表"; if (CollectionUtils.isEmpty(list)) {
int i = 1; return "销售出库单必须要有出库列表";
for (BizSellOutboundSub sub : list) { }
if (sub.getSid() == null) return "第" + i + "个出库商品没有选择库存"; int len = list.size();
if (sub.getNum() == null || sub.getNum() <= 0) return "第" + i + "个出库商品数量有误"; for (int i = 0; i < len; i++) {
if (sub.getCid() == null || StringUtils.isEmpty(sub.getCname())) return "第" + i + "个出库商品数量有误"; BizSellOutboundSub sub = list.get(i);
i++; if (sub.getSid() == null) {
return String.format("第%d个出库商品没有选择库存", i);
}
if (sub.getNum() == null || sub.getNum().compareTo(BigDecimal.ZERO) <= 0) {
return String.format("第%d个出库商品数量有误", i);
}
if (sub.getCid() == null || StringUtils.isEmpty(sub.getCname())) {
return String.format("第%d个出库商品数量有误", i);
}
} }
return null; return null;
} }

@ -13,27 +13,27 @@ import javax.servlet.http.HttpServletResponse;
@RequestMapping("stock/current") @RequestMapping("stock/current")
public class BizStockController { public class BizStockController {
@Resource @Resource
private BizStockService stockService; private BizStockService service;
@PostMapping("search") @PostMapping("search")
public Result search(@RequestBody StockSearch vo) { public Result search(@RequestBody StockSearch vo) {
return Result.success(stockService.search(vo)); return Result.success(service.search(vo));
} }
@GetMapping("getDetail") @GetMapping("getDetail")
public Result getDetail(@RequestParam String cid) { public Result getDetail(@RequestParam String cids) {
if (StringUtils.isEmpty(cid)) return Result.fail("参数错误"); if (StringUtils.isEmpty(cids)) return Result.fail("参数错误");
return Result.success(stockService.getDetail(cid)); return Result.success(service.getDetail(cids));
} }
@GetMapping("getDetailById") @GetMapping("getDetailById")
public Result getDetailById(@RequestParam String ids) { public Result getDetailById(@RequestParam String ids) {
if (StringUtils.isEmpty(ids)) return Result.fail("参数错误"); if (StringUtils.isEmpty(ids)) return Result.fail("参数错误");
return Result.success(stockService.getDetailById(ids)); return Result.success(service.getDetailById(ids));
} }
@PostMapping("export") @PostMapping("export")
public void export(@RequestBody StockSearch vo, HttpServletResponse response) throws Exception { public void export(@RequestBody StockSearch vo, HttpServletResponse response) throws Exception {
stockService.export(vo, response); service.export(vo, response);
} }
} }

@ -15,7 +15,6 @@ import java.net.URLDecoder;
@RequestMapping("file") @RequestMapping("file")
@Slf4j @Slf4j
public class FileController { public class FileController {
@GetMapping("delete") @GetMapping("delete")
public Result delete(@RequestParam String url) throws UnsupportedEncodingException { public Result delete(@RequestParam String url) throws UnsupportedEncodingException {
QiniuUtil.delete(URLDecoder.decode(url, "utf-8")); QiniuUtil.delete(URLDecoder.decode(url, "utf-8"));

@ -1,11 +1,11 @@
package com.toesbieya.my.enumeration; package com.toesbieya.my.enumeration;
public enum BizDocumentFinishEnum { public enum DocFinishEnum {
TO_BE_STARTED(0), UNDERWAY(1), FINISHED(2); TO_BE_STARTED(0), UNDERWAY(1), FINISHED(2);
private final int code; private final int code;
BizDocumentFinishEnum(int code) { DocFinishEnum(int code) {
this.code = code; this.code = code;
} }

@ -1,11 +1,11 @@
package com.toesbieya.my.enumeration; package com.toesbieya.my.enumeration;
public enum BizDocumentHistoryEnum { public enum DocHistoryEnum {
WITHDRAW(0), COMMIT(1), PASS(2), REJECT(3); WITHDRAW(0), COMMIT(1), PASS(2), REJECT(3);
private final int code; private final int code;
BizDocumentHistoryEnum(int code) { DocHistoryEnum(int code) {
this.code = code; this.code = code;
} }

@ -1,11 +1,11 @@
package com.toesbieya.my.enumeration; package com.toesbieya.my.enumeration;
public enum BizDocumentStatusEnum { public enum DocStatusEnum {
DRAFT(0), WAIT_VERIFY(1), VERIFIED(2); DRAFT(0), WAIT_VERIFY(1), VERIFIED(2);
private final int code; private final int code;
BizDocumentStatusEnum(int code) { DocStatusEnum(int code) {
this.code = code; this.code = code;
} }

@ -2,7 +2,6 @@ package com.toesbieya.my.interceptor;
import com.toesbieya.my.model.vo.UserVo; import com.toesbieya.my.model.vo.UserVo;
import com.toesbieya.my.module.PermissionModule; import com.toesbieya.my.module.PermissionModule;
import com.toesbieya.my.module.request.RequestModule;
import com.toesbieya.my.utils.*; import com.toesbieya.my.utils.*;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
@ -15,16 +14,8 @@ public class SecurityInterceptor implements HandlerInterceptor {
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String url = request.getServletPath(); String url = request.getServletPath();
String method = request.getMethod();
String ip = IpUtil.getIp(request); String ip = IpUtil.getIp(request);
if (!RequestModule.urlExistMapping(url, method)) {
WebUtil.responseJson(response, Result.notfound());
log.error("请求地址不存在:{},{},IP:{}", url, method, ip);
ThreadUtil.clearUser();
return false;
}
UserVo user = SessionUtil.get(request); UserVo user = SessionUtil.get(request);
if (user == null) { if (user == null) {

@ -11,5 +11,5 @@ public interface BizDocumentHistoryMapper {
List<BizDocumentHistory> search(DocumentHistorySearch vo); List<BizDocumentHistory> search(DocumentHistorySearch vo);
int add(BizDocumentHistory history); int insert(BizDocumentHistory history);
} }

@ -17,7 +17,7 @@ public interface BizPurchaseInboundMapper {
List<PurchaseInboundExport> export(PurchaseInboundSearch vo); List<PurchaseInboundExport> export(PurchaseInboundSearch vo);
int add(BizPurchaseInbound param); int insert(BizPurchaseInbound param);
void addSub(List<BizPurchaseInboundSub> list); void addSub(List<BizPurchaseInboundSub> list);

@ -2,11 +2,11 @@ package com.toesbieya.my.mapper;
import com.toesbieya.my.model.entity.BizPurchaseOrder; import com.toesbieya.my.model.entity.BizPurchaseOrder;
import com.toesbieya.my.model.entity.BizPurchaseOrderSub; import com.toesbieya.my.model.entity.BizPurchaseOrderSub;
import com.toesbieya.my.model.entity.StatProfitGoods;
import com.toesbieya.my.model.vo.export.PurchaseOrderExport; import com.toesbieya.my.model.vo.export.PurchaseOrderExport;
import com.toesbieya.my.model.vo.search.PurchaseOrderSearch; import com.toesbieya.my.model.vo.search.PurchaseOrderSearch;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
public interface BizPurchaseOrderMapper { public interface BizPurchaseOrderMapper {
@ -18,13 +18,13 @@ public interface BizPurchaseOrderMapper {
List<PurchaseOrderExport> export(PurchaseOrderSearch vo); List<PurchaseOrderExport> export(PurchaseOrderSearch vo);
int add(BizPurchaseOrder param); int insert(BizPurchaseOrder param);
void addSub(List<BizPurchaseOrderSub> list); void addSub(List<BizPurchaseOrderSub> list);
int update(BizPurchaseOrder param); int update(BizPurchaseOrder param);
int updateSubRemainNum(@Param("id") Integer id, @Param("remain_num") double remain_num); int updateSubRemainNum(@Param("id") Integer id, @Param("remain_num") BigDecimal remain_num);
int pass(@Param("id") String id, @Param("vid") Integer vid, @Param("vname") String vname, @Param("vtime") long vtime); int pass(@Param("id") String id, @Param("vid") Integer vid, @Param("vname") String vname, @Param("vtime") long vtime);
@ -35,10 +35,4 @@ public interface BizPurchaseOrderMapper {
void delSubByPid(@Param("pid") String pid); void delSubByPid(@Param("pid") String pid);
int updateFinish(@Param("id") String id, @Param("finish") Integer finish, @Param("ftime") Long ftime); int updateFinish(@Param("id") String id, @Param("finish") Integer finish, @Param("ftime") Long ftime);
double getDailyTotalPurchasePrice(@Param("start") Long start, @Param("end") Long end);
List<StatProfitGoods> getDailyProfitGoods(@Param("start") long start, @Param("end") long end);
Integer getLastDayFinishOrderNum();
} }

@ -2,11 +2,11 @@ package com.toesbieya.my.mapper;
import com.toesbieya.my.model.entity.BizSellOrder; import com.toesbieya.my.model.entity.BizSellOrder;
import com.toesbieya.my.model.entity.BizSellOrderSub; import com.toesbieya.my.model.entity.BizSellOrderSub;
import com.toesbieya.my.model.entity.StatProfitGoods;
import com.toesbieya.my.model.vo.export.SellOrderExport; import com.toesbieya.my.model.vo.export.SellOrderExport;
import com.toesbieya.my.model.vo.search.SellOrderSearch; import com.toesbieya.my.model.vo.search.SellOrderSearch;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
public interface BizSellOrderMapper { public interface BizSellOrderMapper {
@ -18,13 +18,13 @@ public interface BizSellOrderMapper {
List<SellOrderExport> export(SellOrderSearch vo); List<SellOrderExport> export(SellOrderSearch vo);
int add(BizSellOrder param); int insert(BizSellOrder param);
void addSub(List<BizSellOrderSub> list); void addSub(List<BizSellOrderSub> list);
int update(BizSellOrder param); int update(BizSellOrder param);
int updateSubRemainNum(@Param("id") Integer id, @Param("remain_num") double remain_num); int updateSubRemainNum(@Param("id") Integer id, @Param("remain_num") BigDecimal remain_num);
int pass(@Param("id") String id, @Param("vid") Integer vid, @Param("vname") String vname, @Param("vtime") long vtime); int pass(@Param("id") String id, @Param("vid") Integer vid, @Param("vname") String vname, @Param("vtime") long vtime);
@ -35,10 +35,4 @@ public interface BizSellOrderMapper {
void delSubByPid(@Param("pid") String pid); void delSubByPid(@Param("pid") String pid);
int updateFinish(@Param("id") String id, @Param("finish") Integer finish, @Param("ftime") Long ftime); int updateFinish(@Param("id") String id, @Param("finish") Integer finish, @Param("ftime") Long ftime);
double getDailyTotalPurchasePrice(@Param("start") Long start, @Param("end") Long end);
List<StatProfitGoods> getDailyProfitGoods(@Param("start") long start, @Param("end") long end);
Integer getLastDayFinishOrderNum();
} }

@ -17,7 +17,7 @@ public interface BizSellOutboundMapper {
List<SellOutboundExport> export(SellOutboundSearch vo); List<SellOutboundExport> export(SellOutboundSearch vo);
int add(BizSellOutbound param); int insert(BizSellOutbound param);
void addSub(List<BizSellOutboundSub> list); void addSub(List<BizSellOutboundSub> list);

@ -6,26 +6,19 @@ import com.toesbieya.my.model.vo.result.StockSearchResult;
import com.toesbieya.my.model.vo.search.StockSearch; import com.toesbieya.my.model.vo.search.StockSearch;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
public interface BizStockMapper { public interface BizStockMapper {
List<StockSearchResult> search(StockSearch vo); List<StockSearchResult> search(StockSearch vo);
List<BizStock> getDetail(@Param("cid") String cid); List<BizStock> getDetail(@Param("cids") String cids);
List<BizStock> getDetailById(@Param("ids") String ids); List<BizStock> getDetailById(@Param("ids") String ids);
List<StockExport> export(StockSearch vo); List<StockExport> export(StockSearch vo);
int deleteByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(BizStock record);
int updateByPrimaryKey(BizStock record);
int updateBatchSelective(List<BizStock> list);
int batchInsert(@Param("list") List<BizStock> list); int batchInsert(@Param("list") List<BizStock> list);
int outbound(@Param("id") Integer id, @Param("num") Double num); int outbound(@Param("id") Integer id, @Param("num") BigDecimal num);
} }

@ -5,6 +5,7 @@ import com.toesbieya.my.model.entity.StatProfitGoods;
import com.toesbieya.my.model.entity.StatProfitTotal; import com.toesbieya.my.model.entity.StatProfitTotal;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
public interface StatisticMapper { public interface StatisticMapper {
@ -18,11 +19,23 @@ public interface StatisticMapper {
boolean checkDailyFinishOrderExist(@Param("time") long time); boolean checkDailyFinishOrderExist(@Param("time") long time);
int insertFinishOrder(StatFinishOrder param);
boolean checkDailyProfitExist(@Param("time") long time); boolean checkDailyProfitExist(@Param("time") long time);
int insertFinishOrder(StatFinishOrder param);
int insertProfitTotal(StatProfitTotal param); int insertProfitTotal(StatProfitTotal param);
int insertProfitGoodsBatch(@Param("list") List<StatProfitGoods> list); 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();
} }

@ -2,11 +2,13 @@ package com.toesbieya.my.model.entity;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
@Data @Data
public class BizDocumentSub { public class BizDocumentSub {
private Integer id; private Integer id;
private String pid; private String pid;
private Integer cid; private Integer cid;
private String cname; private String cname;
private Double num; private BigDecimal num;
} }

@ -4,6 +4,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.ToString; import lombok.ToString;
import java.math.BigDecimal;
@Data @Data
@ToString(callSuper = true) @ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ -12,5 +14,5 @@ public class BizPurchaseOrder extends BizDocument<BizPurchaseOrderSub> {
private String sname; private String sname;
private Integer finish; private Integer finish;
private Long ftime; private Long ftime;
private Double total; private BigDecimal total;
} }

@ -4,10 +4,12 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.ToString; import lombok.ToString;
import java.math.BigDecimal;
@Data @Data
@ToString(callSuper = true) @ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class BizPurchaseOrderSub extends BizDocumentSub { public class BizPurchaseOrderSub extends BizDocumentSub {
private Double price; private BigDecimal price;
private Double remain_num; private BigDecimal remain_num;
} }

@ -4,6 +4,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.ToString; import lombok.ToString;
import java.math.BigDecimal;
@Data @Data
@ToString(callSuper = true) @ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ -12,5 +14,5 @@ public class BizSellOrder extends BizDocument<BizSellOrderSub> {
private String customer_name; private String customer_name;
private Integer finish; private Integer finish;
private Long ftime; private Long ftime;
private Double total; private BigDecimal total;
} }

@ -4,10 +4,12 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.ToString; import lombok.ToString;
import java.math.BigDecimal;
@Data @Data
@ToString(callSuper = true) @ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class BizSellOrderSub extends BizDocumentSub { public class BizSellOrderSub extends BizDocumentSub {
private Double price; private BigDecimal price;
private Double remain_num; private BigDecimal remain_num;
} }

@ -5,6 +5,8 @@ import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data @Data
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@ -13,8 +15,8 @@ public class BizStock {
private Integer id; private Integer id;
private Integer cid; private Integer cid;
private String cname; private String cname;
private Double num; private BigDecimal num;
private Double price; private BigDecimal price;
private Long ctime; private Long ctime;
private String cgrkid; private String cgrkid;
private String cgddid; private String cgddid;

@ -2,11 +2,13 @@ package com.toesbieya.my.model.entity;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
@Data @Data
public class StatProfitTotal { public class StatProfitTotal {
private Integer id; private Integer id;
private Double purchase; private BigDecimal purchase;
private Double sell; private BigDecimal sell;
private Double profit; private BigDecimal profit;
private Long time; private Long time;
} }

@ -1,10 +0,0 @@
package com.toesbieya.my.model.vo;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
@Data
public class IpResultVo {
private Integer code;
private JSONObject data;
}

@ -0,0 +1,21 @@
package com.toesbieya.my.model.vo;
import com.toesbieya.my.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;
}

@ -0,0 +1,16 @@
package com.toesbieya.my.model.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SocketOfflineVo {
//用户的sessionKey
private String key;
//断开时间
private Long time;
}

@ -5,6 +5,8 @@ import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
@Data @Data
public class StockExport { public class StockExport {
@ExcelIgnore @ExcelIgnore
@ -20,11 +22,11 @@ public class StockExport {
@ExcelProperty(value = "库存总数", index = 2) @ExcelProperty(value = "库存总数", index = 2)
@ColumnWidth(20) @ColumnWidth(20)
private double total_num; private BigDecimal total_num;
@ExcelProperty(value = "库存总值", index = 3) @ExcelProperty(value = "库存总值", index = 3)
@ColumnWidth(20) @ColumnWidth(20)
private double total_price; private BigDecimal total_price;
@ExcelProperty(value = "采购订单号", index = 4) @ExcelProperty(value = "采购订单号", index = 4)
@ColumnWidth(20) @ColumnWidth(20)
@ -32,11 +34,11 @@ public class StockExport {
@ExcelProperty(value = "采购单价", index = 5) @ExcelProperty(value = "采购单价", index = 5)
@ColumnWidth(20) @ColumnWidth(20)
private double cg_price; private BigDecimal cg_price;
@ExcelProperty(value = "采购数量", index = 6) @ExcelProperty(value = "采购数量", index = 6)
@ColumnWidth(20) @ColumnWidth(20)
private double cg_num; private BigDecimal cg_num;
@ExcelProperty(value = "采购入库单号", index = 7) @ExcelProperty(value = "采购入库单号", index = 7)
@ColumnWidth(20) @ColumnWidth(20)
@ -48,5 +50,5 @@ public class StockExport {
@ExcelProperty(value = "入库数量", index = 9) @ExcelProperty(value = "入库数量", index = 9)
@ColumnWidth(20) @ColumnWidth(20)
private double rk_num; private BigDecimal rk_num;
} }

@ -2,10 +2,12 @@ package com.toesbieya.my.model.vo.result;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
@Data @Data
public class StockSearchResult { public class StockSearchResult {
private Integer cid; private Integer cid;
private String cname; private String cname;
private Double total_num; private BigDecimal total_num;
private Double total_price; private BigDecimal total_price;
} }

@ -2,10 +2,12 @@ package com.toesbieya.my.model.vo.statictis;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
@Data @Data
public class FourBlockStat { public class FourBlockStat {
private int online; private long online;
private double purchase; private BigDecimal purchase;
private double sell; private BigDecimal sell;
private double profit; private BigDecimal profit;
} }

@ -4,6 +4,7 @@ import com.toesbieya.my.model.entity.SysResource;
import com.toesbieya.my.model.vo.UserVo; import com.toesbieya.my.model.vo.UserVo;
import com.toesbieya.my.service.SysResourceService; import com.toesbieya.my.service.SysResourceService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -14,6 +15,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@Slf4j @Slf4j
@Component
public class PermissionModule { public class PermissionModule {
private final static ConcurrentHashMap<String, Integer> urlMap = new ConcurrentHashMap<>(128); private final static ConcurrentHashMap<String, Integer> urlMap = new ConcurrentHashMap<>(128);
private final static ConcurrentHashMap<String, Integer> adminUrlMap = new ConcurrentHashMap<>(128); private final static ConcurrentHashMap<String, Integer> adminUrlMap = new ConcurrentHashMap<>(128);

@ -6,7 +6,10 @@ import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.OnConnect; import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect; import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent; import com.corundumstudio.socketio.annotation.OnEvent;
import com.toesbieya.my.constant.SessionConstant;
import com.toesbieya.my.constant.SocketConstant; import com.toesbieya.my.constant.SocketConstant;
import com.toesbieya.my.model.vo.SocketOfflineVo;
import com.toesbieya.my.utils.RedisUtil;
import com.toesbieya.my.utils.SessionUtil; import com.toesbieya.my.utils.SessionUtil;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -21,21 +24,25 @@ import java.util.function.BiConsumer;
@Component @Component
@Slf4j @Slf4j
public class SocketModule { public class WebSocketServer {
private static final ConcurrentHashMap<Integer, UserObject> socketMap = new ConcurrentHashMap<>(128); private final ConcurrentHashMap<Integer, UserObject> socketMap = new ConcurrentHashMap<>(128);
private static SocketIOServer server; private final SocketIOServer server;
@Autowired @Autowired
public SocketModule(SocketIOServer server) { public WebSocketServer(SocketIOServer server) {
SocketModule.server = server; this.server = server;
//启动socket服务前清空redis中的在线用户信息
RedisUtil.del(SocketConstant.REDIS_ONLINE_USER);
server.start(); server.start();
} }
public static void sendEvent(String event, Integer uid, Object... data) { public void sendEvent(String event, Integer uid, Object... data) {
sendEvent(event, uid, data, null); sendEvent(event, uid, data, null);
} }
public static void sendEvent(String event, Integer uid, Object data, BiConsumer<UserObject, SocketIOClient> consumer) { public void sendEvent(String event, Integer uid, Object data, BiConsumer<UserObject, SocketIOClient> consumer) {
UserObject obj = socketMap.get(uid); UserObject obj = socketMap.get(uid);
if (obj == null) return; if (obj == null) return;
@ -49,48 +56,67 @@ public class SocketModule {
if (consumer != null) consumer.accept(obj, client); if (consumer != null) consumer.accept(obj, client);
} }
public static void broadcast(String event, Object... data) { public void broadcast(String event, Object... data) {
server.getBroadcastOperations().sendEvent(event, data); server.getBroadcastOperations().sendEvent(event, data);
} }
public static boolean online(Integer uid) { public void logout(Integer uid, String msg) {
return uid != null && socketMap.containsKey(uid);
}
public static void logout(Integer uid, String msg) {
sendEvent(SocketConstant.EVENT_LOGOUT, uid, msg, (obj, client) -> { sendEvent(SocketConstant.EVENT_LOGOUT, uid, msg, (obj, client) -> {
SessionUtil.remove(obj.getToken()); SessionUtil.remove(obj.getToken());
client.disconnect(); client.disconnect();
socketMap.remove(uid);
}); });
} }
public static int getOnlineNum() {
return socketMap.size();
}
@OnConnect @OnConnect
public void onConnect(SocketIOClient client) { public void onConnect(SocketIOClient client) {
UserObject obj = new UserObject(client); UserObject obj = new UserObject(client);
Integer uid = obj.getUid(); Integer uid = obj.getUid();
//用户session是否过期?
if (!RedisUtil.exist(obj.getKey())) {
logout(uid, "登陆信息过期,请重新登陆");
return;
}
//如果存在,说明该账号重复登陆,强制登出
if (socketMap.containsKey(uid)) { if (socketMap.containsKey(uid)) {
logout(uid, "该账号在其他位置登录"); logout(uid, "该账号在其他位置登录");
} }
else socketMap.put(uid, obj);
socketMap.put(uid, obj);
//放入在线用户ID集合
RedisUtil.sadd(SocketConstant.REDIS_ONLINE_USER, uid);
//移除离线表的信息
RedisUtil.hdel(SocketConstant.REDIS_OFFLINE_USER, String.valueOf(uid));
} }
@OnDisconnect @OnDisconnect
public void onDisconnect(SocketIOClient client) { public void onDisconnect(SocketIOClient client) {
long now = System.currentTimeMillis();
UserObject obj = new UserObject(client); UserObject obj = new UserObject(client);
Integer uid = obj.getUid(); Integer uid = obj.getUid();
String sessionKey = obj.getKey();
//重复登陆时,不需要执行操作
UserObject already = socketMap.get(uid); UserObject already = socketMap.get(uid);
if (already == null || !sessionKey.equals(already.getKey())) {
return;
}
socketMap.remove(uid);
if (already == null) return; //移除在线用户ID集合对应的ID
RedisUtil.srem(SocketConstant.REDIS_ONLINE_USER, uid);
//只有token相同时才移除 //在用户session未过期时设置离线表信息
if (obj.getToken().equals(already.getToken())) { if (RedisUtil.exist(sessionKey)) {
socketMap.remove(uid); RedisUtil.hset(
SocketConstant.REDIS_OFFLINE_USER,
String.valueOf(uid),
new SocketOfflineVo(sessionKey, now)
);
} }
} }
@ -101,6 +127,7 @@ public class SocketModule {
@Data @Data
private static class UserObject { private static class UserObject {
private String key; //redis的键名
private Integer uid; //用户id private Integer uid; //用户id
private String token; //redis中的token private String token; //redis中的token
private UUID uuid; //socketClient自己的sessionID private UUID uuid; //socketClient自己的sessionID
@ -112,6 +139,7 @@ public class SocketModule {
list = params.get("token"); list = params.get("token");
this.token = list.get(0); this.token = list.get(0);
this.uuid = client.getSessionId(); this.uuid = client.getSessionId();
this.key = SessionConstant.REDIS_NAMESPACE + this.token;
} }
} }
} }

@ -6,18 +6,11 @@ import com.toesbieya.my.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
@ -27,29 +20,14 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
public class RequestModule { public class RequestModule {
private final static String IP_LIMIT_KEY = "limit:url-ip:"; private final static String IP_LIMIT_KEY = "limit:url-ip:";
private final static String BLACK_IP_KEY = "limit:black-ip:"; private final static String BLACK_IP_KEY = "limit:black-ip:";
private final static int REQUEST_URL_INIT_VALUE = 128;
//判断能拿到令牌的最大时间,毫秒 //判断能拿到令牌的最大时间,毫秒
private final static long TIME_OUT = 200L; private final static long TIME_OUT = 200L;
//所有controller的<url,mappingMethod>,一个url只会有一个mappingMethod
private final static HashMap<String, String> requestUrlMap = new HashMap<>(REQUEST_URL_INIT_VALUE);
//ip暂时拉黑的时间,单位秒 //ip暂时拉黑的时间,单位秒
private final static long EXPIRE_SECONDS = 10L; private final static long EXPIRE_SECONDS = 10L;
//url的总访问频率限制 //url的总访问频率限制
private static ConcurrentHashMap<String, RateLimiterHelper> limitMap; private static ConcurrentHashMap<String, RateLimiterHelper> limitMap;
private RequestMappingHandlerMapping mapping;
private SysResourceService resourceService; private SysResourceService resourceService;
//根据请求地址和请求方法判断是否为合法请求
public static boolean urlExistMapping(String url, String method) {
String s = requestUrlMap.get(url);
return s != null && s.equals(method);
}
/** /**
* 未在resource表中配置的不进行限制 * 未在resource表中配置的不进行限制
* *
@ -81,28 +59,12 @@ public class RequestModule {
public void init() { public void init() {
Instant start = Instant.now(); Instant start = Instant.now();
initRequestMap();
initLimitMap(); initLimitMap();
Instant end = Instant.now(); Instant end = Instant.now();
log.info("路由模块启动成功,耗时:{}毫秒", ChronoUnit.MILLIS.between(start, end)); log.info("路由模块启动成功,耗时:{}毫秒", ChronoUnit.MILLIS.between(start, end));
} }
private void initRequestMap() {
// 获取url与类和方法的对应信息
Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
for (RequestMappingInfo info : map.keySet()) {
Set<String> patterns = info.getPatternsCondition().getPatterns();
Set<RequestMethod> methods = info.getMethodsCondition().getMethods();
if (methods.size() <= 0) {
log.warn("url{}没有设置请求方法", patterns);
continue;
}
requestUrlMap.put(patterns.iterator().next(), methods.iterator().next().toString());
}
}
private void initLimitMap() { private void initLimitMap() {
limitMap = new ConcurrentHashMap<>(); limitMap = new ConcurrentHashMap<>();
List<SysResource> resources = resourceService.getAll(); List<SysResource> resources = resourceService.getAll();
@ -117,11 +79,6 @@ public class RequestModule {
limitMap.put(url, new RateLimiterHelper(totalRate, ipRate)); limitMap.put(url, new RateLimiterHelper(totalRate, ipRate));
} }
@Autowired
public void setMapping(RequestMappingHandlerMapping mapping) {
this.mapping = mapping;
}
@Autowired @Autowired
public void setResourceService(SysResourceService resourceService) { public void setResourceService(SysResourceService resourceService) {
this.resourceService = resourceService; this.resourceService = resourceService;

@ -1,4 +1,4 @@
package com.toesbieya.my.module; package com.toesbieya.my.schedule;
import com.toesbieya.my.constant.DocumentConstant; import com.toesbieya.my.constant.DocumentConstant;
import com.toesbieya.my.utils.DateUtil; import com.toesbieya.my.utils.DateUtil;
@ -19,28 +19,32 @@ import java.util.Map;
@Component @Component
@Slf4j @Slf4j
@DependsOn("redisUtil") @DependsOn("redisUtil")
public class RedisModule { public class DocumentTask {
@PostConstruct @PostConstruct
public void init() { public void run() {
Instant start = Instant.now(); template("初始化单据ID", 0);
}
initDocumentsID();
Instant end = Instant.now(); //每天零点重置单据ID的值
log.info("redis模块启动成功,耗时:{}毫秒", ChronoUnit.MILLIS.between(start, end)); @Async("scheduledExecutor")
@Scheduled(cron = "1 0 0 */1 * ?")
public void autoRefreshDocumentID() {
template("定时更新单据ID", 1);
} }
//初始化单据ID //启动时初始化单据ID
private void initDocumentsID() { private void initDocumentsID() {
String[] fields = new String[DocumentConstant.DOCUMENT_TYPE.length + 1]; String[] fields = new String[DocumentConstant.DOCUMENT_TYPE.length + 1];
fields[0] = "date"; fields[0] = "date";
System.arraycopy(DocumentConstant.DOCUMENT_TYPE, 0, fields, 1, fields.length - 1); System.arraycopy(DocumentConstant.DOCUMENT_TYPE, 0, fields, 1, fields.length - 1);
List<Object> result = RedisUtil.hmget(DocumentConstant.DOCUMENT_TYPE_REDIS_KEY, fields); List<Object> result = RedisUtil.hmget(DocumentConstant.DOCUMENT_TYPE_REDIS_KEY, fields);
long now = DateUtil.getTimestampNow(); long now = DateUtil.getTimestampNow();
//日期不是今天时,更新全部,初始值为1 //日期不是今天时,更新全部
if (null == result.get(0) || now != (long) result.get(0)) { Object firstItem = result.get(0);
if (null == firstItem || now != (long) firstItem) {
updateAllDocument(now); updateAllDocument(now);
log.info("更新【{}】种单据ID成功", DocumentConstant.DOCUMENT_TYPE.length); log.info("更新【{}】种单据ID成功", DocumentConstant.DOCUMENT_TYPE.length);
return; return;
@ -50,18 +54,21 @@ public class RedisModule {
int updateNum = 0; int updateNum = 0;
Map<String, Object> update = new HashMap<>(); Map<String, Object> update = new HashMap<>();
int resultSize = result.size(); int resultSize = result.size();
for (int i = 1; i < resultSize; i++) { for (int i = 1; i < resultSize; i++) {
if (result.get(i) == null) { if (result.get(i) == null) {
updateNum++; updateNum++;
update.put(DocumentConstant.DOCUMENT_TYPE[i - 1], 1); update.put(DocumentConstant.DOCUMENT_TYPE[i - 1], 1);
} }
} }
if (updateNum > 0) { if (updateNum > 0) {
RedisUtil.hmset(DocumentConstant.DOCUMENT_TYPE_REDIS_KEY, update); RedisUtil.hmset(DocumentConstant.DOCUMENT_TYPE_REDIS_KEY, update);
log.info("更新增加的单据【{}】种", updateNum); log.info("更新增加的单据【{}】种", updateNum);
} }
} }
//每种单据的值置为1
private void updateAllDocument(long now) { private void updateAllDocument(long now) {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
map.put("date", now); map.put("date", now);
@ -71,26 +78,29 @@ public class RedisModule {
RedisUtil.hmset(DocumentConstant.DOCUMENT_TYPE_REDIS_KEY, map); RedisUtil.hmset(DocumentConstant.DOCUMENT_TYPE_REDIS_KEY, map);
} }
//每天零点初始化单据ID //模板
@Async("scheduledExecutor") private void template(String action, int type) {
@Scheduled(cron = "1 0 0 */1 * ?") Instant start = Instant.now();
public void autoRefreshDocumentID() {
log.info("开始定时更新单据ID......当前共有【{}】种待更新......", DocumentConstant.DOCUMENT_TYPE.length);
String lockKey = DocumentConstant.UPDATE_DOCUMENTS_LOCK_KEY; String lockKey = DocumentConstant.UPDATE_DOCUMENTS_LOCK_KEY;
try (RedisUtil.Locker locker = new RedisUtil.Locker(lockKey)) { try (RedisUtil.Locker locker = new RedisUtil.Locker(lockKey)) {
if (!locker.lock()) { if (!locker.lock()) {
log.error("定时更新单据ID失败,获取锁【{}】失败", lockKey); log.error("{}失败,获取锁【{}】失败", action, lockKey);
return; return;
} }
updateAllDocument(DateUtil.getTimestampNow()); if (type == 0) {
initDocumentsID();
}
else {
updateAllDocument(DateUtil.getTimestampNow());
}
log.info("定时更新单据ID结束,成功更新【{}】种", DocumentConstant.DOCUMENT_TYPE.length); log.info("{}成功,耗时:{}毫秒", action, ChronoUnit.MILLIS.between(start, Instant.now()));
} catch (Exception e) { }
log.error("定时更新单据ID失败", e); catch (Exception e) {
log.error("{}失败", action, e);
} }
} }
} }

@ -0,0 +1,66 @@
package com.toesbieya.my.schedule;
import com.alibaba.fastjson.JSONObject;
import com.toesbieya.my.constant.SessionConstant;
import com.toesbieya.my.constant.SocketConstant;
import com.toesbieya.my.model.vo.SocketOfflineVo;
import com.toesbieya.my.utils.RedisUtil;
import com.toesbieya.my.utils.SessionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.DependsOn;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.Set;
@Component
@Slf4j
@DependsOn("redisUtil")
public class SessionTask {
@PostConstruct
public void run() {
cleanSession();
}
@Async("scheduledExecutor")
@Scheduled(cron = "0 */1 * * * ?")
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);
//删除离线表信息
String token = sessionKey.replace(SessionConstant.REDIS_NAMESPACE, "");
Integer uid = SessionUtil.getUidFromToken(token);
RedisUtil.hdel(SocketConstant.REDIS_OFFLINE_USER, String.valueOf(uid));
}
}
});
}
catch (Exception e) {
log.error("清理session失败", e);
}
}
}

@ -0,0 +1,116 @@
package com.toesbieya.my.schedule;
import com.toesbieya.my.mapper.StatisticMapper;
import com.toesbieya.my.model.entity.StatFinishOrder;
import com.toesbieya.my.model.entity.StatProfitGoods;
import com.toesbieya.my.model.entity.StatProfitTotal;
import com.toesbieya.my.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
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 {
@Resource
private StatisticMapper statisticMapper;
@PostConstruct
public void run() {
this.autoStat();
}
//每天零点统计信息
@Async("scheduledExecutor")
@Scheduled(cron = "1 0 0 */1 * ?")
public void autoStat() {
log.info("开始统计信息...");
long lastDay = DateUtil.getTimestampBeforeNow(1);
long today = DateUtil.getTimestampNow();
//检查是否已统计过昨日已完成的订单数
if (!statisticMapper.checkDailyFinishOrderExist(lastDay)) {
Integer lastDayPurchaseOrderFinish = statisticMapper.getPurchaseOrderLastDayFinishOrderNum();
Integer lastDaySellOrderFinish = statisticMapper.getSellOrderLastDayFinishOrderNum();
StatFinishOrder param = new StatFinishOrder();
param.setPurchase(lastDayPurchaseOrderFinish);
param.setSell(lastDaySellOrderFinish);
param.setTime(lastDay);
statisticMapper.insertFinishOrder(param);
}
//检查是否已统计过昨日的采购额、销售额、毛利
if (!statisticMapper.checkDailyProfitExist(lastDay)) {
//昨日各个商品的采购额、销售额
List<StatProfitGoods> purchaseProfitGoods = statisticMapper.getPurchaseOrderDailyProfitGoods(lastDay, today);
List<StatProfitGoods> sellProfitGoods = statisticMapper.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);
statisticMapper.insertProfitTotal(statProfitTotal);
if (purchaseProfitGoods.size() > 0) {
statisticMapper.insertProfitGoodsBatch(purchaseProfitGoods);
}
}
log.info("结束统计信息...");
}
}

@ -1,5 +1,6 @@
package com.toesbieya.my.service; package com.toesbieya.my.service;
import com.toesbieya.my.annoation.TimeCost;
import com.toesbieya.my.annoation.UserAction; import com.toesbieya.my.annoation.UserAction;
import com.toesbieya.my.enumeration.GeneralStatusEnum; import com.toesbieya.my.enumeration.GeneralStatusEnum;
import com.toesbieya.my.enumeration.RecLoginHistoryEnum; import com.toesbieya.my.enumeration.RecLoginHistoryEnum;
@ -10,7 +11,6 @@ import com.toesbieya.my.model.vo.*;
import com.toesbieya.my.utils.QiniuUtil; import com.toesbieya.my.utils.QiniuUtil;
import com.toesbieya.my.utils.Result; import com.toesbieya.my.utils.Result;
import com.toesbieya.my.utils.SessionUtil; import com.toesbieya.my.utils.SessionUtil;
import com.toesbieya.my.utils.Util;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -26,6 +26,7 @@ public class AccountService {
@Resource @Resource
private RecService recService; private RecService recService;
@TimeCost
public Result login(LoginParam param, String ip) { public Result login(LoginParam param, String ip) {
SysUser user = userMapper.getByNameAndPwd(param.getUsername(), param.getPassword()); SysUser user = userMapper.getByNameAndPwd(param.getUsername(), param.getPassword());
@ -41,7 +42,7 @@ public class AccountService {
} }
//设置token //设置token
String token = Util.UUID(); String token = SessionUtil.generateToken(user);
//存入redis的数据 //存入redis的数据
UserVo userVo = new UserVo(user); UserVo userVo = new UserVo(user);

@ -11,13 +11,13 @@ import java.util.List;
@Service @Service
public class BizDocumentHistoryService { public class BizDocumentHistoryService {
@Resource @Resource
private BizDocumentHistoryMapper documentHistoryMapper; private BizDocumentHistoryMapper historyMapper;
public List<BizDocumentHistory> search(DocumentHistorySearch vo) { public List<BizDocumentHistory> search(DocumentHistorySearch vo) {
return documentHistoryMapper.search(vo); return historyMapper.search(vo);
} }
public List<BizDocumentHistory> getByPid(String pid) { public List<BizDocumentHistory> getByPid(String pid) {
return documentHistoryMapper.getByPid(pid); return historyMapper.getByPid(pid);
} }
} }

@ -2,11 +2,10 @@ package com.toesbieya.my.service;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.toesbieya.my.annoation.Lock; import com.toesbieya.my.annoation.Lock;
import com.toesbieya.my.annoation.Tx;
import com.toesbieya.my.annoation.UserAction; import com.toesbieya.my.annoation.UserAction;
import com.toesbieya.my.enumeration.BizDocumentFinishEnum; import com.toesbieya.my.enumeration.DocFinishEnum;
import com.toesbieya.my.enumeration.BizDocumentHistoryEnum; import com.toesbieya.my.enumeration.DocHistoryEnum;
import com.toesbieya.my.enumeration.BizDocumentStatusEnum; import com.toesbieya.my.enumeration.DocStatusEnum;
import com.toesbieya.my.exception.JsonResultException; import com.toesbieya.my.exception.JsonResultException;
import com.toesbieya.my.mapper.BizDocumentHistoryMapper; import com.toesbieya.my.mapper.BizDocumentHistoryMapper;
import com.toesbieya.my.mapper.BizPurchaseInboundMapper; import com.toesbieya.my.mapper.BizPurchaseInboundMapper;
@ -18,13 +17,19 @@ import com.toesbieya.my.model.vo.export.PurchaseInboundExport;
import com.toesbieya.my.model.vo.result.PageResult; import com.toesbieya.my.model.vo.result.PageResult;
import com.toesbieya.my.model.vo.search.PurchaseInboundSearch; import com.toesbieya.my.model.vo.search.PurchaseInboundSearch;
import com.toesbieya.my.model.vo.update.DocumentStatusUpdate; import com.toesbieya.my.model.vo.update.DocumentStatusUpdate;
import com.toesbieya.my.utils.*; import com.toesbieya.my.utils.DocumentUtil;
import com.toesbieya.my.utils.ExcelUtil;
import com.toesbieya.my.utils.Result;
import com.toesbieya.my.utils.Util;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -32,69 +37,69 @@ import java.util.List;
@Slf4j @Slf4j
public class BizPurchaseInboundService { public class BizPurchaseInboundService {
@Resource @Resource
private BizPurchaseInboundMapper purchaseInboundMapper; private BizPurchaseInboundMapper mainMapper;
@Resource @Resource
private BizPurchaseOrderMapper purchaseOrderMapper; private BizPurchaseOrderMapper orderMapper;
@Resource @Resource
private BizDocumentHistoryMapper documentHistoryMapper; private BizDocumentHistoryMapper historyMapper;
@Resource @Resource
private BizStockMapper stockMapper; private BizStockMapper stockMapper;
@Resource @Resource
private RecService recService; private RecService recService;
public BizPurchaseInbound getById(String id) { public BizPurchaseInbound getById(String id) {
BizPurchaseInbound inbound = purchaseInboundMapper.getById(id); BizPurchaseInbound main = mainMapper.getById(id);
if (inbound == null) return null;
List<BizPurchaseInboundSub> list = purchaseInboundMapper.getSubById(id); if (main == null) return null;
inbound.setData(list);
List<RecAttachment> imageList = recService.getAttachmentByPid(id); main.setData(this.getSubById(id));
inbound.setImageList(imageList); main.setImageList(recService.getAttachmentByPid(id));
return inbound;
return main;
} }
public List<BizPurchaseInboundSub> getSubById(String id) { public List<BizPurchaseInboundSub> getSubById(String id) {
return purchaseInboundMapper.getSubById(id); return mainMapper.getSubById(id);
} }
public PageResult<BizPurchaseInbound> search(PurchaseInboundSearch vo) { public PageResult<BizPurchaseInbound> search(PurchaseInboundSearch vo) {
PageHelper.startPage(vo.getPage(), vo.getPageSize()); PageHelper.startPage(vo.getPage(), vo.getPageSize());
List<BizPurchaseInbound> list = purchaseInboundMapper.search(vo); return new PageResult<>(mainMapper.search(vo));
return new PageResult<>(list);
} }
public void export(PurchaseInboundSearch vo, HttpServletResponse response) throws Exception { public void export(PurchaseInboundSearch vo, HttpServletResponse response) throws Exception {
List<PurchaseInboundExport> list = purchaseInboundMapper.export(vo); List<PurchaseInboundExport> list = mainMapper.export(vo);
ExcelUtil.exportSimply(list, response, "采购入库单导出"); ExcelUtil.exportSimply(list, response, "采购入库单导出");
} }
@UserAction("'添加采购入库单'") @UserAction("'添加采购入库单'")
@Tx @Transactional(rollbackFor = Exception.class)
public Result add(BizPurchaseInbound doc) { public Result add(BizPurchaseInbound doc) {
return addInbound(doc); return addMain(doc);
} }
@UserAction("'修改采购入库单'+#doc.id") @UserAction("'修改采购入库单'+#doc.id")
@Lock("#doc.id") @Lock("#doc.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result update(BizPurchaseInbound doc) { public Result update(BizPurchaseInbound doc) {
return updateInbound(doc); return updateMain(doc);
} }
@UserAction("'提交采购入库单'+#doc.id") @UserAction("'提交采购入库单'+#doc.id")
@Lock("#doc.id") @Lock("#doc.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result commit(BizPurchaseInbound doc) { public Result commit(BizPurchaseInbound doc) {
boolean isFirstCreate = StringUtils.isEmpty(doc.getId()); boolean isFirstCreate = StringUtils.isEmpty(doc.getId());
Result result = isFirstCreate ? addInbound(doc) : updateInbound(doc); Result result = isFirstCreate ? addMain(doc) : updateMain(doc);
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(doc.getId()) .pid(doc.getId())
.type(BizDocumentHistoryEnum.COMMIT.getCode()) .type(DocHistoryEnum.COMMIT.getCode())
.uid(doc.getCid()) .uid(doc.getCid())
.uname(doc.getCname()) .uname(doc.getCname())
.status_before(BizDocumentStatusEnum.DRAFT.getCode()) .status_before(DocStatusEnum.DRAFT.getCode())
.status_after(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_after(DocStatusEnum.WAIT_VERIFY.getCode())
.time(System.currentTimeMillis()) .time(System.currentTimeMillis())
.build() .build()
); );
@ -105,23 +110,23 @@ public class BizPurchaseInboundService {
@UserAction("'撤回采购入库单'+#vo.id") @UserAction("'撤回采购入库单'+#vo.id")
@Lock("#vo.id") @Lock("#vo.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result withdraw(DocumentStatusUpdate vo, UserVo user) { public Result withdraw(DocumentStatusUpdate vo, UserVo user) {
String id = vo.getId(); String id = vo.getId();
String info = vo.getInfo(); String info = vo.getInfo();
if (purchaseInboundMapper.reject(id) < 1) { if (mainMapper.reject(id) < 1) {
return Result.fail("撤回失败,请刷新重试"); return Result.fail("撤回失败,请刷新重试");
} }
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(id) .pid(id)
.type(BizDocumentHistoryEnum.WITHDRAW.getCode()) .type(DocHistoryEnum.WITHDRAW.getCode())
.uid(user.getId()) .uid(user.getId())
.uname(user.getName()) .uname(user.getName())
.status_before(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_before(DocStatusEnum.WAIT_VERIFY.getCode())
.status_after(BizDocumentStatusEnum.DRAFT.getCode()) .status_after(DocStatusEnum.DRAFT.getCode())
.time(System.currentTimeMillis()) .time(System.currentTimeMillis())
.info(info) .info(info)
.build() .build()
@ -132,63 +137,74 @@ public class BizPurchaseInboundService {
@UserAction("'通过采购入库单'+#vo.id") @UserAction("'通过采购入库单'+#vo.id")
@Lock({"#vo.pid", "#vo.id"}) @Lock({"#vo.pid", "#vo.id"})
@Tx @Transactional(rollbackFor = Exception.class)
public Result pass(DocumentStatusUpdate vo, UserVo user) { public Result pass(DocumentStatusUpdate vo, UserVo user) {
String id = vo.getId(); String id = vo.getId();
String info = vo.getInfo(); String info = vo.getInfo();
String pid = vo.getPid(); String pid = vo.getPid();
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
/*检查采购订单状态、入库商品是否符合订单要求*/ //检查采购订单状态、入库商品是否符合订单要求
List<BizPurchaseInboundSub> inboundSubList = purchaseInboundMapper.getSubById(vo.getId()); List<BizPurchaseInboundSub> inboundSubList = mainMapper.getSubById(vo.getId());
String err = checkOrder(vo.getPid(), inboundSubList); String err = checkOrder(vo.getPid(), inboundSubList);
if (err != null) return Result.fail("通过失败," + err); if (err != null) return Result.fail("通过失败," + err);
if (purchaseInboundMapper.pass(id, user.getId(), user.getName(), now) < 1) { if (mainMapper.pass(id, user.getId(), user.getName(), now) < 1) {
return Result.fail("通过失败,请刷新重试"); return Result.fail("通过失败,请刷新重试");
} }
/*修改采购订单完成情况、子表的未入库数量*/ //修改采购订单完成情况、子表的未入库数量
List<BizStock> stockList = new ArrayList<>(); List<BizStock> stockList = new ArrayList<>();
BizDocumentFinishEnum finish = BizDocumentFinishEnum.FINISHED; DocFinishEnum finish = DocFinishEnum.FINISHED;
//使用一级缓存 //使用一级缓存
List<BizPurchaseOrderSub> orderSubList = purchaseOrderMapper.getSubById(pid); List<BizPurchaseOrderSub> orderSubList = orderMapper.getSubById(pid);
//如果有任意一个采购商品的remain_num大于采购商品的num,则完成情况为进行中,否则为已完成
//生成需要入库的商品列表
for (BizPurchaseOrderSub orderSub : orderSubList) { for (BizPurchaseOrderSub orderSub : orderSubList) {
if (orderSub.getRemain_num().equals(0D)) continue; if (orderSub.getRemain_num().equals(BigDecimal.ZERO)) {
continue;
}
BizPurchaseInboundSub inboundSub = Util.find(inboundSubList, i -> i.getCid().equals(orderSub.getCid())); BizPurchaseInboundSub inboundSub = Util.find(inboundSubList, i -> i.getCid().equals(orderSub.getCid()));
if (inboundSub == null) continue; if (inboundSub == null) continue;
stockList.add( stockList.add(
BizStock.builder() BizStock.builder()
.cid(inboundSub.getCid()) .cid(inboundSub.getCid()).cname(inboundSub.getCname()).num(inboundSub.getNum())
.cname(inboundSub.getCname()) .price(orderSub.getPrice()).ctime(now).cgddid(pid).cgrkid(id)
.num(inboundSub.getNum())
.price(orderSub.getPrice())
.ctime(now)
.cgddid(pid)
.cgrkid(id)
.build() .build()
); );
double gap = orderSub.getRemain_num() - inboundSub.getNum();
if (gap > 0) finish = BizDocumentFinishEnum.UNDERWAY; BigDecimal gap = orderSub.getRemain_num().subtract(inboundSub.getNum());
//更新采购订单子表
purchaseOrderMapper.updateSubRemainNum(orderSub.getId(), gap); //如果有任意一个采购商品的remain_num大于采购商品的num,则完成情况为进行中,否则为已完成
if (gap.compareTo(BigDecimal.ZERO) > 0) {
finish = DocFinishEnum.UNDERWAY;
}
//更新采购订单子表的remain_num
orderMapper.updateSubRemainNum(orderSub.getId(), gap);
} }
//更新采购订单完成情况 //更新采购订单完成情况
purchaseOrderMapper.updateFinish(pid, finish.getCode(), finish == BizDocumentFinishEnum.FINISHED ? now : null); if (1 > orderMapper.updateFinish(pid, finish.getCode(), finish == DocFinishEnum.FINISHED ? now : null)) {
throw new JsonResultException("通过失败,采购订单状态有误,请刷新重试");
}
//插入库存 //插入库存
if (stockList.size() == 0) throw new JsonResultException("通过失败,入库异常"); if (stockList.size() == 0) throw new JsonResultException("通过失败,入库异常");
stockMapper.batchInsert(stockList); stockMapper.batchInsert(stockList);
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(id) .pid(id)
.type(BizDocumentHistoryEnum.PASS.getCode()) .type(DocHistoryEnum.PASS.getCode())
.uid(user.getId()) .uid(user.getId())
.uname(user.getName()) .uname(user.getName())
.status_before(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_before(DocStatusEnum.WAIT_VERIFY.getCode())
.status_after(BizDocumentStatusEnum.VERIFIED.getCode()) .status_after(DocStatusEnum.VERIFIED.getCode())
.time(now) .time(now)
.info(info) .info(info)
.build() .build()
@ -199,23 +215,23 @@ public class BizPurchaseInboundService {
@UserAction("'驳回采购入库单'+#vo.id") @UserAction("'驳回采购入库单'+#vo.id")
@Lock("#vo.id") @Lock("#vo.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result reject(DocumentStatusUpdate vo, UserVo user) { public Result reject(DocumentStatusUpdate vo, UserVo user) {
String id = vo.getId(); String id = vo.getId();
String info = vo.getInfo(); String info = vo.getInfo();
if (purchaseInboundMapper.reject(id) < 1) { if (mainMapper.reject(id) < 1) {
return Result.fail("驳回失败,请刷新重试"); return Result.fail("驳回失败,请刷新重试");
} }
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(id) .pid(id)
.type(BizDocumentHistoryEnum.REJECT.getCode()) .type(DocHistoryEnum.REJECT.getCode())
.uid(user.getId()) .uid(user.getId())
.uname(user.getName()) .uname(user.getName())
.status_before(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_before(DocStatusEnum.WAIT_VERIFY.getCode())
.status_after(BizDocumentStatusEnum.DRAFT.getCode()) .status_after(DocStatusEnum.DRAFT.getCode())
.time(System.currentTimeMillis()) .time(System.currentTimeMillis())
.info(info) .info(info)
.build() .build()
@ -226,29 +242,40 @@ public class BizPurchaseInboundService {
@UserAction("'删除采购入库单'+#id") @UserAction("'删除采购入库单'+#id")
@Lock("#id") @Lock("#id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result del(String id) { public Result del(String id) {
if (purchaseInboundMapper.del(id) < 1) return Result.fail("删除失败"); if (mainMapper.del(id) < 1) {
purchaseInboundMapper.delSubByPid(id); return Result.fail("删除失败");
}
//同时删除子表和附件
mainMapper.delSubByPid(id);
recService.delAttachmentByPid(id); recService.delAttachmentByPid(id);
return Result.success("删除成功"); return Result.success("删除成功");
} }
private Result addInbound(BizPurchaseInbound doc) { private Result addMain(BizPurchaseInbound doc) {
String err = checkOrder(doc.getPid(), doc.getData()); List<BizPurchaseInboundSub> subList = doc.getData();
String err = checkOrder(doc.getPid(), subList);
if (err != null) return Result.fail(err); if (err != null) return Result.fail(err);
String id = DocumentUtil.getDocumentID("CGRK"); String id = DocumentUtil.getDocumentID("CGRK");
if (StringUtils.isEmpty(id)) return Result.fail("获取单号失败");
doc.setId(id); if (StringUtils.isEmpty(id)) {
for (BizPurchaseInboundSub sub : doc.getData()) { return Result.fail("获取单号失败");
sub.setPid(id);
} }
purchaseInboundMapper.add(doc); doc.setId(id);
purchaseInboundMapper.addSub(doc.getData());
//设置子表的pid
subList.forEach(sub -> sub.setPid(id));
mainMapper.insert(doc);
mainMapper.addSub(subList);
//插入附件
List<RecAttachment> uploadImageList = doc.getUploadImageList(); List<RecAttachment> uploadImageList = doc.getUploadImageList();
Long time = System.currentTimeMillis(); Long time = System.currentTimeMillis();
for (RecAttachment attachment : uploadImageList) { for (RecAttachment attachment : uploadImageList) {
@ -260,19 +287,27 @@ public class BizPurchaseInboundService {
return Result.success("添加成功", id); return Result.success("添加成功", id);
} }
private Result updateInbound(BizPurchaseInbound doc) { private Result updateMain(BizPurchaseInbound doc) {
String err = checkUpdateStatus(doc.getId()); String docId = doc.getId();
String err = checkUpdateStatus(docId);
if (err == null) err = checkOrder(doc.getPid(), doc.getData()); if (err == null) err = checkOrder(doc.getPid(), doc.getData());
if (err != null) return Result.fail(err); if (err != null) return Result.fail(err);
purchaseInboundMapper.delSubByPid(doc.getId()); //更新主表
purchaseInboundMapper.update(doc); mainMapper.update(doc);
purchaseInboundMapper.addSub(doc.getData());
//删除旧的子表
mainMapper.delSubByPid(docId);
//插入新的子表
mainMapper.addSub(doc.getData());
//附件增删
List<RecAttachment> uploadImageList = doc.getUploadImageList(); List<RecAttachment> uploadImageList = doc.getUploadImageList();
Long time = System.currentTimeMillis(); Long time = System.currentTimeMillis();
for (RecAttachment attachment : uploadImageList) { for (RecAttachment attachment : uploadImageList) {
attachment.setPid(doc.getId()); attachment.setPid(docId);
attachment.setTime(time); attachment.setTime(time);
} }
recService.handleAttachment(uploadImageList, doc.getDeleteImageList()); recService.handleAttachment(uploadImageList, doc.getDeleteImageList());
@ -282,29 +317,40 @@ public class BizPurchaseInboundService {
//只有拟定状态的单据才能修改 //只有拟定状态的单据才能修改
private String checkUpdateStatus(String id) { private String checkUpdateStatus(String id) {
BizPurchaseInbound doc = purchaseInboundMapper.getById(id); BizPurchaseInbound doc = mainMapper.getById(id);
if (doc == null || !doc.getStatus().equals(0)) return "单据状态已更新,请刷新后重试"; if (doc == null || !doc.getStatus().equals(DocStatusEnum.DRAFT.getCode())) {
return "单据状态已更新,请刷新后重试";
}
return null; return null;
} }
//检查采购订单是否已审核、未完成、还有未入库的商品 //检查采购订单是否已审核、未完成、还有未入库的商品
private String checkOrder(String pid, List<BizPurchaseInboundSub> docSubList) { private String checkOrder(String pid, List<BizPurchaseInboundSub> docSubList) {
BizPurchaseOrder order = purchaseOrderMapper.getById(pid); BizPurchaseOrder order = orderMapper.getById(pid);
if (order == null || order.getStatus() != 2 || order.getFinish() == 2) {
if (order == null
|| !order.getStatus().equals(DocStatusEnum.VERIFIED.getCode())
|| order.getFinish().equals(DocFinishEnum.FINISHED.getCode())
) {
return "采购订单状态异常"; return "采购订单状态异常";
} }
List<BizPurchaseOrderSub> orderSubList = purchaseOrderMapper.getSubById(pid);
if (orderSubList.size() <= 0) return "没有找到采购订单的数据"; List<BizPurchaseOrderSub> orderSubList = orderMapper.getSubById(pid);
if (CollectionUtils.isEmpty(orderSubList)) return "没有找到采购订单的数据";
//判断入库商品是否合法
for (BizPurchaseInboundSub inboundSub : docSubList) { for (BizPurchaseInboundSub inboundSub : docSubList) {
BizPurchaseOrderSub orderSub = Util.find(orderSubList, t -> t.getCid().equals(inboundSub.getCid())); BizPurchaseOrderSub orderSub = Util.find(orderSubList, t -> t.getCid().equals(inboundSub.getCid()));
if (orderSub == null) { if (orderSub == null) {
return "入库商品【" + inboundSub.getCname() + "】不在采购订单中"; return String.format("入库商品【%s】不在采购订单中", inboundSub.getCname());
} }
if (orderSub.getRemain_num().equals(0D)) { if (orderSub.getRemain_num().compareTo(BigDecimal.ZERO) <= 0) {
return "入库商品【" + inboundSub.getCname() + "】已全部入库"; return String.format("入库商品【%s】已全部入库", inboundSub.getCname());
} }
if (orderSub.getRemain_num() < inboundSub.getNum()) { if (orderSub.getRemain_num().compareTo(inboundSub.getNum()) < 0) {
return "入库商品【" + inboundSub.getCname() + "】的数量超出订单数量"; return String.format("入库商品【%s】的数量超出订单数量", inboundSub.getCname());
} }
} }
return null; return null;

@ -2,13 +2,15 @@ package com.toesbieya.my.service;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.toesbieya.my.annoation.Lock; import com.toesbieya.my.annoation.Lock;
import com.toesbieya.my.annoation.Tx;
import com.toesbieya.my.annoation.UserAction; import com.toesbieya.my.annoation.UserAction;
import com.toesbieya.my.enumeration.BizDocumentHistoryEnum; import com.toesbieya.my.enumeration.DocHistoryEnum;
import com.toesbieya.my.enumeration.BizDocumentStatusEnum; import com.toesbieya.my.enumeration.DocStatusEnum;
import com.toesbieya.my.mapper.BizDocumentHistoryMapper; import com.toesbieya.my.mapper.BizDocumentHistoryMapper;
import com.toesbieya.my.mapper.BizPurchaseOrderMapper; import com.toesbieya.my.mapper.BizPurchaseOrderMapper;
import com.toesbieya.my.model.entity.*; import com.toesbieya.my.model.entity.BizDocumentHistory;
import com.toesbieya.my.model.entity.BizPurchaseOrder;
import com.toesbieya.my.model.entity.BizPurchaseOrderSub;
import com.toesbieya.my.model.entity.RecAttachment;
import com.toesbieya.my.model.vo.UserVo; import com.toesbieya.my.model.vo.UserVo;
import com.toesbieya.my.model.vo.export.PurchaseOrderExport; import com.toesbieya.my.model.vo.export.PurchaseOrderExport;
import com.toesbieya.my.model.vo.result.PageResult; import com.toesbieya.my.model.vo.result.PageResult;
@ -19,6 +21,7 @@ import com.toesbieya.my.utils.ExcelUtil;
import com.toesbieya.my.utils.Result; import com.toesbieya.my.utils.Result;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -29,66 +32,65 @@ import java.util.List;
@Slf4j @Slf4j
public class BizPurchaseOrderService { public class BizPurchaseOrderService {
@Resource @Resource
private BizPurchaseOrderMapper purchaseOrderMapper; private BizPurchaseOrderMapper mainMapper;
@Resource @Resource
private BizDocumentHistoryMapper documentHistoryMapper; private BizDocumentHistoryMapper historyMapper;
@Resource @Resource
private RecService recService; private RecService recService;
public BizPurchaseOrder getById(String id) { public BizPurchaseOrder getById(String id) {
BizPurchaseOrder order = purchaseOrderMapper.getById(id); BizPurchaseOrder main = mainMapper.getById(id);
if (order == null) return null;
List<BizPurchaseOrderSub> list = purchaseOrderMapper.getSubById(id); if (main == null) return null;
order.setData(list);
List<RecAttachment> imageList = recService.getAttachmentByPid(id);
order.setImageList(imageList);
return order; main.setData(this.getSubById(id));
main.setImageList(recService.getAttachmentByPid(id));
return main;
} }
public List<BizPurchaseOrderSub> getSubById(String id) { public List<BizPurchaseOrderSub> getSubById(String id) {
return purchaseOrderMapper.getSubById(id); return mainMapper.getSubById(id);
} }
public PageResult<BizPurchaseOrder> search(PurchaseOrderSearch vo) { public PageResult<BizPurchaseOrder> search(PurchaseOrderSearch vo) {
PageHelper.startPage(vo.getPage(), vo.getPageSize()); PageHelper.startPage(vo.getPage(), vo.getPageSize());
return new PageResult<>(purchaseOrderMapper.search(vo)); return new PageResult<>(mainMapper.search(vo));
} }
public void export(PurchaseOrderSearch vo, HttpServletResponse response) throws Exception { public void export(PurchaseOrderSearch vo, HttpServletResponse response) throws Exception {
List<PurchaseOrderExport> list = purchaseOrderMapper.export(vo); List<PurchaseOrderExport> list = mainMapper.export(vo);
ExcelUtil.exportSimply(list, response, "采购订单导出"); ExcelUtil.exportSimply(list, response, "采购订单导出");
} }
@UserAction("'添加采购订单'") @UserAction("'添加采购订单'")
@Tx @Transactional(rollbackFor = Exception.class)
public Result add(BizPurchaseOrder doc) { public Result add(BizPurchaseOrder doc) {
return addOrder(doc); return addMain(doc);
} }
@UserAction("'修改采购订单'+#doc.id") @UserAction("'修改采购订单'+#doc.id")
@Lock("#doc.id") @Lock("#doc.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result update(BizPurchaseOrder doc) { public Result update(BizPurchaseOrder doc) {
return updateOrder(doc); return updateMain(doc);
} }
@UserAction("'提交采购订单'+#doc.id") @UserAction("'提交采购订单'+#doc.id")
@Lock("#doc.id") @Lock("#doc.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result commit(BizPurchaseOrder doc) { public Result commit(BizPurchaseOrder doc) {
boolean isFirstCreate = StringUtils.isEmpty(doc.getId()); boolean isFirstCreate = StringUtils.isEmpty(doc.getId());
Result result = isFirstCreate ? addOrder(doc) : updateOrder(doc); Result result = isFirstCreate ? addMain(doc) : updateMain(doc);
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(doc.getId()) .pid(doc.getId())
.type(BizDocumentHistoryEnum.COMMIT.getCode()) .type(DocHistoryEnum.COMMIT.getCode())
.uid(doc.getCid()) .uid(doc.getCid())
.uname(doc.getCname()) .uname(doc.getCname())
.status_before(BizDocumentStatusEnum.DRAFT.getCode()) .status_before(DocStatusEnum.DRAFT.getCode())
.status_after(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_after(DocStatusEnum.WAIT_VERIFY.getCode())
.time(System.currentTimeMillis()) .time(System.currentTimeMillis())
.build() .build()
); );
@ -99,23 +101,23 @@ public class BizPurchaseOrderService {
@UserAction("'撤回采购订单'+#vo.id") @UserAction("'撤回采购订单'+#vo.id")
@Lock("#vo.id") @Lock("#vo.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result withdraw(DocumentStatusUpdate vo, UserVo user) { public Result withdraw(DocumentStatusUpdate vo, UserVo user) {
String id = vo.getId(); String id = vo.getId();
String info = vo.getInfo(); String info = vo.getInfo();
if (purchaseOrderMapper.reject(id) < 1) { if (mainMapper.reject(id) < 1) {
return Result.fail("撤回失败,请刷新重试"); return Result.fail("撤回失败,请刷新重试");
} }
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(id) .pid(id)
.type(BizDocumentHistoryEnum.WITHDRAW.getCode()) .type(DocHistoryEnum.WITHDRAW.getCode())
.uid(user.getId()) .uid(user.getId())
.uname(user.getName()) .uname(user.getName())
.status_before(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_before(DocStatusEnum.WAIT_VERIFY.getCode())
.status_after(BizDocumentStatusEnum.DRAFT.getCode()) .status_after(DocStatusEnum.DRAFT.getCode())
.time(System.currentTimeMillis()) .time(System.currentTimeMillis())
.info(info) .info(info)
.build() .build()
@ -126,24 +128,24 @@ public class BizPurchaseOrderService {
@UserAction("'通过采购订单'+#vo.id") @UserAction("'通过采购订单'+#vo.id")
@Lock("#vo.id") @Lock("#vo.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result pass(DocumentStatusUpdate vo, UserVo user) { public Result pass(DocumentStatusUpdate vo, UserVo user) {
String id = vo.getId(); String id = vo.getId();
String info = vo.getInfo(); String info = vo.getInfo();
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if (purchaseOrderMapper.pass(id, user.getId(), user.getName(), now) < 1) { if (mainMapper.pass(id, user.getId(), user.getName(), now) < 1) {
return Result.fail("通过失败,请刷新重试"); return Result.fail("通过失败,请刷新重试");
} }
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(id) .pid(id)
.type(BizDocumentHistoryEnum.PASS.getCode()) .type(DocHistoryEnum.PASS.getCode())
.uid(user.getId()) .uid(user.getId())
.uname(user.getName()) .uname(user.getName())
.status_before(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_before(DocStatusEnum.WAIT_VERIFY.getCode())
.status_after(BizDocumentStatusEnum.VERIFIED.getCode()) .status_after(DocStatusEnum.VERIFIED.getCode())
.time(now) .time(now)
.info(info) .info(info)
.build() .build()
@ -154,23 +156,23 @@ public class BizPurchaseOrderService {
@UserAction("'驳回采购订单'+#vo.id") @UserAction("'驳回采购订单'+#vo.id")
@Lock("#vo.id") @Lock("#vo.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result reject(DocumentStatusUpdate vo, UserVo user) { public Result reject(DocumentStatusUpdate vo, UserVo user) {
String id = vo.getId(); String id = vo.getId();
String info = vo.getInfo(); String info = vo.getInfo();
if (purchaseOrderMapper.reject(id) < 1) { if (mainMapper.reject(id) < 1) {
return Result.fail("驳回失败,请刷新重试"); return Result.fail("驳回失败,请刷新重试");
} }
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(id) .pid(id)
.type(BizDocumentHistoryEnum.REJECT.getCode()) .type(DocHistoryEnum.REJECT.getCode())
.uid(user.getId()) .uid(user.getId())
.uname(user.getName()) .uname(user.getName())
.status_before(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_before(DocStatusEnum.WAIT_VERIFY.getCode())
.status_after(BizDocumentStatusEnum.DRAFT.getCode()) .status_after(DocStatusEnum.DRAFT.getCode())
.time(System.currentTimeMillis()) .time(System.currentTimeMillis())
.info(info) .info(info)
.build() .build()
@ -181,27 +183,41 @@ public class BizPurchaseOrderService {
@UserAction("'删除采购订单'+#id") @UserAction("'删除采购订单'+#id")
@Lock("#id") @Lock("#id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result del(String id) { public Result del(String id) {
if (purchaseOrderMapper.del(id) < 1) return Result.fail("删除失败"); if (mainMapper.del(id) < 1) {
purchaseOrderMapper.delSubByPid(id); return Result.fail("删除失败");
}
//同时删除子表和附件
mainMapper.delSubByPid(id);
recService.delAttachmentByPid(id); recService.delAttachmentByPid(id);
return Result.success("删除成功"); return Result.success("删除成功");
} }
private Result addOrder(BizPurchaseOrder doc) { private Result addMain(BizPurchaseOrder doc) {
String id = DocumentUtil.getDocumentID("CGDD"); String id = DocumentUtil.getDocumentID("CGDD");
if (StringUtils.isEmpty(id)) return Result.fail("获取单号失败");
if (StringUtils.isEmpty(id)) {
return Result.fail("获取单号失败");
}
doc.setId(id); doc.setId(id);
for (BizPurchaseOrderSub sub : doc.getData()) {
List<BizPurchaseOrderSub> subList = doc.getData();
//设置子表的pid、剩余未出库数量
for (BizPurchaseOrderSub sub : subList) {
sub.setPid(id); sub.setPid(id);
sub.setRemain_num(sub.getNum()); sub.setRemain_num(sub.getNum());
} }
purchaseOrderMapper.add(doc); //插入主表和子表
purchaseOrderMapper.addSub(doc.getData()); mainMapper.insert(doc);
mainMapper.addSub(subList);
//插入附件
List<RecAttachment> uploadImageList = doc.getUploadImageList(); List<RecAttachment> uploadImageList = doc.getUploadImageList();
Long time = System.currentTimeMillis(); Long time = System.currentTimeMillis();
for (RecAttachment attachment : uploadImageList) { for (RecAttachment attachment : uploadImageList) {
@ -213,23 +229,28 @@ public class BizPurchaseOrderService {
return Result.success("添加成功", id); return Result.success("添加成功", id);
} }
private Result updateOrder(BizPurchaseOrder doc) { private Result updateMain(BizPurchaseOrder doc) {
String err = checkUpdateStatus(doc.getId()); String docId = doc.getId();
String err = checkUpdateStatus(docId);
if (err != null) return Result.fail(err); if (err != null) return Result.fail(err);
purchaseOrderMapper.delSubByPid(doc.getId()); //更新主表
purchaseOrderMapper.update(doc); mainMapper.update(doc);
//删除旧的子表
mainMapper.delSubByPid(docId);
//插入新的子表
List<BizPurchaseOrderSub> subList = doc.getData(); List<BizPurchaseOrderSub> subList = doc.getData();
for (BizPurchaseOrderSub sub : subList) { subList.forEach(sub -> sub.setRemain_num(sub.getNum()));
sub.setRemain_num(sub.getNum()); mainMapper.addSub(subList);
}
purchaseOrderMapper.addSub(subList);
//附件增删
List<RecAttachment> uploadImageList = doc.getUploadImageList(); List<RecAttachment> uploadImageList = doc.getUploadImageList();
Long time = System.currentTimeMillis(); Long time = System.currentTimeMillis();
for (RecAttachment attachment : uploadImageList) { for (RecAttachment attachment : uploadImageList) {
attachment.setPid(doc.getId()); attachment.setPid(docId);
attachment.setTime(time); attachment.setTime(time);
} }
recService.handleAttachment(uploadImageList, doc.getDeleteImageList()); recService.handleAttachment(uploadImageList, doc.getDeleteImageList());
@ -239,8 +260,10 @@ public class BizPurchaseOrderService {
//只有拟定状态的单据才能修改 //只有拟定状态的单据才能修改
private String checkUpdateStatus(String id) { private String checkUpdateStatus(String id) {
BizPurchaseOrder doc = purchaseOrderMapper.getById(id); BizPurchaseOrder doc = mainMapper.getById(id);
if (doc == null || !doc.getStatus().equals(0)) return "单据状态已更新,请刷新后重试"; if (doc == null || !doc.getStatus().equals(DocStatusEnum.DRAFT.getCode())) {
return "单据状态已更新,请刷新后重试";
}
return null; return null;
} }
} }

@ -2,10 +2,9 @@ package com.toesbieya.my.service;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.toesbieya.my.annoation.Lock; import com.toesbieya.my.annoation.Lock;
import com.toesbieya.my.annoation.Tx;
import com.toesbieya.my.annoation.UserAction; import com.toesbieya.my.annoation.UserAction;
import com.toesbieya.my.enumeration.BizDocumentHistoryEnum; import com.toesbieya.my.enumeration.DocHistoryEnum;
import com.toesbieya.my.enumeration.BizDocumentStatusEnum; import com.toesbieya.my.enumeration.DocStatusEnum;
import com.toesbieya.my.mapper.BizDocumentHistoryMapper; import com.toesbieya.my.mapper.BizDocumentHistoryMapper;
import com.toesbieya.my.mapper.BizSellOrderMapper; import com.toesbieya.my.mapper.BizSellOrderMapper;
import com.toesbieya.my.mapper.BizStockMapper; import com.toesbieya.my.mapper.BizStockMapper;
@ -22,6 +21,7 @@ import com.toesbieya.my.utils.ExcelUtil;
import com.toesbieya.my.utils.Result; import com.toesbieya.my.utils.Result;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -34,69 +34,66 @@ import java.util.stream.Collectors;
@Slf4j @Slf4j
public class BizSellOrderService { public class BizSellOrderService {
@Resource @Resource
private BizSellOrderMapper sellOrderMapper; private BizSellOrderMapper mainMapper;
@Resource @Resource
private BizStockMapper stockMapper; private BizStockMapper stockMapper;
@Resource @Resource
private BizDocumentHistoryMapper documentHistoryMapper; private BizDocumentHistoryMapper historyMapper;
@Resource @Resource
private RecService recService; private RecService recService;
public BizSellOrder getById(String id) { public BizSellOrder getById(String id) {
BizSellOrder order = sellOrderMapper.getById(id); BizSellOrder main = mainMapper.getById(id);
if (order == null) return null; if (main == null) return null;
List<BizSellOrderSub> list = sellOrderMapper.getSubById(id); main.setData(this.getSubById(id));
order.setData(list); main.setImageList(recService.getAttachmentByPid(id));
List<RecAttachment> imageList = recService.getAttachmentByPid(id);
order.setImageList(imageList);
return order; return main;
} }
public List<BizSellOrderSub> getSubById(String id) { public List<BizSellOrderSub> getSubById(String id) {
return sellOrderMapper.getSubById(id); return mainMapper.getSubById(id);
} }
public PageResult<BizSellOrder> search(SellOrderSearch vo) { public PageResult<BizSellOrder> search(SellOrderSearch vo) {
PageHelper.startPage(vo.getPage(), vo.getPageSize()); PageHelper.startPage(vo.getPage(), vo.getPageSize());
return new PageResult<>(sellOrderMapper.search(vo)); return new PageResult<>(mainMapper.search(vo));
} }
public void export(SellOrderSearch vo, HttpServletResponse response) throws Exception { public void export(SellOrderSearch vo, HttpServletResponse response) throws Exception {
List<SellOrderExport> list = sellOrderMapper.export(vo); List<SellOrderExport> list = mainMapper.export(vo);
ExcelUtil.exportSimply(list, response, "销售订单导出"); ExcelUtil.exportSimply(list, response, "销售订单导出");
} }
@UserAction("'添加销售订单'") @UserAction("'添加销售订单'")
@Tx @Transactional(rollbackFor = Exception.class)
public Result add(BizSellOrder doc) { public Result add(BizSellOrder doc) {
return addOrder(doc); return addMain(doc);
} }
@UserAction("'修改销售订单'+#doc.id") @UserAction("'修改销售订单'+#doc.id")
@Lock("#doc.id") @Lock("#doc.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result update(BizSellOrder doc) { public Result update(BizSellOrder doc) {
return updateOrder(doc); return updateMain(doc);
} }
@UserAction("'提交销售订单'+#doc.id") @UserAction("'提交销售订单'+#doc.id")
@Lock("#doc.id") @Lock("#doc.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result commit(BizSellOrder doc) { public Result commit(BizSellOrder doc) {
boolean isFirstCreate = StringUtils.isEmpty(doc.getId()); boolean isFirstCreate = StringUtils.isEmpty(doc.getId());
Result result = isFirstCreate ? addOrder(doc) : updateOrder(doc); Result result = isFirstCreate ? addMain(doc) : updateMain(doc);
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(doc.getId()) .pid(doc.getId())
.type(BizDocumentHistoryEnum.COMMIT.getCode()) .type(DocHistoryEnum.COMMIT.getCode())
.uid(doc.getCid()) .uid(doc.getCid())
.uname(doc.getCname()) .uname(doc.getCname())
.status_before(BizDocumentStatusEnum.DRAFT.getCode()) .status_before(DocStatusEnum.DRAFT.getCode())
.status_after(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_after(DocStatusEnum.WAIT_VERIFY.getCode())
.time(System.currentTimeMillis()) .time(System.currentTimeMillis())
.build() .build()
); );
@ -107,23 +104,23 @@ public class BizSellOrderService {
@UserAction("'撤回销售订单'+#vo.id") @UserAction("'撤回销售订单'+#vo.id")
@Lock("#vo.id") @Lock("#vo.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result withdraw(DocumentStatusUpdate vo, UserVo user) { public Result withdraw(DocumentStatusUpdate vo, UserVo user) {
String id = vo.getId(); String id = vo.getId();
String info = vo.getInfo(); String info = vo.getInfo();
if (sellOrderMapper.reject(id) < 1) { if (mainMapper.reject(id) < 1) {
return Result.fail("撤回失败,请刷新重试"); return Result.fail("撤回失败,请刷新重试");
} }
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(id) .pid(id)
.type(BizDocumentHistoryEnum.WITHDRAW.getCode()) .type(DocHistoryEnum.WITHDRAW.getCode())
.uid(user.getId()) .uid(user.getId())
.uname(user.getName()) .uname(user.getName())
.status_before(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_before(DocStatusEnum.WAIT_VERIFY.getCode())
.status_after(BizDocumentStatusEnum.DRAFT.getCode()) .status_after(DocStatusEnum.DRAFT.getCode())
.time(System.currentTimeMillis()) .time(System.currentTimeMillis())
.info(info) .info(info)
.build() .build()
@ -134,24 +131,24 @@ public class BizSellOrderService {
@UserAction("'通过销售订单'+#vo.id") @UserAction("'通过销售订单'+#vo.id")
@Lock("#vo.id") @Lock("#vo.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result pass(DocumentStatusUpdate vo, UserVo user) { public Result pass(DocumentStatusUpdate vo, UserVo user) {
String id = vo.getId(); String id = vo.getId();
String info = vo.getInfo(); String info = vo.getInfo();
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if (sellOrderMapper.pass(id, user.getId(), user.getName(), now) < 1) { if (mainMapper.pass(id, user.getId(), user.getName(), now) < 1) {
return Result.fail("通过失败,请刷新重试"); return Result.fail("通过失败,请刷新重试");
} }
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(id) .pid(id)
.type(BizDocumentHistoryEnum.PASS.getCode()) .type(DocHistoryEnum.PASS.getCode())
.uid(user.getId()) .uid(user.getId())
.uname(user.getName()) .uname(user.getName())
.status_before(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_before(DocStatusEnum.WAIT_VERIFY.getCode())
.status_after(BizDocumentStatusEnum.VERIFIED.getCode()) .status_after(DocStatusEnum.VERIFIED.getCode())
.time(now) .time(now)
.info(info) .info(info)
.build() .build()
@ -162,23 +159,23 @@ public class BizSellOrderService {
@UserAction("'驳回销售订单'+#vo.id") @UserAction("'驳回销售订单'+#vo.id")
@Lock("#vo.id") @Lock("#vo.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result reject(DocumentStatusUpdate vo, UserVo user) { public Result reject(DocumentStatusUpdate vo, UserVo user) {
String id = vo.getId(); String id = vo.getId();
String info = vo.getInfo(); String info = vo.getInfo();
if (sellOrderMapper.reject(id) < 1) { if (mainMapper.reject(id) < 1) {
return Result.fail("驳回失败,请刷新重试"); return Result.fail("驳回失败,请刷新重试");
} }
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(id) .pid(id)
.type(BizDocumentHistoryEnum.REJECT.getCode()) .type(DocHistoryEnum.REJECT.getCode())
.uid(user.getId()) .uid(user.getId())
.uname(user.getName()) .uname(user.getName())
.status_before(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_before(DocStatusEnum.WAIT_VERIFY.getCode())
.status_after(BizDocumentStatusEnum.DRAFT.getCode()) .status_after(DocStatusEnum.DRAFT.getCode())
.time(System.currentTimeMillis()) .time(System.currentTimeMillis())
.info(info) .info(info)
.build() .build()
@ -189,30 +186,43 @@ public class BizSellOrderService {
@UserAction("'删除销售订单'+#id") @UserAction("'删除销售订单'+#id")
@Lock("#id") @Lock("#id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result del(String id) { public Result del(String id) {
if (sellOrderMapper.del(id) < 1) return Result.fail("删除失败"); if (mainMapper.del(id) < 1) {
sellOrderMapper.delSubByPid(id); return Result.fail("删除失败");
}
//同时删除子表和附件
mainMapper.delSubByPid(id);
recService.delAttachmentByPid(id); recService.delAttachmentByPid(id);
return Result.success("删除成功"); return Result.success("删除成功");
} }
private Result addOrder(BizSellOrder doc) { private Result addMain(BizSellOrder doc) {
String err = checkStock(doc.getData()); String err = checkStock(doc.getData());
if (err != null) return Result.fail(err); if (err != null) return Result.fail(err);
String id = DocumentUtil.getDocumentID("XSDD"); String id = DocumentUtil.getDocumentID("XSDD");
if (StringUtils.isEmpty(id)) return Result.fail("获取单号失败");
if (StringUtils.isEmpty(id)) {
return Result.fail("获取单号失败");
}
doc.setId(id); doc.setId(id);
for (BizSellOrderSub sub : doc.getData()) {
List<BizSellOrderSub> subList = doc.getData();
for (BizSellOrderSub sub : subList) {
sub.setPid(id); sub.setPid(id);
sub.setRemain_num(sub.getNum()); sub.setRemain_num(sub.getNum());
} }
sellOrderMapper.add(doc); //插入主表和子表
sellOrderMapper.addSub(doc.getData()); mainMapper.insert(doc);
mainMapper.addSub(subList);
//插入附件
List<RecAttachment> uploadImageList = doc.getUploadImageList(); List<RecAttachment> uploadImageList = doc.getUploadImageList();
Long time = System.currentTimeMillis(); Long time = System.currentTimeMillis();
for (RecAttachment attachment : uploadImageList) { for (RecAttachment attachment : uploadImageList) {
@ -224,24 +234,29 @@ public class BizSellOrderService {
return Result.success("添加成功", id); return Result.success("添加成功", id);
} }
private Result updateOrder(BizSellOrder doc) { private Result updateMain(BizSellOrder doc) {
String err = checkUpdateStatus(doc.getId()); String docId = doc.getId();
String err = checkUpdateStatus(docId);
if (err == null) err = checkStock(doc.getData()); if (err == null) err = checkStock(doc.getData());
if (err != null) return Result.fail(err); if (err != null) return Result.fail(err);
sellOrderMapper.delSubByPid(doc.getId()); //更新主表
sellOrderMapper.update(doc); mainMapper.update(doc);
//删除旧的子表
mainMapper.delSubByPid(docId);
//插入新的子表
List<BizSellOrderSub> subList = doc.getData(); List<BizSellOrderSub> subList = doc.getData();
for (BizSellOrderSub sub : subList) { subList.forEach(sub->sub.setRemain_num(sub.getNum()));
sub.setRemain_num(sub.getNum()); mainMapper.addSub(subList);
}
sellOrderMapper.addSub(subList);
//附件增删
List<RecAttachment> uploadImageList = doc.getUploadImageList(); List<RecAttachment> uploadImageList = doc.getUploadImageList();
Long time = System.currentTimeMillis(); Long time = System.currentTimeMillis();
for (RecAttachment attachment : uploadImageList) { for (RecAttachment attachment : uploadImageList) {
attachment.setPid(doc.getId()); attachment.setPid(docId);
attachment.setTime(time); attachment.setTime(time);
} }
recService.handleAttachment(uploadImageList, doc.getDeleteImageList()); recService.handleAttachment(uploadImageList, doc.getDeleteImageList());
@ -251,8 +266,10 @@ public class BizSellOrderService {
//只有拟定状态的单据才能修改 //只有拟定状态的单据才能修改
private String checkUpdateStatus(String id) { private String checkUpdateStatus(String id) {
BizSellOrder doc = sellOrderMapper.getById(id); BizSellOrder doc = mainMapper.getById(id);
if (doc == null || !doc.getStatus().equals(0)) return "单据状态已更新,请刷新后重试"; if (doc == null || !doc.getStatus().equals(DocStatusEnum.DRAFT.getCode())) {
return "单据状态已更新,请刷新后重试";
}
return null; return null;
} }
@ -268,7 +285,7 @@ public class BizSellOrderService {
int stockListLength = stockList.size(); int stockListLength = stockList.size();
if (subListLength != stockListLength) { if (subListLength != stockListLength) {
BizSellOrderSub sub = list.get(stockListLength); BizSellOrderSub sub = list.get(stockListLength);
return "商品【" + sub.getCname() + "】库存不足"; return String.format("商品【%s】库存不足", sub.getCname());
} }
list.sort(Comparator.comparing(BizDocumentSub::getCid)); list.sort(Comparator.comparing(BizDocumentSub::getCid));
@ -276,8 +293,8 @@ public class BizSellOrderService {
for (int i = 0; i < subListLength; i++) { for (int i = 0; i < subListLength; i++) {
BizSellOrderSub sub = list.get(i); BizSellOrderSub sub = list.get(i);
StockSearchResult stock = stockList.get(i); StockSearchResult stock = stockList.get(i);
if (sub.getNum() > stock.getTotal_num()) { if (sub.getNum().compareTo(stock.getTotal_num()) > 0) {
return "商品【" + sub.getCname() + "】库存不足"; return String.format("商品【%s】库存不足", sub.getCname());
} }
} }

@ -2,11 +2,10 @@ package com.toesbieya.my.service;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.toesbieya.my.annoation.Lock; import com.toesbieya.my.annoation.Lock;
import com.toesbieya.my.annoation.Tx;
import com.toesbieya.my.annoation.UserAction; import com.toesbieya.my.annoation.UserAction;
import com.toesbieya.my.enumeration.BizDocumentFinishEnum; import com.toesbieya.my.enumeration.DocFinishEnum;
import com.toesbieya.my.enumeration.BizDocumentHistoryEnum; import com.toesbieya.my.enumeration.DocHistoryEnum;
import com.toesbieya.my.enumeration.BizDocumentStatusEnum; import com.toesbieya.my.enumeration.DocStatusEnum;
import com.toesbieya.my.exception.JsonResultException; import com.toesbieya.my.exception.JsonResultException;
import com.toesbieya.my.mapper.BizDocumentHistoryMapper; import com.toesbieya.my.mapper.BizDocumentHistoryMapper;
import com.toesbieya.my.mapper.BizSellOrderMapper; import com.toesbieya.my.mapper.BizSellOrderMapper;
@ -18,13 +17,19 @@ import com.toesbieya.my.model.vo.export.SellOutboundExport;
import com.toesbieya.my.model.vo.result.PageResult; import com.toesbieya.my.model.vo.result.PageResult;
import com.toesbieya.my.model.vo.search.SellOutboundSearch; import com.toesbieya.my.model.vo.search.SellOutboundSearch;
import com.toesbieya.my.model.vo.update.DocumentStatusUpdate; import com.toesbieya.my.model.vo.update.DocumentStatusUpdate;
import com.toesbieya.my.utils.*; import com.toesbieya.my.utils.DocumentUtil;
import com.toesbieya.my.utils.ExcelUtil;
import com.toesbieya.my.utils.Result;
import com.toesbieya.my.utils.Util;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -34,11 +39,11 @@ import java.util.stream.Collectors;
@Slf4j @Slf4j
public class BizSellOutboundService { public class BizSellOutboundService {
@Resource @Resource
private BizSellOutboundMapper sellOutboundMapper; private BizSellOutboundMapper mainMapper;
@Resource @Resource
private BizSellOrderMapper sellOrderMapper; private BizSellOrderMapper orderMapper;
@Resource @Resource
private BizDocumentHistoryMapper documentHistoryMapper; private BizDocumentHistoryMapper historyMapper;
@Resource @Resource
private BizStockMapper stockMapper; private BizStockMapper stockMapper;
@Resource @Resource
@ -47,58 +52,58 @@ public class BizSellOutboundService {
private BizStockService stockService; private BizStockService stockService;
public BizSellOutbound getById(String id) { public BizSellOutbound getById(String id) {
BizSellOutbound outbound = sellOutboundMapper.getById(id); BizSellOutbound main = mainMapper.getById(id);
if (outbound == null) return null;
List<BizSellOutboundSub> list = sellOutboundMapper.getSubById(id); if (main == null) return null;
outbound.setData(list);
List<RecAttachment> imageList = recService.getAttachmentByPid(id); main.setData(this.getSubById(id));
outbound.setImageList(imageList); main.setImageList(recService.getAttachmentByPid(id));
return outbound;
return main;
} }
public List<BizSellOutboundSub> getSubById(String pid) { public List<BizSellOutboundSub> getSubById(String pid) {
return sellOutboundMapper.getSubById(pid); return mainMapper.getSubById(pid);
} }
public PageResult<BizSellOutbound> search(SellOutboundSearch vo) { public PageResult<BizSellOutbound> search(SellOutboundSearch vo) {
PageHelper.startPage(vo.getPage(), vo.getPageSize()); PageHelper.startPage(vo.getPage(), vo.getPageSize());
List<BizSellOutbound> list = sellOutboundMapper.search(vo); return new PageResult<>(mainMapper.search(vo));
return new PageResult<>(list);
} }
public void export(SellOutboundSearch vo, HttpServletResponse response) throws Exception { public void export(SellOutboundSearch vo, HttpServletResponse response) throws Exception {
List<SellOutboundExport> list = sellOutboundMapper.export(vo); List<SellOutboundExport> list = mainMapper.export(vo);
ExcelUtil.exportSimply(list, response, "销售出库单导出"); ExcelUtil.exportSimply(list, response, "销售出库单导出");
} }
@UserAction("'添加销售出库单'") @UserAction("'添加销售出库单'")
@Tx @Transactional(rollbackFor = Exception.class)
public Result add(BizSellOutbound doc) { public Result add(BizSellOutbound doc) {
return addOutbound(doc); return addMain(doc);
} }
@UserAction("'修改销售出库单'+#doc.id") @UserAction("'修改销售出库单'+#doc.id")
@Lock("#doc.id") @Lock("#doc.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result update(BizSellOutbound doc) { public Result update(BizSellOutbound doc) {
return updateOutbound(doc); return updateMain(doc);
} }
@UserAction("'提交销售出库单'+#doc.id") @UserAction("'提交销售出库单'+#doc.id")
@Lock("#doc.id") @Lock("#doc.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result commit(BizSellOutbound doc) { public Result commit(BizSellOutbound doc) {
boolean isFirstCreate = StringUtils.isEmpty(doc.getId()); boolean isFirstCreate = StringUtils.isEmpty(doc.getId());
Result result = isFirstCreate ? addOutbound(doc) : updateOutbound(doc); Result result = isFirstCreate ? addMain(doc) : updateMain(doc);
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(doc.getId()) .pid(doc.getId())
.type(BizDocumentHistoryEnum.COMMIT.getCode()) .type(DocHistoryEnum.COMMIT.getCode())
.uid(doc.getCid()) .uid(doc.getCid())
.uname(doc.getCname()) .uname(doc.getCname())
.status_before(BizDocumentStatusEnum.DRAFT.getCode()) .status_before(DocStatusEnum.DRAFT.getCode())
.status_after(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_after(DocStatusEnum.WAIT_VERIFY.getCode())
.time(System.currentTimeMillis()) .time(System.currentTimeMillis())
.build() .build()
); );
@ -109,23 +114,23 @@ public class BizSellOutboundService {
@UserAction("'撤回销售出库单'+#vo.id") @UserAction("'撤回销售出库单'+#vo.id")
@Lock("#vo.id") @Lock("#vo.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result withdraw(DocumentStatusUpdate vo, UserVo user) { public Result withdraw(DocumentStatusUpdate vo, UserVo user) {
String id = vo.getId(); String id = vo.getId();
String info = vo.getInfo(); String info = vo.getInfo();
if (sellOutboundMapper.reject(id) < 1) { if (mainMapper.reject(id) < 1) {
return Result.fail("撤回失败,请刷新重试"); return Result.fail("撤回失败,请刷新重试");
} }
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(id) .pid(id)
.type(BizDocumentHistoryEnum.WITHDRAW.getCode()) .type(DocHistoryEnum.WITHDRAW.getCode())
.uid(user.getId()) .uid(user.getId())
.uname(user.getName()) .uname(user.getName())
.status_before(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_before(DocStatusEnum.WAIT_VERIFY.getCode())
.status_after(BizDocumentStatusEnum.DRAFT.getCode()) .status_after(DocStatusEnum.DRAFT.getCode())
.time(System.currentTimeMillis()) .time(System.currentTimeMillis())
.info(info) .info(info)
.build() .build()
@ -136,59 +141,70 @@ public class BizSellOutboundService {
@UserAction("'通过销售出库单'+#vo.id") @UserAction("'通过销售出库单'+#vo.id")
@Lock({"#vo.pid", "#vo.id"}) @Lock({"#vo.pid", "#vo.id"})
@Tx @Transactional(rollbackFor = Exception.class)
public Result pass(DocumentStatusUpdate vo, UserVo user) { public Result pass(DocumentStatusUpdate vo, UserVo user) {
String id = vo.getId(); String id = vo.getId();
String info = vo.getInfo(); String info = vo.getInfo();
String pid = vo.getPid(); String pid = vo.getPid();
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
List<BizSellOutboundSub> outboundSubList = sellOutboundMapper.getSubById(vo.getId()); List<BizSellOutboundSub> subList = this.getSubById(vo.getId());
String err = check(vo.getPid(), outboundSubList); String err = check(vo.getPid(), subList);
if (err != null) return Result.fail("通过失败," + err); if (err != null) return Result.fail("通过失败," + err);
if (sellOutboundMapper.pass(id, user.getId(), user.getName(), now) < 1) { if (mainMapper.pass(id, user.getId(), user.getName(), now) < 1) {
return Result.fail("通过失败,请刷新重试"); return Result.fail("通过失败,请刷新重试");
} }
//获取销售订单子表
List<BizSellOrderSub> orderSubList = sellOrderMapper.getSubById(pid);
//按分类分组统计出库数量,并出库 //按分类分组统计出库数量,并出库
Map<Integer, Double> outboundCount = new HashMap<>(); Map<Integer, BigDecimal> outboundCount = new HashMap<>();
for (BizSellOutboundSub outboundSub : outboundSubList) { for (BizSellOutboundSub outboundSub : subList) {
int rows = stockMapper.outbound(outboundSub.getSid(), outboundSub.getNum()); int rows = stockMapper.outbound(outboundSub.getSid(), outboundSub.getNum());
if (rows == 0) throw new JsonResultException("通过失败,商品" + outboundSub.getCname() + "库存不足"); if (rows == 0) {
throw new JsonResultException(String.format("通过失败,商品%s库存不足", outboundSub.getCname()));
}
Integer cid = outboundSub.getCid(); Integer cid = outboundSub.getCid();
Double num = outboundCount.getOrDefault(cid, 0D); BigDecimal num = outboundCount.getOrDefault(cid, BigDecimal.ZERO);
outboundCount.put(cid, num + outboundSub.getNum()); outboundCount.put(cid, num.add(outboundSub.getNum()));
} }
//更新销售订单子表的剩余未出库数量,记录销售订单的完成情况 //更新销售订单子表的剩余未出库数量,记录销售订单的完成情况
BizDocumentFinishEnum finish = BizDocumentFinishEnum.FINISHED; DocFinishEnum finish = DocFinishEnum.FINISHED;
List<BizSellOrderSub> orderSubList = orderMapper.getSubById(pid);
for (BizSellOrderSub orderSub : orderSubList) { for (BizSellOrderSub orderSub : orderSubList) {
if (orderSub.getRemain_num().equals(0D)) continue; if (orderSub.getRemain_num().equals(BigDecimal.ZERO)) {
Double outboundNum = outboundCount.get(orderSub.getCid()); continue;
}
BigDecimal outboundNum = outboundCount.get(orderSub.getCid());
if (outboundNum == null) continue; if (outboundNum == null) continue;
double gap = orderSub.getRemain_num() - outboundNum; BigDecimal gap = orderSub.getRemain_num().subtract(outboundNum);
if (gap > 0) finish = BizDocumentFinishEnum.UNDERWAY;
//如果有任意一个采购商品的remain_num大于采购商品的num,则完成情况为进行中,否则为已完成
if (gap.compareTo(BigDecimal.ZERO) > 0) {
finish = DocFinishEnum.UNDERWAY;
}
sellOrderMapper.updateSubRemainNum(orderSub.getId(), gap); orderMapper.updateSubRemainNum(orderSub.getId(), gap);
} }
//更新销售订单完成情况 //更新销售订单完成情况
sellOrderMapper.updateFinish(pid, finish.getCode(), finish == BizDocumentFinishEnum.FINISHED ? now : null); if (1 > orderMapper.updateFinish(pid, finish.getCode(), finish == DocFinishEnum.FINISHED ? now : null)) {
throw new JsonResultException("通过失败,销售订单状态有误,请刷新重试");
}
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(id) .pid(id)
.type(BizDocumentHistoryEnum.PASS.getCode()) .type(DocHistoryEnum.PASS.getCode())
.uid(user.getId()) .uid(user.getId())
.uname(user.getName()) .uname(user.getName())
.status_before(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_before(DocStatusEnum.WAIT_VERIFY.getCode())
.status_after(BizDocumentStatusEnum.VERIFIED.getCode()) .status_after(DocStatusEnum.VERIFIED.getCode())
.time(now) .time(now)
.info(info) .info(info)
.build() .build()
@ -199,23 +215,23 @@ public class BizSellOutboundService {
@UserAction("'驳回销售出库单'+#vo.id") @UserAction("'驳回销售出库单'+#vo.id")
@Lock("#vo.id") @Lock("#vo.id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result reject(DocumentStatusUpdate vo, UserVo user) { public Result reject(DocumentStatusUpdate vo, UserVo user) {
String id = vo.getId(); String id = vo.getId();
String info = vo.getInfo(); String info = vo.getInfo();
if (sellOutboundMapper.reject(id) < 1) { if (mainMapper.reject(id) < 1) {
return Result.fail("驳回失败,请刷新重试"); return Result.fail("驳回失败,请刷新重试");
} }
documentHistoryMapper.add( historyMapper.insert(
BizDocumentHistory.builder() BizDocumentHistory.builder()
.pid(id) .pid(id)
.type(BizDocumentHistoryEnum.REJECT.getCode()) .type(DocHistoryEnum.REJECT.getCode())
.uid(user.getId()) .uid(user.getId())
.uname(user.getName()) .uname(user.getName())
.status_before(BizDocumentStatusEnum.WAIT_VERIFY.getCode()) .status_before(DocStatusEnum.WAIT_VERIFY.getCode())
.status_after(BizDocumentStatusEnum.DRAFT.getCode()) .status_after(DocStatusEnum.DRAFT.getCode())
.time(System.currentTimeMillis()) .time(System.currentTimeMillis())
.info(info) .info(info)
.build() .build()
@ -226,29 +242,39 @@ public class BizSellOutboundService {
@UserAction("'删除销售出库单'+#id") @UserAction("'删除销售出库单'+#id")
@Lock("#id") @Lock("#id")
@Tx @Transactional(rollbackFor = Exception.class)
public Result del(String id) { public Result del(String id) {
if (sellOutboundMapper.del(id) < 1) return Result.fail("删除失败"); if (mainMapper.del(id) < 1) {
sellOutboundMapper.delSubByPid(id); return Result.fail("删除失败");
}
//同时删除子表和附件
mainMapper.delSubByPid(id);
recService.delAttachmentByPid(id); recService.delAttachmentByPid(id);
return Result.success("删除成功"); return Result.success("删除成功");
} }
private Result addOutbound(BizSellOutbound doc) { private Result addMain(BizSellOutbound doc) {
String err = check(doc.getPid(), doc.getData()); List<BizSellOutboundSub> subList = doc.getData();
String err = check(doc.getPid(), subList);
if (err != null) return Result.fail(err); if (err != null) return Result.fail(err);
String id = DocumentUtil.getDocumentID("XSCK"); String id = DocumentUtil.getDocumentID("XSCK");
if (StringUtils.isEmpty(id)) return Result.fail("获取单号失败");
doc.setId(id); if (StringUtils.isEmpty(id)) {
for (BizSellOutboundSub sub : doc.getData()) { return Result.fail("获取单号失败");
sub.setPid(id);
} }
sellOutboundMapper.add(doc); doc.setId(id);
sellOutboundMapper.addSub(doc.getData());
subList.forEach(sub -> sub.setPid(id));
mainMapper.insert(doc);
mainMapper.addSub(subList);
//插入附件
List<RecAttachment> uploadImageList = doc.getUploadImageList(); List<RecAttachment> uploadImageList = doc.getUploadImageList();
Long time = System.currentTimeMillis(); Long time = System.currentTimeMillis();
for (RecAttachment attachment : uploadImageList) { for (RecAttachment attachment : uploadImageList) {
@ -260,19 +286,21 @@ public class BizSellOutboundService {
return Result.success("添加成功", id); return Result.success("添加成功", id);
} }
private Result updateOutbound(BizSellOutbound doc) { private Result updateMain(BizSellOutbound doc) {
String err = checkUpdateStatus(doc.getId()); String docId = doc.getId();
String err = checkUpdateStatus(docId);
if (err == null) err = check(doc.getPid(), doc.getData()); if (err == null) err = check(doc.getPid(), doc.getData());
if (err != null) return Result.fail(err); if (err != null) return Result.fail(err);
sellOutboundMapper.delSubByPid(doc.getId()); mainMapper.update(doc);
sellOutboundMapper.update(doc); mainMapper.delSubByPid(docId);
sellOutboundMapper.addSub(doc.getData()); mainMapper.addSub(doc.getData());
List<RecAttachment> uploadImageList = doc.getUploadImageList(); List<RecAttachment> uploadImageList = doc.getUploadImageList();
Long time = System.currentTimeMillis(); Long time = System.currentTimeMillis();
for (RecAttachment attachment : uploadImageList) { for (RecAttachment attachment : uploadImageList) {
attachment.setPid(doc.getId()); attachment.setPid(docId);
attachment.setTime(time); attachment.setTime(time);
} }
recService.handleAttachment(uploadImageList, doc.getDeleteImageList()); recService.handleAttachment(uploadImageList, doc.getDeleteImageList());
@ -282,33 +310,33 @@ public class BizSellOutboundService {
//只有拟定状态的单据才能修改 //只有拟定状态的单据才能修改
private String checkUpdateStatus(String id) { private String checkUpdateStatus(String id) {
BizSellOutbound doc = sellOutboundMapper.getById(id); BizSellOutbound doc = mainMapper.getById(id);
if (doc == null || !doc.getStatus().equals(0)) return "单据状态已更新,请刷新后重试"; if (doc == null || !doc.getStatus().equals(DocStatusEnum.DRAFT.getCode())) {
return "单据状态已更新,请刷新后重试";
}
return null; return null;
} }
//添加、修改、通过前都需要检查 //添加、修改、通过前都需要检查
private String check(String pid, List<BizSellOutboundSub> docSubList) { private String check(String pid, List<BizSellOutboundSub> docSubList) {
BizSellOrder order = sellOrderMapper.getById(pid); BizSellOrder order = orderMapper.getById(pid);
//检查销售订单是否已审核、未完成 //检查销售订单是否已审核、未完成
if (order == null || order.getStatus() != 2 || order.getFinish() == 2) { if (order == null
|| !order.getStatus().equals(DocStatusEnum.VERIFIED.getCode())
|| order.getFinish().equals(DocFinishEnum.FINISHED.getCode())
) {
return "销售订单状态异常"; return "销售订单状态异常";
} }
List<BizSellOrderSub> orderSubList = sellOrderMapper.getSubById(pid); List<BizSellOrderSub> orderSubList = orderMapper.getSubById(pid);
if (orderSubList.size() <= 0) return "没有找到销售订单的数据";
if (CollectionUtils.isEmpty(orderSubList)) {
return "没有找到销售订单的数据";
}
//按分类统计商品的出库数量 //按分类统计商品的出库数量
Map<Integer, Double> outboundCount = Map<Integer, BigDecimal> outboundCount = this.getOutboundCount(docSubList);
docSubList
.stream()
.collect(
Collectors.groupingBy(
BizSellOutboundSub::getCid,
Collectors.summingDouble(BizSellOutboundSub::getNum)
)
);
String[] cids = new String[outboundCount.size()]; String[] cids = new String[outboundCount.size()];
@ -320,11 +348,11 @@ public class BizSellOutboundService {
if (orderSub == null) { if (orderSub == null) {
return "未在销售订单中找到对应的出库商品"; return "未在销售订单中找到对应的出库商品";
} }
if (orderSub.getRemain_num().equals(0D)) { if (orderSub.getRemain_num().equals(BigDecimal.ZERO)) {
return "出库商品【" + orderSub.getCname() + "】已全部出库"; return String.format("出库商品【%s】已全部出库", orderSub.getCname());
} }
if (orderSub.getRemain_num() < outboundCount.get(cid)) { if (orderSub.getRemain_num().compareTo(outboundCount.get(cid)) < 0) {
return "出库商品【" + orderSub.getCname() + "】的数量超出订单数量"; return String.format("出库商品【%s】的数量超出订单数量", orderSub.getCname());
} }
cids[index] = String.valueOf(cid); cids[index] = String.valueOf(cid);
index++; index++;
@ -334,11 +362,29 @@ public class BizSellOutboundService {
List<BizStock> stockList = stockService.getDetail(String.join(",", cids)); List<BizStock> stockList = stockService.getDetail(String.join(",", cids));
for (BizSellOutboundSub sub : docSubList) { for (BizSellOutboundSub sub : docSubList) {
BizStock stock = Util.find(stockList, i -> i.getId().equals(sub.getSid())); BizStock stock = Util.find(stockList, i -> i.getId().equals(sub.getSid()));
if (stock == null || stock.getNum() < sub.getNum()) { if (stock == null || stock.getNum().compareTo(sub.getNum()) < 0) {
return "出库商品【" + sub.getCname() + "】(采购入库单:" + sub.getPid() + ")库存不足"; return String.format("出库商品【%s】(采购入库单:%s)库存不足", sub.getCname(), sub.getPid());
} }
} }
return null; return null;
} }
private Map<Integer, BigDecimal> getOutboundCount(List<BizSellOutboundSub> list) {
if (CollectionUtils.isEmpty(list)) {
return new HashMap<>();
}
return list
.stream()
.collect(
Collectors.groupingBy(
BizSellOutboundSub::getCid,
Collectors.reducing(
BigDecimal.ZERO,
BizSellOutboundSub::getNum,
BigDecimal::add
)
)
);
}
} }

@ -30,8 +30,8 @@ public class BizStockService {
return new PageResult<>(stockMapper.search(vo)); return new PageResult<>(stockMapper.search(vo));
} }
public List<BizStock> getDetail(String cid) { public List<BizStock> getDetail(String cids) {
return stockMapper.getDetail(cid); return stockMapper.getDetail(cids);
} }
public List<BizStock> getDetailById(String ids) { public List<BizStock> getDetailById(String ids) {

@ -1,23 +1,27 @@
package com.toesbieya.my.service; package com.toesbieya.my.service;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.toesbieya.my.annoation.UserAction;
import com.toesbieya.my.constant.MsgConstant; import com.toesbieya.my.constant.MsgConstant;
import com.toesbieya.my.constant.SocketConstant; import com.toesbieya.my.constant.SocketConstant;
import com.toesbieya.my.mapper.MsgMapper; import com.toesbieya.my.mapper.MsgMapper;
import com.toesbieya.my.model.entity.Msg; import com.toesbieya.my.model.entity.Msg;
import com.toesbieya.my.model.entity.MsgState; import com.toesbieya.my.model.entity.MsgState;
import com.toesbieya.my.model.vo.SocketEventVo;
import com.toesbieya.my.model.vo.UserVo; import com.toesbieya.my.model.vo.UserVo;
import com.toesbieya.my.model.vo.result.PageResult; import com.toesbieya.my.model.vo.result.PageResult;
import com.toesbieya.my.model.vo.search.MsgPersonalSearch; import com.toesbieya.my.model.vo.search.MsgPersonalSearch;
import com.toesbieya.my.model.vo.search.MsgSearch; import com.toesbieya.my.model.vo.search.MsgSearch;
import com.toesbieya.my.module.SocketModule;
import com.toesbieya.my.utils.Result; import com.toesbieya.my.utils.Result;
import com.toesbieya.my.utils.WebSocketUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
@Service @Service
@Slf4j @Slf4j
@ -31,35 +35,50 @@ public class MsgService {
return new PageResult<>(list); return new PageResult<>(list);
} }
@UserAction("'添加消息:'+#msg.title")
public Result add(Msg msg) { public Result add(Msg msg) {
msg.setId(msgMapper.insert(msg)); msg.setId(msgMapper.insert(msg));
return Result.success("添加成功", msg); return Result.success("添加成功", msg);
} }
@UserAction("'修改消息:'+#msg.title")
public Result update(Msg msg) { public Result update(Msg msg) {
int rows = msgMapper.update(msg); int rows = msgMapper.update(msg);
return rows > 0 ? Result.success("修改成功") : Result.fail("修改失败,请刷新重试"); return rows > 0 ? Result.success("修改成功") : Result.fail("修改失败,请刷新重试");
} }
@UserAction("'发布消息:'+#msg.title")
public Result publish(Msg msg) { public Result publish(Msg msg) {
boolean isFirstCreate = msg.getId() == null; boolean isFirstCreate = msg.getId() == null;
Result result = isFirstCreate ? add(msg) : update(msg); Result result = isFirstCreate ? add(msg) : update(msg);
if (result.isSuccess()) { if (result.isSuccess()) {
result.setMsg("提交成功"); result.setMsg("提交成功");
result.setData(msg); result.setData(msg);
SocketEventVo eventVo = new SocketEventVo();
eventVo.setEvent(SocketConstant.EVENT_NEW_MESSAGE);
if (msg.getBroadcast().equals(MsgConstant.TO_ALL)) { if (msg.getBroadcast().equals(MsgConstant.TO_ALL)) {
SocketModule.broadcast(SocketConstant.EVENT_NEW_MESSAGE); eventVo.setType(SocketConstant.REDIS_EVENT_BROADCAST);
WebSocketUtil.sendEvent(eventVo);
} }
else { else {
String recipient = msg.getRecipient(); String recipient = msg.getRecipient();
if (!StringUtils.isEmpty(recipient)) { if (!StringUtils.isEmpty(recipient)) {
for (String id : recipient.split(",")) { String[] ids = recipient.split(",");
SocketModule.sendEvent(SocketConstant.EVENT_NEW_MESSAGE, Integer.valueOf(id)); List<Integer> to = Arrays.stream(ids).map(Integer::valueOf).collect(Collectors.toList());
}
eventVo.setType(SocketConstant.REDIS_EVENT_SPECIFIC);
eventVo.setTo(to);
WebSocketUtil.sendEvent(eventVo);
} }
} }
} }
else result.setMsg("发布失败," + result.getMsg()); else result.setMsg("发布失败," + result.getMsg());
return result; return result;
} }

@ -1,21 +1,17 @@
package com.toesbieya.my.service; package com.toesbieya.my.service;
import com.toesbieya.my.mapper.BizPurchaseOrderMapper;
import com.toesbieya.my.mapper.BizSellOrderMapper;
import com.toesbieya.my.mapper.StatisticMapper; import com.toesbieya.my.mapper.StatisticMapper;
import com.toesbieya.my.model.entity.StatFinishOrder; import com.toesbieya.my.model.entity.StatFinishOrder;
import com.toesbieya.my.model.entity.StatProfitGoods; import com.toesbieya.my.model.entity.StatProfitGoods;
import com.toesbieya.my.model.entity.StatProfitTotal; import com.toesbieya.my.model.entity.StatProfitTotal;
import com.toesbieya.my.model.vo.statictis.FourBlockStat; import com.toesbieya.my.model.vo.statictis.FourBlockStat;
import com.toesbieya.my.module.SocketModule;
import com.toesbieya.my.utils.DateUtil; import com.toesbieya.my.utils.DateUtil;
import com.toesbieya.my.utils.WebSocketUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -24,24 +20,25 @@ import java.util.Map;
@Service @Service
@Slf4j @Slf4j
public class StatisticService { public class StatisticService {
@Resource
private BizPurchaseOrderMapper purchaseOrderMapper;
@Resource
private BizSellOrderMapper sellOrderMapper;
@Resource @Resource
private StatisticMapper statisticMapper; private StatisticMapper statisticMapper;
//获取首页四个色块的数据,在线用户、今日采购额、今日销售额、今日毛利润 //获取首页四个色块的数据,在线用户、今日采购额、今日销售额、今日毛利润
public FourBlockStat getFourBlock() { public FourBlockStat getFourBlock() {
long now = DateUtil.getTimestampNow(); long now = DateUtil.getTimestampNow();
FourBlockStat stat = new FourBlockStat(); FourBlockStat stat = new FourBlockStat();
double purchase = purchaseOrderMapper.getDailyTotalPurchasePrice(now, null);
double sell = sellOrderMapper.getDailyTotalPurchasePrice(now, null); BigDecimal purchase = statisticMapper.getPurchaseOrderDailyTotalPurchasePrice(now, null);
int onlineNum = SocketModule.getOnlineNum(); BigDecimal sell = statisticMapper.getSellOrderDailyTotalPurchasePrice(now, null);
stat.setOnline(onlineNum == 0 ? 1 : onlineNum);//进行此请求时在线用户必然大于0
long onlineNum = WebSocketUtil.getOnlineUserNum();
stat.setOnline(onlineNum == 0L ? 1L : onlineNum);//进行此请求时在线用户必然大于0
stat.setPurchase(purchase); stat.setPurchase(purchase);
stat.setSell(sell); stat.setSell(sell);
stat.setProfit(sell - purchase); stat.setProfit(sell.subtract(purchase));
return stat; return stat;
} }
@ -65,109 +62,37 @@ public class StatisticService {
//获取今日的信息 //获取今日的信息
long today = DateUtil.getTimestampNow(); long today = DateUtil.getTimestampNow();
long nextDay = DateUtil.getTimestampBeforeNow(-1); long nextDay = DateUtil.getTimestampBeforeNow(-1);
history.addAll(purchaseOrderMapper.getDailyProfitGoods(today, nextDay)); history.addAll(statisticMapper.getPurchaseOrderDailyProfitGoods(today, nextDay));
history.addAll(sellOrderMapper.getDailyProfitGoods(today, nextDay)); history.addAll(statisticMapper.getSellOrderDailyProfitGoods(today, nextDay));
Map<Integer, StatProfitGoods> map = new HashMap<>(history.size()); Map<Integer, StatProfitGoods> map = new HashMap<>(history.size());
//根据商品分类计算
for (StatProfitGoods p : history) { for (StatProfitGoods p : history) {
Integer cid = p.getCid(); Integer cid = p.getCid();
if (p.getPurchase() == null) p.setPurchase(0D);
if (p.getSell() == null) p.setSell(0D);
if (p.getProfit() == null) p.setProfit(p.getSell() - p.getPurchase());
StatProfitGoods already = map.get(cid);
if (already == null) map.put(cid, p);
else {
Double pT = already.getPurchase() + p.getPurchase();
Double sT = already.getSell() + p.getSell();
already.setPurchase(pT);
already.setSell(sT);
already.setProfit(sT - pT);
}
}
return map.values();
}
//每天零点统计信息 if (p.getPurchase() == null) {
@Async("scheduledExecutor") p.setPurchase(new BigDecimal(0));
@Scheduled(cron = "1 0 0 */1 * ?")
@PostConstruct
public void autoStat() {
log.info("开始统计信息...");
long lastDay = DateUtil.getTimestampBeforeNow(1);
long today = DateUtil.getTimestampNow();
//检查是否已统计过昨日已完成的订单数
if (!statisticMapper.checkDailyFinishOrderExist(lastDay)) {
Integer lastDayPurchaseOrderFinish = purchaseOrderMapper.getLastDayFinishOrderNum();
Integer lastDaySellOrderFinish = sellOrderMapper.getLastDayFinishOrderNum();
StatFinishOrder param = new StatFinishOrder();
param.setPurchase(lastDayPurchaseOrderFinish);
param.setSell(lastDaySellOrderFinish);
param.setTime(lastDay);
statisticMapper.insertFinishOrder(param);
}
//检查是否已统计过昨日的采购额、销售额、毛利
if (!statisticMapper.checkDailyProfitExist(lastDay)) {
//昨日各个商品的采购额、销售额
List<StatProfitGoods> purchaseProfitGoods = purchaseOrderMapper.getDailyProfitGoods(lastDay, today);
List<StatProfitGoods> sellProfitGoods = sellOrderMapper.getDailyProfitGoods(lastDay, today);
//昨日的采购总额、销售总额
double totalPurchase = 0;
double totalSell = 0;
Map<Integer, StatProfitGoods> map = new HashMap<>(sellProfitGoods.size());
for (StatProfitGoods p : sellProfitGoods) {
map.put(p.getCid(), p);
} }
if (p.getSell() == null) {
for (StatProfitGoods p : purchaseProfitGoods) { p.setSell(new BigDecimal(0));
p.setTime(lastDay);
Integer cid = p.getCid();
Double purchase = p.getPurchase();
totalPurchase += purchase;
StatProfitGoods s = map.get(cid);
if (s != null) {
Double sell = s.getSell();
totalSell += sell;
p.setSell(sell);
p.setProfit(sell - purchase);
map.remove(cid);
}
else {
p.setSell(0D);
p.setProfit(-purchase);
}
} }
if (p.getProfit() == null) {
for (StatProfitGoods s : map.values()) { p.setProfit(p.getSell().subtract(p.getPurchase()));
s.setTime(lastDay);
s.setPurchase(0D);
Double sell = s.getSell();
s.setProfit(sell);
totalSell += sell;
purchaseProfitGoods.add(s);
} }
double totalProfit = totalSell - totalPurchase; StatProfitGoods already = map.get(cid);
StatProfitTotal statProfitTotal = new StatProfitTotal();
statProfitTotal.setPurchase(totalPurchase);
statProfitTotal.setSell(totalSell);
statProfitTotal.setProfit(totalProfit);
statProfitTotal.setTime(lastDay);
statisticMapper.insertProfitTotal(statProfitTotal);
if (purchaseProfitGoods.size() > 0) { if (already == null) map.put(cid, p);
statisticMapper.insertProfitGoodsBatch(purchaseProfitGoods); else {
BigDecimal pT = already.getPurchase().add(p.getPurchase());
BigDecimal sT = already.getSell().add(p.getSell());
already.setPurchase(pT);
already.setSell(sT);
already.setProfit(sT.subtract(pT));
} }
} }
log.info("结束统计信息..."); return map.values();
} }
} }

@ -1,20 +1,24 @@
package com.toesbieya.my.service; package com.toesbieya.my.service;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.toesbieya.my.annoation.Tx;
import com.toesbieya.my.annoation.UserAction; import com.toesbieya.my.annoation.UserAction;
import com.toesbieya.my.mapper.SysUserMapper; import com.toesbieya.my.mapper.SysUserMapper;
import com.toesbieya.my.model.entity.SysUser; import com.toesbieya.my.model.entity.SysUser;
import com.toesbieya.my.model.vo.UserVo; import com.toesbieya.my.model.vo.UserVo;
import com.toesbieya.my.model.vo.result.PageResult; import com.toesbieya.my.model.vo.result.PageResult;
import com.toesbieya.my.model.vo.search.UserSearch; import com.toesbieya.my.model.vo.search.UserSearch;
import com.toesbieya.my.module.SocketModule;
import com.toesbieya.my.utils.Result; import com.toesbieya.my.utils.Result;
import com.toesbieya.my.utils.Util;
import com.toesbieya.my.utils.WebSocketUtil;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils; import org.springframework.util.DigestUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Service @Service
public class SysUserService { public class SysUserService {
@ -27,8 +31,12 @@ public class SysUserService {
List<UserVo> users = userMapper.search(vo); List<UserVo> users = userMapper.search(vo);
//当前在线的用户id
Set<Integer> onlineUserIds = WebSocketUtil.getOnlineUserIds();
//设置在线情况
for (UserVo user : users) { for (UserVo user : users) {
user.setOnline(SocketModule.online(user.getId())); user.setOnline(Util.some(onlineUserIds, i -> user.getId().equals(i)));
} }
return new PageResult<>(users); return new PageResult<>(users);
@ -59,18 +67,23 @@ public class SysUserService {
} }
@UserAction("'删除用户:'+#user.name") @UserAction("'删除用户:'+#user.name")
@Tx @Transactional(rollbackFor = Exception.class)
public Result del(SysUser user) { public Result del(SysUser user) {
userMapper.del(user.getId()); int rows = userMapper.del(user.getId());
SocketModule.logout(user.getId(), "该用户已删除"); WebSocketUtil.sendLogoutEvent(Collections.singletonList(user.getId()), "该用户已删除");
return Result.success("删除成功"); return rows > 0 ? Result.success("删除成功") : Result.fail("删除失败,请刷新后重试");
} }
@UserAction @UserAction
public Result kick(List<SysUser> users) { public Result kick(List<SysUser> users) {
for (SysUser user : users) { WebSocketUtil.sendLogoutEvent(
SocketModule.logout(user.getId(), null); users
} .stream()
.map(SysUser::getId)
.collect(Collectors.toList()),
"你已被强制下线,请重新登陆"
);
return Result.success("踢出成功"); return Result.success("踢出成功");
} }

@ -33,9 +33,9 @@ public class DocumentUtil {
RedisScript<Long> redisScript = new DefaultRedisScript<>(GET_DOCUMENT_ID_SCRIPT, Long.class); RedisScript<Long> redisScript = new DefaultRedisScript<>(GET_DOCUMENT_ID_SCRIPT, Long.class);
Long result = RedisUtil.execute( Long result = RedisUtil.getStringRedisTemplate().execute(
redisScript, redisScript,
Arrays.asList(DocumentConstant.DOCUMENT_TYPE_REDIS_KEY, DocumentConstant.DOCUMENT_TYPE_REDIS_KEY), Arrays.asList(DocumentConstant.UPDATE_DOCUMENTS_LOCK_KEY, DocumentConstant.DOCUMENT_TYPE_REDIS_KEY),
String.valueOf(DateUtil.getTimestampNow()), String.valueOf(DateUtil.getTimestampNow()),
type type
); );

@ -4,7 +4,7 @@ import com.google.common.io.ByteStreams;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.*;
import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript; import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -18,19 +18,43 @@ import java.util.concurrent.TimeUnit;
@Slf4j @Slf4j
public class RedisUtil { public class RedisUtil {
private static String INCREMENT_AND_EXPIRE_SCRIPT = null; private static String INCREMENT_AND_EXPIRE_SCRIPT = null;
private static RedisTemplate<Object, Object> redisTemplate; private static RedisTemplate<String, Object> redisTemplate;
private static StringRedisTemplate stringRedisTemplate;
static { static {
try { try {
INCREMENT_AND_EXPIRE_SCRIPT = new String(ByteStreams.toByteArray(new ClassPathResource("/script/increase_and_expire.lua").getInputStream())); INCREMENT_AND_EXPIRE_SCRIPT = new String(ByteStreams.toByteArray(new ClassPathResource("/script/increase_and_expire.lua").getInputStream()));
} catch (IOException e) { }
catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@Autowired @Autowired
public RedisUtil(RedisTemplate<Object, Object> redisTemplate) { public RedisUtil(RedisTemplate<String, Object> redisTemplate, StringRedisTemplate stringRedisTemplate) {
RedisUtil.redisTemplate = redisTemplate; 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) { public static boolean exist(String key) {
@ -38,20 +62,24 @@ public class RedisUtil {
return result != null && result; return result != null && result;
} }
public static void del(String... keys) {
redisTemplate.delete(Arrays.asList(keys));
}
public static long incrAndExpire(String key, int time) { public static long incrAndExpire(String key, int time) {
RedisScript<Long> redisScript = new DefaultRedisScript<>(INCREMENT_AND_EXPIRE_SCRIPT, Long.class); RedisScript<Long> redisScript = new DefaultRedisScript<>(INCREMENT_AND_EXPIRE_SCRIPT, Long.class);
Long result = redisTemplate.execute(redisScript, Collections.singletonList(key), time); Long result = redisTemplate.execute(redisScript, Collections.singletonList(key), time);
return result == null ? 0 : result; return result == null ? 0 : result;
} }
public static void expireImmediately(String key) {
redisTemplate.expire(key, 0L, TimeUnit.MILLISECONDS);
}
public static Object get(String key) { public static Object get(String key) {
return redisTemplate.opsForValue().get(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) { public static void set(String key, Object value, long expire) {
redisTemplate.opsForValue().set(key, value, expire, TimeUnit.SECONDS); redisTemplate.opsForValue().set(key, value, expire, TimeUnit.SECONDS);
} }
@ -60,10 +88,19 @@ public class RedisUtil {
return redisTemplate.opsForHash().get(key, 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) { public static void hset(String key, String field, Object value) {
redisTemplate.opsForHash().put(key, field, value); redisTemplate.opsForHash().put(key, field, value);
} }
//fields需要是String类型
public static void hdel(String key, Object... fields) {
redisTemplate.opsForHash().delete(key, fields);
}
public static List<Object> hmget(String key, String... field) { public static List<Object> hmget(String key, String... field) {
return redisTemplate.opsForHash().multiGet(key, Arrays.asList(field)); return redisTemplate.opsForHash().multiGet(key, Arrays.asList(field));
} }
@ -72,14 +109,33 @@ public class RedisUtil {
redisTemplate.opsForHash().putAll(key, map); redisTemplate.opsForHash().putAll(key, map);
} }
public static <T> T execute(RedisScript<T> script, List<Object> keys, Object... args) { public static long sadd(String key, Object... members) {
return redisTemplate.execute(script, keys, args); 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 RedisTemplate<Object, Object> getRedisTemplate() { public static RedisTemplate<String, Object> getRedisTemplate() {
return redisTemplate; return redisTemplate;
} }
public static StringRedisTemplate getStringRedisTemplate() {
return stringRedisTemplate;
}
public static class Locker implements Closeable { public static class Locker implements Closeable {
private final String key; private final String key;
private final String value; private final String value;
@ -99,14 +155,14 @@ public class RedisUtil {
public boolean lock() { public boolean lock() {
String LOCK_LUA_SCRIPT = "return redis.call('set',KEYS[1],ARGV[1],'EX',ARGV[2],'NX')"; 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); RedisScript<Boolean> redisScript = new DefaultRedisScript<>(LOCK_LUA_SCRIPT, Boolean.class);
Boolean result = RedisUtil.execute(redisScript, Collections.singletonList(key), value, expire); Boolean result = redisTemplate.execute(redisScript, Collections.singletonList(key), value, expire);
return Objects.equals(result, true); return result != null;
} }
public void unlock() { 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"; 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); RedisScript<Boolean> redisScript = new DefaultRedisScript<>(UNLOCK_LUA_SCRIPT, Boolean.class);
Boolean result = RedisUtil.execute(redisScript, Collections.singletonList(key), value); Boolean result = redisTemplate.execute(redisScript, Collections.singletonList(key), value);
if (result == null || !result) { if (result == null || !result) {
log.error("redis锁释放失败,key:{},value:{}", key, value); log.error("redis锁释放失败,key:{},value:{}", key, value);
} }

@ -2,18 +2,20 @@ package com.toesbieya.my.utils;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.toesbieya.my.constant.SessionConstant; import com.toesbieya.my.constant.SessionConstant;
import com.toesbieya.my.model.entity.SysUser;
import com.toesbieya.my.model.vo.UserVo; import com.toesbieya.my.model.vo.UserVo;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
public class SessionUtil { public class SessionUtil {
private static long expire = 3600 * 8; //token中的连接符
private static final String tokenSeparator = "-*-";
public static void remove(String token) { public static void remove(String token) {
if (StringUtils.isEmpty(token)) return; if (StringUtils.isEmpty(token)) return;
RedisUtil.expireImmediately(SessionConstant.REDIS_NAMESPACE + token); RedisUtil.del(SessionConstant.REDIS_NAMESPACE + token);
} }
public static void save(UserVo user) { public static void save(UserVo user) {
@ -21,7 +23,7 @@ public class SessionUtil {
if (StringUtils.isEmpty(token)) return; if (StringUtils.isEmpty(token)) return;
RedisUtil.set(SessionConstant.REDIS_NAMESPACE + token, user, expire); RedisUtil.set(SessionConstant.REDIS_NAMESPACE + token, user, SessionConstant.EXPIRE);
} }
public static UserVo get() { public static UserVo get() {
@ -43,4 +45,18 @@ public class SessionUtil {
String token = request.getHeader(SessionConstant.TOKEN_KEY); String token = request.getHeader(SessionConstant.TOKEN_KEY);
return get(token); 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;
}
} }

@ -6,7 +6,6 @@ import javax.validation.constraints.NotNull;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -37,10 +36,6 @@ public class Util {
return new String(baKeyword, StandardCharsets.ISO_8859_1); return new String(baKeyword, StandardCharsets.ISO_8859_1);
} }
public static <T> T getOrDefault(T o, T defaultValue) {
return o == null ? defaultValue : o;
}
public static boolean isInteger(String str) { public static boolean isInteger(String str) {
Pattern pattern = Pattern.compile("^[-+]?[\\d]*$"); Pattern pattern = Pattern.compile("^[-+]?[\\d]*$");
return pattern.matcher(str).matches(); return pattern.matcher(str).matches();
@ -54,51 +49,26 @@ public class Util {
return stringWriter.toString(); return stringWriter.toString();
} }
public static String formatByte(long byteNumber) {
//换算单位
double FORMAT = 1024.0;
double kbNumber = byteNumber / FORMAT;
if (kbNumber < FORMAT) {
return new DecimalFormat("#.##KB").format(kbNumber);
}
double mbNumber = kbNumber / FORMAT;
if (mbNumber < FORMAT) {
return new DecimalFormat("#.##MB").format(mbNumber);
}
double gbNumber = mbNumber / FORMAT;
if (gbNumber < FORMAT) {
return new DecimalFormat("#.##GB").format(gbNumber);
}
double tbNumber = gbNumber / FORMAT;
return new DecimalFormat("#.##TB").format(tbNumber);
}
public static <T> T find(Iterable<T> list, Predicate<T> predicate) { public static <T> T find(Iterable<T> list, Predicate<T> predicate) {
if (list == null) return null; if (list == null) return null;
for (T t : list) { for (T t : list) {
if (predicate.test(t)) return t; if (predicate.test(t)) return t;
} }
return null; return null;
} }
public static <T> int findIndex(Iterable<T> list, Predicate<T> predicate) { public static <T> int findIndex(Iterable<T> list, Predicate<T> predicate) {
int i = -1; int i = -1;
if (list == null) return i; if (list == null) return i;
for (T t : list) { for (T t : list) {
i++; i++;
if (predicate.test(t)) return i; if (predicate.test(t)) return i;
} }
return -1; return -1;
} }
public static <T> boolean some(Iterable<T> list, Predicate<T> predicate) { public static <T> boolean some(Iterable<T> list, Predicate<T> predicate) {
int index = findIndex(list, predicate); int index = findIndex(list, predicate);
return index > -1; return index > -1;
} }
} }

@ -0,0 +1,36 @@
package com.toesbieya.my.utils;
import com.toesbieya.my.constant.SocketConstant;
import com.toesbieya.my.model.vo.SocketEventVo;
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,28 +0,0 @@
package com.toesbieya.my.utils;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import java.util.Properties;
public class YmlUtil {
private static Properties properties;
public static Object get(String key) {
if (properties != null) {
return properties.get(key);
}
Resource resource = new ClassPathResource("application.yml");
try {
YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
yamlFactory.setResources(resource);
properties = yamlFactory.getObject();
} catch (Exception e) {
e.printStackTrace();
return null;
}
assert properties != null;
return properties.get(key);
}
}

@ -20,14 +20,14 @@ spring:
min-idle: 50 min-idle: 50
max-active: 2000 max-active: 2000
max-wait: 1000 max-wait: 1000
session:
store-type: redis
servlet: servlet:
multipart: multipart:
#单文件上传最大值 #单文件上传最大值
max-file-size: 10MB max-file-size: 10MB
#单次请求最大值 #单次请求最大值
max-request-size: 10MB max-request-size: 10MB
aop:
proxy-target-class: true
mybatis: mybatis:
mapper-locations: mapper-locations:
@ -43,21 +43,14 @@ socket:
#hostname: 172.24.52.184 #hostname: 172.24.52.184
hostname: localhost hostname: localhost
port: 12580 port: 12580
max-frame-payload: 1048576 max-frame-payload-length: 1048576
max-http-content: 1048576 max-http-content-length: 1048576
event:
logout: logout
new-message: new-message
qiniu: qiniu:
access-key: access-key access-key:
secret-key: secret-key secret-key:
bucket: bucket bucket:
#七牛的临时上传凭证的有效期,单位秒 #七牛的临时上传凭证的有效期,单位秒
token-expires: 3600 token-expire: 3600
#七牛的临时上传凭证的redis键名 #七牛的临时上传凭证的redis键名
redis-cache-key: qiniu-token redis-cache-key: qiniu-token
#logging:
# level:
# com.toesbieya.my.mapper: DEBUG

@ -19,7 +19,7 @@
order by id desc order by id desc
</select> </select>
<insert id="add" parameterType="com.toesbieya.my.model.entity.BizDocumentHistory"> <insert id="insert" parameterType="com.toesbieya.my.model.entity.BizDocumentHistory">
insert into biz_document_history (pid, type, uid, uname, status_before, status_after, time, info) insert into biz_document_history (pid, type, uid, uname, status_before, status_after, time, info)
VALUES (#{pid}, #{type}, #{uid}, #{uname}, #{status_before}, #{status_after}, #{time}, #{info}) VALUES (#{pid}, #{type}, #{uid}, #{uname}, #{status_before}, #{status_after}, #{time}, #{info})
</insert> </insert>

@ -49,7 +49,7 @@
<include refid="searchCondition"/> <include refid="searchCondition"/>
order by ctime desc order by ctime desc
</select> </select>
<insert id="add" parameterType="com.toesbieya.my.model.entity.BizPurchaseInbound"> <insert id="insert" parameterType="com.toesbieya.my.model.entity.BizPurchaseInbound">
insert into biz_purchase_inbound insert into biz_purchase_inbound
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
id,pid,cid,cname,ctime, id,pid,cid,cname,ctime,

@ -55,7 +55,7 @@
<include refid="searchCondition"/> <include refid="searchCondition"/>
order by ctime desc order by ctime desc
</select> </select>
<insert id="add" parameterType="com.toesbieya.my.model.entity.BizPurchaseOrder"> <insert id="insert" parameterType="com.toesbieya.my.model.entity.BizPurchaseOrder">
insert into biz_purchase_order insert into biz_purchase_order
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
id,sid,sname,cid,cname,ctime,finish,total, id,sid,sname,cid,cname,ctime,finish,total,
@ -130,29 +130,4 @@
set remain_num=#{remain_num} set remain_num=#{remain_num}
where id = #{id} where id = #{id}
</update> </update>
<select id="getDailyTotalPurchasePrice" resultType="java.lang.Double">
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="getLastDayFinishOrderNum" 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="getDailyProfitGoods" resultType="com.toesbieya.my.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>
</mapper> </mapper>

@ -55,7 +55,7 @@
<include refid="searchCondition"/> <include refid="searchCondition"/>
order by ctime desc order by ctime desc
</select> </select>
<insert id="add" parameterType="com.toesbieya.my.model.entity.BizSellOrder"> <insert id="insert" parameterType="com.toesbieya.my.model.entity.BizSellOrder">
insert into biz_sell_order insert into biz_sell_order
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
id,customer_id,customer_name,cid,cname,ctime,finish,total, id,customer_id,customer_name,cid,cname,ctime,finish,total,
@ -130,29 +130,4 @@
set remain_num=#{remain_num} set remain_num=#{remain_num}
where id = #{id} where id = #{id}
</update> </update>
<select id="getDailyTotalPurchasePrice" resultType="java.lang.Double">
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="getLastDayFinishOrderNum" 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="getDailyProfitGoods" resultType="com.toesbieya.my.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> </mapper>

@ -49,7 +49,7 @@
<include refid="searchCondition"/> <include refid="searchCondition"/>
order by ctime desc order by ctime desc
</select> </select>
<insert id="add" parameterType="com.toesbieya.my.model.entity.BizSellOutbound"> <insert id="insert" parameterType="com.toesbieya.my.model.entity.BizSellOutbound">
insert into biz_sell_outbound insert into biz_sell_outbound
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
id,pid,cid,cname,ctime, id,pid,cid,cname,ctime,

@ -13,6 +13,7 @@
<if test="startTime!=null">and ctime <![CDATA[ >= ]]> #{startTime}</if> <if test="startTime!=null">and ctime <![CDATA[ >= ]]> #{startTime}</if>
<if test="endTime!=null">and ctime <![CDATA[ <= ]]> #{endTime}</if> <if test="endTime!=null">and ctime <![CDATA[ <= ]]> #{endTime}</if>
</sql> </sql>
<select id="search" parameterType="com.toesbieya.my.model.vo.search.StockSearch" <select id="search" parameterType="com.toesbieya.my.model.vo.search.StockSearch"
resultType="com.toesbieya.my.model.vo.result.StockSearchResult"> resultType="com.toesbieya.my.model.vo.result.StockSearchResult">
select cid, select cid,
@ -25,18 +26,21 @@
and num >0 and num >0
group by cid group by cid
</select> </select>
<select id="getDetail" resultType="com.toesbieya.my.model.entity.BizStock"> <select id="getDetail" resultType="com.toesbieya.my.model.entity.BizStock">
select * select *
from biz_stock from biz_stock
where cid in (${cid}) where cid in (${cids})
and num > 0 and num > 0
order by cgddid desc, cgrkid desc order by cgddid desc, cgrkid desc
</select> </select>
<select id="getDetailById" resultType="com.toesbieya.my.model.entity.BizStock"> <select id="getDetailById" resultType="com.toesbieya.my.model.entity.BizStock">
select * select *
from biz_stock from biz_stock
where id in (${ids}) where id in (${ids})
</select> </select>
<select id="export" parameterType="com.toesbieya.my.model.vo.search.StockSearch" <select id="export" parameterType="com.toesbieya.my.model.vo.search.StockSearch"
resultType="com.toesbieya.my.model.vo.export.StockExport"> resultType="com.toesbieya.my.model.vo.export.StockExport">
select a.cid,a.cname,a.total_num,a.total_price,b.cgddid,b.cgrkid,b.price cg_price, select a.cid,a.cname,a.total_num,a.total_price,b.cgddid,b.cgrkid,b.price cg_price,
@ -59,107 +63,7 @@
left join biz_purchase_order_sub d on c.cid = d.cid and d.pid = b.cgddid left join biz_purchase_order_sub d on c.cid = d.cid and d.pid = b.cgddid
order by a.cid,b.cgddid desc, b.cgrkid desc order by a.cid,b.cgddid desc, b.cgrkid desc
</select> </select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete
from biz_stock
where id = #{id,jdbcType=INTEGER}
</delete>
<update id="updateByPrimaryKeySelective" parameterType="com.toesbieya.my.model.entity.BizStock">
update biz_stock
<set>
<if test="cid != null">
cid = #{cid,jdbcType=INTEGER},
</if>
<if test="cname != null">
cname = #{cname,jdbcType=VARCHAR},
</if>
<if test="num != null">
num = #{num,jdbcType=DECIMAL},
</if>
<if test="price != null">
price = #{price,jdbcType=DECIMAL},
</if>
<if test="ctime != null">
ctime = #{ctime,jdbcType=BIGINT},
</if>
<if test="cgrkid != null">
cgrkid = #{cgrkid,jdbcType=VARCHAR},
</if>
<if test="cgddid != null">
cgddid = #{cgddid,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.toesbieya.my.model.entity.BizStock">
update biz_stock
set cid = #{cid,jdbcType=INTEGER},
cname = #{cname,jdbcType=VARCHAR},
num = #{num,jdbcType=DECIMAL},
price = #{price,jdbcType=DECIMAL},
ctime = #{ctime,jdbcType=BIGINT},
cgrkid = #{cgrkid,jdbcType=VARCHAR},
cgddid = #{cgddid,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateBatchSelective" parameterType="java.util.List">
update biz_stock
<trim prefix="set" suffixOverrides=",">
<trim prefix="cid = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.cid != null">
when id = #{item.id,jdbcType=INTEGER} then #{item.cid,jdbcType=INTEGER}
</if>
</foreach>
</trim>
<trim prefix="cname = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.cname != null">
when id = #{item.id,jdbcType=INTEGER} then #{item.cname,jdbcType=VARCHAR}
</if>
</foreach>
</trim>
<trim prefix="num = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.num != null">
when id = #{item.id,jdbcType=INTEGER} then #{item.num,jdbcType=DECIMAL}
</if>
</foreach>
</trim>
<trim prefix="price = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.price != null">
when id = #{item.id,jdbcType=INTEGER} then #{item.price,jdbcType=DECIMAL}
</if>
</foreach>
</trim>
<trim prefix="ctime = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.ctime != null">
when id = #{item.id,jdbcType=INTEGER} then #{item.ctime,jdbcType=BIGINT}
</if>
</foreach>
</trim>
<trim prefix="cgrkid = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.cgrkid != null">
when id = #{item.id,jdbcType=INTEGER} then #{item.cgrkid,jdbcType=VARCHAR}
</if>
</foreach>
</trim>
<trim prefix="cgddid = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.cgddid != null">
when id = #{item.id,jdbcType=INTEGER} then #{item.cgddid,jdbcType=VARCHAR}
</if>
</foreach>
</trim>
</trim>
where id in
<foreach close=")" collection="list" item="item" open="(" separator=", ">
#{item.id,jdbcType=INTEGER}
</foreach>
</update>
<insert id="batchInsert" keyColumn="id" keyProperty="id" parameterType="com.toesbieya.my.model.entity.BizStock" <insert id="batchInsert" keyColumn="id" keyProperty="id" parameterType="com.toesbieya.my.model.entity.BizStock"
useGeneratedKeys="true"> useGeneratedKeys="true">
insert into biz_stock insert into biz_stock
@ -171,6 +75,7 @@
#{item.cgddid,jdbcType=VARCHAR}) #{item.cgddid,jdbcType=VARCHAR})
</foreach> </foreach>
</insert> </insert>
<update id="outbound"> <update id="outbound">
update biz_stock update biz_stock
set num = num - #{num,jdbcType=DECIMAL} set num = num - #{num,jdbcType=DECIMAL}

@ -8,6 +8,7 @@
<if test="start!=null">and time <![CDATA[ >= ]]> #{start}</if> <if test="start!=null">and time <![CDATA[ >= ]]> #{start}</if>
<if test="end!=null">and time <![CDATA[ <= ]]> #{end}</if> <if test="end!=null">and time <![CDATA[ <= ]]> #{end}</if>
</select> </select>
<select id="searchGoodsProfit" resultType="com.toesbieya.my.model.entity.StatProfitGoods"> <select id="searchGoodsProfit" resultType="com.toesbieya.my.model.entity.StatProfitGoods">
select * select *
from stat_profit_goods from stat_profit_goods
@ -15,6 +16,7 @@
<if test="start!=null">and time <![CDATA[ >= ]]> #{start}</if> <if test="start!=null">and time <![CDATA[ >= ]]> #{start}</if>
<if test="end!=null">and time <![CDATA[ <= ]]> #{end}</if> <if test="end!=null">and time <![CDATA[ <= ]]> #{end}</if>
</select> </select>
<select id="searchFinishOrder" resultType="com.toesbieya.my.model.entity.StatFinishOrder"> <select id="searchFinishOrder" resultType="com.toesbieya.my.model.entity.StatFinishOrder">
select * select *
from stat_finish_order from stat_finish_order
@ -22,6 +24,7 @@
<if test="start!=null">and time <![CDATA[ >= ]]> #{start}</if> <if test="start!=null">and time <![CDATA[ >= ]]> #{start}</if>
<if test="end!=null">and time <![CDATA[ <= ]]> #{end}</if> <if test="end!=null">and time <![CDATA[ <= ]]> #{end}</if>
</select> </select>
<select id="getHistoryTotalProfitGoods" resultType="com.toesbieya.my.model.entity.StatProfitGoods"> <select id="getHistoryTotalProfitGoods" resultType="com.toesbieya.my.model.entity.StatProfitGoods">
select t1.*, select t1.*,
t2.name cname t2.name cname
@ -33,24 +36,29 @@
group by cid) t1 group by cid) t1
join sys_category t2 on t1.cid = t2.id join sys_category t2 on t1.cid = t2.id
</select> </select>
<select id="checkDailyFinishOrderExist" resultType="java.lang.Boolean"> <select id="checkDailyFinishOrderExist" resultType="java.lang.Boolean">
select count(0) select count(0)
from stat_finish_order from stat_finish_order
where time = #{time} where time = #{time}
</select> </select>
<insert id="insertFinishOrder" parameterType="com.toesbieya.my.model.entity.StatFinishOrder">
insert into stat_finish_order (purchase, sell, time)
values (#{purchase}, #{sell}, #{time})
</insert>
<select id="checkDailyProfitExist" resultType="java.lang.Boolean"> <select id="checkDailyProfitExist" resultType="java.lang.Boolean">
select count(0) select count(0)
from stat_profit_total from stat_profit_total
where time = #{time} where time = #{time}
</select> </select>
<insert id="insertFinishOrder" parameterType="com.toesbieya.my.model.entity.StatFinishOrder">
insert into stat_finish_order (purchase, sell, time)
values (#{purchase}, #{sell}, #{time})
</insert>
<insert id="insertProfitTotal" parameterType="com.toesbieya.my.model.entity.StatProfitTotal"> <insert id="insertProfitTotal" parameterType="com.toesbieya.my.model.entity.StatProfitTotal">
insert into stat_profit_total (purchase, sell, profit, time) insert into stat_profit_total (purchase, sell, profit, time)
values (#{purchase}, #{sell}, #{profit}, #{time}) values (#{purchase}, #{sell}, #{profit}, #{time})
</insert> </insert>
<insert id="insertProfitGoodsBatch" keyColumn="id" keyProperty="id" <insert id="insertProfitGoodsBatch" keyColumn="id" keyProperty="id"
parameterType="com.toesbieya.my.model.entity.StatProfitGoods" parameterType="com.toesbieya.my.model.entity.StatProfitGoods"
useGeneratedKeys="true"> useGeneratedKeys="true">
@ -61,4 +69,68 @@
(#{item.cid},#{item.purchase},#{item.sell},#{item.profit},#{item.time}) (#{item.cid},#{item.purchase},#{item.sell},#{item.profit},#{item.time})
</foreach> </foreach>
</insert> </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="com.toesbieya.my.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="com.toesbieya.my.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> </mapper>
Loading…
Cancel
Save