DomainOrderService.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. package com.izouma.nineth.service;
  2. import com.alibaba.excel.util.StringUtils;
  3. import com.google.zxing.WriterException;
  4. import com.izouma.nineth.domain.DomainOrder;
  5. import com.izouma.nineth.domain.FileObject;
  6. import com.izouma.nineth.domain.User;
  7. import com.izouma.nineth.dto.PageQuery;
  8. import com.izouma.nineth.enums.CollectionStatus;
  9. import com.izouma.nineth.enums.OrderStatus;
  10. import com.izouma.nineth.enums.PayMethod;
  11. import com.izouma.nineth.exception.BusinessException;
  12. import com.izouma.nineth.repo.DomainOrderRepo;
  13. import com.izouma.nineth.repo.UserRepo;
  14. import com.izouma.nineth.service.storage.StorageService;
  15. import com.izouma.nineth.utils.ImageUtils;
  16. import com.izouma.nineth.utils.JpaUtils;
  17. import com.izouma.nineth.utils.SecurityUtils;
  18. import lombok.AllArgsConstructor;
  19. import org.apache.commons.lang3.RandomStringUtils;
  20. import org.springframework.data.annotation.Transient;
  21. import org.springframework.data.domain.Page;
  22. import org.springframework.stereotype.Service;
  23. import javax.imageio.ImageIO;
  24. import java.awt.*;
  25. import java.awt.image.BufferedImage;
  26. import java.io.ByteArrayInputStream;
  27. import java.io.ByteArrayOutputStream;
  28. import java.io.IOException;
  29. import java.io.InputStream;
  30. import java.math.BigDecimal;
  31. import java.text.SimpleDateFormat;
  32. import java.time.LocalDateTime;
  33. import java.util.*;
  34. import java.util.List;
  35. import java.util.regex.Matcher;
  36. import java.util.regex.Pattern;
  37. @Service
  38. @AllArgsConstructor
  39. public class DomainOrderService {
  40. private DomainOrderRepo domainOrderRepo;
  41. private ContentAuditService contentAuditService;
  42. private UserRepo userRepo;
  43. private AssetService assetService;
  44. private SysConfigService sysConfigService;
  45. private StorageService storageService;
  46. public Page<DomainOrder> all(PageQuery pageQuery) {
  47. return domainOrderRepo
  48. .findAll(JpaUtils.toSpecification(pageQuery, DomainOrder.class), JpaUtils.toPageRequest(pageQuery));
  49. }
  50. public boolean isContainChinese(String str) {
  51. if (StringUtils.isEmpty(str)) {
  52. throw new BusinessException("sms context is empty!");
  53. }
  54. Pattern p = Pattern.compile("[\u4E00-\u9FA5|\\!|\\,|\\。|\\(|\\)|\\《|\\》|\\“|\\”|\\?|\\:|\\;|\\【|\\】]");
  55. Matcher m = p.matcher(str);
  56. if (m.find()) {
  57. return true;
  58. }
  59. return false;
  60. }
  61. public DomainOrder create(Long userId, String domain, BigDecimal price, Long year) {
  62. List<DomainOrder> notPaidOrders = domainOrderRepo.findAllByUserIdAndOrderStatus(userId, OrderStatus.NOT_PAID);
  63. Long superUserId = Long.valueOf(sysConfigService.getString("domain_superUserId"));
  64. if (!superUserId.equals(SecurityUtils.getAuthenticatedUser().getId())) {
  65. if (isContainChinese(domain)) {
  66. throw new BusinessException("禁止注册中文域名");
  67. }
  68. if (notPaidOrders.size() > 0) {
  69. throw new BusinessException("已存在未支付订单,不可继续下单");
  70. }
  71. if (domain.length() < 9) {
  72. throw new BusinessException("四位及以下域名只能官方创建。");
  73. }
  74. }
  75. Map<String, Object> checkResult = check(domain);
  76. if (!(Boolean) checkResult.get("result")) {
  77. throw new BusinessException(checkResult.get("reason").toString());
  78. }
  79. // if (price.compareTo(BigDecimal.valueOf(40L)) != 0) {
  80. // throw new BusinessException("订单价格与配置不符,请重新下单.");
  81. // }
  82. User user = userRepo.findById(userId).orElseThrow(new BusinessException("未找到用户"));
  83. if (domain.contains(".")) {
  84. int dotIndex = domain.indexOf(".");
  85. domain = domain.substring(0, dotIndex);
  86. }
  87. DomainOrder domainOrder = new DomainOrder();
  88. // domainOrder.setPic(Collections.singletonList(fileObject));
  89. domainOrder.setPicName(domain);
  90. domainOrder.setPrice(price);
  91. domainOrder.setDomainName((domain + ".nft").toLowerCase());
  92. domainOrder.setYears(year);
  93. domainOrder.setStatus(CollectionStatus.PENDING);
  94. domainOrder.setOrderStatus(OrderStatus.NOT_PAID);
  95. domainOrder.setUserId(user.getId());
  96. domainOrder.setUserAvatar(user.getAvatar());
  97. domainOrder.setUserName(user.getNickname());
  98. return domainOrderRepo.save(domainOrder);
  99. }
  100. public Map<String, Object> check(String domain) {
  101. Long superUserId = Long.valueOf(sysConfigService.getString("domain_superUserId"));
  102. String visibleDomain = domain + ".nft";
  103. List<String> keywords = Arrays.asList(sysConfigService.getString("domain_keyword").split(","));
  104. Map<String, Object> result = new HashMap<>();
  105. if (!superUserId.equals(SecurityUtils.getAuthenticatedUser().getId())) {
  106. if (keywords.stream().anyMatch(keyword -> org.apache.commons.lang.StringUtils.equals(keyword, domain))) {
  107. result.put("result", false);
  108. result.put("reason", "包含敏感关键字");
  109. return result;
  110. }
  111. if (visibleDomain.length() < 9 || visibleDomain.length() > 20) {
  112. result.put("result", false);
  113. result.put("reason", "域名长度不合规");
  114. return result;
  115. }
  116. if (!contentAuditService.auditText(domain)) {
  117. result.put("result", false);
  118. result.put("reason", "该域名内容不合规");
  119. return result;
  120. }
  121. }
  122. Integer count = domainOrderRepo
  123. .countAllByDomainNameEqualsAndOrderStatusNot(visibleDomain, OrderStatus.CANCELLED);
  124. if (count > 0) {
  125. result.put("result", false);
  126. result.put("reason", "该域名已被注册");
  127. return result;
  128. }
  129. result.put("result", true);
  130. result.put("reason", "可以注册");
  131. return result;
  132. }
  133. public List<Map<String, Object>> search(String domain) {
  134. if (domain.contains(".")) {
  135. int dotIndex = domain.indexOf(".");
  136. domain = domain.substring(0, dotIndex);
  137. }
  138. List<DomainOrder> used = domainOrderRepo.searchUsedDomain("%" + domain + "%", OrderStatus.CANCELLED);
  139. String n = domain.substring(domain.length() - 1);
  140. List<Map<String, Object>> recommend = new ArrayList<>();
  141. for (int i = 0; i < 100; i++) {
  142. if (i != 0) {
  143. domain = domain + n;
  144. }
  145. Map<String, Object> checkResult = check(domain);
  146. if ((Boolean) checkResult.get("result")) {
  147. Map<String, Object> sold = new HashMap<>();
  148. sold.put("domain", (domain + ".nft").toLowerCase());
  149. sold.put("sold", false);
  150. recommend.add(sold);
  151. }
  152. if (recommend.size() > 2) {
  153. break;
  154. }
  155. }
  156. List<Map<String, Object>> result = new ArrayList<>(recommend);
  157. used.forEach(domainOrder -> {
  158. Map<String, Object> sold = new HashMap<>();
  159. sold.put("domain", domainOrder.getDomainName().toLowerCase());
  160. sold.put("sold", true);
  161. result.add(sold);
  162. });
  163. return result;
  164. }
  165. @Transient
  166. public void notify(Long id, PayMethod payMethod, String transactionId) throws FontFormatException, IOException, WriterException {
  167. DomainOrder domainOrder = domainOrderRepo.findById(id).orElseThrow(new BusinessException("未找到星图"));
  168. if (!domainOrder.getOrderStatus().equals(OrderStatus.NOT_PAID)) {
  169. throw new BusinessException("订单已经处理");
  170. }
  171. BufferedImage img = domainImg(domainOrder.getDomainName());
  172. ByteArrayOutputStream os = new ByteArrayOutputStream();
  173. ImageIO.write(img, "jpg", os);
  174. InputStream input = new ByteArrayInputStream(os.toByteArray());
  175. String path = "image/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date())
  176. + RandomStringUtils.randomAlphabetic(8) + ".jpg";
  177. String realUrl = storageService.uploadFromInputStream(input, path);
  178. FileObject fileObject = new FileObject();
  179. fileObject.setName(domainOrder.getDomainName());
  180. fileObject.setType("image/jpeg");
  181. fileObject.setUrl(realUrl);
  182. domainOrder.setOrderStatus(OrderStatus.FINISH);
  183. domainOrder.setPayMethod(payMethod);
  184. domainOrder.setPic(Collections.singletonList(fileObject));
  185. domainOrder.setTransactionId(transactionId);
  186. domainOrder.setStatus(CollectionStatus.SUCCESS);
  187. domainOrder.setCreateAssetId(createAsset(domainOrder));
  188. domainOrder.setEndTime(LocalDateTime.now().plusYears(domainOrder.getYears()));
  189. domainOrderRepo.save(domainOrder);
  190. }
  191. public void cancel(DomainOrder domainOrder) {
  192. domainOrder.setOrderStatus(OrderStatus.CANCELLED);
  193. domainOrder.setStatus(CollectionStatus.FAIL);
  194. domainOrderRepo.save(domainOrder);
  195. }
  196. public Long createAsset(DomainOrder domainOrder) {
  197. return assetService.createAsset(domainOrder, userRepo.findById(domainOrder.getUserId())
  198. .orElseThrow(new BusinessException("无用户记录")), null, BigDecimal.ZERO, "域名", null, false).getId();
  199. }
  200. public BufferedImage domainImg(String domain) throws IOException, FontFormatException, WriterException {
  201. String domainName;
  202. if (domain.contains(".")) {
  203. int dotIndex = domain.indexOf(".");
  204. domainName = domain.substring(0, dotIndex).toUpperCase();
  205. } else {
  206. domainName = domain.toUpperCase();
  207. }
  208. InputStream is1 = this.getClass()
  209. .getResourceAsStream("/font/Akronim Regular_mianfeiziti1.ttf");
  210. Font font1 = Font.createFont(Font.TRUETYPE_FONT, is1);
  211. is1.close();
  212. InputStream is2 = this.getClass()
  213. .getResourceAsStream("/font/VonwaonBitmap_12pxLite.ttf");
  214. Font font2 = Font.createFont(Font.TRUETYPE_FONT, is2);
  215. is2.close();
  216. int length = domainName.length();
  217. BufferedImage shareImg;
  218. if (length <= 2) {
  219. InputStream is3 = this.getClass().getResourceAsStream("/static/img/png_jing.png");
  220. shareImg = ImageIO.read(is3);
  221. is3.close();
  222. } else if (length <= 4) {
  223. InputStream is3 = this.getClass().getResourceAsStream("/static/img/png_lv.png");
  224. shareImg = ImageIO.read(is3);
  225. is3.close();
  226. } else {
  227. InputStream is3 = this.getClass().getResourceAsStream("/static/img/png_zi.png");
  228. shareImg = ImageIO.read(is3);
  229. is3.close();
  230. }
  231. BufferedImage result = new BufferedImage(shareImg.getWidth(), shareImg.getHeight(), BufferedImage.TYPE_INT_RGB);
  232. Graphics2D g = result.createGraphics();
  233. g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
  234. // g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  235. // g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
  236. g.setComposite(AlphaComposite.SrcOver);
  237. g.drawImage(shareImg, 0, 0, null);
  238. // BufferedImage avatarImg = ImageUtils.makeRoundedCorner(ImageUtils.scale(ImageIO.read(new URL(user.getAvatar())),
  239. // 80, 80,
  240. // ImageUtils.Fit.COVER), 40);
  241. // g.drawImage(avatarImg, 334, 136, null);
  242. int domainLength = domainName.length();
  243. if (domainLength > 10) {
  244. g.setColor(new Color(255, 255, 255));
  245. Font topFont = font1.deriveFont(Font.PLAIN, 130f);
  246. Font downFont = font2.deriveFont(Font.BOLD, 36f);
  247. int subIndex = domainLength / 3;
  248. String str1 = domainName.substring(0, subIndex);
  249. String str2 = domainName.substring(subIndex, subIndex + subIndex);
  250. String str3 = domainName.substring(subIndex + subIndex, domainLength);
  251. ImageUtils.drawCenteredString(g, str1, new Rectangle(0, 180, shareImg
  252. .getWidth(), 86), topFont);
  253. ImageUtils.drawCenteredString(g, str2, new Rectangle(0, 300, shareImg
  254. .getWidth(), 86), topFont);
  255. ImageUtils.drawCenteredString(g, str3, new Rectangle(0, 420, shareImg
  256. .getWidth(), 86), topFont);
  257. ImageUtils.drawCenteredString(g, ".NFT", new Rectangle(0, 540, shareImg
  258. .getWidth(), 86), topFont);
  259. g.setColor(new Color(255, 255, 255));
  260. ImageUtils.drawCenteredString(g, domain, new Rectangle(0, 650, shareImg
  261. .getWidth(), 12), downFont);
  262. }
  263. if (domainLength > 5 & domainLength <= 10) {
  264. g.setColor(new Color(255, 255, 255));
  265. Font topFont = font1.deriveFont(Font.PLAIN, 190f);
  266. Font downFont = font2.deriveFont(Font.BOLD, 36f);
  267. int subIndex = domainLength / 2;
  268. String str1 = domainName.substring(0, subIndex);
  269. String str2 = domainName.substring(subIndex, domainLength);
  270. ImageUtils.drawCenteredString(g, str1, new Rectangle(0, 180, shareImg
  271. .getWidth(), 86), topFont);
  272. ImageUtils.drawCenteredString(g, str2, new Rectangle(0, 350, shareImg
  273. .getWidth(), 86), topFont);
  274. ImageUtils.drawCenteredString(g, ".NFT", new Rectangle(0, 520, shareImg
  275. .getWidth(), 86), topFont);
  276. g.setColor(new Color(255, 255, 255));
  277. ImageUtils.drawCenteredString(g, domain, new Rectangle(0, 650, shareImg
  278. .getWidth(), 12), downFont);
  279. }
  280. if (domainLength <= 5) {
  281. g.setColor(new Color(255, 255, 255));
  282. Font topFont = font1.deriveFont(Font.PLAIN, 200f);
  283. Font downFont = font2.deriveFont(Font.BOLD, 36f);
  284. ImageUtils.drawCenteredString(g, domainName, new Rectangle(0, 243, shareImg
  285. .getWidth(), 86), topFont);
  286. ImageUtils.drawCenteredString(g, ".NFT", new Rectangle(0, 462, shareImg
  287. .getWidth(), 86), topFont);
  288. g.setColor(new Color(255, 255, 255));
  289. ImageUtils.drawCenteredString(g, domain, new Rectangle(0, 612, shareImg
  290. .getWidth(), 12), downFont);
  291. }
  292. //二维码
  293. // QRCodeWriter qrCodeWriter = new QRCodeWriter();
  294. // Map<EncodeHintType, Object> hints = new HashMap<>();
  295. // hints.put(EncodeHintType.MARGIN, 2);
  296. // BitMatrix bitMatrix = qrCodeWriter
  297. // .encode(env.getProperty("general.host") + "/wx/share?invitor=" + user.getId(),
  298. // BarcodeFormat.QR_CODE, 252, 252, hints);
  299. // g.drawImage(MatrixToImageWriter.toBufferedImage(bitMatrix), 250, 386, null);
  300. return result;
  301. }
  302. }