diff --git a/stdiet-admin/src/main/java/com/stdiet/StdietApplication.java b/stdiet-admin/src/main/java/com/stdiet/StdietApplication.java index 02ec1e09f..fdcaebd37 100644 --- a/stdiet-admin/src/main/java/com/stdiet/StdietApplication.java +++ b/stdiet-admin/src/main/java/com/stdiet/StdietApplication.java @@ -3,6 +3,7 @@ package com.stdiet; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.scheduling.annotation.EnableAsync; /** * 启动程序 @@ -10,6 +11,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; * @author ruoyi */ @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) +@EnableAsync public class StdietApplication { public static void main(String[] args) diff --git a/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysRecipesPlanController.java b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysRecipesPlanController.java new file mode 100644 index 000000000..d91d238c5 --- /dev/null +++ b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysRecipesPlanController.java @@ -0,0 +1,60 @@ +package com.stdiet.web.controller.custom; + +import java.util.List; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.stdiet.common.annotation.Log; +import com.stdiet.common.core.controller.BaseController; +import com.stdiet.common.core.domain.AjaxResult; +import com.stdiet.common.enums.BusinessType; +import com.stdiet.custom.domain.SysRecipesPlan; +import com.stdiet.custom.service.ISysRecipesPlanService; +import com.stdiet.common.utils.poi.ExcelUtil; +import com.stdiet.common.core.page.TableDataInfo; + +/** + * 食谱计划Controller + * + * @author xzj + * @date 2021-01-15 + */ +@RestController +@RequestMapping("/recipes/recipesPlan") +public class SysRecipesPlanController extends BaseController +{ + @Autowired + private ISysRecipesPlanService sysRecipesPlanService; + + /** + * 查询食谱计划列表 + */ + @PreAuthorize("@ss.hasPermi('recipes:recipesPlan:list')") + @GetMapping("/list") + public TableDataInfo list(SysRecipesPlan sysRecipesPlan) + { + startPage(); + List list = sysRecipesPlanService.selectSysRecipesPlanList(sysRecipesPlan); + return getDataTable(list); + } + + /** + * 导出食谱计划列表 + */ + @PreAuthorize("@ss.hasPermi('recipes:recipesPlan:export')") + @Log(title = "食谱计划", businessType = BusinessType.EXPORT) + @GetMapping("/export") + public AjaxResult export(SysRecipesPlan sysRecipesPlan) + { + List list = sysRecipesPlanService.selectSysRecipesPlanList(sysRecipesPlan); + ExcelUtil util = new ExcelUtil(SysRecipesPlan.class); + return util.exportExcel(list, "recipesPlan"); + } +} \ No newline at end of file diff --git a/stdiet-common/src/main/java/com/stdiet/common/utils/SynchrolockUtil.java b/stdiet-common/src/main/java/com/stdiet/common/utils/SynchrolockUtil.java new file mode 100644 index 000000000..5245feb95 --- /dev/null +++ b/stdiet-common/src/main/java/com/stdiet/common/utils/SynchrolockUtil.java @@ -0,0 +1,120 @@ +package com.stdiet.common.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.Random; +import java.util.concurrent.TimeUnit; + +@Component +public class SynchrolockUtil { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + /** + * 存储到redis中的锁标志 + */ + private static final String LOCKED = "LOCKED"; + + /** + * 默认请求锁的超时时间(ms 毫秒) + */ + private static final long TIME_OUT = 1000*60; + + /** + * 默认锁的有效时间(s) + */ + public static final int EXPIRE = 60*5; + + /** + * 锁flag + */ + private volatile boolean isLocked = false; + + @Autowired + private StringRedisTemplate redisTemplate; + + /** + * 默认锁时间60s + * + * @param key + * @return + */ + public boolean lock(String key) { + + return lock(key, EXPIRE, TIME_OUT); + + } + + /** + * @param key + * @param expireTime 锁时间,单位秒 + * @return + */ + public boolean lock(String key, int expireTime) { + return lock(key, expireTime, TIME_OUT); + } + + /** + * @param key 锁定key + * @param expireTime 锁过期时间 (秒) + * @param timeOut 请求锁超时时间 (毫秒) + * @return + */ + public boolean lock(String key, int expireTime, long timeOut) { + // 系统当前时间,纳秒 + long nowTime = System.nanoTime(); + logger.info("key = {}, lock start time = {}.", key, nowTime / 1000000); + // 请求锁超时时间,纳秒 + long timeout = timeOut * 1000000; + final Random random = new Random(); + // 不断循环向Master节点请求锁,当请求时间(System.nanoTime() - nano)超过设定的超时时间则放弃请求锁 + // 这个可以防止一个客户端在某个宕掉的master节点上阻塞过长时间 + // 如果一个master节点不可用了,应该尽快尝试下一个master节点 + synchronized (this) { + while ((System.nanoTime() - nowTime) < timeout) { + // 将锁作为key存储到redis缓存中,存储成功则获得锁 + if (redisTemplate.opsForValue().setIfAbsent(key, LOCKED)) { + isLocked = true; + // 设置锁的有效期,也是锁的自动释放时间,也是一个客户端在其他客户端能抢占锁之前可以执行任务的时间 + // 可以防止因异常情况无法释放锁而造成死锁情况的发生 + redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); + + // 上锁成功结束请求 + break; + } + // 获取锁失败时,应该在随机延时后进行重试,避免不同客户端同时重试导致谁都无法拿到锁的情况出现 + // 睡眠10毫秒后继续请求锁 + try { + Thread.sleep(10, random.nextInt(50000)); + } catch (InterruptedException e) { + logger.error("获取分布式锁休眠被中断:", e); + } + } + } + logger.info("key = {}, lock end time = {} ,spend time = {}ms.", key, nowTime / 1000000, (System.nanoTime() - nowTime) / 1000000); + return isLocked; + + } + + public boolean isLock(String key) { + //redisTemplate.getConnectionFactory().getConnection().time(); + return redisTemplate.hasKey(key); + } + + public void unlock(String key) { + // 释放锁 + // 不管请求锁是否成功,只要已经上锁,客户端都会进行释放锁的操作 + if (isLock(key)) { + long startTime = System.currentTimeMillis(); + logger.info("unlock key = {} start.", key, startTime); + redisTemplate.delete(key); + long endTime = System.currentTimeMillis(); + logger.info("unlock key = {} , end, spend time = {}ms.", key, (endTime - startTime)); + } + } + +} \ No newline at end of file diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysRecipesPlan.java b/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysRecipesPlan.java new file mode 100644 index 000000000..668fe0541 --- /dev/null +++ b/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysRecipesPlan.java @@ -0,0 +1,143 @@ +package com.stdiet.custom.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.stdiet.common.annotation.Excel; +import com.stdiet.common.core.domain.BaseEntity; + +/** + * 食谱计划对象 sys_recipes_plan + * + * @author xzj + * @date 2021-01-15 + */ +public class SysRecipesPlan extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** $column.columnComment */ + private Long id; + + /** 订单ID */ + @Excel(name = "订单ID") + private Long orderId; + + /** 食谱开始日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "食谱开始日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date startDate; + + /** 食谱结束日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "食谱结束日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date endDate; + + /** 食谱ID */ + @Excel(name = "食谱ID") + private Long recipesId; + + /** 食谱是否发送,0未发送 1已发送 */ + @Excel(name = "食谱是否发送,0未发送 1已发送") + private Integer sendFlag; + + /** 食谱发送时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "食谱发送时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date sendTime; + + /** 删除标识 0未删除 1已删除 默认0 */ + private Integer delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setOrderId(Long orderId) + { + this.orderId = orderId; + } + + public Long getOrderId() + { + return orderId; + } + public void setStartDate(Date startDate) + { + this.startDate = startDate; + } + + public Date getStartDate() + { + return startDate; + } + public void setEndDate(Date endDate) + { + this.endDate = endDate; + } + + public Date getEndDate() + { + return endDate; + } + public void setRecipesId(Long recipesId) + { + this.recipesId = recipesId; + } + + public Long getRecipesId() + { + return recipesId; + } + public void setSendFlag(Integer sendFlag) + { + this.sendFlag = sendFlag; + } + + public Integer getSendFlag() + { + return sendFlag; + } + public void setSendTime(Date sendTime) + { + this.sendTime = sendTime; + } + + public Date getSendTime() + { + return sendTime; + } + public void setDelFlag(Integer delFlag) + { + this.delFlag = delFlag; + } + + public Integer getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("orderId", getOrderId()) + .append("startDate", getStartDate()) + .append("endDate", getEndDate()) + .append("recipesId", getRecipesId()) + .append("sendFlag", getSendFlag()) + .append("sendTime", getSendTime()) + .append("createTime", getCreateTime()) + .append("createBy", getCreateBy()) + .append("updateTime", getUpdateTime()) + .append("updateBy", getUpdateBy()) + .append("delFlag", getDelFlag()) + .toString(); + } +} \ No newline at end of file diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysRecipesPlanMapper.java b/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysRecipesPlanMapper.java new file mode 100644 index 000000000..616aecf96 --- /dev/null +++ b/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysRecipesPlanMapper.java @@ -0,0 +1,75 @@ +package com.stdiet.custom.mapper; + +import java.util.List; +import com.stdiet.custom.domain.SysRecipesPlan; + +/** + * 食谱计划Mapper接口 + * + * @author xzj + * @date 2021-01-15 + */ +public interface SysRecipesPlanMapper +{ + /** + * 查询食谱计划 + * + * @param id 食谱计划ID + * @return 食谱计划 + */ + public SysRecipesPlan selectSysRecipesPlanById(Long id); + + /** + * 查询食谱计划列表 + * + * @param sysRecipesPlan 食谱计划 + * @return 食谱计划集合 + */ + public List selectSysRecipesPlanList(SysRecipesPlan sysRecipesPlan); + + /** + * 新增食谱计划 + * + * @param sysRecipesPlan 食谱计划 + * @return 结果 + */ + public int insertSysRecipesPlan(SysRecipesPlan sysRecipesPlan); + + /** + * 修改食谱计划 + * + * @param sysRecipesPlan 食谱计划 + * @return 结果 + */ + public int updateSysRecipesPlan(SysRecipesPlan sysRecipesPlan); + + /** + * 删除食谱计划 + * + * @param id 食谱计划ID + * @return 结果 + */ + public int deleteSysRecipesPlanById(Long id); + + /** + * 批量删除食谱计划 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteSysRecipesPlanByIds(Long[] ids); + + /** + * 批量添加食谱计划 + * + * @return 结果 + */ + int insertBatch(List sysRecipesPlanList); + + /** + * 根据订单ID删除对应食谱计划 + * @param orderId + * @return + */ + int delRecipesPlanByOrderId(Long orderId); +} \ No newline at end of file diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysCommissionDayService.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysCommissionDayService.java index 465e25a71..e5b48559b 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysCommissionDayService.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysCommissionDayService.java @@ -26,10 +26,10 @@ public interface ISysCommissionDayService { List calculateCommissionByDay(SysCommision sysCommision); /** - * 根据订单ID计算该笔订单的服务到期时间 - * @param orderId + * 根据订单计算该笔订单的服务到期时间 + * @param sysOrder 订单对象 * @return */ - LocalDate getServerEndDate(Long orderId); + LocalDate getServerEndDate(SysOrder sysOrder); } diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysOrderService.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysOrderService.java index 0cbef6bdb..a3d744dc5 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysOrderService.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysOrderService.java @@ -1,6 +1,7 @@ package com.stdiet.custom.service; import java.math.BigDecimal; +import java.util.Date; import java.util.List; import com.stdiet.custom.domain.SysOrder; @@ -66,4 +67,11 @@ public interface ISysOrderService * @return */ public BigDecimal selectAllOrderAmount(SysOrder sysOrder); + + /** + * 根据订单ID更新该订单的服务到期时间 + * @param orderId + * @return + */ + int updateOrderServerEndDate(Long orderId); } \ No newline at end of file diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysRecipesPlanService.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysRecipesPlanService.java new file mode 100644 index 000000000..a349ca941 --- /dev/null +++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysRecipesPlanService.java @@ -0,0 +1,70 @@ +package com.stdiet.custom.service; + +import java.util.List; +import com.stdiet.custom.domain.SysRecipesPlan; +import org.springframework.core.annotation.Order; + +/** + * 食谱计划Service接口 + * + * @author xzj + * @date 2021-01-15 + */ +public interface ISysRecipesPlanService +{ + /** + * 查询食谱计划 + * + * @param id 食谱计划ID + * @return 食谱计划 + */ + public SysRecipesPlan selectSysRecipesPlanById(Long id); + + /** + * 查询食谱计划列表 + * + * @param sysRecipesPlan 食谱计划 + * @return 食谱计划集合 + */ + public List selectSysRecipesPlanList(SysRecipesPlan sysRecipesPlan); + + /** + * 新增食谱计划 + * + * @param sysRecipesPlan 食谱计划 + * @return 结果 + */ + public int insertSysRecipesPlan(SysRecipesPlan sysRecipesPlan); + + /** + * 修改食谱计划 + * + * @param sysRecipesPlan 食谱计划 + * @return 结果 + */ + public int updateSysRecipesPlan(SysRecipesPlan sysRecipesPlan); + + /** + * 批量删除食谱计划 + * + * @param ids 需要删除的食谱计划ID + * @return 结果 + */ + public int deleteSysRecipesPlanByIds(Long[] ids); + + /** + * 删除食谱计划信息 + * + * @param id 食谱计划ID + * @return 结果 + */ + public int deleteSysRecipesPlanById(Long id); + + /** + * 根据订单ID生成对应的食谱计划 + * + * @param orderId 订单ID + * @return 结果 + */ + public void autoGenerateRecipesPlanByOrderId(Long orderId); +} \ No newline at end of file diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysCommissionDayServiceImpl.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysCommissionDayServiceImpl.java index c7941a128..e46282397 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysCommissionDayServiceImpl.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysCommissionDayServiceImpl.java @@ -60,18 +60,43 @@ public class SysCommissionDayServiceImpl implements ISysCommissionDayService { return result; } + /** + * 根据订单计算该笔订单的服务到期时间 + * @param sysOrder 订单对象 + * @return + */ @Override - public LocalDate getServerEndDate(Long orderId){ - SysOrder sysOrder = sysOrderMapper.selectSysOrderById(orderId); - if(sysOrder != null){ - SysOrderPause sysOrderPause = new SysOrderPause(); - sysOrderPause.setOrderId(orderId); - List pausesList = sysOrderPauseMapper.selectSysOrderPauseList(sysOrderPause); - sysOrder.setOrderPauseList(pausesList); - SysOrderCommisionDayDetail sysOrderCommisionDayDetail = statisticsOrderMessage(sysOrder); - return sysOrderCommisionDayDetail.getServerEndDate(); + public LocalDate getServerEndDate(SysOrder sysOrder){ + LocalDate serverEndDate = null; + if(sysOrder != null && sysOrder.getStartTime() != null){ + //服务开始时间(客户建档时间) + LocalDate serverStartDate = DateUtils.dateToLocalDate(sysOrder.getStartTime()); + //订单总服务月数 + int serverMonth = sysOrder.getServeTimeId() != null ? sysOrder.getServeTimeId().intValue()/30 : 0; + //赠送时长 + int giveDay = sysOrder.getGiveServeDay() != null ? sysOrder.getGiveServeDay().intValue() : 0; + //服务到期时间(加赠送时间,不加暂停时间) + serverEndDate = serverStartDate.plusMonths(serverMonth).plusDays(giveDay); + List pausesList = sysOrder.getOrderPauseList(); + if(pausesList == null){ + if(sysOrder.getOrderId() != null){ + SysOrderPause sysOrderPause = new SysOrderPause(); + sysOrderPause.setOrderId(sysOrder.getOrderId()); + pausesList = sysOrderPauseMapper.selectSysOrderPauseList(sysOrderPause); + }else{ + pausesList = new ArrayList<>(); + } + } + //System.out.println("结束时间:"+serverEndDate); + //每年每月暂停天数,key为年份加月份,如:2021年1月=20211 + Map everyYearMonthPauseDay = getEveryYearMonthPauseDay(pausesList, serverStartDate, serverEndDate); + //该笔订单暂停总天数 + int pauseTotalDay = getTotalByMap(everyYearMonthPauseDay); + //System.out.println("暂停天数:"+pauseTotalDay); + //服务到期时间加上暂停时间 + serverEndDate = serverEndDate.plusDays(pauseTotalDay); } - return null; + return serverEndDate; } @@ -381,7 +406,7 @@ public class SysCommissionDayServiceImpl implements ISysCommissionDayService { boolean breakFlag = false; //写100防止死循环 for(int i = 0; i < 100; i++){ - if(ChronoUnit.DAYS.between(everyMonthLastDate, endDate) >= 0){ + if(ChronoUnit.DAYS.between(everyMonthLastDate, endDate) > 0){ day = Period.between(everyMonthFirstDate, everyMonthLastDate).getDays() + 1; }else{ day = Period.between(everyMonthFirstDate, endDate).getDays() + 1; diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysOrderPauseServiceImpl.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysOrderPauseServiceImpl.java index 8c70e5271..8100534d8 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysOrderPauseServiceImpl.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysOrderPauseServiceImpl.java @@ -4,12 +4,15 @@ import java.time.LocalDate; import java.util.Date; import java.util.List; import com.stdiet.common.utils.DateUtils; +import com.stdiet.custom.domain.SysOrder; import com.stdiet.custom.service.ISysCommissionDayService; +import com.stdiet.custom.service.ISysOrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.stdiet.custom.mapper.SysOrderPauseMapper; import com.stdiet.custom.domain.SysOrderPause; import com.stdiet.custom.service.ISysOrderPauseService; +import org.springframework.transaction.annotation.Transactional; /** * 订单服务暂停Service业务层处理 @@ -18,6 +21,7 @@ import com.stdiet.custom.service.ISysOrderPauseService; * @date 2021-01-07 */ @Service +@Transactional public class SysOrderPauseServiceImpl implements ISysOrderPauseService { @Autowired @@ -26,6 +30,9 @@ public class SysOrderPauseServiceImpl implements ISysOrderPauseService @Autowired private ISysCommissionDayService sysCommissionDayService; + @Autowired + private ISysOrderService sysOrderService; + /** * 查询订单服务暂停 * @@ -60,7 +67,11 @@ public class SysOrderPauseServiceImpl implements ISysOrderPauseService public int insertSysOrderPause(SysOrderPause sysOrderPause) { sysOrderPause.setCreateTime(DateUtils.getNowDate()); - return sysOrderPauseMapper.insertSysOrderPause(sysOrderPause); + if(sysOrderPauseMapper.insertSysOrderPause(sysOrderPause) > 0){ + //修改订单服务到期时间 + return sysOrderService.updateOrderServerEndDate(sysOrderPause.getOrderId()); + } + return 0; } /** @@ -73,7 +84,10 @@ public class SysOrderPauseServiceImpl implements ISysOrderPauseService public int updateSysOrderPause(SysOrderPause sysOrderPause) { sysOrderPause.setUpdateTime(DateUtils.getNowDate()); - return sysOrderPauseMapper.updateSysOrderPause(sysOrderPause); + if(sysOrderPauseMapper.updateSysOrderPause(sysOrderPause) > 0){ + return sysOrderService.updateOrderServerEndDate(sysOrderPause.getOrderId()); + } + return 0; } /** @@ -85,7 +99,11 @@ public class SysOrderPauseServiceImpl implements ISysOrderPauseService @Override public int deleteSysOrderPauseByIds(Long[] ids) { - return sysOrderPauseMapper.deleteSysOrderPauseByIds(ids); + SysOrderPause sysOrderPause = selectSysOrderPauseById(ids[0]); + if(sysOrderPause != null && sysOrderPauseMapper.deleteSysOrderPauseByIds(ids) > 0){ + return sysOrderService.updateOrderServerEndDate(sysOrderPause.getOrderId()); + } + return 0; } /** @@ -97,7 +115,11 @@ public class SysOrderPauseServiceImpl implements ISysOrderPauseService @Override public int deleteSysOrderPauseById(Long id) { - return sysOrderPauseMapper.deleteSysOrderPauseById(id); + SysOrderPause sysOrderPause = selectSysOrderPauseById(id); + if(sysOrderPause != null && sysOrderPauseMapper.deleteSysOrderPauseById(id) > 0){ + return sysOrderService.updateOrderServerEndDate(sysOrderPause.getOrderId()); + } + return 0; } /** diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysOrderServiceImpl.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysOrderServiceImpl.java index b0cec801c..3c29682a4 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysOrderServiceImpl.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysOrderServiceImpl.java @@ -1,15 +1,22 @@ package com.stdiet.custom.service.impl; import java.math.BigDecimal; +import java.time.LocalDate; import java.util.Date; import java.util.List; +import java.util.Map; import com.stdiet.common.utils.DateUtils; +import com.stdiet.custom.domain.SysOrderCommisionDayDetail; +import com.stdiet.custom.domain.SysOrderPause; +import com.stdiet.custom.service.ISysCommissionDayService; +import com.stdiet.custom.service.ISysOrderPauseService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.stdiet.custom.mapper.SysOrderMapper; import com.stdiet.custom.domain.SysOrder; import com.stdiet.custom.service.ISysOrderService; +import org.springframework.transaction.annotation.Transactional; /** * 销售订单Service业务层处理 @@ -18,10 +25,14 @@ import com.stdiet.custom.service.ISysOrderService; * @date 2020-09-24 */ @Service +@Transactional public class SysOrderServiceImpl implements ISysOrderService { @Autowired private SysOrderMapper sysOrderMapper; + @Autowired + private ISysCommissionDayService sysCommissionDayService; + /** * 查询销售订单 * @@ -55,6 +66,8 @@ public class SysOrderServiceImpl implements ISysOrderService { Date orderTime = DateUtils.getNowDate(); sysOrder.setCreateTime(orderTime); // sysOrder.setOrderTime(orderTime); + //计算服务到期时间 + setOrderServerEndDate(sysOrder); sysOrder.setOrderId(Long.parseLong(DateUtils.parseDateToStr(DateUtils.YYYYMMDDHHMMSS, orderTime))); return sysOrderMapper.insertSysOrder(sysOrder); } @@ -68,6 +81,8 @@ public class SysOrderServiceImpl implements ISysOrderService { @Override public int updateSysOrder(SysOrder sysOrder) { sysOrder.setUpdateTime(DateUtils.getNowDate()); + //计算服务到期时间 + setOrderServerEndDate(sysOrder); return sysOrderMapper.updateSysOrder(sysOrder); } @@ -102,4 +117,30 @@ public class SysOrderServiceImpl implements ISysOrderService { public BigDecimal selectAllOrderAmount(SysOrder sysOrder) { return sysOrderMapper.selectAllOrderAmount(sysOrder); } + + /** + * 根据订单ID更新该订单的服务到期时间 + * @param orderId + * @return + */ + @Override + public int updateOrderServerEndDate(Long orderId){ + //更新订单服务到期时间 + SysOrder sysOrder = selectSysOrderById(orderId); + if(sysOrder != null){ + //设置服务到期时间 + setOrderServerEndDate(sysOrder); + sysOrder.setUpdateTime(new Date()); + return updateSysOrder(sysOrder); + } + return 0; + } + + /** + * 给对象SysOrder对象设置服务到期时间 + * @param sysOrder + */ + private void setOrderServerEndDate(SysOrder sysOrder){ + sysOrder.setServerEndTime(DateUtils.localDateToDate(sysCommissionDayService.getServerEndDate(sysOrder))); + } } \ No newline at end of file diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysRecipesPlanServiceImpl.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysRecipesPlanServiceImpl.java new file mode 100644 index 000000000..8f2107850 --- /dev/null +++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysRecipesPlanServiceImpl.java @@ -0,0 +1,243 @@ +package com.stdiet.custom.service.impl; + +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import com.stdiet.common.utils.DateUtils; +import com.stdiet.common.utils.SynchrolockUtil; +import com.stdiet.custom.domain.SysOrder; +import com.stdiet.custom.domain.SysOrderPause; +import com.stdiet.custom.service.ISysOrderPauseService; +import com.stdiet.custom.service.ISysOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.annotation.QueryAnnotation; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import com.stdiet.custom.mapper.SysRecipesPlanMapper; +import com.stdiet.custom.domain.SysRecipesPlan; +import com.stdiet.custom.service.ISysRecipesPlanService; +import org.springframework.transaction.annotation.Transactional; + +/** + * 食谱计划Service业务层处理 + * + * @author xzj + * @date 2021-01-15 + */ +@Service +@Transactional +public class SysRecipesPlanServiceImpl implements ISysRecipesPlanService +{ + @Autowired + private SysRecipesPlanMapper sysRecipesPlanMapper; + + @Autowired + private ISysOrderService sysOrderService; + + @Autowired + private ISysOrderPauseService sysOrderPauseService; + + @Autowired + private SynchrolockUtil synchrolockUtil; + + public static final String generateRecipesPlanLockKey = "generateRecipesPlanLock::%s"; + + /** + * 查询食谱计划 + * + * @param id 食谱计划ID + * @return 食谱计划 + */ + @Override + public SysRecipesPlan selectSysRecipesPlanById(Long id) + { + return sysRecipesPlanMapper.selectSysRecipesPlanById(id); + } + + /** + * 查询食谱计划列表 + * + * @param sysRecipesPlan 食谱计划 + * @return 食谱计划 + */ + @Override + public List selectSysRecipesPlanList(SysRecipesPlan sysRecipesPlan) + { + return sysRecipesPlanMapper.selectSysRecipesPlanList(sysRecipesPlan); + } + + /** + * 新增食谱计划 + * + * @param sysRecipesPlan 食谱计划 + * @return 结果 + */ + @Override + public int insertSysRecipesPlan(SysRecipesPlan sysRecipesPlan) + { + sysRecipesPlan.setCreateTime(DateUtils.getNowDate()); + return sysRecipesPlanMapper.insertSysRecipesPlan(sysRecipesPlan); + } + + /** + * 修改食谱计划 + * + * @param sysRecipesPlan 食谱计划 + * @return 结果 + */ + @Override + public int updateSysRecipesPlan(SysRecipesPlan sysRecipesPlan) + { + sysRecipesPlan.setUpdateTime(DateUtils.getNowDate()); + return sysRecipesPlanMapper.updateSysRecipesPlan(sysRecipesPlan); + } + + /** + * 批量删除食谱计划 + * + * @param ids 需要删除的食谱计划ID + * @return 结果 + */ + @Override + public int deleteSysRecipesPlanByIds(Long[] ids) + { + return sysRecipesPlanMapper.deleteSysRecipesPlanByIds(ids); + } + + /** + * 删除食谱计划信息 + * + * @param id 食谱计划ID + * @return 结果 + */ + @Override + public int deleteSysRecipesPlanById(Long id) + { + return sysRecipesPlanMapper.deleteSysRecipesPlanById(id); + } + + /** + * 根据订单ID生成对应的食谱计划 + * + * @param orderId 订单ID + * @return 结果 + */ + @Override + @Async("generateRecipesPlan") + public void autoGenerateRecipesPlanByOrderId(Long orderId){ + if(orderId == null || orderId <= 0){ + return; + } + SysOrder sysOrder = sysOrderService.selectSysOrderById(orderId); + if(sysOrder == null){ + return; + } + try{ + //获取redis中该订单对应的锁 + if(synchrolockUtil.lock(String.format(generateRecipesPlanLockKey, orderId))){ + //删除该订单对于食谱 + sysRecipesPlanMapper.delRecipesPlanByOrderId(orderId); + //订单服务开始时间、结束时间不能为空 + if(sysOrder.getStartTime() != null && sysOrder.getServerEndTime() != null){ + SysOrderPause pauseParam = new SysOrderPause(); + pauseParam.setOrderId(sysOrder.getOrderId()); + //暂停记录列表 + List pauseList = sysOrderPauseService.selectSysOrderPauseList(pauseParam); + List planList = generatePlan(orderId, DateUtils.dateToLocalDate(sysOrder.getStartTime()), DateUtils.dateToLocalDate(sysOrder.getServerEndTime()), pauseList); + if(planList != null && planList.size() > 0){ + sysRecipesPlanMapper.insertBatch(planList); + } + for (SysRecipesPlan sysRecipesPlan : planList) { + getTestDate(sysRecipesPlan.getStartDate(), sysRecipesPlan.getEndDate()); + } + } + } + } + catch (Exception e) { + e.printStackTrace(); + } finally { + // 一定要释放锁 + synchrolockUtil.unlock(String.format(generateRecipesPlanLockKey, orderId)); + } + } + + public void getTestDate(Date date, Date date2){ + LocalDate d = DateUtils.dateToLocalDate(date); + LocalDate d2 = DateUtils.dateToLocalDate(date2); + String s1 = d.getYear() +"-" + d.getMonthValue() + "-" + d.getDayOfMonth(); + String s2 = d2.getYear() +"-" + d2.getMonthValue() + "-" + d2.getDayOfMonth(); + System.out.println(s1 + " " + s2); + } + + /** + * 根据订单ID、订单开始服务时间、结束时间、暂停列表生成食谱计划列表 + * @param orderId 订单ID + * @param serverStartDate 服务开始时间 + * @param serverEndDate 服务结束时间 + * @param pauseList 暂停列表 + * @return + */ + public List generatePlan(Long orderId, LocalDate serverStartDate, LocalDate serverEndDate, List pauseList){ + List planList = new ArrayList<>(); + boolean breakFlag = false; + LocalDate planStartDate = serverStartDate; + LocalDate planEndDate = planStartDate.plusDays(6); + while (true){ + + SysRecipesPlan sysRecipesPlan = new SysRecipesPlan(); + //判断是否大于服务到期时间 + if(ChronoUnit.DAYS.between(planEndDate, serverEndDate) > 0){ + + }else{ + planEndDate = serverEndDate; + breakFlag = true; + } + long pauseDay = getPauseDayeCount(planStartDate, planEndDate, pauseList); + //加上暂停时间 + planEndDate = planEndDate.plusDays(pauseDay); + sysRecipesPlan.setStartDate(DateUtils.localDateToDate(planStartDate)); + sysRecipesPlan.setEndDate(DateUtils.localDateToDate(planEndDate)); + sysRecipesPlan.setOrderId(orderId); + planList.add(sysRecipesPlan); + + planStartDate = planEndDate.plusDays(1); + planEndDate = planStartDate.plusDays(6); + + if(breakFlag){ + break; + } + } + return planList; + } + + /** + * 根据食谱开始时间、结束时间、暂停列表获取在食谱计划范围内的暂停天数 + * @param planStartDate 计划开始时间 + * @param planEndDate 计划结束时间 + * @param pauseList 暂停列表 + * @return + */ + public long getPauseDayeCount(LocalDate planStartDate, LocalDate planEndDate, List pauseList){ + long pauseDay = 0; + //判断这个时间内是否存在暂停 + if(pauseList != null && pauseList.size() > 0){ + for(SysOrderPause sysOrderPause : pauseList){ + LocalDate pauseStartDate = DateUtils.dateToLocalDate(sysOrderPause.getPauseStartDate()); + LocalDate pauseEndDate = DateUtils.dateToLocalDate(sysOrderPause.getPauseEndDate()); + if(ChronoUnit.DAYS.between(pauseEndDate, planStartDate) > 0 || ChronoUnit.DAYS.between(planEndDate, pauseStartDate) > 0){ + continue; + } + if(ChronoUnit.DAYS.between(pauseStartDate, planStartDate) > 0){ + pauseStartDate = planStartDate; + } + if(ChronoUnit.DAYS.between(planEndDate, pauseEndDate) > 0){ + pauseEndDate = planEndDate; + } + pauseDay += ChronoUnit.DAYS.between(pauseStartDate, pauseEndDate); + } + } + return pauseDay; + } +} \ No newline at end of file diff --git a/stdiet-custom/src/main/resources/mapper/custom/SysRecipesPlanMapper.xml b/stdiet-custom/src/main/resources/mapper/custom/SysRecipesPlanMapper.xml new file mode 100644 index 000000000..62a3cbe8a --- /dev/null +++ b/stdiet-custom/src/main/resources/mapper/custom/SysRecipesPlanMapper.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + select id, order_id, start_date, end_date, recipes_id, send_flag, send_time, create_time, create_by, update_time, update_by, del_flag from sys_recipes_plan + + + + + + + + insert into sys_recipes_plan + + order_id, + start_date, + end_date, + recipes_id, + send_flag, + send_time, + create_time, + create_by, + update_time, + update_by, + del_flag, + + + #{orderId}, + #{startDate}, + #{endDate}, + #{recipesId}, + #{sendFlag}, + #{sendTime}, + #{createTime}, + #{createBy}, + #{updateTime}, + #{updateBy}, + #{delFlag}, + + + + + update sys_recipes_plan + + order_id = #{orderId}, + start_date = #{startDate}, + end_date = #{endDate}, + recipes_id = #{recipesId}, + send_flag = #{sendFlag}, + send_time = #{sendTime}, + create_time = #{createTime}, + create_by = #{createBy}, + update_time = #{updateTime}, + update_by = #{updateBy}, + del_flag = #{delFlag}, + + where id = #{id} and del_flag = 0 + + + + update sys_recipes_plan set del_flag = 0 where id = #{id} + + + + update sys_recipes_plan set del_flag = 0 where id in + + #{id} + + + + + + INSERT INTO sys_recipes_plan + (order_id, start_date, end_date) + VALUES + + (#{plan.orderId}, #{plan.startDate}, #{plan.end_date}) + + + + + + update sys_recipes_plan set del_flag = 0 and order_id = #{orderId} + + + \ No newline at end of file diff --git a/stdiet-ui/src/views/custom/order/index.vue b/stdiet-ui/src/views/custom/order/index.vue index 30c89e88c..51c0650e9 100644 --- a/stdiet-ui/src/views/custom/order/index.vue +++ b/stdiet-ui/src/views/custom/order/index.vue @@ -260,6 +260,11 @@ {{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }} + + +