package com.izouma.nineth.service; import com.alibaba.excel.util.StringUtils; import com.alibaba.fastjson.JSONArray; import com.google.zxing.WriterException; import com.izouma.nineth.config.GeneralProperties; import com.izouma.nineth.config.RedisKeys; import com.izouma.nineth.domain.Asset; import com.izouma.nineth.domain.DomainOrder; import com.izouma.nineth.domain.FileObject; import com.izouma.nineth.domain.User; import com.izouma.nineth.dto.PageQuery; import com.izouma.nineth.dto.excel.DomainCountDTO; import com.izouma.nineth.dto.nftdomain.DomainResult; import com.izouma.nineth.dto.nftdomain.DomainTop; import com.izouma.nineth.enums.*; import com.izouma.nineth.event.OrderNotifyEvent; import com.izouma.nineth.exception.BusinessException; import com.izouma.nineth.repo.AssetRepo; import com.izouma.nineth.repo.DomainOrderRepo; import com.izouma.nineth.repo.OrderRepo; import com.izouma.nineth.repo.UserRepo; import com.izouma.nineth.service.storage.StorageService; import com.izouma.nineth.utils.ImageUtils; import com.izouma.nineth.utils.JpaUtils; import com.izouma.nineth.utils.SecurityUtils; import com.sun.xml.bind.v2.TODO; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; import org.apache.rocketmq.spring.core.RocketMQTemplate; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.annotation.Transient; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.redis.core.BoundValueOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.util.*; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Matcher; import java.util.regex.Pattern; @Service @AllArgsConstructor @Slf4j public class DomainOrderService { private DomainOrderRepo domainOrderRepo; private ContentAuditService contentAuditService; private UserRepo userRepo; private AssetService assetService; private SysConfigService sysConfigService; private StorageService storageService; private RockRecordService rockRecordService; private AssetRepo assetRepo; private RedisTemplate redisTemplate; private CacheService cacheService; private UserBalanceService userBalanceService; private GeneralProperties generalProperties; private RocketMQTemplate rocketMQTemplate; private OrderRepo orderRepo; public Page all(PageQuery pageQuery) { return domainOrderRepo .findAll(JpaUtils.toSpecification(pageQuery, DomainOrder.class), JpaUtils.toPageRequest(pageQuery)); } @Cacheable(value = "newestDomain") public List newest() { PageRequest pageRequest = PageRequest.of(0, 50); return domainOrderRepo.findAllByOrderStatusOrderByCreatedAtDesc(OrderStatus.FINISH, pageRequest).getContent(); } public boolean isContainChinese(String str) { if (StringUtils.isEmpty(str)) { throw new BusinessException("sms context is empty!"); } boolean canChinese = sysConfigService.getBoolean("domain_sc"); Pattern p; if (!canChinese) { p = Pattern.compile("[\u4E00-\u9FA5|\\!|\\,|\\。|\\(|\\)|\\《|\\》|\\“|\\”|\\?|\\:|\\;|\\【|\\】]"); } else { p = Pattern.compile("[\\!|\\,|\\。|\\(|\\)|\\《|\\》|\\“|\\”|\\?|\\:|\\;|\\【|\\】]"); } Matcher m = p.matcher(str); return m.find(); } public DomainOrder create(Long userId, String domain, BigDecimal price, Long year) { AtomicBoolean checkPoint = checkPoint(userId); List notPaidOrders = domainOrderRepo.findAllByUserIdAndOrderStatus(userId, OrderStatus.NOT_PAID); Long superUserId = Long.valueOf(sysConfigService.getString("domain_superUserId")); int min = sysConfigService.getInt("domain_minimum"); min = min + 4; if (notPaidOrders.size() > 0) { throw new BusinessException("已存在未支付订单,不可继续下单"); } if (domain.contains(".uni")) { throw new BusinessException("域名后缀不符合规定."); } if (!superUserId.equals(SecurityUtils.getAuthenticatedUser().getId())) { if (isContainChinese(domain)) { throw new BusinessException("禁止注册中文域名"); } if (!checkPoint.get()) { if (domain.length() < min || domain.length() > 20) { throw new BusinessException("四位及以下域名只能官方创建。"); } } else { if (domain.length() < 6 || domain.length() > 20) { throw new BusinessException("四位以下域名只能官方创建。"); } } } String realName; int dotIndex = domain.indexOf("."); realName = domain.substring(0, dotIndex); Map checkResult = check(realName); if (!(Boolean) checkResult.get("result")) { throw new BusinessException(checkResult.get("reason").toString()); } BigDecimal singlePrice = sysConfigService.getBigDecimal("domain_price"); if (singlePrice.multiply(BigDecimal.valueOf(year)).compareTo(price) != 0) { throw new BusinessException("价格不符"); } // LocalDateTime startTime = LocalDateTime.of(2023, 2, 10, 17, 0, 0); // if (LocalDateTime.now().isBefore(startTime)) { // throw new BusinessException("时间不符"); // } // if (price.compareTo(BigDecimal.valueOf(40L)) != 0) { // throw new BusinessException("订单价格与配置不符,请重新下单."); // } User user = userRepo.findById(userId).orElseThrow(new BusinessException("未找到用户")); if (domain.contains(".")) { int dotIndex1 = domain.indexOf("."); domain = domain.substring(0, dotIndex1); } DomainOrder domainOrder = new DomainOrder(); // domainOrder.setPic(Collections.singletonList(fileObject)); // domain = domain.replaceAll("[^a-zA-Z0-9\\u4E00-\\u9FA5]", ""); domainOrder.setPicName(domain); domainOrder.setPrice(price); domainOrder.setDomainName((domain + ".nft").toLowerCase()); domainOrder.setYears(year); domainOrder.setStatus(CollectionStatus.PENDING); domainOrder.setOrderStatus(OrderStatus.NOT_PAID); domainOrder.setUserId(user.getId()); domainOrder.setUserAvatar(user.getAvatar()); domainOrder.setUserName(user.getNickname()); if (checkPoint.get()) { if (realName.length() < 5) { increaseCount(userId, 1); } } return domainOrderRepo.save(domainOrder); } public void increaseCount(Long userId, Integer usePoint) { if (usePoint > 0) { // 扣除积分 userRepo.addVipPoint(userId, -usePoint); cacheService.clearUserMy(userId); } } public void decreaseCount(DomainOrder order) { userRepo.addVipPoint(order.getUserId(), 1); cacheService.clearUserMy(order.getUserId()); log.info("取消加积分用户ID:{},订单ID:{},积分:{}", order.getUserId(), order.getId(), 1); } public AtomicBoolean checkPoint(Long userId) { AtomicBoolean atomicBoolean = new AtomicBoolean(false); User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在")); if (user.getVipPoint() > 0) { atomicBoolean.set(true); } return atomicBoolean; // Map collections = JSONObject.parseObject(sysConfigService // .getString("domain_collection"), new TypeReference>() { // }); // if (collections.size() == 0) { // return new AtomicBoolean(false); // } // List statuses = new ArrayList<>(); // statuses.add(AssetStatus.NORMAL); // statuses.add(AssetStatus.AUCTIONING); // AtomicBoolean vipPoint = new AtomicBoolean(false); // collections.forEach((k, v) -> { // List assets = assetRepo.findAllByCollectionIdAndStatusInAndUserId(k, statuses, userId); // if (assets.size() > 0) { // BoundValueOperations ops = redisTemplate.boundValueOps(RedisKeys.DOMAIN_COUNT + userId); // Integer count = (Integer) ops.get(); // if (count != null) { // if (count > 0) { // vipPoint.set(true); // } // } else { // vipPoint.set(false); // } // } // }); // return vipPoint; } public Map check(String domain) { int min = sysConfigService.getInt("domain_minimum"); min = min + 4; AtomicBoolean checkPoint = checkPoint(SecurityUtils.getAuthenticatedUser().getId()); Map result = new HashMap<>(); Long superUserId = Long.valueOf(sysConfigService.getString("domain_superUserId")); String visibleDomain = domain; if (isContainChinese(domain)) { result.put("result", false); result.put("reason", "禁止使用中文"); return result; } if (domain.contains(".uni")) { result.put("result", false); result.put("reason", "禁止使用.uni"); return result; } if (!domain.contains(".nft")) { visibleDomain = domain + ".nft"; } List keywords = Arrays.asList(sysConfigService.getString("domain_keyword").split(",")); if (!superUserId.equals(SecurityUtils.getAuthenticatedUser().getId())) { if (keywords.stream().anyMatch(keyword -> org.apache.commons.lang.StringUtils.equals(keyword, domain))) { result.put("result", false); result.put("reason", "包含敏感关键字"); return result; } if (!checkPoint.get()) { if (visibleDomain.length() < min || visibleDomain.length() > 20) { result.put("result", false); result.put("reason", "域名长度不合规"); return result; } } else { if (visibleDomain.length() < 6 || visibleDomain.length() > 20) { result.put("result", false); result.put("reason", "域名长度不合规"); return result; } } if (!contentAuditService.auditText(domain)) { result.put("result", false); result.put("reason", "该域名内容不合规"); return result; } } Integer count = domainOrderRepo .countAllByDomainNameEqualsAndOrderStatusNot(visibleDomain, OrderStatus.CANCELLED); if (count > 0) { result.put("result", false); result.put("reason", "该域名已被注册"); return result; } result.put("result", true); result.put("reason", "可以注册"); return result; } public List> search(String domain) { if (domain.contains(".")) { int dotIndex = domain.indexOf("."); domain = domain.substring(0, dotIndex); } // domain = domain.replaceAll("[^a-zA-Z0-9\\u4E00-\\u9FA5]", ""); Pageable pageable = PageRequest.of(0, 3, Sort.by("createdAt").descending()); List used = domainOrderRepo.searchUsedDomain("%" + domain + "%", OrderStatus.CANCELLED, pageable) .getContent(); String n = domain.substring(domain.length() - 1); List> recommend = new ArrayList<>(); for (int i = 0; i < 100; i++) { if (i != 0) { domain = domain + n; } Map checkResult = check(domain); if ((Boolean) checkResult.get("result")) { Map sold = new HashMap<>(); sold.put("domain", (domain + ".nft").toLowerCase()); sold.put("sold", false); recommend.add(sold); } if (recommend.size() > 2) { break; } } List> result = new ArrayList<>(recommend); used.forEach(domainOrder -> { Map sold = new HashMap<>(); if (!domainOrder.getDomainName().contains(".uni")) { Asset asset = assetRepo .findFirstByNameAndStatus("RID元宇宙域名 " + domainOrder.getDomainName(), AssetStatus.NORMAL); if (asset != null) { if (asset.isConsignment()) { sold.put("canAsk", false); sold.put("collectionId", asset.getPublicCollectionId()); } else { if (asset.isPublicShow()) { sold.put("collectionId", asset.getPublicCollectionId()); } sold.put("canAsk", true); } sold.put("id", domainOrder.getId()); sold.put("domain", domainOrder.getDomainName().toLowerCase()); sold.put("endTime", domainOrder.getEndTime()); sold.put("sold", true); sold.put("isOpenHyperLink", domainOrder.isOpenHyperLink()); if (domainOrder.getHyperLinkType() != null) { sold.put("HyperLinkType", domainOrder.getHyperLinkType()); } if (domainOrder.getAddress() != null) { sold.put("Address", domainOrder.getAddress()); } result.add(sold); } } }); return result; } @Transient public void notify(Long id, PayMethod payMethod, String transactionId) throws FontFormatException, IOException, WriterException { // 取消订单与订单回调不能同时进行,需要抢锁 if (!getOrderLock(id)) { log.info("订单回调失败 orderId: {} redis锁定, 重新发送到队列", id); rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(), new OrderNotifyEvent(id, payMethod, transactionId, System.currentTimeMillis())); return; } DomainOrder domainOrder = domainOrderRepo.findById(id).orElseThrow(new BusinessException("未找到星图")); if (!domainOrder.getOrderStatus().equals(OrderStatus.NOT_PAID)) { throw new BusinessException("订单已经处理"); } BufferedImage img = domainImg(domainOrder.getDomainName()); ByteArrayOutputStream os = new ByteArrayOutputStream(); ImageIO.write(img, "jpg", os); InputStream input = new ByteArrayInputStream(os.toByteArray()); String path = "image/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + RandomStringUtils.randomAlphabetic(8) + ".jpg"; String realUrl = storageService.uploadFromInputStream(input, path); FileObject fileObject = new FileObject(); fileObject.setName(domainOrder.getDomainName()); fileObject.setType("image/jpeg"); fileObject.setUrl(realUrl); domainOrder.setOrderStatus(OrderStatus.FINISH); domainOrder.setPayMethod(payMethod); domainOrder.setPic(Collections.singletonList(fileObject)); domainOrder.setTransactionId(transactionId); // domainOrder.setStatus(CollectionStatus.SUCCESS); domainOrder.setCreateAssetId(createAsset(domainOrder)); domainOrder.setEndTime(LocalDateTime.now().plusYears(domainOrder.getYears())); domainOrderRepo.save(domainOrder); rockRecordService.addRock(domainOrder.getUserId(), domainOrder.getPrice(), "购买"); releaseOrderLock(id); } public void cancel(DomainOrder domainOrder) { log.info("尝试取消订单 {}", domainOrder.getId()); // 取消订单与订单回调不能同时进行,需要抢锁 if (!getOrderLock(domainOrder.getId())) { log.error("订单取消失败 {}, redis锁了", domainOrder.getId()); return; } domainOrder.setOrderStatus(OrderStatus.CANCELLED); domainOrder.setStatus(CollectionStatus.FAIL); if (domainOrder.getPicName().length() < 5) { decreaseCount(domainOrder); } domainOrderRepo.save(domainOrder); releaseOrderLock(domainOrder.getId()); } public Long createAsset(DomainOrder domainOrder) { return assetService.createAsset(domainOrder, userRepo.findById(domainOrder.getUserId()) .orElseThrow(new BusinessException("无用户记录")), null, domainOrder .getPrice(), "域名", null, false).getId(); } public BufferedImage domainImg(String domain) throws IOException, FontFormatException, WriterException { String domainName; if (domain.contains(".")) { int dotIndex = domain.indexOf("."); domainName = domain.substring(0, dotIndex).toUpperCase(); } else { domainName = domain.toUpperCase(); } Pattern p; p = Pattern.compile("[\u4E00-\u9FA5|\\!|\\,|\\。|\\(|\\)|\\《|\\》|\\“|\\”|\\?|\\:|\\;|\\【|\\】]"); Matcher m = p.matcher(domain); boolean chinese = m.find(); Font font1; Font font2; if (!chinese) { InputStream is1 = this.getClass() .getResourceAsStream("/font/VonwaonBitmap_16pxLite.ttf"); font1 = Font.createFont(Font.TRUETYPE_FONT, is1); is1.close(); InputStream is2 = this.getClass() .getResourceAsStream("/font/VonwaonBitmap_12pxLite.ttf"); font2 = Font.createFont(Font.TRUETYPE_FONT, is2); is2.close(); } else { InputStream is1 = this.getClass() .getResourceAsStream("/font/尔雅荣耀手书.ttf"); font1 = Font.createFont(Font.TRUETYPE_FONT, is1); is1.close(); InputStream is2 = this.getClass() .getResourceAsStream("/font/尔雅荣耀手书.ttf"); font2 = Font.createFont(Font.TRUETYPE_FONT, is2); is2.close(); } int length = domainName.length(); BufferedImage shareImg; if (chinese) { InputStream is3 = this.getClass().getResourceAsStream("/static/img/png_baijiaxing.png"); shareImg = ImageIO.read(is3); is3.close(); } else { if (length == 1) { InputStream is3 = this.getClass().getResourceAsStream("/static/img/png_jing.png"); shareImg = ImageIO.read(is3); is3.close(); } else if (length == 2) { InputStream is3 = this.getClass().getResourceAsStream("/static/img/png_lv.png"); shareImg = ImageIO.read(is3); is3.close(); } else if (length == 3) { InputStream is3 = this.getClass().getResourceAsStream("/static/img/png_b.png"); shareImg = ImageIO.read(is3); is3.close(); } else if (length == 4) { InputStream is3 = this.getClass().getResourceAsStream("/static/img/png_h.png"); shareImg = ImageIO.read(is3); is3.close(); } else { InputStream is3 = this.getClass().getResourceAsStream("/static/img/png_zi.png"); shareImg = ImageIO.read(is3); is3.close(); } } BufferedImage result = new BufferedImage(shareImg.getWidth(), shareImg.getHeight(), BufferedImage.TYPE_INT_RGB); Graphics2D g = result.createGraphics(); g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); // g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g.setComposite(AlphaComposite.SrcOver); g.drawImage(shareImg, 0, 0, null); // BufferedImage avatarImg = ImageUtils.makeRoundedCorner(ImageUtils.scale(ImageIO.read(new URL(user.getAvatar())), // 80, 80, // ImageUtils.Fit.COVER), 40); // g.drawImage(avatarImg, 334, 136, null); int domainLength = domainName.length(); if (chinese) { g.setColor(new Color(255, 241, 187)); Font topFont = font1.deriveFont(Font.PLAIN, 180f); Font downFont = font2.deriveFont(Font.PLAIN, 30f); ImageUtils.drawCenteredString(g, domainName, new Rectangle(5, 200, shareImg .getWidth(), 86), topFont); ImageUtils.drawCenteredString(g, ".NFT", new Rectangle(-10, 370, shareImg .getWidth(), 86), topFont); g.setColor(new Color(255, 255, 255)); ImageUtils.drawCenteredString(g, domain, new Rectangle(0, 600, shareImg .getWidth(), 12), downFont); } else { if (domainLength > 10) { g.setColor(new Color(255, 255, 255)); Font topFont = font1.deriveFont(Font.PLAIN, 130f); Font downFont = font2.deriveFont(Font.BOLD, 36f); int subIndex = domainLength / 3; String str1 = domainName.substring(0, subIndex); String str2 = domainName.substring(subIndex, subIndex + subIndex); String str3 = domainName.substring(subIndex + subIndex, domainLength); ImageUtils.drawCenteredString(g, str1, new Rectangle(0, 180, shareImg .getWidth(), 86), topFont); ImageUtils.drawCenteredString(g, str2, new Rectangle(0, 300, shareImg .getWidth(), 86), topFont); ImageUtils.drawCenteredString(g, str3, new Rectangle(0, 420, shareImg .getWidth(), 86), topFont); ImageUtils.drawCenteredString(g, ".NFT", new Rectangle(0, 540, shareImg .getWidth(), 86), topFont); g.setColor(new Color(255, 255, 255)); ImageUtils.drawCenteredString(g, domain, new Rectangle(0, 650, shareImg .getWidth(), 12), downFont); } if (domainLength > 5 & domainLength <= 10) { g.setColor(new Color(255, 255, 255)); Font topFont = font1.deriveFont(Font.PLAIN, 190f); Font downFont = font2.deriveFont(Font.BOLD, 36f); int subIndex = domainLength / 2; String str1 = domainName.substring(0, subIndex); String str2 = domainName.substring(subIndex, domainLength); ImageUtils.drawCenteredString(g, str1, new Rectangle(0, 180, shareImg .getWidth(), 86), topFont); ImageUtils.drawCenteredString(g, str2, new Rectangle(0, 350, shareImg .getWidth(), 86), topFont); ImageUtils.drawCenteredString(g, ".NFT", new Rectangle(0, 520, shareImg .getWidth(), 86), topFont); g.setColor(new Color(255, 255, 255)); ImageUtils.drawCenteredString(g, domain, new Rectangle(0, 650, shareImg .getWidth(), 12), downFont); } if (domainLength <= 5) { g.setColor(new Color(255, 255, 255)); Font topFont = font1.deriveFont(Font.PLAIN, 240f); Font downFont = font2.deriveFont(Font.BOLD, 36f); ImageUtils.drawCenteredString(g, domainName, new Rectangle(17, 220, shareImg .getWidth(), 86), topFont); ImageUtils.drawCenteredString(g, ".NFT", new Rectangle(-10, 420, shareImg .getWidth(), 86), topFont); g.setColor(new Color(255, 255, 255)); ImageUtils.drawCenteredString(g, domain, new Rectangle(0, 620, shareImg .getWidth(), 12), downFont); } } //二维码 // QRCodeWriter qrCodeWriter = new QRCodeWriter(); // Map hints = new HashMap<>(); // hints.put(EncodeHintType.MARGIN, 2); // BitMatrix bitMatrix = qrCodeWriter // .encode(env.getProperty("general.host") + "/wx/share?invitor=" + user.getId(), // BarcodeFormat.QR_CODE, 252, 252, hints); // g.drawImage(MatrixToImageWriter.toBufferedImage(bitMatrix), 250, 386, null); return result; } public List top20() { List> map = assetRepo.domainTop20(); JSONArray jsonArray = new JSONArray(); jsonArray.addAll(map); return jsonArray.toJavaList(DomainCountDTO.class); } // 获取订单锁,有效时间1小时 public boolean getOrderLock(Long orderId) { BoundValueOperations ops = redisTemplate.boundValueOps(RedisKeys.DOMAIN_LOCK + orderId); Boolean flag = ops.setIfAbsent(1, 1, TimeUnit.HOURS); return Boolean.TRUE.equals(flag); } // 释放订单锁 public void releaseOrderLock(Long orderId) { redisTemplate.delete(RedisKeys.DOMAIN_LOCK + orderId); } public void pass(Long id) { domainOrderRepo.findById(id).ifPresent(domainOrder -> { domainOrder.setStatus(CollectionStatus.SUCCESS); assetRepo.findById(domainOrder.getCreateAssetId()).ifPresent(asset1 -> { asset1.setStatus(AssetStatus.NORMAL); domainOrderRepo.save(domainOrder); assetRepo.save(asset1); }); }); } public void deny(Long id, String result) { domainOrderRepo.findById(id).ifPresent(domainOrder -> { domainOrder.setStatus(CollectionStatus.FAIL); domainOrder.setOrderStatus(OrderStatus.CANCELLED); domainOrder.setResult(result); assetRepo.findById(domainOrder.getCreateAssetId()).ifPresent(asset1 -> { asset1.setStatus(AssetStatus.DESTROYED); domainOrderRepo.save(domainOrder); assetRepo.save(asset1); }); //退款 userBalanceService.addBalance(domainOrder.getUserId(), domainOrder.getPrice(), domainOrder .getId(), BalanceType.REFUND); }); } @Scheduled(cron = "0 0/5 9-20 * * ?") public void batchPass() { long time = sysConfigService.getInt("domain_pendingTime"); LocalDateTime lastTime = LocalDateTime.now().minusHours(time - 1); List domainOrders = domainOrderRepo .findAllByStatusAndCreatedAtBeforeAndOrderStatus(CollectionStatus.PENDING, lastTime, OrderStatus.FINISH); domainOrders.forEach(domainOrder -> { try { pass(domainOrder.getId()); } catch (Exception e) { log.info("自动通过出错" + domainOrder.getDomainName()); } }); } public List newestOrder() { List> map = orderRepo.newestDomainOrder(); JSONArray jsonArray = new JSONArray(); jsonArray.addAll(map); return jsonArray.toJavaList(DomainResult.class); } public List domainTop() { List> map = assetRepo .domainBuyerTop60(LocalDateTime.now().minusDays(7L), LocalDateTime.now()); JSONArray jsonArray = new JSONArray(); jsonArray.addAll(map); return jsonArray.toJavaList(DomainTop.class); } public void addHyperLink(Long assetId, boolean openHyperLink, HyperLinkType hyperLinkType, String address) { Asset asset = assetRepo.findByIdAndStatus(assetId, AssetStatus.NORMAL) .orElseThrow(new BusinessException("没找到记录")); DomainOrder domainOrder = domainOrderRepo.findById(asset.getCollectionId()) .orElseThrow(new BusinessException("没找到记录")); domainOrder.setOpenHyperLink(openHyperLink); domainOrder.setHyperLinkType(hyperLinkType); domainOrder.setAddress(address); domainOrder.setCurrentOwnerId(SecurityUtils.getAuthenticatedUser().getId()); domainOrderRepo.save(domainOrder); } }