LotServiceImpl.java 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. package cn.hobbystocks.auc.service.impl;
  2. import cn.hobbystocks.auc.cache.CacheMap;
  3. import cn.hobbystocks.auc.common.constant.Constants;
  4. import cn.hobbystocks.auc.common.core.redis.Locker;
  5. import cn.hobbystocks.auc.common.core.redis.RedisCache;
  6. import cn.hobbystocks.auc.common.core.text.Convert;
  7. import cn.hobbystocks.auc.common.user.UserUtils;
  8. import cn.hobbystocks.auc.common.utils.CloneUtils;
  9. import cn.hobbystocks.auc.common.utils.DateUtils;
  10. import cn.hobbystocks.auc.common.utils.SensitiveDataUtils;
  11. import cn.hobbystocks.auc.common.utils.StringUtils;
  12. import cn.hobbystocks.auc.domain.*;
  13. import cn.hobbystocks.auc.event.ChangeEvent;
  14. import cn.hobbystocks.auc.event.EventPublisher;
  15. import cn.hobbystocks.auc.event.JPushEvent;
  16. import cn.hobbystocks.auc.event.StartBiddingEvent;
  17. import cn.hobbystocks.auc.handle.RuleHandlerHolder;
  18. import cn.hobbystocks.auc.handle.context.Live;
  19. import cn.hobbystocks.auc.handle.context.LiveContext;
  20. import cn.hobbystocks.auc.mapper.*;
  21. import cn.hobbystocks.auc.service.ILotService;
  22. import cn.hobbystocks.auc.task.DynamicTaskService;
  23. import cn.hobbystocks.auc.vo.LiveVO;
  24. import cn.hobbystocks.auc.vo.LotVO;
  25. import cn.hobbystocks.auc.vo.SelfVO;
  26. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  27. import com.baomidou.mybatisplus.core.metadata.IPage;
  28. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  29. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  30. import lombok.extern.slf4j.Slf4j;
  31. import org.springframework.beans.BeanUtils;
  32. import org.springframework.beans.factory.annotation.Autowired;
  33. import org.springframework.stereotype.Service;
  34. import org.springframework.transaction.annotation.Isolation;
  35. import org.springframework.transaction.annotation.Transactional;
  36. import org.springframework.util.CollectionUtils;
  37. import java.util.*;
  38. import java.util.concurrent.TimeUnit;
  39. import java.util.concurrent.atomic.AtomicLong;
  40. import java.util.regex.Matcher;
  41. import java.util.regex.Pattern;
  42. import java.util.stream.Collectors;
  43. @Service
  44. @Slf4j
  45. public class LotServiceImpl extends ServiceImpl<LotMapper,Lot> implements ILotService
  46. {
  47. @Autowired
  48. private LotMapper lotMapper;
  49. @Autowired
  50. private BidMapper bidMapper;
  51. @Autowired
  52. private Locker locker;
  53. @Autowired
  54. private RuleHandlerHolder ruleHandlerHolder;
  55. @Autowired
  56. private RedisCache redisCache;
  57. @Autowired
  58. private AuctionMapper auctionMapper;
  59. @Autowired
  60. public EventPublisher eventPublisher;
  61. @Autowired(required = false)
  62. private CacheMap cacheMap;
  63. @Autowired
  64. private DynamicTaskService dynamicTaskService;
  65. @Autowired
  66. private LotServiceImpl _thiz;
  67. @Autowired
  68. private LotGroupMapper lotGroupMapper;
  69. @Autowired
  70. private LotFansMapper lotFansMapper;
  71. @Override
  72. public Lot selectLotById(Long id) {
  73. return lotMapper.selectLotById(id);
  74. }
  75. @Override
  76. public LotGroup selectLotGroupById(Long id) {
  77. return lotGroupMapper.selectLotGroupById(id);
  78. }
  79. @Override
  80. public List<Lot> selectLotList(Lot lot) {
  81. IPage<Lot> lotIPage=new Page<>(lot.getPageNum(),lot.getPageSize());
  82. return lotMapper.selectLotList(lotIPage,lot);
  83. }
  84. @Override
  85. public List<Lot> selectLotByGroupIds(Long[] groupIds) {
  86. return null;
  87. }
  88. @Override
  89. public List<LotGroup> selectLotGroupList(LotGroup lotGroup) {
  90. return lotGroupMapper.selectLotGroupList(lotGroup);
  91. }
  92. @Override
  93. public void cancelLotGroup(Long id) {
  94. LotGroup dbLotGroup = lotGroupMapper.selectLotGroupById(id);
  95. dbLotGroup.setStatus(Constants.GROUP_STATUS_WAITING);
  96. dbLotGroup.setPubStatus(Constants.PUB_STATUS_NO_PUBLISHED);
  97. lotGroupMapper.updateLotGroup(dbLotGroup);
  98. }
  99. @Override
  100. public List<Lot> selectLotByGroupId(Long id) {
  101. return lotMapper.selectLotByGroupId(id);
  102. }
  103. @Override
  104. public List<LotGroup> canCreateLive(Long merchantId) {
  105. return lotGroupMapper.canCreateLive(merchantId);
  106. }
  107. @Override
  108. public List<LotGroup> findPubbedLotGroupByIds(Long[] lotGroupIds,Long merchantId) {
  109. return lotGroupMapper.findPubbedLotGroupByLotIds(lotGroupIds,merchantId);
  110. }
  111. @Override
  112. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  113. public Long party(LotGroup lotGroup) {
  114. AtomicLong result = new AtomicLong(0);
  115. locker.tryLock(String.format(Constants.REDIS_GROUP_LOCK_LOT_TEMPLATE, lotGroup.getId()), () -> {
  116. LotGroup dbLotGroup = lotGroupMapper.selectLotGroupById(lotGroup.getId());
  117. Lot currLot = lotMapper.selectLotById(dbLotGroup.getNextLotId());
  118. Lot nextLot = new Lot();
  119. BeanUtils.copyProperties(dbLotGroup, nextLot, "id");
  120. nextLot.setStatus(Constants.LOT_STATUS_WAITING);
  121. nextLot.setStartTime(null);
  122. nextLot.setCreateTime(new Date());
  123. nextLot.setUpdateTime(null);
  124. nextLot.setPubTime(new Date());
  125. nextLot.setPubStatus(Constants.PUB_STATUS_PUBLISHED);
  126. nextLot.setGroupId(lotGroup.getId());
  127. nextLot.setAuctionId(2L);
  128. String name = currLot.getName();
  129. int i = name.lastIndexOf("#");
  130. if (i > 0 && i != name.length() -1) {
  131. String numStr = name.substring(i + 1);
  132. String nextNum = "";
  133. try {
  134. long l = Long.parseLong(numStr);
  135. nextNum = "#" + (l + 1);
  136. }catch (Exception ignored) {}
  137. nextLot.setName(nextLot.getName() + nextNum);
  138. }
  139. lotMapper.updateLot(
  140. Lot.builder()
  141. .id(currLot.getId())
  142. .startTime(new Date())
  143. .build());
  144. currLot.setStartTime(new Date());
  145. long l = Objects.isNull(dbLotGroup.getFinishNum()) ? 0 : dbLotGroup.getFinishNum();
  146. if (l >= dbLotGroup.getNum()) {
  147. throw new RuntimeException("商品库存已经用完");
  148. }else if (l<dbLotGroup.getNum()-1){
  149. lotMapper.insertLot(nextLot);
  150. }
  151. lotGroupMapper.updateLotGroup(LotGroup.builder()
  152. .id(lotGroup.getId())
  153. .lotId(currLot.getId())
  154. .nextLotId(nextLot.getId())
  155. .finishNum(Objects.isNull(dbLotGroup.getFinishNum()) ? 0 : dbLotGroup.getFinishNum() + 1)
  156. .status(Constants.LOT_STATUS_STARTING)
  157. .build()
  158. );
  159. pubLot(currLot);
  160. result.set(currLot.getId());
  161. eventPublisher.publishStartBiddingEvent(new StartBiddingEvent(dbLotGroup.getId()));
  162. }, true, "开启失败,请重试!");
  163. return result.get();
  164. }
  165. @Override
  166. public List<LotGroup> findStartingGroupByLotIds(Long[] lotIds) {
  167. return lotGroupMapper.findStartingGroupByIds(lotIds);
  168. }
  169. @Override
  170. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  171. public void updateExpire(LotFans fans) {
  172. lotFansMapper.updateLotFans(
  173. LotFans.builder()
  174. .id(fans.getId())
  175. .type("pay_expire")
  176. .expire(DateUtils.addDays(fans.getCreateTime(), 1))
  177. .build());
  178. lotMapper.updateLot(Lot.builder().id(fans.getLotId()).status(Constants.LOT_STATUS_PASS).build());
  179. }
  180. @Override
  181. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  182. public void updateSoldAndPaid(LotFans fans, Long groupId) {
  183. lotFansMapper.deleteLotFansById(fans.getId());
  184. lotMapper.updatePay(fans.getLotId(), 1);
  185. lotGroupMapper.addSold(groupId);
  186. }
  187. @Override
  188. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  189. public void handleEndLotGroup(LotGroup lotGroup, String status) {
  190. LotGroup dbLotGroup = lotGroupMapper.selectLotGroupById(lotGroup.getId());
  191. lotGroupMapper.updateLotGroupSold(dbLotGroup.getId());
  192. }
  193. @Override
  194. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  195. public int insertLot(Lot lot) {
  196. lot.setCreateTime(DateUtils.getNowDate());
  197. int result = lotMapper.insertLot(lot);
  198. dynamicTask(lot);
  199. return result;
  200. }
  201. @Override
  202. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  203. public int insertLotGroup(LotGroup lotGroup) {
  204. final int i = lotGroupMapper.insertLotGroup(lotGroup);
  205. Lot lot = new Lot();
  206. BeanUtils.copyProperties(lotGroup, lot, "id");
  207. lot.setStatus(Constants.LOT_STATUS_WAITING);
  208. lot.setStartTime(null);
  209. lot.setCreateTime(new Date());
  210. lot.setUpdateTime(null);
  211. lot.setPubTime(new Date());
  212. lot.setPubStatus(Constants.PUB_STATUS_PUBLISHED);
  213. lot.setGroupId(lotGroup.getId());
  214. lot.setNum(1L);
  215. lot.setName(lot.getName() + "#1");
  216. lotMapper.insertLot(lot);
  217. lotGroupMapper.updateLotGroup(LotGroup.builder().id(lotGroup.getId()).nextLotId(lot.getId()).build());
  218. return i;
  219. }
  220. @Override
  221. public int updateLot(Lot lot) {
  222. lot.setUpdateTime(DateUtils.getNowDate());
  223. return lotMapper.updateLot(lot);
  224. }
  225. @Override
  226. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  227. public int updateLotGroup(LotGroup lotGroup) {
  228. LotGroup dbLotGroup = lotGroupMapper.selectLotGroupById(lotGroup.getId());
  229. if (Objects.nonNull(lotGroup.getNum()) && dbLotGroup.getNum() > lotGroup.getNum()) {
  230. int count = lotMapper.selectLotByGroupId(lotGroup.getId()).size() - 1;
  231. if (count > lotGroup.getNum()) {
  232. throw new RuntimeException("数量不合法");
  233. }
  234. }
  235. lotGroup.setUpdateTime(DateUtils.getNowDate());
  236. int result = lotGroupMapper.updateLotGroup(lotGroup);
  237. dbLotGroup = lotGroupMapper.selectLotGroupById(lotGroup.getId());
  238. Lot lot = lotMapper.selectLotById(dbLotGroup.getNextLotId());
  239. if (Constants.LOT_STATUS_WAITING.equals(lot.getStatus())) {
  240. String name = lot.getName();
  241. String nextNum = "";
  242. int i = name.lastIndexOf("#");
  243. if (i > 0 && i != name.length() -1) {
  244. String numStr = name.substring(i + 1);
  245. try {
  246. long l = Long.parseLong(numStr);
  247. nextNum = "#" + l;
  248. }catch (Exception ignored) {}
  249. }
  250. BeanUtils.copyProperties(dbLotGroup, lot, "id","createTime", "name");
  251. lot.setStatus(Constants.LOT_STATUS_WAITING);
  252. lot.setStartTime(null);
  253. lot.setPubTime(new Date());
  254. lot.setPubStatus(Constants.PUB_STATUS_PUBLISHED);
  255. lot.setGroupId(lotGroup.getId());
  256. lot.setName(dbLotGroup.getName() + nextNum);
  257. updateLot(lot);
  258. }
  259. return result;
  260. }
  261. @Override
  262. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  263. public int updateLotGroup0(LotGroup lotGroup) {
  264. return lotGroupMapper.updateLotGroup(lotGroup);
  265. }
  266. @Override
  267. public int updateLotView(Lot lot) {
  268. lot.setUpdateTime(DateUtils.getNowDate());
  269. int result = lotMapper.updateLotView(lot);
  270. dynamicTask(lot);
  271. return result;
  272. }
  273. @Override
  274. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  275. public int updateLotEx(Lot lot) {
  276. lot.setUpdateTime(DateUtils.getNowDate());
  277. int result = lotMapper.updateLotEx(lot);
  278. dynamicTask(lot);
  279. return result;
  280. }
  281. @Override
  282. public List<Lot> selectBidding() {
  283. return lotMapper.selectBidding();
  284. }
  285. @Override
  286. public List<Lot> selectCancel() {
  287. return lotMapper.selectCancel();
  288. }
  289. @Override
  290. public int deleteLotByIds(String ids) {
  291. return lotMapper.deleteLotByIds(Convert.toLongArray(ids));
  292. }
  293. @Override
  294. public int deleteLotById(Long id) {
  295. return lotMapper.deleteLotById(id);
  296. }
  297. @Override
  298. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  299. public void pubLot(Lot lot) {
  300. locker.tryLock(String.format(Constants.REDIS_LOCK_LOT_TEMPLATE, lot.getId()), () ->{
  301. lot.setPubTime(new Date());
  302. lot.setPubStatus(Constants.PUB_STATUS_PUBLISHED);
  303. lot.setUpdateTime(new Date());
  304. lotMapper.updateLot(lot);
  305. //构建竞价拍卖上下文
  306. LiveContext liveContext = ruleHandlerHolder.pubLive(lot);
  307. if (liveContext.isLotUpdate()) {
  308. lotMapper.updateLot(lot);
  309. }
  310. redisCache.setCacheMapValue(String.format(Constants.REDIS_MAP_AUC_LOT_TEMPLATE, lot.getAuctionId()), lot.getId().toString(), liveContext.getLive());
  311. }, true);
  312. }
  313. @Override
  314. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  315. public void pubLots(Auction auction) {
  316. List<Lot> lots = lotMapper.selectLotByAucId(auction.getId());
  317. for (Lot lot : lots) {
  318. lot.setUpdateBy(auction.getUpdateBy());
  319. pubLot(lot);
  320. }
  321. }
  322. @Override
  323. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  324. public void insertLotAndPub(Lot lot) {
  325. insertLot(lot);
  326. pubLot(lot);
  327. }
  328. @Override
  329. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  330. public void updateLotAndPub(Lot lot) {
  331. updateLot(lot);
  332. pubLot(lot);
  333. }
  334. @Override
  335. public void removeLot(Lot lot) {
  336. Lot condition = new Lot();
  337. condition.setId(lot.getId());
  338. condition.setDelFlag(Constants.DEL_FLAG_DELETED);
  339. lotMapper.updateLot(condition);
  340. }
  341. @Override
  342. public void cancelLot(Lot lot) {
  343. lot.setUpdateTime(new Date());
  344. lot.setStatus(Constants.LOT_STATUS_CANCELLED);
  345. lot.setPubStatus(Constants.PUB_STATUS_NO_PUBLISHED);
  346. lotMapper.updateLot(lot);
  347. ruleHandlerHolder.cancelLot(lot);
  348. }
  349. @Override
  350. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  351. public void live(Live live) {
  352. live = redisCache.getCacheMapValue(String.format(Constants.REDIS_MAP_AUC_LOT_TEMPLATE, live.getLot().getAuctionId()), live.getLot().getId().toString());
  353. // 1秒的轮询 会存在失效数据 判断是否是失效数据
  354. if (Objects.isNull(live)) {
  355. //是失效数据
  356. return;
  357. }
  358. cacheMap.putLive(live);
  359. List<Bid> bidList = redisCache.getCacheList(String.format(Constants.REDIS_MAP_AUC_LOT_BID_TEMPLATE, live.getLot().getId()));
  360. // 创建当前 context
  361. LiveContext liveContext = LiveContext.builder()
  362. .live(live)
  363. .dbLot(Lot.builder()
  364. .id(live.getLot().getId())
  365. .auctionId(live.getLot().getAuctionId())
  366. .build())
  367. .bidList(bidList)
  368. .dbBid(getLastBid(bidList))
  369. .build();
  370. // 分析并设置当前状态
  371. ruleHandlerHolder.live(liveContext);
  372. // 更新当前状态 到数据库和缓存
  373. updateToRedisAndDb(liveContext);
  374. // 发送极光推送
  375. jPush(liveContext);
  376. }
  377. private void jPush(LiveContext liveContext) {
  378. Live live = liveContext.getLive();
  379. if (live.getCurrentEndTime() < (System.currentTimeMillis() + 1000 * 60 * 5)) {
  380. Long expire = redisCache.redisTemplate.getExpire(String.format(Constants.REDIS_LOCK_PUSH_LOT_TEMPLATE, live.getLot().getId()));
  381. if (Objects.isNull(expire) || expire < 0L) {
  382. eventPublisher.publishJPush(JPushEvent.builder().live(live).build());
  383. redisCache.setCacheObject(String.format(Constants.REDIS_LOCK_PUSH_LOT_TEMPLATE, live.getLot().getId()), "jPush", 10, TimeUnit.MINUTES);
  384. }
  385. }
  386. }
  387. private Bid getLastBid(List<Bid> bidList) {
  388. if (!CollectionUtils.isEmpty(bidList)) {
  389. return bidList.get(0);
  390. }
  391. return null;
  392. }
  393. private void updateToRedisAndDb(LiveContext liveContext) {
  394. Live live = liveContext.getLive();
  395. List<Bid> dataList = liveContext.getBidList();
  396. ChangeEvent changeEvent = new ChangeEvent(live);
  397. if (liveContext.isLotUpdate()) {
  398. liveContext.getDbLot().setUpdateTime(new Date());
  399. lotMapper.updateLot(liveContext.getDbLot());
  400. }
  401. if (liveContext.isBidUpdate()) {
  402. bidMapper.updateBid(liveContext.getDbBid());
  403. redisCache.setList(String.format(Constants.REDIS_MAP_AUC_LOT_BID_TEMPLATE, live.getLot().getId()), dataList);
  404. changeEvent.setBid(liveContext.getDbBid());
  405. }
  406. if (liveContext.isLiveUpdate()) {
  407. if (Constants.LOT_STATUS_SOLD.equals(live.getLot().getStatus()) ||
  408. Constants.LOT_STATUS_PASS.equals(live.getLot().getStatus())) {
  409. redisCache.delCacheMapValue(String.format(Constants.REDIS_MAP_AUC_LOT_TEMPLATE, live.getLot().getAuctionId()), live.getLot().getId().toString());
  410. redisCache.deleteObject(String.format(Constants.REDIS_MAP_AUC_LOT_BID_TEMPLATE, live.getLot().getId()));
  411. if (Constants.LOT_STATUS_SOLD.equals(live.getLot().getStatus())) {
  412. if(live.getBidId()==null){
  413. long bidid = bidMapper.getCurrentBid(live.getLot().getId());
  414. live.setBidId(bidid);
  415. }
  416. eventPublisher.publishSoldEvent(live, dataList);
  417. }
  418. eventPublisher.publishEndEvent(live);
  419. }else {
  420. redisCache.setCacheMapValue(String.format(Constants.REDIS_MAP_AUC_LOT_TEMPLATE, live.getLot().getAuctionId()), live.getLot().getId().toString(), live);
  421. }
  422. eventPublisher.publishChangeEvent(changeEvent);
  423. }
  424. }
  425. @Override
  426. public List<Lot> live(Long auctionId) {
  427. LambdaQueryWrapper<Lot> queryWrapper=new LambdaQueryWrapper<>();
  428. queryWrapper.eq(Lot::getAuctionId,auctionId).eq(Lot::getDelFlag,Constants.DEL_FLAG_NO_DELETE);
  429. return lotMapper.selectList(queryWrapper);
  430. }
  431. @Override
  432. public List<LiveVO> selfLive(SelfVO selfVO) {
  433. Map<String, Live> cacheLive = CloneUtils.clone(cacheMap.viewAuction(selfVO.getAuctionId()));
  434. return cacheLive.values().stream()
  435. .filter(live -> live.getAccountList().contains(UserUtils.getSimpleUserInfo().getId().toString()) &&
  436. Constants.LOT_STATUS_BIDDING.equals(live.getLot().getStatus()))
  437. .map(live -> {
  438. List<Bid> bidList = bidMapper.selectBidByLotId(live.getLot().getId());
  439. LiveVO liveVO = new LiveVO(live);
  440. if (!CollectionUtils.isEmpty(bidList)) {
  441. liveVO.setLastPriceTime(bidList.get(0).getCreateTime().getTime());
  442. }
  443. liveVO.setCurrUserBids(
  444. Objects.requireNonNull(bidList).stream()
  445. .filter(bid -> bid.getAccountId().equals(UserUtils.getSimpleUserInfo().getId().toString()))
  446. .collect(Collectors.toList())
  447. );
  448. return SensitiveDataUtils.handleViewDataSafe(liveVO);
  449. }).sorted(this::sort)
  450. .collect(Collectors.toList());
  451. }
  452. private int sort(LiveVO live1, LiveVO live2) {
  453. return (int)(live2.getLastPriceTime() - live1.getLastPriceTime());
  454. }
  455. @Override
  456. public List<LotVO> selfFinish(SelfVO selfVO) {
  457. return finishOrWin(selfVO, null);
  458. }
  459. @Override
  460. public List<LotVO> selfWin(SelfVO selfVO) {
  461. return finishOrWin(selfVO, 1);
  462. }
  463. private List<LotVO> finishOrWin(SelfVO selfVO, Integer win) {
  464. String account = UserUtils.getSimpleUserInfo().getId().toString();
  465. List<LotVO> resultList = new ArrayList<>();
  466. List<Lot> lotList = lotMapper.selectLotByAucId(selfVO.getAuctionId());
  467. lotList.forEach(lot -> {
  468. if (Constants.LOT_STATUS_PASS.equals(lot.getStatus()) || Constants.LOT_STATUS_SOLD.equals(lot.getStatus())) {
  469. Bid condition = new Bid();
  470. condition.setLotId(lot.getId());
  471. condition.setAccountId(account);
  472. condition.setStatus(win);
  473. List<Bid> bids = bidMapper.selectBidList(condition);
  474. if (!CollectionUtils.isEmpty(bids)) {
  475. LotVO lotVO = new LotVO();
  476. BeanUtils.copyProperties(lot, lotVO);
  477. lotVO.setBids(bids);
  478. resultList.add(SensitiveDataUtils.handleViewDataSafe(lotVO));
  479. }
  480. }
  481. });
  482. return resultList;
  483. }
  484. @Override
  485. @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
  486. public void handleDelay(Long id) {
  487. Lot dbLot = lotMapper.selectLotById(id);
  488. Lot update = new Lot();
  489. BeanUtils.copyProperties(dbLot, update);
  490. update.setCreateBy("SYSTEM");
  491. update.setCreateTime(new Date());
  492. update.setPubStatus(Constants.PUB_STATUS_NO_PUBLISHED);
  493. update.setStatus(Constants.LOT_STATUS_WAITING);
  494. update.setDelFlag(Constants.DEL_FLAG_NO_DELETE);
  495. update.setStartTime(DateUtils.addDays(dbLot.getStartTime(), 1));
  496. update.setEndTime(DateUtils.addDays(dbLot.getEndTime(), 1));
  497. String name = update.getName();
  498. if (!StringUtils.isEmpty(name)) {
  499. Pattern pattern = Pattern.compile("第(\\d+)期");
  500. Matcher matcher = pattern.matcher(name);
  501. if (matcher.find()) {
  502. String group = matcher.group(0);
  503. String noStr = matcher.group(1);
  504. int no = (Integer.parseInt(noStr)) + 1;
  505. name = name.replace(group, "第" + no + "期");
  506. update.setName(name);
  507. }
  508. }
  509. lotMapper.insertLotClone(update);
  510. dbLot.setDelayPublish(null);
  511. lotMapper.updateLotView(dbLot);
  512. if (!Objects.equals(dbLot.getPubStatus(), Constants.PUB_STATUS_PUBLISHED)) {
  513. pubLot(dbLot);
  514. }
  515. dynamicTask(update);
  516. }
  517. @Override
  518. public void dynamicTasks() {
  519. lotMapper.dynamicLot().forEach(this::dynamicTask);
  520. }
  521. @Override
  522. public void dynamicTask(Lot lot) {
  523. //延时发布时间
  524. String delayPublish = lot.getDelayPublish();
  525. if (!StringUtils.isEmpty(delayPublish)) {
  526. dynamicTaskService.updateTask(lot.getId().toString(), DateUtils.getNextExecutionTime(delayPublish), () -> {
  527. _thiz.handleDelay(lot.getId());
  528. });
  529. }else {
  530. dynamicTaskService.removeTask(lot.getId().toString());
  531. }
  532. }
  533. }