BidingController.java 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. package cn.hobbystocks.auc.web;
  2. import cn.hobbystocks.auc.app.AppClient;
  3. import cn.hobbystocks.auc.cache.CacheMap;
  4. import cn.hobbystocks.auc.common.constant.Constants;
  5. import cn.hobbystocks.auc.common.core.controller.BaseController;
  6. import cn.hobbystocks.auc.common.core.domain.AjaxResult;
  7. import cn.hobbystocks.auc.common.core.redis.RedisCache;
  8. import cn.hobbystocks.auc.common.core.text.Convert;
  9. import cn.hobbystocks.auc.common.user.UserInfo;
  10. import cn.hobbystocks.auc.common.user.UserUtils;
  11. import cn.hobbystocks.auc.common.utils.CloneUtils;
  12. import cn.hobbystocks.auc.common.utils.PaginationUtil;
  13. import cn.hobbystocks.auc.common.utils.SensitiveDataUtils;
  14. import cn.hobbystocks.auc.domain.*;
  15. import cn.hobbystocks.auc.event.EventPublisher;
  16. import cn.hobbystocks.auc.forest.CommonForestClient;
  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.BidRecordMapper;
  21. import cn.hobbystocks.auc.mapper.DepositOrderMapper;
  22. import cn.hobbystocks.auc.service.IBidService;
  23. import cn.hobbystocks.auc.service.ILotService;
  24. import cn.hobbystocks.auc.vo.BidVO;
  25. import com.alibaba.fastjson.JSON;
  26. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  27. import com.github.pagehelper.Page;
  28. import com.google.common.collect.Lists;
  29. import com.google.common.collect.Sets;
  30. import io.swagger.annotations.Api;
  31. import io.swagger.annotations.ApiOperation;
  32. import lombok.extern.slf4j.Slf4j;
  33. import org.springframework.beans.factory.annotation.Autowired;
  34. import org.springframework.beans.factory.annotation.Value;
  35. import org.springframework.util.CollectionUtils;
  36. import org.springframework.util.StringUtils;
  37. import org.springframework.web.bind.annotation.*;
  38. import java.util.*;
  39. import java.util.stream.Collectors;
  40. /**
  41. * 出价
  42. */
  43. @RestController
  44. @RequestMapping({"/bid/bidding"})
  45. @Slf4j
  46. @Api(tags = "出价相关接口")
  47. public class BidingController extends BaseController {
  48. // region Params
  49. @Value("${hobbystocks.host.pointUrl}")
  50. private String pointUrl;
  51. @Autowired
  52. private CommonForestClient client;
  53. @Autowired
  54. private IBidService bidService;
  55. @Autowired
  56. private ILotService lotService;
  57. @Autowired
  58. private AppClient appClient;
  59. @Autowired
  60. private EventPublisher eventPublisher;
  61. @Autowired
  62. private CacheMap cacheMap;
  63. @Autowired
  64. private BidRecordMapper bidRecordMapper;
  65. @Autowired
  66. private RedisCache redisCache;
  67. @Autowired
  68. private RuleHandlerHolder ruleHandlerHolder;
  69. @Autowired
  70. private DepositOrderMapper depositOrderMapper;
  71. // endregion
  72. // region Controllers
  73. @ApiOperation("同步数据")
  74. @PostMapping("/sync")
  75. public AjaxResult sync() {
  76. eventPublisher.sync();
  77. return AjaxResult.success();
  78. }
  79. @ApiOperation("出价拍卖增加价格")
  80. @PostMapping({"/addPrice"})
  81. public AjaxResult addPriceV2(@RequestBody BidVO bid) {
  82. log.info("add price {}", bid);
  83. // 创建bidRecord
  84. UserInfo userInfo = UserUtils.getUserInfo();
  85. Lot dbLot = lotService.selectLotById(bid.getLotId());
  86. if (!hasPaidDeposit(userInfo.getId(), dbLot)) {
  87. log.warn("addPrice fail, user has no paid deposit, userId:{} auctionId:{} lotId:{}",
  88. userInfo.getId(), bid.getAuctionId(), bid.getLotId());
  89. return AjaxResult.error("请先缴纳保证金");
  90. }
  91. // 创建bidRecord
  92. bid.setCreateBy(userInfo.getSub());
  93. bid.setAccount(userInfo.getAccount());
  94. String accountId = String.valueOf(userInfo.getId());
  95. bid.setAccountId(accountId);
  96. bid.setAvatar(userInfo.getAvatar());
  97. bid.setUserCode(bidService.getOrCreateUserCode(dbLot.getAuctionId(), accountId));
  98. bid.setBidNo(UUID.randomUUID().toString());
  99. //用户出价记录日志,无论是否出价成功都记录
  100. Long recordId = createBidRecord(bid);
  101. /*if (Objects.equals(2, userInfo.getAccountStatus())) {
  102. return AjaxResult.error("暂时无法参与当前竞价");
  103. }
  104. if (!Objects.equals(1, userInfo.getFaceVerify()) && !bid.getTest()) {
  105. return AjaxResult.error("请先进行实名认证");
  106. }
  107. if(!userInfo.isHasAddress()) {
  108. return AjaxResult.error("请先添加地址");
  109. }*/
  110. // 判断拍卖状态
  111. String error = checkLotStatus(bid);
  112. if (StringUtils.hasLength(error)) {
  113. log.warn("出价失败:{}", error);
  114. return AjaxResult.error("出价失败");
  115. }
  116. Lot lot = cacheMap.viewLot(bid.getAuctionId(), bid.getLotId()).getLot();
  117. /*if (Objects.equals(lot.getMerchantId().intValue(), userInfo.getMerchantId())) {
  118. log.warn("出价失败,商家无法参与自己的竞价拍卖");
  119. return AjaxResult.error("出价失败,商家无法参与自己的竞价拍卖");
  120. }*/
  121. try {
  122. bidService.addPrice(bid,() ->{ });
  123. }catch (RuntimeException e) {
  124. log.error("addPrice error {}", bid, e);
  125. return AjaxResult.error("当前价格已变动");
  126. }
  127. return AjaxResult.success();
  128. }
  129. /*
  130. * 直播间竞拍提速版,使用redis维护出价信息,拍卖结束后统一录入数据库,每秒更新redis数据同步到数据库的表里面
  131. * 出价限制由拍卖的接口提供,这里只检查缓存中是否存在,不存在则不能参加:
  132. * */
  133. @PostMapping({"/v3/addPrice"})
  134. public AjaxResult addPriceV4(@RequestBody BidVO bid) {
  135. UserInfo userInfo = UserUtils.getSimpleUserInfo();
  136. if(userInfo!=null){
  137. String nickname = String.valueOf(userInfo.getSub());
  138. bid.setCreateBy(nickname);
  139. bid.setAccount(nickname);
  140. String accountId = String.valueOf(userInfo.getId());
  141. bid.setAccountId(accountId);
  142. bid.setAvatar(userInfo.getAvatar());
  143. bid.setAuctionId(2L);
  144. bid.setBidNo(UUID.randomUUID().toString());
  145. createBidRecordCache(bid);
  146. }
  147. else{return AjaxResult.error("出价失败");}
  148. //从本场拍卖的缓存中拿限制信息,未能通过的用户不能出价参拍
  149. Map<String,String> forbbidenUsermap = redisCache.getCacheMap(String.format(Constants.REDIS_MAP_AUC_LOT_BID_USER_TEMPLATE, bid.getLotId()));
  150. if(forbbidenUsermap.containsKey(userInfo.getId().toString())){
  151. return AjaxResult.error(forbbidenUsermap.get(userInfo.getId().toString()));
  152. }
  153. // 判断拍卖状态
  154. String error = checkLotStatus(bid);
  155. if (StringUtils.hasLength(error)) {
  156. log.warn("出价失败:{}", error);
  157. return AjaxResult.error("出价失败");
  158. }
  159. try {
  160. bidService.addPriceV3(bid,() ->{ });
  161. }catch (RuntimeException e) {
  162. log.error("addPriceV3 error {}", bid, e);
  163. return AjaxResult.error("当前价格已变动");
  164. }
  165. return AjaxResult.success();
  166. }
  167. @ApiOperation("查询并返回指定拍卖中已结束的拍卖物品列表,并以分页的形式展示")
  168. @PostMapping("/view/{auctionId}/finished")
  169. public AjaxResult viewFinished(@RequestBody BidVO bidVO, @PathVariable Long auctionId) {
  170. log.info("= " + bidVO + "=");
  171. bidVO.setOrderBy("real_end_time desc");
  172. startPage(bidVO);
  173. List<Lot> lots = lotService.selectLotList(Lot.builder()
  174. .auctionId(auctionId)
  175. .delFlag(Constants.DEL_FLAG_NO_DELETE)
  176. .goodsType(bidVO.getGoodsType())
  177. .status(Constants.LOT_STATUS_SOLD)
  178. .privateDomain(0)
  179. .build());
  180. Page page = (Page) lots;
  181. PaginationUtil.PageResult<Lot> lotlist = new PaginationUtil.PageResult<>(((Page<Lot>) page).getResult(), Integer.parseInt(page.getTotal() + ""), page.getPageNum(), bidVO.getPageSize());
  182. lotlist.getItems().forEach(lot->{
  183. lot.setDealAccount(SensitiveDataUtils.maskString(lot.getDealAccount(), 4));
  184. lot.setUpdateBy(SensitiveDataUtils.maskString(lot.getUpdateBy(), 4));
  185. });
  186. return AjaxResult.success(lotlist);
  187. }
  188. @ApiOperation("获取指定拍卖ID的所有拍卖品信息")
  189. @PostMapping("/view/{auctionId}/starting")
  190. public AjaxResult viewBidding(@RequestBody BidVO bidVO, @PathVariable Long auctionId) {
  191. log.info("= " + bidVO + "=");
  192. Map<String, Live> map = bidService.view(auctionId);
  193. Set<String> statusSet = Sets.newHashSet(Constants.LOT_STATUS_STARTING, Constants.LOT_STATUS_BIDDING, Constants.LOT_STATUS_WAITING);
  194. List<Live> list = map.values().stream()
  195. .filter(live -> statusSet.contains(live.getLot().getStatus()) && live.getShow())
  196. .filter(live -> StringUtils.isEmpty(bidVO.getGoodsType()) || Objects.equals(live.getLot().getGoodsType(), bidVO.getGoodsType()))
  197. .map(SensitiveDataUtils::handleViewDataSafe)
  198. .sorted(this::sort)
  199. .collect(Collectors.toList());
  200. return AjaxResult.success(PaginationUtil.page(bidVO, list));
  201. }
  202. @ApiOperation("从 Redis 缓存中获取id对应的 Live 对象,并将其返回")
  203. @GetMapping("/viewEx/{auctionId}/{id}")
  204. public AjaxResult viewEx(@PathVariable Long auctionId,@PathVariable Long id) {
  205. Live live = redisCache.getCacheMapValue(String.format(Constants.REDIS_AUC_TEMPLATE, auctionId), id.toString());
  206. return AjaxResult.success(JSON.toJSON(live));
  207. }
  208. @ApiOperation("获取并返回Live 对象,该对象包含了特定拍卖品的详细信息,包括出价记录、交易账户信息等")
  209. @GetMapping("/view/{auctionId}/{id}")
  210. public AjaxResult view(@PathVariable Long auctionId, @PathVariable Long id) {
  211. Live live = bidService.viewLot(auctionId, id);
  212. Lot lot = lotService.selectLotById(id);
  213. UserInfo userInfo = null;
  214. try {
  215. userInfo = UserUtils.getUserInfo(Convert.toInt(lot.getDealAccountId()));
  216. }
  217. catch (Exception e) {
  218. log.error("getUserInfo error", e);
  219. }
  220. try {
  221. log.info("request param auction {} id {}",auctionId,id);
  222. // region 获取用户禁止拍卖的检查信息并写入缓存
  223. UserInfo curruserInfo = UserUtils.getUserInfo(getUserId());
  224. boolean isForbiddenUser = false;
  225. String forbiddenReason = "";
  226. if (Objects.equals(2, curruserInfo.getAccountStatus())) {
  227. isForbiddenUser = true;
  228. forbiddenReason = "暂时无法参与当前竞价";
  229. }
  230. if (!Objects.equals(1, curruserInfo.getFaceVerify())) {
  231. isForbiddenUser = true;
  232. forbiddenReason = "请先进行实名认证";
  233. }
  234. if(!curruserInfo.isHasAddress()) {
  235. isForbiddenUser = true;
  236. forbiddenReason = "请先添加地址";
  237. }
  238. if (Objects.equals(lot.getMerchantId().intValue(), curruserInfo.getMerchantId())) {
  239. isForbiddenUser = true;
  240. forbiddenReason = "出价失败";
  241. }
  242. Long merchantId = lot.getMerchantId();
  243. Long userId = Long.valueOf(getUserId());
  244. if(isForbiddenUser){
  245. redisCache.setCacheMapValue(String.format(Constants.REDIS_MAP_AUC_LOT_BID_USER_TEMPLATE, lot.getId()), curruserInfo.getId().toString(), forbiddenReason);
  246. }
  247. else{
  248. redisCache.delCacheMapValue(String.format(Constants.REDIS_MAP_AUC_LOT_BID_USER_TEMPLATE, lot.getId()), curruserInfo.getId().toString());
  249. }
  250. // endregion
  251. }
  252. catch (Exception e) {
  253. log.error("get curruserInfo error", e);
  254. }
  255. final Lot clone = CloneUtils.clone(lot);
  256. List<Bid> bids = bidService.selectBidList(Bid.builder().lotId(lot.getId()).build());
  257. List<Bid> bidsDealList = bids.stream()
  258. .filter(bid -> bid.getStatus() == 1 && bid.getAccountId().equals(lot.getDealAccountId()))
  259. .collect(Collectors.toList());
  260. // 检查 bidsList 是否存在,并且如果存在,找到 anonymous 字段等于 1 的 Bid 对象
  261. boolean isDealAccountAnonymous = false;
  262. if (!bidsDealList.isEmpty()) {
  263. for (Bid bid : bidsDealList) {
  264. if (bid.getAnonymous() == 1) {
  265. isDealAccountAnonymous = true;
  266. break; // 如果只需要找到第一个符合条件的对象,可以在这里停止循环
  267. }
  268. }
  269. }
  270. if (Objects.isNull(live)) {
  271. LiveContext liveContext = LiveContext.builder().dbLot(lot).bidList(bids).build();
  272. ruleHandlerHolder.sync(liveContext);
  273. live = liveContext.getLive();
  274. if (Objects.equals(auctionId, 2L)) {
  275. Long groupId = lot.getGroupId();
  276. LotGroup lotGroup = lotService.selectLotGroupById(groupId);
  277. if (lotGroup.getFinishNum() >= lotGroup.getNum()) {
  278. live.setFinish(1);
  279. }else {
  280. live.setFinish(0);
  281. }
  282. }
  283. if(Objects.nonNull(userInfo)){
  284. live.getLot().setDealAccountavatar(userInfo.getAvatar());
  285. if (clone != null) {
  286. clone.setDealAccountavatar(userInfo.getAvatar());
  287. }
  288. }
  289. if(Objects.equals(getUserId().toString(), lot.getDealAccountId())){
  290. // live.getLot().setOrderId(lot.getOrderId());
  291. }
  292. else{
  293. if (clone != null) {
  294. if(isDealAccountAnonymous){
  295. clone.setDealAccountavatar(null);
  296. clone.setDealAccount(null);
  297. }
  298. }
  299. }
  300. live.setLot(clone);
  301. return AjaxResult.success(SensitiveDataUtils.handleViewDataSafe(live));
  302. }
  303. live.setLot(clone);
  304. if (Objects.equals(auctionId, 2L)) {
  305. Long groupId = lot.getGroupId();
  306. LotGroup lotGroup = lotService.selectLotGroupById(groupId);
  307. if (lotGroup.getFinishNum() >= lotGroup.getNum()) {
  308. live.setFinish(1);
  309. }else {
  310. live.setFinish(0);
  311. }
  312. }
  313. if(Objects.nonNull(userInfo)){
  314. live.getLot().setDealAccountavatar(userInfo.getAvatar());
  315. }
  316. if(Objects.equals(getUserId().toString(), lot.getDealAccountId())){
  317. // live.getLot().setOrderId(lot.getOrderId());
  318. }
  319. else{
  320. // live.getLot().setOrderId(null);
  321. if(isDealAccountAnonymous){
  322. live.getLot().setDealAccountavatar(null);
  323. live.getLot().setDealAccount(null);
  324. }
  325. }
  326. log.info("/bid/bidding/view/ result {}", live);
  327. log.info("/bid/bidding/view/ result {}", SensitiveDataUtils.handleViewDataSafe(live));
  328. return AjaxResult.success(SensitiveDataUtils.handleViewDataSafe(live));
  329. }
  330. /*
  331. * 配合v3的竞价使用,查询缓存中的竞价结果
  332. * */
  333. @GetMapping("/viewv3/{auctionId}/{id}")
  334. public AjaxResult viewV4(@PathVariable Long auctionId, @PathVariable Long id) {
  335. Live live = bidService.viewLot(auctionId, id);
  336. Lot lot = lotService.selectLotById(id);
  337. UserInfo userInfo = UserUtils.getUserInfo(Convert.toInt(lot.getDealAccountId()));
  338. final Lot clone = CloneUtils.clone(lot);
  339. List<Bid> bids = bidService.selectBidList(Bid.builder().lotId(lot.getId()).build());
  340. List<Bid> bidsDealList = bids.stream()
  341. .filter(bid -> bid.getStatus() == 1 && bid.getAccountId().equals(lot.getDealAccountId()))
  342. .collect(Collectors.toList());
  343. // 检查 bidsList 是否存在,并且如果存在,找到 anonymous 字段等于 1 的 Bid 对象
  344. boolean isDealAccountAnonymous = false;
  345. if (!bidsDealList.isEmpty()) {
  346. for (Bid bid : bidsDealList) {
  347. if (bid.getAnonymous() == 1) {
  348. isDealAccountAnonymous = true;
  349. break; // 如果只需要找到第一个符合条件的对象,可以在这里停止循环
  350. }
  351. }
  352. }
  353. if (Objects.isNull(live)) {
  354. LiveContext liveContext = LiveContext.builder().dbLot(lot).bidList(bids).build();
  355. ruleHandlerHolder.sync(liveContext);
  356. live = liveContext.getLive();
  357. if (Objects.equals(auctionId, 2L)) {
  358. Long groupId = lot.getGroupId();
  359. LotGroup lotGroup = lotService.selectLotGroupById(groupId);
  360. if (lotGroup.getFinishNum() >= lotGroup.getNum()) {
  361. live.setFinish(1);
  362. }else {
  363. live.setFinish(0);
  364. }
  365. }
  366. if(Objects.nonNull(userInfo)){
  367. live.getLot().setDealAccountavatar(userInfo.getAvatar());
  368. if (clone != null) {
  369. clone.setDealAccountavatar(userInfo.getAvatar());
  370. }
  371. }
  372. if(Objects.equals(getUserId().toString(), lot.getDealAccountId())){
  373. // live.getLot().setOrderId(lot.getOrderId());
  374. }
  375. else{
  376. if (clone != null) {
  377. // clone.setOrderId(null);
  378. if(isDealAccountAnonymous){
  379. clone.setDealAccountavatar(null);
  380. clone.setDealAccount(null);
  381. }
  382. }
  383. }
  384. live.setLot(clone);
  385. log.info("/bid/bidding/view/ result {}", live);
  386. log.info("/bid/bidding/view/ result {}", SensitiveDataUtils.handleViewDataSafe(live));
  387. return AjaxResult.success(SensitiveDataUtils.handleViewDataSafe(live));
  388. }
  389. if (Objects.equals(auctionId, 2L)) {
  390. Long groupId = lot.getGroupId();
  391. LotGroup lotGroup = lotService.selectLotGroupById(groupId);
  392. if (lotGroup.getFinishNum() >= lotGroup.getNum()) {
  393. live.setFinish(1);
  394. }else {
  395. live.setFinish(0);
  396. }
  397. }
  398. if(Objects.nonNull(userInfo)){
  399. live.getLot().setDealAccountavatar(userInfo.getAvatar());
  400. }
  401. if(Objects.equals(getUserId().toString(), lot.getDealAccountId())){
  402. // live.getLot().setOrderId(lot.getOrderId());
  403. }
  404. else{
  405. // live.getLot().setOrderId(null);
  406. if(isDealAccountAnonymous){
  407. live.getLot().setDealAccountavatar(null);
  408. live.getLot().setDealAccount(null);
  409. }
  410. }
  411. log.info("/bid/bidding/view/ result {}", live);
  412. log.info("/bid/bidding/view/ result {}", SensitiveDataUtils.handleViewDataSafe(live));
  413. return AjaxResult.success(SensitiveDataUtils.handleViewDataSafe(live));
  414. }
  415. @GetMapping("/viewcache/{auctionId}/{id}")
  416. public AjaxResult viewV3cache(@PathVariable Long auctionId, @PathVariable Long id) {
  417. List<BidVO> bidList = redisCache.getCacheList(String.format(Constants.REDIS_MAP_AUC_LOT_BID_LIST_PREFIX,id));
  418. return AjaxResult.success(bidList);
  419. }
  420. @ApiOperation("查询拍卖品出价记录等信息")
  421. @PostMapping("/list")
  422. public AjaxResult listBid(@RequestBody BidVO bidVO) {
  423. Lot dbLot = lotService.selectLotById(bidVO.getLotId());
  424. if (Constants.LOT_STATUS_SOLD.equals(dbLot.getStatus()) ||
  425. Constants.LOT_STATUS_CANCELLED.equals(dbLot.getStatus()) ||
  426. Constants.LOT_STATUS_PASS.equals(dbLot.getStatus())) {
  427. return findBidPageFromDb(bidVO);
  428. }
  429. if (bidVO.getPageSize() > 20 || (bidVO.getPageSize() * bidVO.getPageNum()) > 20) {
  430. return findBidPageFromDb(bidVO);
  431. }else {
  432. Integer userId = UserUtils.getSimpleUserInfo().getId();
  433. List<Bid> list = bidService.selectCacheBidList(bidVO).stream().map(bid -> {
  434. boolean sensitive=false;
  435. if (Objects.equals(1, bid.getAnonymous())) {
  436. bid.setAvatar("/MC143302022060920611/avatar/1666182630730.jpg");
  437. bid.setAccount("匿名用户");
  438. sensitive=true;
  439. }
  440. if (org.apache.commons.lang3.StringUtils.isBlank(bid.getAvatar())){
  441. bid.setAvatar("/MC143302022060920611/avatar/1666182630730.jpg");
  442. }
  443. if (org.apache.commons.lang3.StringUtils.isBlank(bid.getAccount())){
  444. bid.setAccount("匿名用户");
  445. sensitive=true;
  446. }
  447. bid.setCurrentAccount(Objects.equals(Integer.parseInt(bid.getAccountId()), userId));
  448. if (!sensitive) {
  449. return SensitiveDataUtils.handleViewDataSafe(bid);
  450. }
  451. return bid;
  452. }).collect(Collectors.toList());
  453. if (!CollectionUtils.isEmpty(list)) {
  454. log.info("CollectionUtils list {}", list);
  455. // 使用 Comparator 接口进行排序
  456. list.sort((bid1, bid2) -> bid2.getAmount().compareTo(bid1.getAmount()));
  457. log.info("CollectionUtils list size after sort {}", list.size());
  458. Bid bidLast = list.get(0);
  459. Long total = bidLast.getRound();
  460. log.info("CollectionUtils bidLast {}", bidLast);
  461. List<List<Bid>> partition = Lists.partition(list, bidVO.getPageSize());
  462. List<Bid> resultList = Lists.newArrayList();
  463. log.info("CollectionUtils partition {}", partition.size());
  464. if (partition.size() >= bidVO.getPageNum()) {
  465. log.info("CollectionUtils partitionget {}", partition.get(bidVO.getPageNum() - 1));
  466. log.info("CollectionUtils partitionget {}", resultList.size());
  467. resultList = partition.get(bidVO.getPageNum() - 1);
  468. }
  469. return AjaxResult.success(new PaginationUtil.PageResult<>(resultList, total.intValue(), bidVO.getPageNum(), bidVO.getPageSize()));
  470. }else {
  471. log.info("CollectionUtils list is empty");
  472. return AjaxResult.success(PaginationUtil.page(bidVO, list));
  473. }
  474. }
  475. }
  476. private String checkLotStatus(BidVO bid) {
  477. log.info("checkLotStatus cacheMap {}",cacheMap);
  478. log.info("checkLotStatus bid {}",bid);
  479. Live live = cacheMap.viewLot(bid.getAuctionId(), bid.getLotId());
  480. log.info("checkLotStatus live {}",live);
  481. if (Objects.isNull(live)) {
  482. List<Bid> bids = bidService.selectBidList(Bid.builder().lotId(bid.getLotId()).build());
  483. log.info("sync bids {}",bids);
  484. Lot lot = lotService.selectLotById(bid.getLotId());
  485. log.info("sync lot {}",lot);
  486. LiveContext liveContext = LiveContext.builder().dbLot(lot).bidList(bids).build();
  487. ruleHandlerHolder.sync(liveContext);
  488. log.info("sync liveContext {}",liveContext);
  489. live = liveContext.getLive();
  490. live.setLot(lot);
  491. live.setFinish(0);
  492. cacheMap.putLive(live);
  493. log.info("cacheMap putLive {}",live);
  494. return null;
  495. }
  496. if (Constants.LOT_STATUS_WAITING.equals(live.getLot().getStatus())) {
  497. return "拍卖还未开始";
  498. }
  499. if (!Lists.newArrayList(Constants.LOT_STATUS_BIDDING, Constants.LOT_STATUS_STARTING).contains(live.getLot().getStatus())) {
  500. return "拍卖已结束";
  501. }
  502. return null;
  503. }
  504. private Long createBidRecord(Bid bid){
  505. BidRecord record = BidRecord.builder()
  506. .lotId(bid.getLotId())
  507. .bidNo(bid.getBidNo())
  508. .userId(Long.parseLong(bid.getAccountId()))
  509. .amount(bid.getAmount())
  510. .createTime(new Date()).build();
  511. bidRecordMapper.insertBidRecord(record);
  512. return record.getId();
  513. }
  514. private boolean hasPaidDeposit(Integer userId, Lot lot) {
  515. if (Objects.isNull(userId) || Objects.isNull(lot)) {
  516. return false;
  517. }
  518. LambdaQueryWrapper<DepositOrder> queryWrapper = new LambdaQueryWrapper<DepositOrder>()
  519. .eq(DepositOrder::getUserId, userId)
  520. .eq(DepositOrder::getStatus, 1);
  521. if (Objects.nonNull(lot.getDeposit())) {
  522. queryWrapper.eq(DepositOrder::getDepositType, "拍品")
  523. .eq(DepositOrder::getLotId, lot.getId());
  524. } else {
  525. queryWrapper.eq(DepositOrder::getDepositType, "拍卖会")
  526. .eq(DepositOrder::getAuctionId, lot.getAuctionId());
  527. }
  528. return depositOrderMapper.selectCount(queryWrapper) > 0;
  529. }
  530. private void createBidRecordCache(Bid bid){
  531. List<BidRecord> bidList = new ArrayList<>();
  532. BidRecord record = BidRecord.builder()
  533. .lotId(bid.getLotId())
  534. .bidNo(bid.getBidNo())
  535. .userId(Long.parseLong(bid.getAccountId()))
  536. .amount(bid.getAmount())
  537. .createTime(new Date()).build();
  538. bidList.add(record);
  539. redisCache.addToCacheList(String.format(Constants.REDIS_MAP_AUC_LOT_BIDRECORD_LIST_PREFIX, bid.getLotId()), bidList);
  540. }
  541. private int sort(Live live1, Live live2) {
  542. int sort1 = Objects.nonNull(live1.getLot().getSort()) ? live1.getLot().getSort() : 0;
  543. int sort2 = Objects.nonNull(live2.getLot().getSort()) ? live2.getLot().getSort() : 0;
  544. return (sort2 - sort1) == 0 ? (int)(live1.getCurrentEndTime() - live2.getCurrentEndTime()) : (sort2 - sort1);
  545. }
  546. private AjaxResult findBidPageFromDb(BidVO bidVO) {
  547. bidVO.setDelFlag(Constants.DEL_FLAG_NO_DELETE);
  548. startPage(bidVO);
  549. List<Bid> data = bidService.selectBidList(bidVO);
  550. Integer userId = UserUtils.getSimpleUserInfo().getId();
  551. data.forEach(bid -> {
  552. boolean sensitive=false;
  553. if (Objects.equals(1, bid.getAnonymous())) {
  554. bid.setAvatar("/MC143302022060920611/avatar/1666182630730.jpg");
  555. bid.setAccount("匿名用户");
  556. sensitive=true;
  557. }
  558. if (org.apache.commons.lang3.StringUtils.isBlank(bid.getAvatar())){
  559. bid.setAvatar("/MC143302022060920611/avatar/1666182630730.jpg");
  560. }
  561. if (org.apache.commons.lang3.StringUtils.isBlank(bid.getAccount())){
  562. bid.setAccount("匿名用户");
  563. sensitive=true;
  564. }
  565. bid.setCurrentAccount(Objects.equals(Integer.parseInt(bid.getAccountId()), userId));
  566. if (!sensitive) {
  567. SensitiveDataUtils.handleViewDataSafe(bid);
  568. }
  569. });
  570. Page page = (Page) data;
  571. return AjaxResult.success(new PaginationUtil.PageResult<>(((Page<Bid>) data).getResult(), Integer.parseInt(page.getTotal() + ""), page.getPageNum(), bidVO.getPageSize()));
  572. }
  573. }