From cb882cf9273de27bfc37a0a85569cf62cf0586b3 Mon Sep 17 00:00:00 2001 From: Houpn Date: Fri, 8 Sep 2023 11:10:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E7=89=A9=E6=B5=81=E5=85=AC?= =?UTF-8?q?=E5=8F=B8=E7=99=BB=E5=BD=95=E4=BB=A5=E5=8F=8A=E4=B8=8B=E5=8D=95?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/constant/SecurityConstant.java | 14 ++ .../hiver/core/common/utils/SecurityUtil.java | 102 +++++++++++- .../cc/hiver/core/common/vo/TokenCompany.java | 71 ++++++++ .../jwt/TokenAuthenticationFilter.java | 51 +++++- .../hiver/core}/dao/LogiticsCompanyDao.java | 8 +- .../hiver/core}/entity/LogiticsCompany.java | 8 +- .../core}/service/LogiticsCompanyService.java | 4 +- .../LogiticsCompanyServiceImpl.java | 8 +- .../core/serviceimpl/WorkerServiceImpl.java | 14 +- .../java/cc/hiver/core/vo/LcomDetailVO.java | 26 +++ .../mall/controller/LcomAuthController.java | 155 ++++++++++++++++++ .../controller/LogiticsCompanyController.java | 4 +- .../hiver/mall/controller/SaleController.java | 31 +++- .../mall/controller/WorkerAuthController.java | 5 +- .../java/cc/hiver/mall/entity/OrderXd.java | 2 +- .../cc/hiver/mall/pojo/dto/SaleDetailDTO.java | 67 ++++++++ .../mall/pojo/dto/SaleDetailQueryDTO.java | 24 +++ .../cc/hiver/mall/pojo/dto/SaleQueryDTO.java | 29 ++++ .../hiver/mall/service/RushOrderService.java | 3 + .../mall/service/SalesAndDetailsService.java | 5 + .../mall/service/StockAndLogService.java | 7 + .../serviceimpl/RushOrderServiceImpl.java | 24 +++ .../SalesAndDetailsServiceImpl.java | 79 ++++++++- .../serviceimpl/StockAndLogServiceImpl.java | 87 ++++++++++ 24 files changed, 796 insertions(+), 32 deletions(-) create mode 100644 hiver-core/src/main/java/cc/hiver/core/common/vo/TokenCompany.java rename {hiver-modules/hiver-mall/src/main/java/cc/hiver/mall => hiver-core/src/main/java/cc/hiver/core}/dao/LogiticsCompanyDao.java (83%) rename {hiver-modules/hiver-mall/src/main/java/cc/hiver/mall => hiver-core/src/main/java/cc/hiver/core}/entity/LogiticsCompany.java (91%) rename {hiver-modules/hiver-mall/src/main/java/cc/hiver/mall => hiver-core/src/main/java/cc/hiver/core}/service/LogiticsCompanyService.java (94%) rename {hiver-modules/hiver-mall/src/main/java/cc/hiver/mall => hiver-core/src/main/java/cc/hiver/core}/serviceimpl/LogiticsCompanyServiceImpl.java (96%) create mode 100644 hiver-core/src/main/java/cc/hiver/core/vo/LcomDetailVO.java create mode 100644 hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/LcomAuthController.java create mode 100644 hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/SaleDetailDTO.java create mode 100644 hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/SaleDetailQueryDTO.java create mode 100644 hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/SaleQueryDTO.java diff --git a/hiver-core/src/main/java/cc/hiver/core/common/constant/SecurityConstant.java b/hiver-core/src/main/java/cc/hiver/core/common/constant/SecurityConstant.java index dd74a726..1c809a2f 100644 --- a/hiver-core/src/main/java/cc/hiver/core/common/constant/SecurityConstant.java +++ b/hiver-core/src/main/java/cc/hiver/core/common/constant/SecurityConstant.java @@ -102,4 +102,18 @@ public interface SecurityConstant { * appToken参数头 */ String APP_YS_HEADER = "appYSToken"; + /** + * appToken参数头 + */ + String APP_WL_HEADER = "appWLToken"; + + /** + * 运送员token前缀key + */ + String COMPANY_TOKEN = "HIVER_COMPANY_TOKEN:"; + + /** + * 运送员交互token前缀key + */ + String TOKEN_COMPANY_PRE = "HIVER_TOKEN_COMPANY_PRE:"; } diff --git a/hiver-core/src/main/java/cc/hiver/core/common/utils/SecurityUtil.java b/hiver-core/src/main/java/cc/hiver/core/common/utils/SecurityUtil.java index 3b7f66cd..354a05f8 100644 --- a/hiver-core/src/main/java/cc/hiver/core/common/utils/SecurityUtil.java +++ b/hiver-core/src/main/java/cc/hiver/core/common/utils/SecurityUtil.java @@ -6,15 +6,13 @@ import cc.hiver.core.common.constant.UserConstant; import cc.hiver.core.common.constant.WorkerConstant; import cc.hiver.core.common.exception.HiverException; import cc.hiver.core.common.redis.RedisTemplateHelper; +import cc.hiver.core.common.vo.TokenCompany; import cc.hiver.core.common.vo.TokenMember; import cc.hiver.core.common.vo.TokenUser; import cc.hiver.core.common.vo.TokenWorker; import cc.hiver.core.config.properties.HiverAppTokenProperties; import cc.hiver.core.config.properties.HiverTokenProperties; -import cc.hiver.core.dao.DepartmentDao; -import cc.hiver.core.dao.MemberDao; -import cc.hiver.core.dao.UserDao; -import cc.hiver.core.dao.WorkerDao; +import cc.hiver.core.dao.*; import cc.hiver.core.dao.mapper.PermissionMapper; import cc.hiver.core.dao.mapper.UserRoleMapper; import cc.hiver.core.entity.*; @@ -81,6 +79,9 @@ public class SecurityUtil { @Autowired private WorkerDao workerDao; + @Autowired + private LogiticsCompanyDao logiticsCompanyDao; + /** * -------------------ToB------------------------- */ @@ -111,6 +112,19 @@ public class SecurityUtil { return worker; } + public LogiticsCompany findCompanyByUsername(String username) { + String key = "companyName::" + username; + // 读取缓存 + String res = redisTemplate.get(key); + if (StrUtil.isNotBlank(res)) { + return new Gson().fromJson(res, LogiticsCompany.class); + } + LogiticsCompany logiticsCompany = logiticsCompanyDao.findByUsername(username); + // 缓存 + redisTemplate.set(key, new Gson().toJson(logiticsCompany), 15L, TimeUnit.DAYS); + return logiticsCompany; + } + public User findUserByMobile(String mobile) { return userToDTO(userDao.findByMobile(mobile)); } @@ -118,6 +132,10 @@ public class SecurityUtil { return workerDao.findByMobile(mobile); } + public LogiticsCompany findCompanyByMobile(String mobile) { + return logiticsCompanyDao.findByMobile(mobile); + } + public User findUserByEmail(String email) { return userToDTO(userDao.findByEmail(email)); } @@ -180,6 +198,25 @@ public class SecurityUtil { return worker; } + public LogiticsCompany checkCompanyPassword(String username, String password) { + LogiticsCompany logiticsCompany; + // 校验用户名 + if (NameUtil.mobile(username)) { + logiticsCompany = findCompanyByMobile(username); + } else { + logiticsCompany = findCompanyByUsername(username); + } + if (logiticsCompany == null) { + return null; + } + // 校验密码 + Boolean isValid = new BCryptPasswordEncoder().matches(password, logiticsCompany.getPassword()); + if (!isValid) { + return null; + } + return logiticsCompany; + } + public String getToken(String username, Boolean saveLogin) { if (StrUtil.isBlank(username)) { throw new HiverException("username不能为空"); @@ -270,6 +307,15 @@ public class SecurityUtil { return findWorkerByUsername(authentication.getName()); } + public LogiticsCompany getCurrCompany() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null || !authentication.isAuthenticated() || authentication.getName() == null + || authentication instanceof AnonymousAuthenticationToken) { + throw new HiverException("未检测到登录用户"); + } + return findCompanyByUsername(authentication.getName()); + } + /** * 获取当前登录用户部分基本信息 id、username、nickname、mobile、email、departmentId、type、permissions(角色和菜单名) * @@ -559,4 +605,52 @@ public class SecurityUtil { return token; } + + public String getAppWLToken(LogiticsCompany logiticsCompany, Boolean saveLogin) { + if (logiticsCompany == null) { + throw new HiverException("logiticsCompany不能为空"); + } + + Boolean saved = false; + if (saveLogin == null || saveLogin) { + saved = true; + if (!tokenProperties.getRedis()) { + tokenProperties.setTokenExpireTime(tokenProperties.getSaveLoginTime() * 60 * 24); + } + } + // 生成token + String token; + TokenCompany tokenCompany; + if (appTokenProperties.getRedis()) { + // redis + token = IdUtil.simpleUUID(); + tokenCompany = new TokenCompany(logiticsCompany, saved); + String key = SecurityConstant.COMPANY_TOKEN + tokenCompany.getId()+":"+tokenCompany.getCompanyName(); + // 单平台登录 之前的token失效 + if (appTokenProperties.getSpl()) { + String oldToken = redisTemplate.get(key); + if (StrUtil.isNotBlank(oldToken)) { + redisTemplate.delete(SecurityConstant.TOKEN_COMPANY_PRE + oldToken); + } + } + redisTemplate.set(key, token, appTokenProperties.getTokenExpireTime(), TimeUnit.DAYS); + redisTemplate.set(SecurityConstant.TOKEN_COMPANY_PRE + token, new Gson().toJson(tokenCompany), appTokenProperties.getTokenExpireTime(), TimeUnit.DAYS); + } else { + // JWT + tokenCompany = new TokenCompany(logiticsCompany, saved); + token = SecurityConstant.TOKEN_SPLIT + Jwts.builder() + // 主题 放入会员信息 + .setSubject(new Gson().toJson(tokenCompany)) + // 失效时间 + .setExpiration(new Date(System.currentTimeMillis() + appTokenProperties.getTokenExpireTime() * 60 * 1000)) + // 签名算法和密钥 + .signWith(SignatureAlgorithm.HS512, SecurityConstant.JWT_SIGN_KEY) + .compact(); + } + // 记录日志使用 + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(tokenCompany, null, null); + SecurityContextHolder.getContext().setAuthentication(authentication); + return token; + + } } diff --git a/hiver-core/src/main/java/cc/hiver/core/common/vo/TokenCompany.java b/hiver-core/src/main/java/cc/hiver/core/common/vo/TokenCompany.java new file mode 100644 index 00000000..e8606107 --- /dev/null +++ b/hiver-core/src/main/java/cc/hiver/core/common/vo/TokenCompany.java @@ -0,0 +1,71 @@ +package cc.hiver.core.common.vo; + +import cc.hiver.core.entity.LogiticsCompany; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.io.Serializable; +import java.util.Collection; + +/** + * 会员令牌(前端) + * @author Yazhi Li + */ +@Data +@AllArgsConstructor +public class TokenCompany implements UserDetails, Serializable { + private String id; + + private String companyName; + + private String username; + + private String password; + + private Boolean platform; + + public TokenCompany(LogiticsCompany logiticsCompany, Boolean platform) { + this.id = logiticsCompany.getId(); + this.companyName = logiticsCompany.getCompanyName(); + this.username = logiticsCompany.getUsername(); + this.password = logiticsCompany.getPassword(); + this.platform = platform; + } + + @Override + public Collection getAuthorities() { + return null; + } + + @Override + public String getPassword() { + return null; + } + + @Override + public String getUsername() { + return null; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } +} diff --git a/hiver-core/src/main/java/cc/hiver/core/config/security/jwt/TokenAuthenticationFilter.java b/hiver-core/src/main/java/cc/hiver/core/config/security/jwt/TokenAuthenticationFilter.java index ee498c2e..db242204 100644 --- a/hiver-core/src/main/java/cc/hiver/core/config/security/jwt/TokenAuthenticationFilter.java +++ b/hiver-core/src/main/java/cc/hiver/core/config/security/jwt/TokenAuthenticationFilter.java @@ -4,6 +4,7 @@ import cc.hiver.core.common.constant.SecurityConstant; import cc.hiver.core.common.redis.RedisTemplateHelper; import cc.hiver.core.common.utils.ResponseUtil; import cc.hiver.core.common.utils.SecurityUtil; +import cc.hiver.core.common.vo.TokenCompany; import cc.hiver.core.common.vo.TokenMember; import cc.hiver.core.common.vo.TokenUser; import cc.hiver.core.common.vo.TokenWorker; @@ -78,8 +79,12 @@ public class TokenAuthenticationFilter extends BasicAuthenticationFilter { if (StrUtil.isBlank(appYSHeader)) { appYSHeader = request.getParameter(SecurityConstant.APP_YS_HEADER); } + String appWLHeader = request.getHeader(SecurityConstant.APP_WL_HEADER); + if (StrUtil.isBlank(appYSHeader)) { + appWLHeader = request.getParameter(SecurityConstant.APP_WL_HEADER); + } Boolean notValid = (StrUtil.isBlank(header) || (!tokenProperties.getRedis() && !header.startsWith(SecurityConstant.TOKEN_SPLIT))) - && StrUtil.isBlank(appHeader) && StrUtil.isBlank(appYSHeader); + && StrUtil.isBlank(appHeader) && StrUtil.isBlank(appYSHeader) && StrUtil.isBlank(appWLHeader); if (notValid) { chain.doFilter(request, response); return; @@ -90,8 +95,10 @@ public class TokenAuthenticationFilter extends BasicAuthenticationFilter { authentication = getAuthentication(header, response); } else if(StrUtil.isNotBlank(appHeader)){ authentication = getAppAuthentication(appHeader, response); - } else { + } else if(StrUtil.isNotBlank(appYSHeader)){ authentication = getAppYSAuthentication(appYSHeader, response); + } else { + authentication = getAppWLAuthentication(appWLHeader, response); } if (authentication == null) { return; @@ -240,4 +247,44 @@ public class TokenAuthenticationFilter extends BasicAuthenticationFilter { } return null; } + + private UsernamePasswordAuthenticationToken getAppWLAuthentication(String appWLHeader, HttpServletResponse response) { + TokenCompany tokenCompany = null; + List authorities = new ArrayList<>(); + + if (appTokenProperties.getRedis()) { + // redis + String v = redisTemplate.get(SecurityConstant.TOKEN_COMPANY_PRE + appWLHeader); + if (StrUtil.isBlank(v)) { + ResponseUtil.out(response, ResponseUtil.resultMap(false, 401, "物流公司登录已失效,请重新登录")); + return null; + } + tokenCompany = new Gson().fromJson(v, TokenCompany.class); + // 权限 + // 重新设置失效时间 + redisTemplate.set(SecurityConstant.COMPANY_TOKEN + tokenCompany.getUsername(), appWLHeader, appTokenProperties.getTokenExpireTime(), TimeUnit.DAYS); + redisTemplate.set(SecurityConstant.TOKEN_COMPANY_PRE + appWLHeader, v, appTokenProperties.getTokenExpireTime(), TimeUnit.DAYS); + } else { + // JWT + try { + // 解析token + Claims claims = Jwts.parser() + .setSigningKey(SecurityConstant.JWT_SIGN_KEY) + .parseClaimsJws(appWLHeader.replace(SecurityConstant.TOKEN_SPLIT, "")) + .getBody(); + // 获取用户 + tokenCompany = new Gson().fromJson(claims.getSubject(), TokenCompany.class); + + } catch (ExpiredJwtException e) { + ResponseUtil.out(response, ResponseUtil.resultMap(false, 401, "登录已失效,请重新登录")); + } catch (Exception e) { + log.error(e.toString()); + ResponseUtil.out(response, ResponseUtil.resultMap(false, 500, "解析token错误")); + } + } + if (tokenCompany != null && StrUtil.isNotBlank(tokenCompany.getId())) { + return new UsernamePasswordAuthenticationToken(tokenCompany, null, null); + } + return null; + } } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/LogiticsCompanyDao.java b/hiver-core/src/main/java/cc/hiver/core/dao/LogiticsCompanyDao.java similarity index 83% rename from hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/LogiticsCompanyDao.java rename to hiver-core/src/main/java/cc/hiver/core/dao/LogiticsCompanyDao.java index 4178c9ed..ea35024a 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/LogiticsCompanyDao.java +++ b/hiver-core/src/main/java/cc/hiver/core/dao/LogiticsCompanyDao.java @@ -13,10 +13,10 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -package cc.hiver.mall.dao; +package cc.hiver.core.dao; import cc.hiver.core.base.HiverBaseDao; -import cc.hiver.mall.entity.LogiticsCompany; +import cc.hiver.core.entity.LogiticsCompany; /** * @author houpn @@ -29,4 +29,8 @@ public interface LogiticsCompanyDao extends HiverBaseDao= tokenProperties.getLoginTimeLimit()) { + redisTemplate.set(loginFailKey, "FAIL", tokenProperties.getLoginAfterTime(), TimeUnit.MINUTES); + } + int restLoginTime = tokenProperties.getLoginTimeLimit() - loginFailTime; + if (restLoginTime > 0 && restLoginTime <= LOGIN_FAIL_TIP_TIME) { + return ResultUtil.error("账号或密码错误,还有" + restLoginTime + "次尝试机会"); + } else if (restLoginTime <= 0) { + return ResultUtil.error("登录错误次数超过限制,请" + tokenProperties.getLoginAfterTime() + "分钟后再试"); + } + return ResultUtil.error("账号或密码错误"); + } + String accessToken = securityUtil.getAppWLToken(logiticsCompany, saveLogin); + LcomDetailVO detailVO = new LcomDetailVO(); + detailVO.setLogiticsCompany(logiticsCompany); + detailVO.setLComToken(accessToken); + return ResultUtil.data(detailVO); + } + + /** + * 线上demo不允许测试账号改密码 + * + * @param password + * @param newPass + * @return + */ + @RequestMapping(value = "/modifyPass", method = RequestMethod.POST) + @ApiOperation(value = "修改密码") + public Result modifyPass(@ApiParam("旧密码") @RequestParam String password, + @ApiParam("新密码") @RequestParam String newPass) { + LogiticsCompany logiticsCompany = securityUtil.getCurrCompany(); + if (!new BCryptPasswordEncoder().matches(password, logiticsCompany.getPassword())) { + return ResultUtil.error("旧密码不正确"); + } + String newEncryptPass = new BCryptPasswordEncoder().encode(newPass); + logiticsCompany.setPassword(newEncryptPass); + logiticsCompanyService.update(logiticsCompany); + // 手动更新缓存 + redisTemplate.delete(COMPANY + logiticsCompany.getUsername()); + return ResultUtil.success("修改密码成功"); + } + + @RequestMapping(value = "/resetPass", method = RequestMethod.POST) + @ApiOperation(value = "重置密码") + public Result resetPass(@RequestParam String[] ids) { + for (String id : ids) { + LogiticsCompany logiticsCompany = logiticsCompanyService.get(id); + logiticsCompany.setPassword(new BCryptPasswordEncoder().encode("123456")); + logiticsCompanyService.update(logiticsCompany); + redisTemplate.delete(COMPANY + logiticsCompany.getUsername()); + } + return ResultUtil.success("操作成功"); + } + + @RequestMapping(value = "/app/info/{id}", method = RequestMethod.GET) + @ApiOperation(value = "小程序端查询物流公司详情页") + public Result disable(@ApiParam("用户唯一id标识") @PathVariable String id) { + LogiticsCompany logiticsCompany = logiticsCompanyService.get(id); + // 手动更新缓存 + return ResultUtil.data(logiticsCompany); + } +} diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/LogiticsCompanyController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/LogiticsCompanyController.java index 450da556..866692ca 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/LogiticsCompanyController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/LogiticsCompanyController.java @@ -19,8 +19,8 @@ import cc.hiver.core.common.utils.PageUtil; import cc.hiver.core.common.utils.ResultUtil; import cc.hiver.core.common.vo.PageVo; import cc.hiver.core.common.vo.Result; -import cc.hiver.mall.entity.LogiticsCompany; -import cc.hiver.mall.service.LogiticsCompanyService; +import cc.hiver.core.entity.LogiticsCompany; +import cc.hiver.core.service.LogiticsCompanyService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/SaleController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/SaleController.java index ca2c71be..561ba534 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/SaleController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/SaleController.java @@ -8,6 +8,7 @@ import cc.hiver.mall.entity.*; import cc.hiver.mall.pojo.dto.SaleDTO; +import cc.hiver.mall.pojo.dto.SaleQueryDTO; import cc.hiver.mall.pojo.vo.SaleQueryVO; import cc.hiver.mall.pojo.vo.SaleVO; import cc.hiver.mall.service.*; @@ -76,6 +77,30 @@ public class SaleController { return ResultUtil.success("下单成功"); } + @RequestMapping(value = "/buyNew", method = RequestMethod.POST) + @ApiOperation(value = "下单操作") + @Transactional + public Result buyNew(@RequestBody SaleQueryDTO saleQueryDTO) { + + + /** + * 订单中是物流且包含扛包工人员的话,直接进入抢单表 + * */ + //1.处理订单表模块 + Sale sale = salesAndDetailsService.handleSalesDetails(saleQueryDTO); + //更新sale + saleQueryDTO.setSale(sale); + //2.处理库存模块 + stockAndLogService.handleSubStockLog(saleQueryDTO.getSaleDetailList()); + //3.处理抢单模块 + rushOrderService.handleNewRushOrder(saleQueryDTO); + //4.消息推送模块 + if(StrUtil.isNotEmpty(saleQueryDTO.getOrderByWorker())) + sendMessageService.handleSendAppMessage(saleQueryDTO.getOrderByWorker()); + + return ResultUtil.success("下单成功"); + } + @RequestMapping(value = "/edit", method = RequestMethod.POST) @ApiOperation(value = "根据id修改货品属性") public Result edit(@RequestBody SaleQueryVO saleQueryVO) { @@ -113,9 +138,9 @@ public class SaleController { public Result> queryAll(@RequestBody SaleVO saleVO) { QueryWrapper queryWrapper = new QueryWrapper<>(); if (!ObjectUtils.isEmpty(saleVO)){ - if (ObjectUtils.isEmpty(saleVO.getPayStatus())) queryWrapper.eq("pay_status",saleVO.getPayStatus()); - if (StringUtils.isEmpty(saleVO.getStatus())) queryWrapper.eq("status",saleVO.getStatus()); - if (StringUtils.isEmpty(saleVO.getTransportType())) queryWrapper.eq("transport_type",saleVO.getTransportType()); + if (!ObjectUtils.isEmpty(saleVO.getPayStatus())) queryWrapper.eq("pay_status",saleVO.getPayStatus()); + if (!StringUtils.isEmpty(saleVO.getStatus())) queryWrapper.eq("status",saleVO.getStatus()); + if (!StringUtils.isEmpty(saleVO.getTransportType())) queryWrapper.eq("transport_type",saleVO.getTransportType()); } List saleList = saleService.list(queryWrapper); return new ResultUtil>().setData(saleList); diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/WorkerAuthController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/WorkerAuthController.java index c8604c6f..1a14e2d5 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/WorkerAuthController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/WorkerAuthController.java @@ -173,7 +173,10 @@ public class WorkerAuthController { return ResultUtil.error("账号或密码错误"); } String accessToken = securityUtil.getAppYSToken(worker, saveLogin); - return ResultUtil.data(accessToken); + WorkerDetailVO detailVO = new WorkerDetailVO(); + detailVO.setWorker(worker); + detailVO.setWorkerToken(accessToken); + return ResultUtil.data(detailVO); } /** diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/OrderXd.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/OrderXd.java index f01dd3f6..5deb67b4 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/OrderXd.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/OrderXd.java @@ -31,7 +31,7 @@ import java.util.Date; @Entity @DynamicInsert @DynamicUpdate -@Table(name = "t_order",uniqueConstraints=@UniqueConstraint(columnNames={"order_by_worker"})) +@Table(name = "t_order") @TableName("t_order") @ApiModel(value = "下单") @EntityListeners(AuditingEntityListener.class) diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/SaleDetailDTO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/SaleDetailDTO.java new file mode 100644 index 00000000..4a738503 --- /dev/null +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/SaleDetailDTO.java @@ -0,0 +1,67 @@ +package cc.hiver.mall.pojo.dto; + +import cc.hiver.core.common.utils.SnowFlakeUtil; +import cc.hiver.mall.entity.SaleDetail; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +@ApiModel(value = "销售单明细表") +@Data +public class SaleDetailDTO implements Serializable { + + @ApiModelProperty(value = "销售单ID") + private String saleId; + + @ApiModelProperty(value = "商品ID") + private String productId; + + @ApiModelProperty(value = "商品名称") + private String productName; + + @ApiModelProperty(value = "单位") + private String unit; + + @ApiModelProperty(value = "店铺ID") + private String shopId; + + @ApiModelProperty(value = "商品分类") + private String categoryId; + + @ApiModelProperty(value = "同一件商品购买属性列表") + private List saleDetailQueryDTO; + + @ApiModelProperty(value = "属性列表") + private String attributeList; + + @ApiModelProperty(value = "市场价") + private BigDecimal price; + + @ApiModelProperty(value = "采购价") + private BigDecimal purchasePrice; + + @ApiModelProperty(value = "批发价") + private BigDecimal wholesalePrice; + + @ApiModelProperty(value = "销售数量") + private Integer productCount; + + @ApiModelProperty(value = "折扣") + private BigDecimal discount; + + @ApiModelProperty(value = "优惠金额") + private BigDecimal discountAmount; + + @ApiModelProperty(value = "实际价格") + private BigDecimal realPrice; + + private static final long serialVersionUID = 1L; + + +} \ No newline at end of file diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/SaleDetailQueryDTO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/SaleDetailQueryDTO.java new file mode 100644 index 00000000..2d023cca --- /dev/null +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/SaleDetailQueryDTO.java @@ -0,0 +1,24 @@ +package cc.hiver.mall.pojo.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +@ApiModel(value = "销售单规格明细") +@Data +public class SaleDetailQueryDTO implements Serializable { + + @ApiModelProperty(value = "商品具体属性") + private String attributeList; + + @ApiModelProperty(value = "销售数量") + private Integer productCount; + + private static final long serialVersionUID = 1L; + + +} \ No newline at end of file diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/SaleQueryDTO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/SaleQueryDTO.java new file mode 100644 index 00000000..fafb9807 --- /dev/null +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/SaleQueryDTO.java @@ -0,0 +1,29 @@ +package cc.hiver.mall.pojo.dto; + +import cc.hiver.mall.entity.Sale; +import cc.hiver.mall.entity.SaleDetail; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +@ApiModel(value = "销售单主表") +@Data +public class SaleQueryDTO implements Serializable { + + @ApiModelProperty(value = "订单") + private Sale sale; + + @ApiModelProperty(value = "订单明细") + private List saleDetailList; + + + @ApiModelProperty(value = "扛包工编号") + private String orderByWorker; + + @ApiModelProperty(value = "物流公司编号") + private String transCompany; + +} \ No newline at end of file diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/RushOrderService.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/RushOrderService.java index 4f5c8605..85e22c9f 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/RushOrderService.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/RushOrderService.java @@ -1,9 +1,12 @@ package cc.hiver.mall.service; import cc.hiver.mall.pojo.dto.SaleDTO; +import cc.hiver.mall.pojo.dto.SaleQueryDTO; public interface RushOrderService { void handleRushOrder(SaleDTO saleDTO); + void handleNewRushOrder(SaleQueryDTO saleQueryDTO); + } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/SalesAndDetailsService.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/SalesAndDetailsService.java index 91c97381..6756dcb7 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/SalesAndDetailsService.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/SalesAndDetailsService.java @@ -2,6 +2,7 @@ package cc.hiver.mall.service; import cc.hiver.mall.entity.Sale; import cc.hiver.mall.pojo.dto.SaleDTO; +import cc.hiver.mall.pojo.dto.SaleQueryDTO; import cc.hiver.mall.pojo.vo.SaleVO; public interface SalesAndDetailsService { @@ -10,4 +11,8 @@ public interface SalesAndDetailsService { public Sale handleBackSalesAndDetails(SaleDTO saleDTO); + public Sale handleSalesDetails(SaleQueryDTO saleDTO); + + public Sale handleBackSalesDetails(SaleQueryDTO saleDTO); + } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/StockAndLogService.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/StockAndLogService.java index fb77d744..a4cedd58 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/StockAndLogService.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/StockAndLogService.java @@ -1,6 +1,7 @@ package cc.hiver.mall.service; import cc.hiver.mall.entity.SaleDetail; +import cc.hiver.mall.pojo.dto.SaleDetailDTO; import java.util.List; @@ -12,4 +13,10 @@ public interface StockAndLogService { //入 void handleIncStockAndLog(List saleDetailList); + //出 + void handleSubStockLog(List saleDetailList); + + //入 + void handleIncStockLog(List saleDetailList); + } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/RushOrderServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/RushOrderServiceImpl.java index 5394a03c..35d0f374 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/RushOrderServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/RushOrderServiceImpl.java @@ -3,6 +3,7 @@ package cc.hiver.mall.serviceimpl; import cc.hiver.mall.entity.OrderXd; import cc.hiver.mall.entity.Sale; import cc.hiver.mall.pojo.dto.SaleDTO; +import cc.hiver.mall.pojo.dto.SaleQueryDTO; import cc.hiver.mall.service.OrderService; import cc.hiver.mall.service.RushOrderService; import cn.hutool.core.util.StrUtil; @@ -38,4 +39,27 @@ public class RushOrderServiceImpl implements RushOrderService { orderService.save(orderXd); } + + @Override + public void handleNewRushOrder(SaleQueryDTO saleQueryDTO) { + /** + * 根据销售单推入至抢单表 + * */ + Sale sale = saleQueryDTO.getSale(); + OrderXd orderXd = new OrderXd(); + orderXd.setOrderId(sale.getId()); + orderXd.setOrderLogistics(sale.getTransportType()); + orderXd.setOrderAddress(sale.getProvince()+","+sale.getCity()+","+sale.getArea()); + if("4".equals(sale.getTransportType())) + orderXd.setOrderStreet(sale.getShareAddress()); + else + orderXd.setOrderStreet(sale.getReceiveAddress()); + orderXd.setOrderStatus(Integer.valueOf(sale.getStatus())); + orderXd.setOrderByWorker(StrUtil.isNotEmpty(saleQueryDTO.getOrderByWorker())? saleQueryDTO.getOrderByWorker() : null); + orderXd.setTransCompany(saleQueryDTO.getTransCompany()); + orderXd.setOrderByWorkertime(sale.getCreateTime()); + orderXd.setTimeout(2); + + orderService.save(orderXd); + } } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/SalesAndDetailsServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/SalesAndDetailsServiceImpl.java index 05129474..7bceb467 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/SalesAndDetailsServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/SalesAndDetailsServiceImpl.java @@ -1,7 +1,11 @@ package cc.hiver.mall.serviceimpl; +import cc.hiver.core.common.utils.BeanUtils; import cc.hiver.mall.entity.*; import cc.hiver.mall.pojo.dto.SaleDTO; +import cc.hiver.mall.pojo.dto.SaleDetailDTO; +import cc.hiver.mall.pojo.dto.SaleDetailQueryDTO; +import cc.hiver.mall.pojo.dto.SaleQueryDTO; import cc.hiver.mall.service.SalesAndDetailsService; import cc.hiver.mall.service.mybatis.ProductService; import cc.hiver.mall.service.mybatis.SaleDetailService; @@ -76,7 +80,7 @@ public class SalesAndDetailsServiceImpl implements SalesAndDetailsService { saleDetail.setPurchasePrice(product.getPurchasePrice()); saleDetailList2.add(saleDetail); } - saleDetailService.saveBatch(saleDetailList); + saleDetailService.saveBatch(saleDetailList2); return sale; } @@ -119,4 +123,77 @@ public class SalesAndDetailsServiceImpl implements SalesAndDetailsService { return sale; } + + @Override + public Sale handleSalesDetails(SaleQueryDTO saleDTO) { + /** + * 1.处理Sale总订单 + * 处理订单状态/收款状态 + * */ + Sale sale = saleDTO.getSale(); + + BigDecimal realAmount = sale.getRealAmount(); + BigDecimal alreadyEarn = sale.getAlreadyEarn(); + if(realAmount == null){ + realAmount = new BigDecimal(0); + } + if(alreadyEarn == null){ + alreadyEarn = new BigDecimal(0); + } + if(realAmount.subtract(alreadyEarn).compareTo(BigDecimal.ZERO)>0 && alreadyEarn.compareTo(BigDecimal.ZERO)>0){ + sale.setPayStatus("2"); + } else if (realAmount.subtract(alreadyEarn).compareTo(BigDecimal.ZERO)==0){ + sale.setPayStatus("1"); + } else { + sale.setPayStatus("0"); + } + + if (StrUtil.isNotBlank(saleDTO.getOrderByWorker())) { + sale.setStatus("2"); + } else { + sale.setStatus("1"); + } + saleService.save(sale); + + String saleId = sale.getId(); + /** + * 2.处理SaleDetail明细单 + * */ + + Product product; + + List saleDetailList = saleDTO.getSaleDetailList(); + List saleDetailList2 = new ArrayList(); + + for(SaleDetailDTO saleDetailDTO : saleDetailList){ + List attributeList = new ArrayList<>(); + int count = 0; + SaleDetail saleDetail = new SaleDetail(); + String productId = saleDetailDTO.getProductId(); + product =productService.getById(productId); + saleDetailDTO.setProductName(product.getProductName()); + saleDetailDTO.setUnit(product.getUnit()); + saleDetailDTO.setShopId(sale.getShopId()); + saleDetailDTO.setCategoryId(product.getCategoryId()); + saleDetailDTO.setSaleId(saleId); + saleDetailDTO.setPrice(product.getPrice()); + saleDetailDTO.setWholesalePrice(product.getWholesalePrice()); + saleDetailDTO.setPurchasePrice(product.getPurchasePrice()); + for(SaleDetailQueryDTO saleDetailQueryDTO : saleDetailDTO.getSaleDetailQueryDTO()){ + attributeList.add(saleDetailQueryDTO.getAttributeList()); + count += saleDetailQueryDTO.getProductCount(); + } + saleDetailDTO.setAttributeList(attributeList.toString()); + saleDetailDTO.setProductCount(count); + BeanUtils.copyBeanProp(saleDetail,saleDetailDTO); + saleDetailList2.add(saleDetail); + } + saleDetailService.saveBatch(saleDetailList2); + return sale; + } + + @Override + public Sale handleBackSalesDetails(SaleQueryDTO saleDTO) { + return null; + } } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/StockAndLogServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/StockAndLogServiceImpl.java index d625f6b2..a922f282 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/StockAndLogServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/StockAndLogServiceImpl.java @@ -1,10 +1,14 @@ package cc.hiver.mall.serviceimpl; import cc.hiver.core.common.utils.BeanUtils; +import cc.hiver.mall.entity.Product; import cc.hiver.mall.entity.SaleDetail; import cc.hiver.mall.entity.Stock; import cc.hiver.mall.entity.StockLog; +import cc.hiver.mall.pojo.dto.SaleDetailDTO; +import cc.hiver.mall.pojo.dto.SaleDetailQueryDTO; import cc.hiver.mall.service.StockAndLogService; +import cc.hiver.mall.service.mybatis.ProductService; import cc.hiver.mall.service.mybatis.SaleDetailService; import cc.hiver.mall.service.mybatis.StockLogService; import cc.hiver.mall.service.mybatis.StockService; @@ -13,6 +17,7 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.math.BigDecimal; import java.util.List; @Service @@ -27,6 +32,9 @@ public class StockAndLogServiceImpl implements StockAndLogService { @Autowired SaleDetailService saleDetailService; + @Autowired + ProductService productService; + @Override public void handleSubStockAndLog(List saleDetailList) { @@ -92,4 +100,83 @@ public class StockAndLogServiceImpl implements StockAndLogService { stockLogService.save(stockLog); } } + + @Override + public void handleSubStockLog(List saleDetailList) { + //根据销售单明细进行库存消减 + for(SaleDetailDTO saleDetailDTO : saleDetailList){ + String productId = saleDetailDTO.getProductId(); + String shopId = saleDetailDTO.getShopId(); + Product product = productService.getById(productId); + List saleDetailQueryDTOS = saleDetailDTO.getSaleDetailQueryDTO(); + QueryWrapper stockQueryWrapper = new QueryWrapper<>(); + for(SaleDetailQueryDTO saleDetailQueryDTO : saleDetailQueryDTOS){ + stockQueryWrapper.eq("product_id",productId); + stockQueryWrapper.eq("attribute_list",saleDetailQueryDTO.getAttributeList()); + //存在库存则修改库存数量 + Stock origin = stockService.getOne(stockQueryWrapper); + if(origin == null){ + //没有就创建入库负记录 + Stock stockNew = new Stock(); + stockNew.setProductName(product.getProductName()); + stockNew.setUnit(product.getUnit()); + stockNew.setShopId(saleDetailDTO.getShopId()); + stockNew.setCategoryId(product.getCategoryId()); + stockNew.setSupplierId(product.getSupplierId()); + stockNew.setProductSn(product.getProductSn()); + stockNew.setBarcode(product.getBarcode()); + stockNew.setProductVideo(product.getProductVideo()); + stockNew.setProductIntro(product.getProductIntro()); + stockNew.setSalesWeek(product.getSalesWeek()); + stockNew.setProductId(productId); + stockNew.setPrintBarcode(product.getPrintBarcode()); + int stockCount = 0; + stockNew.setStockCount(stockCount-saleDetailQueryDTO.getProductCount()); + stockNew.setAttributeList(saleDetailQueryDTO.getAttributeList()); + stockNew.setPrice(saleDetailDTO.getPrice()); + stockNew.setPurchasePrice(saleDetailDTO.getPurchasePrice()); + stockNew.setWholesalePrice(saleDetailDTO.getWholesalePrice()); + stockService.save(stockNew); + + + //2.记录库存履历 + StockLog stockLog = new StockLog(); + stockLog.setChangeType("0");//以商品维度,如果没有库存反向插入一条负库存入库 + stockLog.setProductId(productId); + stockLog.setProductSpecs(saleDetailQueryDTO.getAttributeList()); + stockLog.setStock(stockCount);//出库前数量 + stockLog.setChangeStock(saleDetailQueryDTO.getProductCount());//出库数量 + stockLog.setPrice(saleDetailDTO.getPrice()); + stockLog.setPurchasePrice(saleDetailDTO.getPurchasePrice()); + stockLog.setWholesalePrice(saleDetailDTO.getWholesalePrice()); + stockLog.setShopId(shopId); + stockLogService.save(stockLog); + }else { + Integer stockCount = origin.getStockCount(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", origin.getId()); + updateWrapper.set("stock_count", stockCount - saleDetailQueryDTO.getProductCount()); + stockService.update(updateWrapper); + + //2.记录库存履历 + StockLog stockLog = new StockLog(); + stockLog.setChangeType("1");//出库 + stockLog.setProductId(productId); + stockLog.setProductSpecs(saleDetailQueryDTO.getAttributeList()); + stockLog.setStock(stockCount);//出库前数量 + stockLog.setChangeStock(saleDetailQueryDTO.getProductCount());//出库数量 + stockLog.setPrice(saleDetailDTO.getPrice()); + stockLog.setPurchasePrice(saleDetailDTO.getPurchasePrice()); + stockLog.setWholesalePrice(saleDetailDTO.getWholesalePrice()); + stockLog.setShopId(shopId); + stockLogService.save(stockLog); + } + } + } + } + + @Override + public void handleIncStockLog(List saleDetailList) { + + } }