massageTask.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. package com.ylx.massage.task;
  2. import cn.hutool.core.collection.CollectionUtil;
  3. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  5. import com.ylx.common.constant.MassageConstants;
  6. import com.ylx.common.core.domain.entity.SysDept;
  7. import com.ylx.common.utils.DateUtils;
  8. import com.ylx.common.utils.StringUtils;
  9. import com.ylx.massage.domain.*;
  10. import com.ylx.massage.enums.BillTypeEnum;
  11. import com.ylx.massage.enums.JsStatusEnum;
  12. import com.ylx.massage.enums.OrderStatusEnum;
  13. import com.ylx.massage.enums.OrderWStateEnum;
  14. import com.ylx.massage.mapper.TConsumptionLogMapper;
  15. import com.ylx.massage.service.*;
  16. import com.ylx.massage.utils.DateTimeUtils;
  17. import com.ylx.massage.utils.LocationUtil;
  18. import com.ylx.massage.utils.WeChatUtil;
  19. import com.ylx.system.service.ISysDeptService;
  20. import lombok.extern.slf4j.Slf4j;
  21. import lombok.val;
  22. import org.springframework.beans.factory.annotation.Autowired;
  23. import org.springframework.beans.factory.annotation.Value;
  24. import org.springframework.stereotype.Component;
  25. import javax.annotation.Resource;
  26. import java.math.BigDecimal;
  27. import java.util.*;
  28. /**
  29. * @author jianlong
  30. * @date 2024-04-19 14:11
  31. */
  32. @Slf4j
  33. @Component("massageTask")
  34. public class massageTask {
  35. @Resource
  36. private TOrderService orderService;
  37. @Resource
  38. private LocationUtil locationUtil;
  39. @Resource
  40. private TJsService jsService;
  41. @Resource
  42. private TSignService signService;
  43. @Autowired
  44. private ISysDeptService deptService;
  45. @Autowired
  46. private TRechargeService rechargeService;
  47. @Resource
  48. private TJsDayService jsDayService;
  49. @Resource
  50. private TConsumptionLogService consumptionLogService;
  51. @Resource
  52. private TConsumptionLogMapper consumptionLogMapper;
  53. @Resource
  54. private TWxUserService userService;
  55. @Resource
  56. private WeChatUtil weChatUtil;
  57. @Value("${hCount}")
  58. private String hCount;
  59. @Value("${percent}")
  60. private String percent;
  61. /**
  62. * 取消超时未支付订单
  63. */
  64. public void cancelOrder() {
  65. Date nowDate = new Date();
  66. log.info("开始执行取消订单任务当前时间:{}", nowDate);
  67. Date date = DateTimeUtils.addMinute(nowDate, -5);
  68. log.info("开始执行取消订单任务当前时间减5分钟,{}", date);
  69. long total = 1L;
  70. while (total > 0L) {
  71. total = extracted(date);
  72. }
  73. }
  74. private Long extracted(Date nowDate) {
  75. log.info("extracted 开始执行取消订单任务时间,{}", nowDate);
  76. LambdaQueryWrapper<TOrder> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
  77. objectLambdaQueryWrapper.eq(TOrder::getnStatus, OrderStatusEnum.WAIT_PAY.getCode()).
  78. le(TOrder::getDtCreateTime, nowDate).
  79. orderByAsc(TOrder::getDtCreateTime);
  80. Page<TOrder> page = new Page<>();
  81. page.setSize(MassageConstants.TWO_HUNDRED);
  82. Page<TOrder> resPage = orderService.page(page, objectLambdaQueryWrapper);
  83. if (CollectionUtil.isNotEmpty(resPage.getRecords())) {
  84. resPage.getRecords().forEach(order -> {
  85. TOrder newOrder = new TOrder();
  86. //todo 订单锁
  87. newOrder.setcId(order.getcId());
  88. newOrder.setnStatus(OrderStatusEnum.CANCEL.getCode());
  89. orderService.updateById(newOrder);
  90. log.info("取消超时未支付订单orderNo,{}", order.getOrderNo());
  91. });
  92. }
  93. return resPage.getTotal();
  94. }
  95. public void timeoutNotOrder() {
  96. Date nowDate = new Date();
  97. log.info("开始执行超时未接单任务,{}", nowDate);
  98. Date date = DateTimeUtils.addMinute(nowDate, -10);
  99. log.info("开始执行超时未接单任务当前时间减10分钟,{}", date);
  100. long total = 1L;
  101. while (total > 0L) {
  102. total = timeoutNotOrder(date);
  103. }
  104. }
  105. private Long timeoutNotOrder(Date nowDate) {
  106. LambdaQueryWrapper<TOrder> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
  107. objectLambdaQueryWrapper.eq(TOrder::getnStatus, OrderStatusEnum.WAIT_JD.getCode()).
  108. le(TOrder::getPayTime, nowDate).
  109. orderByAsc(TOrder::getPayTime);
  110. Page<TOrder> page = new Page<>();
  111. page.setSize(MassageConstants.TWO_HUNDRED);
  112. Page<TOrder> resPage = orderService.page(page, objectLambdaQueryWrapper);
  113. if (CollectionUtil.isNotEmpty(resPage.getRecords())) {
  114. resPage.getRecords().forEach(order -> {
  115. //调用拒绝接单
  116. order.setReasonRefusal("超时未接单");
  117. orderService.jujue(order);
  118. });
  119. }
  120. return resPage.getTotal();
  121. }
  122. public void isGetAmount() {
  123. Date nowDate = new Date();
  124. log.info("定时分配出账金额日期,{}", nowDate);
  125. Date date = DateTimeUtils.addDays(nowDate, -7);
  126. log.info("定时分配出账金额日期,{}", date);
  127. isGetAmount(date);
  128. }
  129. private void isGetAmount(Date date) {
  130. //查询所有部门
  131. List<SysDept> sysDepts = deptService.selectDeptList(new SysDept());
  132. //遍历部门技师
  133. sysDepts.forEach(sysDept -> {
  134. LambdaQueryWrapper<TJs> jsLambdaQueryWrapper = new LambdaQueryWrapper<>();
  135. jsLambdaQueryWrapper.eq(TJs::getnTong, JsStatusEnum.JS_PASS.getCode()).eq(TJs::getDeptId, sysDept.getDeptId());
  136. List<TJs> jsList = jsService.list(jsLambdaQueryWrapper);
  137. if (CollectionUtil.isNotEmpty(jsList)) {
  138. jsList.forEach(js -> {
  139. //根据技师openId 查询未领取金额
  140. LambdaQueryWrapper<TConsumptionLog> logLambdaQueryWrapper = new LambdaQueryWrapper<>();
  141. logLambdaQueryWrapper.eq(TConsumptionLog::getIsGet, MassageConstants.INTEGER_ZERO).
  142. eq(TConsumptionLog::getOpenId, js.getcOpenId()).
  143. in(TConsumptionLog::getBillType, Arrays.asList(BillTypeEnum.INCOME.getCode(), BillTypeEnum.DISTRIBUTION.getCode())).
  144. le(TConsumptionLog::getCreateTime, date).
  145. orderByAsc(TConsumptionLog::getCreateTime);
  146. List<TConsumptionLog> consumptionLogList = consumptionLogService.list(logLambdaQueryWrapper);
  147. if (CollectionUtil.isNotEmpty(consumptionLogList)) {
  148. //处理可提现金额
  149. //1.修改余额记录状态
  150. consumptionLogList.forEach(consumptionLog -> {
  151. //修改状态未已到提现账户
  152. consumptionLog.setIsGet(MassageConstants.INTEGER_ONE);
  153. });
  154. int i = consumptionLogMapper.insertOrUpdateBatch(consumptionLogList);
  155. //2.修改技师提现账户
  156. BigDecimal getAmount = consumptionLogList.stream().map(TConsumptionLog::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
  157. TWxUser user = userService.getByOpenId(js.getcOpenId());
  158. user.setGetAmount(user.getGetAmount().add(getAmount));
  159. userService.updateById(user);
  160. }
  161. });
  162. }
  163. });
  164. }
  165. public void cancelNewJs() {
  166. Date nowDate = new Date();
  167. log.info("开始执行取消新技师标识任务当前时间,{}", nowDate);
  168. long flag = 1L;
  169. while (flag > 0L) {
  170. LambdaQueryWrapper<TJs> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
  171. Date date = DateTimeUtils.addDays(nowDate, -7);
  172. log.info("开始执行取新技师当前时间减7天,{}", date);
  173. objectLambdaQueryWrapper.eq(TJs::getnB2, MassageConstants.INTEGER_ONE).
  174. le(TJs::getcTime, date).
  175. gt(TJs::getId, String.valueOf(flag)).
  176. orderByAsc(TJs::getId);
  177. Page<TJs> page = new Page<>();
  178. page.setSize(MassageConstants.TWO_HUNDRED);
  179. Page<TJs> page1 = jsService.page(page, objectLambdaQueryWrapper);
  180. if (CollectionUtil.isNotEmpty(page1.getRecords())) {
  181. page1.getRecords().forEach(tjs -> {
  182. TJs js = new TJs();
  183. js.setId(tjs.getId());
  184. js.setnB2(MassageConstants.INTEGER_ZERO);
  185. jsService.updateById(js);
  186. log.info("取消新技师标识,{}", js.getcOpenId() + js.getcName());
  187. });
  188. Optional<String> maxId = page1.getRecords().stream().max(Comparator.comparing(TJs::getId)).map(TJs::getId);
  189. flag = Long.parseLong(maxId.orElse("0"));
  190. } else {
  191. flag = 0L;
  192. }
  193. }
  194. }
  195. public void cancelHotJs() {
  196. Date nowDate = new Date();
  197. log.info("开始执行取消技师热度标识任务当前时间,{}", nowDate);
  198. Date date = DateTimeUtils.addDays(nowDate, -3);
  199. long flag = 1L;
  200. while (flag > 0L) {
  201. LambdaQueryWrapper<TJs> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
  202. objectLambdaQueryWrapper.eq(TJs::getnB3, MassageConstants.INTEGER_ONE).gt(TJs::getId, String.valueOf(flag)).orderByAsc(TJs::getId);
  203. Page<TJs> page = new Page<>();
  204. page.setSize(MassageConstants.TWO_HUNDRED);
  205. Page<TJs> page1 = jsService.page(page, objectLambdaQueryWrapper);
  206. if (CollectionUtil.isNotEmpty(page1.getRecords())) {
  207. page1.getRecords().forEach(tjs -> {
  208. List<TOrder> list = orderService.list(new LambdaQueryWrapper<TOrder>().eq(TOrder::getcJsId, tjs.getId()).ge(TOrder::getDtCreateTime, date));
  209. if (CollectionUtil.isEmpty(list) || list.size() < 3) {
  210. TJs js = new TJs();
  211. js.setId(tjs.getId());
  212. js.setnB3(MassageConstants.INTEGER_ZERO);
  213. jsService.updateById(js);
  214. log.info("取消热度技师标识,{}", js.getcOpenId() + js.getcName());
  215. }
  216. });
  217. Optional<String> maxId = page1.getRecords().stream().max(Comparator.comparing(TJs::getId)).map(TJs::getId);
  218. flag = Long.parseLong(maxId.orElse("0"));
  219. } else {
  220. flag = 0L;
  221. }
  222. }
  223. }
  224. /**
  225. * 定时下岗
  226. * 12:01 查询前一天 是否有上岗记录
  227. * 如果有上岗记录 没有下岗记录
  228. * 插入一条(前一天)下岗记录(并计算在线时长) 和当天上岗记录
  229. *
  230. * @param date yyyy-MM-dd
  231. **/
  232. public void RegularLayoff(String date) {
  233. Date date2 = new Date();
  234. if (StringUtils.isNotBlank(date)) {
  235. date2 = DateTimeUtils.parseDate(date, DateTimeUtils.DATE_FORMAT);
  236. } else {
  237. date2 = DateTimeUtils.addDays(date2, -1);
  238. }
  239. Date startDate = DateTimeUtils.getStartDate(date2);
  240. Date endDate = DateTimeUtils.getEndDate(date2);
  241. long total = 1L;
  242. while (total > 0L) {
  243. Page<TSign> signPage = new Page<>();
  244. signPage.setSize(MassageConstants.TWO_HUNDRED);
  245. LambdaQueryWrapper<TSign> signLambdaQueryWrapper = new LambdaQueryWrapper<>();
  246. //上岗
  247. signLambdaQueryWrapper.isNull(TSign::getLayoffTime).ge(TSign::getSingTime, startDate).le(TSign::getSingTime, endDate);
  248. Page<TSign> page = signService.page(signPage, signLambdaQueryWrapper);
  249. if (CollectionUtil.isNotEmpty(page.getRecords())) {
  250. page.getRecords().forEach(sign -> {
  251. sign.setLayoffTime(endDate);
  252. Long layoff = DateTimeUtils.dateToStamp(sign.getLayoffTime());
  253. Long sing = DateTimeUtils.dateToStamp(sign.getSingTime());
  254. Long time = layoff - sing;
  255. time = time / 1000;
  256. time = time / 60;
  257. sign.setOnlineTime(time.intValue());
  258. signService.updateById(sign);
  259. //增加上岗记录
  260. TSign tSign = new TSign();
  261. tSign.setSingTime(endDate);
  262. tSign.setName(sign.getName());
  263. tSign.setJsId(sign.getJsId());
  264. tSign.setDeptId(sign.getDeptId());
  265. tSign.setDeptName(sign.getDeptName());
  266. tSign.setOpenId(sign.getOpenId());
  267. signService.save(tSign);
  268. });
  269. }
  270. total = page.getTotal();
  271. }
  272. //查询所有部门
  273. List<SysDept> sysDepts = deptService.selectDeptList(new SysDept());
  274. sysDepts.forEach(sysDept -> {
  275. //查询所有技师
  276. LambdaQueryWrapper<TJs> jsLambdaQueryWrapper = new LambdaQueryWrapper<>();
  277. jsLambdaQueryWrapper.eq(TJs::getnTong, JsStatusEnum.JS_PASS.getCode()).eq(TJs::getDeptId, sysDept.getDeptId());
  278. List<TJs> jsList = jsService.list(jsLambdaQueryWrapper);
  279. if (CollectionUtil.isNotEmpty(jsList)) {
  280. jsList.forEach(js -> {
  281. TJsDay tJsDay = new TJsDay();
  282. tJsDay.setDeptName(js.getCity());
  283. tJsDay.setDeptId(js.getDeptId());
  284. tJsDay.setOpenId(js.getcOpenId());
  285. tJsDay.setJsId(js.getId());
  286. tJsDay.setName(js.getcName());
  287. Integer onLine = signService.getOnLineTime(js.getId(), startDate, endDate);
  288. tJsDay.setOnLine(onLine);
  289. Integer orderNum = orderService.getOrderNum(js.getId(), startDate, endDate);
  290. tJsDay.setOrderNum(orderNum);
  291. Integer addNum = orderService.getAddNum(js.getId(), startDate, endDate);
  292. tJsDay.setAddNum(addNum);
  293. Integer upgradeNum = orderService.getUpgradeNum(js.getId(), startDate, endDate);
  294. tJsDay.setUpgradeNum(upgradeNum);
  295. BigDecimal turnover = orderService.getTurnover(js.getId(), startDate, endDate);
  296. tJsDay.setTurnover(turnover);
  297. BigDecimal recharge = rechargeService.getRecharge(js.getId(), startDate, endDate);
  298. tJsDay.setRecharge(recharge);
  299. tJsDay.setCountDate(DateTimeUtils.formatDate(startDate, DateTimeUtils.DATE_FORMAT));
  300. jsDayService.save(tJsDay);
  301. });
  302. }
  303. });
  304. }
  305. public void sysJsWeiZhi() {
  306. log.info("开始执行同步技师位置时间,{}", DateUtils.getNowDate());
  307. long flag = 1L;
  308. while (flag > 0L) {
  309. LambdaQueryWrapper<TJs> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
  310. objectLambdaQueryWrapper.gt(TJs::getId, String.valueOf(flag)).orderByAsc(TJs::getId);
  311. Page<TJs> page = new Page<>();
  312. page.setSize(MassageConstants.TWO_HUNDRED);
  313. Page<TJs> page1 = jsService.page(page, objectLambdaQueryWrapper);
  314. if (CollectionUtil.isNotEmpty(page1.getRecords())) {
  315. page1.getRecords().forEach(tjs -> {
  316. if (StringUtils.isNotBlank(tjs.getcPhone()) && null != tjs.getLongitude() && null != tjs.getLatitude()) {
  317. locationUtil.geoAdd(LocationUtil.GEO_KEY, tjs.getcPhone(),
  318. Double.parseDouble(tjs.getLongitude().toString()),
  319. Double.parseDouble(tjs.getLatitude().toString()));
  320. }
  321. });
  322. Optional<String> maxId = page1.getRecords().stream().max(Comparator.comparing(TJs::getId)).map(TJs::getId);
  323. flag = Long.parseLong(maxId.orElse("0"));
  324. } else {
  325. flag = 0L;
  326. }
  327. }
  328. log.info("结束执行同步技师位置时间,{}", DateUtils.getNowDate());
  329. }
  330. public void sysJsWeiTicke() {
  331. log.info("开始执行同步技师二维码,{}", DateUtils.getNowDate());
  332. long flag = 1L;
  333. while (flag > 0L) {
  334. LambdaQueryWrapper<TJs> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
  335. objectLambdaQueryWrapper.gt(TJs::getId, String.valueOf(flag)).orderByAsc(TJs::getId);
  336. Page<TJs> page = new Page<>();
  337. page.setSize(MassageConstants.TWO_HUNDRED);
  338. Page<TJs> page1 = jsService.page(page, objectLambdaQueryWrapper);
  339. if (CollectionUtil.isNotEmpty(page1.getRecords())) {
  340. page1.getRecords().forEach(tjs -> {
  341. String token = weChatUtil.getToken();
  342. //获取的二维码ticket
  343. Map<?, ?> jsTicket = weChatUtil.getJsTicket(token, tjs.getId());
  344. tjs.setTicket(jsTicket.get("ticket").toString());
  345. jsService.updateById(tjs);
  346. });
  347. Optional<String> maxId = page1.getRecords().stream().max(Comparator.comparing(TJs::getId)).map(TJs::getId);
  348. flag = Long.parseLong(maxId.orElse("0"));
  349. } else {
  350. flag = 0L;
  351. }
  352. }
  353. log.info("结束执行同步技师二维码,{}", DateUtils.getNowDate());
  354. }
  355. /**
  356. * 1 <48小时 订单服务完成后 进行更新操作 订单状态已完成[nStatus=5]后 更新订单结算状态为待结算[wStatus=1]
  357. * 2 >48小时 订单结算状态更新为 已结算 自动分账 订单总金额划入用户余额
  358. */
  359. public void autoAccount() {
  360. log.info("开始执行同步自动分账,{}", DateUtils.getNowDate());
  361. //执行存储过程
  362. //>48小时 订单状态 [待结算] 更新为 [已结算] 自动分账 订单总金额划入用户余额
  363. orderService.callAutoAccount(Integer.parseInt(hCount), new BigDecimal(percent));
  364. log.info("执行同步自动分账结束,{}", DateUtils.getNowDate());
  365. }
  366. }