package com.izouma.nineth.service; import cn.hutool.core.convert.Convert; import com.izouma.nineth.TokenHistory; import com.izouma.nineth.config.Constants; import com.izouma.nineth.config.GeneralProperties; import com.izouma.nineth.converter.LongArrayConverter; import com.izouma.nineth.domain.Collection; import com.izouma.nineth.domain.*; import com.izouma.nineth.dto.PageQuery; import com.izouma.nineth.dto.PageWrapper; import com.izouma.nineth.dto.UserHistory; import com.izouma.nineth.enums.*; import com.izouma.nineth.exception.BusinessException; import com.izouma.nineth.repo.*; import com.izouma.nineth.utils.JpaUtils; import com.izouma.nineth.utils.SecurityUtils; import com.izouma.nineth.utils.TokenUtils; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.RandomStringUtils; import org.apache.rocketmq.spring.core.RocketMQTemplate; import org.springframework.beans.BeanUtils; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import javax.persistence.criteria.Predicate; import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; import java.util.stream.Collectors; @Service @AllArgsConstructor @Slf4j public class AssetService { private AssetRepo assetRepo; private UserRepo userRepo; private CollectionRepo collectionRepo; private OrderRepo orderRepo; private TokenHistoryRepo tokenHistoryRepo; private SysConfigService sysConfigService; private RocketMQTemplate rocketMQTemplate; private GeneralProperties generalProperties; private ShowroomRepo showroomRepo; private ShowCollectionRepo showCollectionRepo; private CollectionPrivilegeRepo collectionPrivilegeRepo; private PasswordEncoder passwordEncoder; private MintActivityRepo mintActivityRepo; private DestroyRecordRepo destroyRecordRepo; private AirDropService airDropService; public Page all(PageQuery pageQuery) { Page all = assetRepo .findAll(JpaUtils.toSpecification(pageQuery, Asset.class), JpaUtils.toPageRequest(pageQuery)); // Map query = pageQuery.getQuery(); // if (query.containsKey("userId")) { // List orderId = orderRepo // .findAllByUserIdAndOpenedFalse(Convert.convert(Long.class, query.get("userId"))); // return all.map(asset -> { // if (orderId.contains(asset.getOrderId())) { // asset.setOpened(false); // } // return asset; // }); // } return all; } public Asset createAsset(Collection collection, User user, Long orderId, BigDecimal price, String type, Integer number, boolean safeFlag) { Asset asset = Asset.create(collection, user); asset.setTokenId(TokenUtils.genTokenId()); asset.setNumber(number); asset.setOasisId(collection.getOasisId()); asset.setOrderId(orderId); asset.setPrice(price); asset.setTags(new HashSet<>()); if (collection.getTags() != null) { asset.getTags().addAll(collection.getTags()); } User fakeUser = null; if (safeFlag) { fakeUser = createFakeUser(); asset.setOwner(fakeUser.getNickname()); asset.setOwnerId(fakeUser.getId()); asset.setOwnerAvatar(fakeUser.getAvatar()); } assetRepo.saveAndFlush(asset); tokenHistoryRepo.save(TokenHistory.builder() .tokenId(asset.getTokenId()) .fromUser(collection.getMinter()) .fromUserId(collection.getMinterId()) .fromAvatar(collection.getMinterAvatar()) .toUser((safeFlag ? fakeUser : user).getNickname()) .toUserId((safeFlag ? fakeUser : user).getId()) .toAvatar((safeFlag ? fakeUser : user).getAvatar()) .operation(type) .price(price) .build()); rocketMQTemplate.syncSend(generalProperties.getMintTopic(), asset.getId()); if (asset.getOasisId() != null & asset.getSource().equals(AssetSource.OFFICIAL)) { AirDrop airDrop = new AirDrop(); airDrop.setName("建筑空投展厅"); airDrop.setCollectionId(207012L); List userIds = new ArrayList<>(); userIds.add(user.getId()); List nums = new ArrayList<>(); nums.add(1L); airDrop.setType(AirDropType.asset); List dropTargets = new ArrayList<>(); DropTarget dropTarget = new DropTarget(); dropTarget.setNickname(user.getNickname()); dropTarget.setNum(1); dropTarget.setPhone(user.getPhone()); dropTarget.setUserId(user.getId()); dropTargets.add(dropTarget); airDrop.setTargets(dropTargets); airDrop.setUserIds(userIds); airDrop.setNum(nums); airDropService.create(airDrop); } return asset; } public Asset createAsset(BlindBoxItem winItem, User user, Long orderId, BigDecimal price, String type, Integer number, Integer holdDays, boolean safeFlag) { Collection blindBox = collectionRepo.findDetailById(winItem.getBlindBoxId()) .orElseThrow(new BusinessException("盲盒不存在")); Collection collection = collectionRepo.findDetailById(winItem.getCollectionId()) .orElseThrow(new BusinessException("藏品不存在")); Asset asset = Asset.create(winItem, user, holdDays); asset.setTokenId(TokenUtils.genTokenId()); asset.setNumber(number); asset.setOasisId(winItem.getOasisId()); asset.setOrderId(orderId); asset.setPrice(price); asset.setTags(new HashSet<>()); if (blindBox.getTags() != null) { asset.getTags().addAll(blindBox.getTags()); } if (collection.getTags() != null) { asset.getTags().addAll(collection.getTags()); } User fakeUser = null; if (safeFlag) { fakeUser = createFakeUser(); asset.setOwner(fakeUser.getNickname()); asset.setOwnerId(fakeUser.getId()); asset.setOwnerAvatar(fakeUser.getAvatar()); } assetRepo.saveAndFlush(asset); tokenHistoryRepo.save(TokenHistory.builder() .tokenId(asset.getTokenId()) .fromUser(winItem.getMinter()) .fromUserId(winItem.getMinterId()) .fromAvatar(winItem.getMinterAvatar()) .toUser((safeFlag ? fakeUser : user).getNickname()) .toUserId((safeFlag ? fakeUser : user).getId()) .toAvatar((safeFlag ? fakeUser : user).getAvatar()) .operation(type) .price(price) .build()); rocketMQTemplate.syncSend(generalProperties.getMintTopic(), asset.getId()); return asset; } public void publicShow(Long id) { Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录")); if (!asset.getUserId().equals(SecurityUtils.getAuthenticatedUser().getId())) { throw new BusinessException("此藏品不属于你"); } if (asset.isPublicShow()) { return; } if (asset.getStatus() != AssetStatus.NORMAL) { throw new BusinessException("当前状态不可展示"); } User owner = asset.isSafeFlag() ? userRepo.findById(asset.getOwnerId()).orElseThrow(new BusinessException("用户不存在")) : userRepo.findById(asset.getUserId()).orElseThrow(new BusinessException("用户不存在")); Collection collection = Collection.builder() .name(asset.getName()) .pic(asset.getPic()) .minter(asset.getMinter()) .minterId(asset.getMinterId()) .minterAvatar(asset.getMinterAvatar()) .owner(owner.getNickname()) .oasisId(asset.getOasisId()) .ownerId(owner.getId()) .ownerAvatar(owner.getAvatar()) .detail(asset.getDetail()) .type(CollectionType.DEFAULT) .source(CollectionSource.TRANSFER) .sale(0) .stock(1) .total(1) .onShelf(true) .salable(false) .price(BigDecimal.valueOf(0)) .properties(asset.getProperties()) .canResale(asset.isCanResale()) .royalties(asset.getRoyalties()) .serviceCharge(asset.getServiceCharge()) .assetId(id) .number(asset.getNumber()) .tags(new HashSet<>()) .build(); if (asset.getTags() != null) { collection.getTags().addAll(asset.getTags()); } collectionRepo.save(collection); asset.setPublicShow(true); asset.setPublicCollectionId(collection.getId()); assetRepo.save(asset); } public synchronized void consignment(Long id, BigDecimal price, String tradeCode) { Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录")); if (!asset.getUserId().equals(SecurityUtils.getAuthenticatedUser().getId())) { throw new BusinessException("此藏品不属于你"); } int holdDays; if (asset.getSource() == AssetSource.GIFT) { holdDays = sysConfigService.getInt("gift_days"); } else { if (ObjectUtils.isEmpty(asset.getHoldDays())) { holdDays = sysConfigService.getInt("hold_days"); } else { holdDays = asset.getHoldDays(); } } if (holdDays == 0 && AssetSource.OFFICIAL.equals(asset.getSource())) { BigDecimal officialConsignment = sysConfigService.getBigDecimal("OFFICIAL_CONSIGNMENT"); //天转小时 int hour = officialConsignment.multiply(new BigDecimal("24")).intValue(); if (ChronoUnit.HOURS.between(asset.getCreatedAt(), LocalDateTime.now()) < hour) { throw new BusinessException("需持有满" + hour + "小时后才能寄售上架"); } } if (ChronoUnit.DAYS.between(asset.getCreatedAt(), LocalDateTime.now()) < holdDays) { throw new BusinessException("需持有满" + holdDays + "天才能寄售上架"); } User owner = asset.isSafeFlag() ? userRepo.findById(asset.getOwnerId()).orElseThrow(new BusinessException("用户不存在")) : userRepo.findById(asset.getUserId()).orElseThrow(new BusinessException("用户不存在")); if (!passwordEncoder.matches(tradeCode, userRepo.findTradeCode(asset.getUserId()))) { throw new BusinessException("交易密码错误"); } // if (StringUtils.isBlank(owner.getSettleAccountId())) { // throw new BusinessException("请先绑定银行卡"); // } if (asset.isConsignment()) { throw new BusinessException("已寄售,请勿重新操作"); } if (asset.getStatus() != AssetStatus.NORMAL) { throw new BusinessException("当前状态不可寄售"); } if (asset.isPublicShow()) { cancelPublic(asset); } //寄售中的展厅需要先删除展厅 if (CollectionType.SHOWROOM.equals(asset.getType())) { if (showroomRepo.findByAssetId(id).isPresent()) { throw new BusinessException("请先删除展厅"); } } Collection collection = Collection.builder() .name(asset.getName()) .pic(asset.getPic()) .minter(asset.getMinter()) .minterId(asset.getMinterId()) .minterAvatar(asset.getMinterAvatar()) .owner(owner.getNickname()) .ownerId(owner.getId()) .oasisId(asset.getOasisId()) .ownerAvatar(owner.getAvatar()) .detail(asset.getDetail()) .type(CollectionType.DEFAULT) .source(CollectionSource.TRANSFER) .sale(0) .stock(1) .total(1) .onShelf(true) .salable(true) .price(price) .properties(asset.getProperties()) .canResale(asset.isCanResale()) .royalties(asset.getRoyalties()) .serviceCharge(asset.getServiceCharge()) .assetId(id) .number(asset.getNumber()) .tags(new HashSet<>()) .build(); if (asset.getTags() != null) { collection.getTags().addAll(asset.getTags()); } collectionRepo.save(collection); asset.setPublicShow(true); asset.setConsignment(true); asset.setPublicCollectionId(collection.getId()); asset.setSellPrice(price); assetRepo.save(asset); } public void cancelConsignment(Long id) { Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录")); if (!asset.getUserId().equals(SecurityUtils.getAuthenticatedUser().getId())) { throw new BusinessException("此藏品不属于你"); } cancelConsignment(asset); } public void cancelConsignment(Asset asset) { if (!asset.getUserId().equals(SecurityUtils.getAuthenticatedUser().getId())) { throw new BusinessException("此藏品不属于你"); } if (asset.getPublicCollectionId() != null) { List orders = orderRepo.findByCollectionId(asset.getPublicCollectionId()); if (orders.stream().anyMatch(o -> o.getStatus() != OrderStatus.CANCELLED)) { throw new BusinessException("已有订单不可取消"); } collectionRepo.findById(asset.getPublicCollectionId()) .ifPresent(collection -> { collection.setSalable(false); collectionRepo.save(collection); }); } asset.setConsignment(false); assetRepo.save(asset); } public void cancelPublic(Long id) { Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录")); if (!asset.getUserId().equals(SecurityUtils.getAuthenticatedUser().getId())) { throw new BusinessException("此藏品不属于你"); } cancelPublic(asset); } public void cancelPublic(Asset asset) { if (!asset.getUserId().equals(SecurityUtils.getAuthenticatedUser().getId())) { throw new BusinessException("此藏品不属于你"); } if (!asset.isPublicShow()) { return; } if (asset.isConsignment()) { cancelConsignment(asset); } Collection collection = collectionRepo.findById(asset.getPublicCollectionId()) .orElseThrow(new BusinessException("无展示记录")); collectionRepo.delete(collection); // 如果展厅有此藏品 showCollectionRepo.deleteAllByCollectionId(asset.getPublicCollectionId()); asset.setPublicShow(false); asset.setPublicCollectionId(null); assetRepo.save(asset); } public void usePrivilege(Long assetId, Long privilegeId) { Asset asset = assetRepo.findById(assetId).orElseThrow(new BusinessException("无记录")); asset.getPrivileges().stream().filter(p -> p.getId().equals(privilegeId)).forEach(p -> { if (!p.getName().equals("铸造")) { p.setOpened(true); p.setOpenTime(LocalDateTime.now()); p.setOpenedBy(SecurityUtils.getAuthenticatedUser().getId()); } }); assetRepo.save(asset); } public void transfer(Asset asset, BigDecimal price, User toUser, TransferReason reason, Long orderId) { transfer(asset, price, toUser, reason, orderId, false); } private User createFakeUser() { String name = "0x" + RandomStringUtils.randomAlphabetic(8); return userRepo.save(User.builder() .username(name) .nickname(name) .avatar(Constants.DEFAULT_AVATAR) .build()); } public void transfer(Asset asset, BigDecimal price, User toUser, TransferReason reason, Long orderId, boolean safeFlag) { Objects.requireNonNull(asset, "原藏品不能为空"); Objects.requireNonNull(toUser, "转让人不能为空"); Objects.requireNonNull(reason, "转让原因不能为空"); User newOwner = toUser; if (safeFlag) { newOwner = createFakeUser(); } Asset newAsset = new Asset(); BeanUtils.copyProperties(asset, newAsset); newAsset.setId(null); newAsset.setUserId(toUser.getId()); newAsset.setOwner(newOwner.getNickname()); newAsset.setOwnerId(newOwner.getId()); newAsset.setOwnerAvatar(newOwner.getAvatar()); newAsset.setPublicShow(false); newAsset.setConsignment(false); newAsset.setPublicCollectionId(null); newAsset.setStatus(AssetStatus.NORMAL); newAsset.setPrice(price); newAsset.setSellPrice(null); newAsset.setOrderId(orderId); newAsset.setOasisId(asset.getOasisId()); newAsset.setFromAssetId(asset.getId()); newAsset.setType(CollectionType.DEFAULT); newAsset.setSource(TransferReason.GIFT == reason ? AssetSource.GIFT : AssetSource.TRANSFER); newAsset.setTags(new HashSet<>(asset.getTags())); newAsset.setSafeFlag(safeFlag); newAsset.setHoldDays(asset.getOldHoldDays()); assetRepo.save(newAsset); TokenHistory tokenHistory = TokenHistory.builder() .tokenId(asset.getTokenId()) .fromUser(asset.getOwner()) .fromUserId(asset.getOwnerId()) .fromAvatar(asset.getOwnerAvatar()) .toUser(newOwner.getNickname()) .toUserId(newOwner.getId()) .toAvatar(newOwner.getAvatar()) .operation(reason.getDescription()) .price(TransferReason.GIFT == reason ? null : price) .build(); tokenHistoryRepo.save(tokenHistory); asset.setPublicShow(false); asset.setConsignment(false); asset.setPublicCollectionId(null); switch (reason) { case GIFT: asset.setStatus(AssetStatus.GIFTED); break; case AUCTION: asset.setStatus(AssetStatus.AUCTIONED); break; case TRANSFER: asset.setStatus(AssetStatus.TRANSFERRED); } asset.setOwner(newOwner.getNickname()); asset.setOwnerId(newOwner.getId()); asset.setOwnerAvatar(newOwner.getAvatar()); assetRepo.save(asset); //vip权限转让 CollectionPrivilege collectionPrivilege = collectionPrivilegeRepo.findByCollectionId(asset.getCollectionId()); if (ObjectUtils.isNotEmpty(collectionPrivilege)) { if (collectionPrivilege.isVip()) { //更新vip信息 userRepo.updateVipPurchase(toUser.getId(), 1); userRepo.updateVipPurchase(asset.getUserId(), 0); } } } public List tokenHistory(String tokenId, Long assetId) { if (tokenId == null) { if (assetId == null) return new ArrayList<>(); tokenId = assetRepo.findById(assetId).map(Asset::getTokenId).orElse(null); } if (tokenId == null) return new ArrayList<>(); return tokenHistoryRepo.findByTokenIdOrderByCreatedAtDesc(tokenId); } public void setHistory() { List assets = assetRepo.findByCreatedAtBefore(LocalDateTime.of(2021, 11, 22, 23, 59, 59)); assets.parallelStream().forEach(asset -> { try { User owner = userRepo.findById(asset.getUserId()).orElseThrow(new BusinessException("")); Order order = orderRepo.findById(asset.getOrderId()).orElseThrow(new BusinessException("")); TokenHistory t = TokenHistory.builder() .tokenId(asset.getTokenId()) .fromUser(asset.getMinter()) .fromUserId(asset.getMinterId()) .fromAvatar(asset.getMinterAvatar()) .toUser(owner.getNickname()) .toUserId(owner.getId()) .toAvatar(owner.getAvatar()) .operation("出售") .price(order.getPrice()) .build(); t.setCreatedAt(asset.getCreatedAt()); tokenHistoryRepo.save(t); } catch (Exception e) { } }); } public Page userHistory(Long userId, Long toUserId, Long fromUserId, Pageable pageable) { Page page; if (ObjectUtils.isNotEmpty(toUserId)) { page = tokenHistoryRepo.userHistoryTo(userId, toUserId, pageable); } else if (ObjectUtils.isNotEmpty(fromUserId)) { page = tokenHistoryRepo.userHistoryFrom(userId, fromUserId, pageable); } else { page = tokenHistoryRepo.userHistory(userId, pageable); } Set tokenIds = page.stream().map(TokenHistory::getTokenId).collect(Collectors.toSet()); List assets = tokenIds.isEmpty() ? new ArrayList<>() : assetRepo.findByTokenIdIn(tokenIds); return page.map(tokenHistory -> { UserHistory userHistory = new UserHistory(); BeanUtils.copyProperties(tokenHistory, userHistory); Optional asset = assets.stream().filter(a -> a.getTokenId().equals(tokenHistory.getTokenId())) .findAny(); userHistory.setAssetName(asset.map(Asset::getName).orElse(null)); userHistory.setPic(asset.map(Asset::getPic).orElse(new ArrayList<>())); switch (tokenHistory.getOperation()) { case "出售": case "转让": userHistory.setDescription(tokenHistory.getToUserId().equals(userId) ? "作品交易——买入" : "作品交易——售出"); break; case "转赠": userHistory.setDescription(tokenHistory.getToUserId().equals(userId) ? "他人赠送" : "作品赠送"); break; default: userHistory.setDescription(tokenHistory.getOperation()); } return userHistory; }); } public Page userHistory(Long userId, PageQuery pageQuery) { Page page = tokenHistoryRepo.findAll(((root, criteriaQuery, criteriaBuilder) -> { List and = JpaUtils .toPredicates(pageQuery, TokenHistory.class, root, criteriaQuery, criteriaBuilder); Map query = pageQuery.getQuery(); if (ObjectUtils.isEmpty(query.get("toUserId")) && ObjectUtils.isEmpty(query.get("fromUserId"))) { and.add(criteriaBuilder.or(criteriaBuilder.equal(root.get("toUserId"), userId), criteriaBuilder .equal(root.get("fromUserId"), userId))); } else { if (ObjectUtils.isNotEmpty(query.get("toUserId"))) { and.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("toUserId"), userId))); } else { and.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("fromUserId"), userId))); } } return criteriaBuilder.and(and.toArray(new Predicate[0])); }), JpaUtils.toPageRequest(pageQuery)); Set tokenIds = page.stream().map(TokenHistory::getTokenId).collect(Collectors.toSet()); List assets = tokenIds.isEmpty() ? new ArrayList<>() : assetRepo.findByTokenIdIn(tokenIds); return page.map(tokenHistory -> { UserHistory userHistory = new UserHistory(); BeanUtils.copyProperties(tokenHistory, userHistory); Optional asset = assets.stream().filter(a -> a.getTokenId().equals(tokenHistory.getTokenId())) .findAny(); userHistory.setAssetName(asset.map(Asset::getName).orElse(null)); userHistory.setPic(asset.map(Asset::getPic).orElse(new ArrayList<>())); switch (tokenHistory.getOperation()) { case "出售": case "转让": userHistory.setDescription(tokenHistory.getToUserId().equals(userId) ? "作品交易——买入" : "作品交易——售出"); break; case "转赠": userHistory.setDescription(tokenHistory.getToUserId().equals(userId) ? "他人赠送" : "作品赠送"); break; default: userHistory.setDescription(tokenHistory.getOperation()); } return userHistory; }); } public String mint(LocalDateTime time) { if (time == null) { time = LocalDateTime.now(); } for (Asset asset : assetRepo.toMint(time)) { rocketMQTemplate.syncSend(generalProperties.getMintTopic(), asset.getId()); } return "ok"; } @Cacheable(value = "userStat", key = "#userId") public Map breakdown(Long userId) { List page = tokenHistoryRepo.userHistory(userId); BigDecimal sale = page.stream() .filter(th -> th.getFromUserId().equals(userId) && ObjectUtils.isNotEmpty(th.getPrice())) .map(TokenHistory::getPrice) .reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal buy = page.stream() .filter(th -> th.getToUserId().equals(userId) && ObjectUtils.isNotEmpty(th.getPrice())) .map(TokenHistory::getPrice) .reduce(BigDecimal.ZERO, BigDecimal::add); Map map = new HashMap<>(); map.put("sale", sale); map.put("buy", buy); return map; } public void transferCDN() throws ExecutionException, InterruptedException { ForkJoinPool customThreadPool = new ForkJoinPool(100); customThreadPool.submit(() -> { collectionRepo.selectResource().parallelStream().forEach(list -> { for (int i = 0; i < list.size(); i++) { list.set(i, replaceCDN(list.get(i))); } collectionRepo.updateCDN(Long.parseLong(list.get(0)), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5)); }); assetRepo.selectResource().parallelStream().forEach(list -> { for (int i = 0; i < list.size(); i++) { list.set(i, replaceCDN(list.get(i))); } assetRepo.updateCDN(Long.parseLong(list.get(0)), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5)); }); }).get(); } public String replaceCDN(String url) { if (url == null) return null; return url.replaceAll("https://raex-meta\\.oss-cn-shenzhen\\.aliyuncs\\.com", "https://cdn.raex.vip"); } // @Scheduled(cron = "0 0 0/1 * * ?") // public void offTheShelf() { // LocalDateTime lastTime = LocalDateTime.now().minusHours(120); // Set assetIds = collectionRepo // .findResaleCollectionPriceOver20K(BigDecimal // .valueOf(20000L), CollectionSource.TRANSFER, lastTime, true); // assetIds.forEach(this::cancelConsignmentBySystem); // } @Scheduled(cron = "0 0 0/1 * * ?") public void offTheShelfAll() { LocalDateTime lastTime = LocalDateTime.now().minusHours(240); Set assetIds = collectionRepo .findResaleCollectionPriceOver20K(BigDecimal .valueOf(0L), CollectionSource.TRANSFER, lastTime, true); assetIds.forEach(this::cancelConsignmentBySystem); } public void cancelConsignmentBySystem(Long id) { Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录")); if (asset.getPublicCollectionId() != null) { List orders = orderRepo.findByCollectionId(asset.getPublicCollectionId()); if (orders.stream().anyMatch(o -> o.getStatus() != OrderStatus.CANCELLED)) { throw new BusinessException("已有订单不可取消"); } collectionRepo.findById(asset.getPublicCollectionId()) .ifPresent(collection -> { collection.setSalable(false); collectionRepo.save(collection); }); } asset.setConsignment(false); assetRepo.save(asset); } // @Cacheable(cacheNames = "fmaa", key = "#userId+'#'+#mintActivityId+'#'+#pageable.hashCode()") public PageWrapper findMintActivityAssetsWrap(Long userId, Long mintActivityId, Pageable pageable) { return PageWrapper.of(findMintActivityAssets(userId, mintActivityId, pageable)); } public Page findMintActivityAssets(Long userId, Long mintActivityId, Pageable pageable) { MintActivity mintActivity = mintActivityRepo.findById(mintActivityId).orElse(null); if (mintActivity == null) return new PageImpl<>(Collections.emptyList()); if (!mintActivity.isAudit()) { Set tags = mintActivity.getRule().getTags(); if (tags.isEmpty()) return new PageImpl<>(Collections.emptyList()); return assetRepo.findAll((Specification) (root, query, criteriaBuilder) -> query.distinct(true).where(criteriaBuilder.equal(root.get("userId"), userId), criteriaBuilder.equal(root.get("status"), AssetStatus.NORMAL), root.join("tags").get("id").in(tags.stream().map(Tag::getId).toArray())) .getRestriction(), pageable); } else { return assetRepo.findByUserIdAndStatusAndNameLike(userId, AssetStatus.NORMAL, "%" + mintActivity.getCollectionName() + "%", pageable); } } public void destroy(Long id, Long userId) { Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录")); if (!asset.getUserId().equals(userId)) { throw new BusinessException("此藏品不属于你"); } if (asset.getStatus() != AssetStatus.NORMAL) { throw new BusinessException("当前状态不可寄售"); } if (asset.isPublicShow()) { throw new BusinessException("请先取消公开展示"); // cancelPublic(asset); } User toUser = userRepo.findById(1435297L).orElseThrow(new BusinessException("无记录")); TokenHistory tokenHistory = TokenHistory.builder() .tokenId(asset.getTokenId()) .fromUser(asset.getOwner()) .fromUserId(asset.getOwnerId()) .fromAvatar(asset.getOwnerAvatar()) .toUser(toUser.getNickname()) .toUserId(toUser.getId()) .toAvatar(toUser.getAvatar()) .operation(TransferReason.DESTROY.getDescription()) .price(null) .build(); tokenHistoryRepo.save(tokenHistory); asset.setPublicShow(false); asset.setConsignment(false); asset.setPublicCollectionId(null); asset.setStatus(AssetStatus.DESTROYED); asset.setOwner(toUser.getNickname()); asset.setOwnerId(toUser.getId()); asset.setOwnerAvatar(toUser.getAvatar()); assetRepo.save(asset); //积分记录 destroyRecordRepo.save(DestroyRecord.builder() .userId(userId) .assetId(asset.getId()) .name(asset.getName()) .pic(asset.getPic().get(0).getUrl()) .record(1) .type(RecordType.OBTAIN) .build()); //加积分 userRepo.addDestroyPoint(userId, 1); } public int getRoyalties(Long minterId, int royalties,Long userId) { if (royalties == 3) { return 3; } LongArrayConverter converter = new LongArrayConverter(); String discountMinter = sysConfigService.getString("discount_minter"); List minterIds = converter.convertToEntityAttribute(discountMinter); if (minterIds.contains(minterId)) { String discountCollection = sysConfigService.getString("discount_collection"); List collectionIds = converter.convertToEntityAttribute(discountCollection); Long assetId = assetRepo.findDiscount(userId, collectionIds); if (ObjectUtils.isNotEmpty(assetId)) { return 3; } } return royalties; } }