x1ongzhu 6 vuotta sitten
vanhempi
commit
c72dae2d2a

+ 34 - 0
src/main/java/com/izouma/walkchina/event/SendMsgEvent.java

@@ -0,0 +1,34 @@
+package com.izouma.walkchina.event;
+
+import org.springframework.context.ApplicationEvent;
+
+public class SendMsgEvent extends ApplicationEvent {
+    private Long    userId;
+    private Long    secondUserId;
+    private String  content;
+    private Integer type;
+
+    public SendMsgEvent(Object source, Long userId, Long secondUserId, String content, Integer type) {
+        super(source);
+        this.userId = userId;
+        this.secondUserId = secondUserId;
+        this.content = content;
+        this.type = type;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public Long getSecondUserId() {
+        return secondUserId;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public Integer getType() {
+        return type;
+    }
+}

+ 9 - 1
src/main/java/com/izouma/walkchina/event/UpdateLevelEvent.java

@@ -1,9 +1,17 @@
 package com.izouma.walkchina.event;
 
+import com.izouma.walkchina.domain.UserInfo;
 import org.springframework.context.ApplicationEvent;
 
 public class UpdateLevelEvent extends ApplicationEvent {
-    public UpdateLevelEvent(Object source) {
+    private UserInfo userInfo;
+
+    public UpdateLevelEvent(Object source, UserInfo userInfo) {
         super(source);
+        this.userInfo = userInfo;
+    }
+
+    public UserInfo getUserInfo() {
+        return userInfo;
     }
 }

+ 14 - 1
src/main/java/com/izouma/walkchina/event/UpdatePriceEvent.java

@@ -3,7 +3,20 @@ package com.izouma.walkchina.event;
 import org.springframework.context.ApplicationEvent;
 
 public class UpdatePriceEvent extends ApplicationEvent {
-    public UpdatePriceEvent(Object source) {
+    private Long   userId;
+    private String hirer;
+
+    public UpdatePriceEvent(Object source, Long userId, String hirer) {
         super(source);
+        this.userId = userId;
+        this.hirer = hirer;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public String getHirer() {
+        return hirer;
     }
 }

+ 16 - 0
src/main/java/com/izouma/walkchina/event/UpdateUserJourneyEvent.java

@@ -0,0 +1,16 @@
+package com.izouma.walkchina.event;
+
+import org.springframework.context.ApplicationEvent;
+
+public class UpdateUserJourneyEvent extends ApplicationEvent {
+    private Long userId;
+
+    public UpdateUserJourneyEvent(Object source, Long userId) {
+        super(source);
+        this.userId = userId;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+}

+ 9 - 21
src/main/java/com/izouma/walkchina/service/JourneyService.java

@@ -8,7 +8,9 @@ import com.izouma.walkchina.dto.Location;
 import com.izouma.walkchina.dto.webservice.DirectionResponse;
 import com.izouma.walkchina.dto.webservice.MapRoute;
 import com.izouma.walkchina.event.SendJoinAwardEvent;
+import com.izouma.walkchina.event.SendMsgEvent;
 import com.izouma.walkchina.event.UpdateLevelEvent;
+import com.izouma.walkchina.event.UpdateUserJourneyEvent;
 import com.izouma.walkchina.exception.ServiceException;
 import com.izouma.walkchina.repo.*;
 import lombok.extern.slf4j.Slf4j;
@@ -169,23 +171,9 @@ public class JourneyService {
         Long userId = event.getUserId();
         BigDecimal coin = event.getCoin();
         UserInfo userInfo = userInfoRepository.findById(userId).orElseThrow(new ServiceException("用户不存在"));
-        UserJourney userJourney = userJourneyRepository.findByUserId(userId);
-        JourneyStage journeyStage = journeyStageRepository.findFirstByUserIdAndJourneyIdOrderByCreatedAtDesc(userId, userJourney
-            .getId()).orElseThrow(new ServiceException("无记录"));
         coinService.balanceChange(userInfo, coin, AppConstants.CoinRecordType.JOIN, Strings.REMARK_JOIN, null);
         userInfo.setIsNew(false);
         userInfoRepository.save(userInfo);
-        stageAwardRepository.save(StageAward.builder()
-                                            .userId(userId)
-                                            .journeyId(userJourney.getId())
-                                            .stageId(journeyStage.getId())
-                                            .coin(coin)
-                                            .received(true)
-                                            .needProgress(0D)
-                                            .needSteps(0L)
-                                            .longitude(journeyStage.getOrigin().getLongitude())
-                                            .latitude(journeyStage.getOrigin().getLatitude())
-                                            .build());
     }
 
     private void createStageAward(UserJourney userJourney, JourneyStage journeyStage, Long needSteps) {
@@ -220,6 +208,11 @@ public class JourneyService {
         stageAwardRepository.save(stageAward);
     }
 
+    @EventListener
+    public void updateUserJourney(UpdateUserJourneyEvent event) {
+        updateUserJourney(event.getUserId());
+    }
+
     public void updateUserJourney(Long userId) {
         UserJourney userJourney = userJourneyRepository.findByUserId(userId);
         if (userJourney == null) {
@@ -261,12 +254,7 @@ public class JourneyService {
             Math.round(progress * 100));
         Message lastMsg = messageRepository.findFirstByUserIdAndTypeOrderByCreatedAtDesc(userId, AppConstants.MessageType.PROGRESS_UPDATE);
         if (lastMsg == null || !content.equals(lastMsg.getContent())) {
-            Message msg = Message.builder()
-                                 .userId(userId)
-                                 .content(content)
-                                 .type(AppConstants.MessageType.PROGRESS_UPDATE)
-                                 .build();
-            messageRepository.save(msg);
+            applicationContext.publishEvent(new SendMsgEvent(this, userId, null, content, AppConstants.MessageType.PROGRESS_UPDATE));
         }
 
         if (progress == 1) {
@@ -325,7 +313,7 @@ public class JourneyService {
                                                      .destination(latestStage.getDestination())
                                                      .totalSteps(mySteps + teamSteps)
                                                      .build();
-        applicationContext.publishEvent(new UpdateLevelEvent(userInfo));
+        applicationContext.publishEvent(new UpdateLevelEvent(this, userInfo));
         return stageStat;
     }
 }

+ 31 - 22
src/main/java/com/izouma/walkchina/service/MessageService.java

@@ -5,18 +5,19 @@ import com.izouma.walkchina.constant.Strings;
 import com.izouma.walkchina.domain.Message;
 import com.izouma.walkchina.domain.UserInfo;
 import com.izouma.walkchina.dto.UserDTO;
+import com.izouma.walkchina.event.SendMsgEvent;
 import com.izouma.walkchina.event.SendStepContributeMsgEvent;
 import com.izouma.walkchina.repo.MessageRepository;
 import com.izouma.walkchina.repo.TeamMemberRepository;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.event.EventListener;
-import org.springframework.data.domain.*;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDate;
-import java.time.LocalDateTime;
 import java.util.List;
 
 @Slf4j
@@ -50,32 +51,40 @@ public class MessageService {
             Message msg1 = messageRepository.findFirstByUserIdAndSecondUserIdAndTypeOrderByCreatedAtDesc(leader.getUserId(),
                                                                                                          userInfo.getId(),
                                                                                                          AppConstants.MessageType.STEP_CONTRIBUTE);
-            if (msg1 == null || msg1.getCreatedAt().plusMinutes(5).isBefore(LocalDateTime.now())) {
-                String content = String.format(Strings.MSG_CONTRIBUTE, userInfo.getNickname(), steps);
-                if (msg1 == null || msg1.getContent().equals(content)) {
-                    messageRepository.save(Message.builder()
-                                                  .userId(leader.getUserId())
-                                                  .secondUserId(userInfo.getId())
-                                                  .content(content)
-                                                  .type(AppConstants.MessageType.STEP_CONTRIBUTE)
-                                                  .build());
-                }
+            String content1 = String.format(Strings.MSG_CONTRIBUTE, userInfo.getNickname(), steps);
+            if (msg1 == null || !content1.equals(msg1.getContent())) {
+                messageRepository.save(Message.builder()
+                                              .userId(leader.getUserId())
+                                              .secondUserId(userInfo.getId())
+                                              .content(content1)
+                                              .type(AppConstants.MessageType.STEP_CONTRIBUTE)
+                                              .build());
             }
 
             Message msg2 = messageRepository.findFirstByUserIdAndSecondUserIdAndTypeOrderByCreatedAtDesc(userInfo.getId(),
                                                                                                          leader.getUserId(),
                                                                                                          AppConstants.MessageType.STEP_CONTRIBUTE);
-            if (msg2 == null || msg2.getCreatedAt().plusMinutes(5).isBefore(LocalDateTime.now())) {
-                String content = String.format(Strings.MSG_CONTRIBUTE_TO, leader.getNickname(), steps);
-                if (msg2 == null || msg2.getContent().equals(content)) {
-                    messageRepository.save(Message.builder()
-                                                  .userId(userInfo.getId())
-                                                  .secondUserId(leader.getUserId())
-                                                  .content(String.format(Strings.MSG_CONTRIBUTE_TO, leader.getNickname(), steps))
-                                                  .type(AppConstants.MessageType.STEP_CONTRIBUTE)
-                                                  .build());
-                }
+            String content2 = String.format(Strings.MSG_CONTRIBUTE_TO, leader.getNickname(), steps);
+            if (msg2 == null || !content2.equals(msg2.getContent())) {
+                messageRepository.save(Message.builder()
+                                              .userId(userInfo.getId())
+                                              .secondUserId(leader.getUserId())
+                                              .content(content2)
+                                              .type(AppConstants.MessageType.STEP_CONTRIBUTE)
+                                              .build());
             }
         }
     }
+
+    @Async
+    @EventListener
+    public void sendMessage(SendMsgEvent event) {
+        messageRepository.save(Message.builder()
+                                      .userId(event.getUserId())
+                                      .secondUserId(event.getSecondUserId())
+                                      .content(event.getContent())
+                                      .type(event.getType())
+                                      .isRead(false)
+                                      .build());
+    }
 }

+ 14 - 38
src/main/java/com/izouma/walkchina/service/TeamService.java

@@ -8,8 +8,10 @@ import com.izouma.walkchina.constant.AppConstants;
 import com.izouma.walkchina.constant.Strings;
 import com.izouma.walkchina.domain.*;
 import com.izouma.walkchina.dto.UserDTO;
+import com.izouma.walkchina.event.SendMsgEvent;
 import com.izouma.walkchina.event.SendStepContributeMsgEvent;
 import com.izouma.walkchina.event.UpdatePriceEvent;
+import com.izouma.walkchina.event.UpdateUserJourneyEvent;
 import com.izouma.walkchina.exception.ServiceException;
 import com.izouma.walkchina.repo.*;
 import com.izouma.walkchina.utils.ImageUtils;
@@ -44,8 +46,6 @@ public class TeamService {
     @Autowired
     private UserInfoRepository     userInfoRepository;
     @Autowired
-    private MessageRepository      messageRepository;
-    @Autowired
     private WalkDataRepository     walkDataRepository;
     @Autowired
     private FriendInfoService      friendInfoService;
@@ -58,8 +58,6 @@ public class TeamService {
     @Autowired
     private RewardRecordRepository rewardRecordRepository;
     @Autowired
-    private JourneyService         journeyService;
-    @Autowired
     private ApplicationContext     applicationContext;
 
     public void hire(Long userId, Long target) {
@@ -96,14 +94,9 @@ public class TeamService {
             teamMember.setEndDate(now.toLocalDate());
             teamMember.setGrabbed(true);
             teamMemberRepository.save(teamMember);
-            Message grabMsg = Message.builder()
-                                     .userId(teamMember.getLeader())
-                                     .type(AppConstants.MessageType.NORMAL)
-                                     .content(String.format(Strings.MSG_MEMBER_GRABBED, targetUserInfo.getNickname(), userInfo.getNickname()))
-                                     .active(true)
-                                     .isRead(false)
-                                     .build();
-            messageRepository.save(grabMsg);
+            applicationContext.publishEvent(new SendMsgEvent(this, teamMember.getLeader(), null,
+                                                             String.format(Strings.MSG_MEMBER_GRABBED, targetUserInfo.getNickname(), userInfo.getNickname()),
+                                                             AppConstants.MessageType.NORMAL));
         }
 
         BigDecimal price = Optional.ofNullable(targetUserInfo.getPrice()).orElse(AppConstants.MIN_PRICE);
@@ -126,25 +119,15 @@ public class TeamService {
                                              .build();
         teamMemberRepository.save(newTeamMember);
 
-        applicationContext.publishEvent(new UpdatePriceEvent(targetUserInfo));
-        messageRepository.save(Message.builder()
-                                      .userId(target)
-                                      .content(String.format(Strings.MSG_HIRED, userInfo.getNickname(), targetUserInfo.getPrice()))
-                                      .type(AppConstants.MessageType.NORMAL)
-                                      .build());
-
-        Message grabMsg = Message.builder()
-                                 .userId(userId)
-                                 .type(AppConstants.MessageType.NORMAL)
-                                 .content(String.format(Strings.MSG_HIRE, price, targetUserInfo.getNickname()))
-                                 .active(true)
-                                 .isRead(false)
-                                 .build();
-        messageRepository.save(grabMsg);
+        applicationContext.publishEvent(new UpdatePriceEvent(this, targetUserInfo.getId(), userInfo.getNickname()));
+
+        applicationContext.publishEvent(new SendMsgEvent(this, userId, null,
+                                                         String.format(Strings.MSG_HIRE, price, targetUserInfo.getNickname()),
+                                                         AppConstants.MessageType.NORMAL));
 
         WalkData walkData = walkDataRepository.findByUserIdAndDate(target, LocalDate.now());
         if (walkData != null) {
-            applicationContext.publishEvent(new SendStepContributeMsgEvent(null, userInfo, Math.toIntExact(walkData.getSteps())));
+            applicationContext.publishEvent(new SendStepContributeMsgEvent(this, userInfo, Math.toIntExact(walkData.getSteps())));
         }
     }
 
@@ -317,22 +300,15 @@ public class TeamService {
                                              .build();
         teamMemberRepository.save(newTeamMember);
 
-        applicationContext.publishEvent(new UpdatePriceEvent(targetUserInfo));
-
-        messageRepository.save(Message.builder()
-                                      .userId(userId)
-                                      .content(String.format(Strings.MSG_RECRUIT, targetUserInfo.getNickname()))
-                                      .type(AppConstants.MessageType.NORMAL)
-                                      .active(true)
-                                      .isRead(false)
-                                      .build());
+        applicationContext.publishEvent(new UpdatePriceEvent(this, targetUserInfo.getId(), userInfo.getNickname()));
+        applicationContext.publishEvent(new SendMsgEvent(this, userId, null, String.format(Strings.MSG_RECRUIT, targetUserInfo.getNickname()), AppConstants.MessageType.NORMAL));
     }
 
     @Async
     public void updateLeaderJourney(Long userId) {
         List<UserDTO> leaders = teamMemberRepository.findLeader(userId, LocalDate.now());
         for (UserDTO userDTO : leaders) {
-            journeyService.updateUserJourney(userDTO.getUserId());
+            applicationContext.publishEvent(new UpdateUserJourneyEvent(this, userDTO.getUserId()));
         }
     }
 }

+ 21 - 9
src/main/java/com/izouma/walkchina/service/UserInfoService.java

@@ -4,12 +4,14 @@ import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
 import com.izouma.walkchina.constant.AppConstants;
+import com.izouma.walkchina.constant.Strings;
 import com.izouma.walkchina.domain.FriendInfo;
 import com.izouma.walkchina.domain.MonthWalkData;
 import com.izouma.walkchina.domain.UserInfo;
 import com.izouma.walkchina.dto.RankInfo;
 import com.izouma.walkchina.dto.UserWalkStats;
 import com.izouma.walkchina.event.SendJoinAwardEvent;
+import com.izouma.walkchina.event.SendMsgEvent;
 import com.izouma.walkchina.event.UpdateLevelEvent;
 import com.izouma.walkchina.event.UpdatePriceEvent;
 import com.izouma.walkchina.exception.ServiceException;
@@ -27,6 +29,7 @@ import org.springframework.scheduling.annotation.Async;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
 
+import java.io.FileInputStream;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
@@ -71,6 +74,7 @@ public class UserInfoService {
                            .password(new BCryptPasswordEncoder().encode(password))
                            .nickname("用户" + RandomStringUtils.randomAlphabetic(6))
                            .avatar(AppConstants.DEFAULT_AVATAR)
+                           .isNew(true)
                            .coin(BigDecimal.ZERO)
                            .active(true)
                            .authorities(Collections.singletonList(authorityRepository.findByName(AuthorityName.ROLE_USER)))
@@ -98,6 +102,7 @@ public class UserInfoService {
                                .coin(BigDecimal.ZERO)
                                .price(AppConstants.MIN_PRICE)
                                .active(true)
+                               .isNew(true)
                                .sessionKey(sessionKey)
                                .authorities(Collections.singletonList(authorityRepository.findByName(AuthorityName.ROLE_USER)))
                                .build();
@@ -147,6 +152,7 @@ public class UserInfoService {
                                .coin(BigDecimal.ZERO)
                                .price(AppConstants.MIN_PRICE)
                                .active(true)
+                               .isNew(true)
                                .authorities(Collections.singletonList(authorityRepository.findByName(AuthorityName.ROLE_USER)))
                                .build();
             userInfo = userInfoRepository.save(userInfo);
@@ -192,12 +198,16 @@ public class UserInfoService {
 
     private void uploadUserMarker(UserInfo userInfo) {
         try {
-            storageService.uploadFromInputStream(ImageUtils.getInputStream(ImageUtils.makeMarker("user", userInfo
-                .getAvatar()), "png"), "marker/user/" + userInfo.getId() + ".png");
-            storageService.uploadFromInputStream(ImageUtils.getInputStream(ImageUtils.makeMarker("location", userInfo
-                .getAvatar()), "png"), "marker/location/" + userInfo.getId() + ".png");
+            String path = ImageUtils.makeMarker("user", userInfo.getAvatar());
+            storageService.uploadFromInputStream(new FileInputStream(path), "marker/user/" + userInfo.getId() + ".png");
         } catch (Exception e) {
-            log.error("upload marker", e);
+            log.error("uploadUserMarker", e);
+        }
+        try {
+            String path = ImageUtils.makeMarker("location", userInfo.getAvatar());
+            storageService.uploadFromInputStream(new FileInputStream(path), "marker/location/" + userInfo.getId() + ".png");
+        } catch (Exception e) {
+            log.error("uploadUserMarker", e);
         }
     }
 
@@ -245,11 +255,10 @@ public class UserInfoService {
         userInfoRepository.save(userInfo);
     }
 
-
     @Async
     @EventListener
     public void updateUserPrice(UpdatePriceEvent event) {
-        UserInfo userInfo = (UserInfo) event.getSource();
+        UserInfo userInfo = userInfoRepository.findById(event.getUserId()).orElseThrow(new ServiceException("用户不存在"));
         MonthWalkData monthWalkData = monthWalkDataRepository.findByUserId(userInfo.getId()).orElse(null);
         BigDecimal price = BigDecimal.ZERO;
         if (monthWalkData != null) {
@@ -273,13 +282,16 @@ public class UserInfoService {
         userInfo.setPrice(price);
         userInfoRepository.save(userInfo);
         if (userInfo.getIsNew() != null && userInfo.getIsNew()) {
-            applicationContext.publishEvent(new SendJoinAwardEvent(null, userInfo.getId(), price));
+            applicationContext.publishEvent(new SendJoinAwardEvent(this, userInfo.getId(), price));
+        }
+        if (event.getHirer() != null) {
+            applicationContext.publishEvent(new SendMsgEvent(this, event.getUserId(), null, String.format(Strings.MSG_HIRED, event.getHirer(), price), AppConstants.MessageType.NORMAL));
         }
     }
 
     @EventListener
     public void updateUserLevel(UpdateLevelEvent event) {
-        UserInfo userInfo = (UserInfo) event.getSource();
+        UserInfo userInfo = event.getUserInfo();
         int walkCities = Optional.ofNullable(userInfo.getWalkCities()).orElse(0);
         int level;
         if (walkCities < 4) {

+ 2 - 2
src/main/java/com/izouma/walkchina/service/WalkDataService.java

@@ -69,7 +69,7 @@ public class WalkDataService {
                                          .build();
             monthWalkData.setSteps(steps);
             monthWalkDataRepository.save(monthWalkData);
-            applicationContext.publishEvent(new UpdatePriceEvent(userInfo));
+            applicationContext.publishEvent(new UpdatePriceEvent(this, userInfo.getId(), null));
         }
 
         wxMaRunStepInfoList.stream()
@@ -78,7 +78,7 @@ public class WalkDataService {
                                                              .toLocalDate()
                                                              .isEqual(LocalDate.now())
                                                       && wxMaRunStepInfo.getStep() > 0)
-                           .findAny().ifPresent(stepInfo -> applicationContext.publishEvent(new SendStepContributeMsgEvent(null, userInfo, stepInfo.getStep())));
+                           .findAny().ifPresent(stepInfo -> applicationContext.publishEvent(new SendStepContributeMsgEvent(this, userInfo, stepInfo.getStep())));
 
         teamService.updateLeaderJourney(userId);
     }

+ 30 - 7
src/main/java/com/izouma/walkchina/utils/ImageUtils.java

@@ -7,11 +7,11 @@ import javax.imageio.ImageIO;
 import java.awt.*;
 import java.awt.geom.RoundRectangle2D;
 import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Scanner;
 
 public class ImageUtils {
 
@@ -28,8 +28,10 @@ public class ImageUtils {
     public static BufferedImage scale(BufferedImage src, int width, int height, Fit fit) {
         BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
         Graphics2D g = dest.createGraphics();
-        g.setComposite(AlphaComposite.Src);
+        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+        g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        g.setComposite(AlphaComposite.Src);
         int dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2;
         if (fit == Fit.COVER) {
             dx1 = dy1 = 0;
@@ -107,17 +109,38 @@ public class ImageUtils {
         return output;
     }
 
-    public static BufferedImage makeMarker(String type, String url) throws IOException {
+    public static String makeMarker(String type, String url) throws IOException, InterruptedException {
         Resource bgRes = new ClassPathResource(type.equals("user") ? "static/bg_user_marker.png" : "static/bg_user_location_marker.png");
         InputStream inputStream = bgRes.getInputStream();
         BufferedImage bgImg = ImageIO.read(inputStream);
         Graphics2D g = bgImg.createGraphics();
         g.setComposite(AlphaComposite.Src);
         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+        g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
         BufferedImage avatar = makeRoundedCorner(scale(ImageIO.read(new URL(url)), 36 * 3, 36 * 3, Fit.COVER), 36 * 3 / 2);
         g.setComposite(AlphaComposite.SrcOver);
         g.drawImage(avatar, 8 * 3, 6 * 3, null);
-        return bgImg;
+
+        bgImg = ImageUtils.scale(bgImg, 104, 112, Fit.FILL);
+
+        Path src = Files.createTempFile("marker", ".png");
+        Path dst = Files.createTempFile("marker", ".png");
+        ImageIO.write(bgImg, "png", new File(src.toString()));
+        ProcessBuilder builder = new ProcessBuilder("pngquant", src.toString(), "-o" + dst.toString(), "-f");
+        Process process = builder.start();
+        InputStream stdout = process.getInputStream();
+        InputStream stderr = process.getErrorStream();
+        Scanner scanner1 = new Scanner(stdout);
+        while (scanner1.hasNextLine()) {
+            System.out.println(scanner1.nextLine());
+        }
+        Scanner scanner2 = new Scanner(stderr);
+        while (scanner2.hasNextLine()) {
+            System.out.println(scanner2.nextLine());
+        }
+        int code = process.waitFor();
+        return dst.toString();
     }
 
     public static InputStream getInputStream(BufferedImage bufferedImage, String imageFormat) throws IOException {

BIN
src/main/resources/pngquant/win/pngquant.exe


+ 32 - 15
src/test/java/com/izouma/walkchina/CommonTest.java

@@ -6,7 +6,6 @@ import com.izouma.walkchina.domain.City;
 import com.izouma.walkchina.domain.UserInfo;
 import com.izouma.walkchina.dto.Location;
 import com.izouma.walkchina.dto.LogisticsInfo;
-import com.izouma.walkchina.utils.ImageUtils;
 import net.sourceforge.pinyin4j.PinyinHelper;
 import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
 import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
@@ -20,10 +19,7 @@ import org.json.JSONException;
 import org.json.JSONObject;
 import org.junit.Test;
 
-import javax.imageio.ImageIO;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
+import java.io.*;
 import java.lang.reflect.InvocationTargetException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -33,20 +29,11 @@ import java.nio.file.Paths;
 import java.text.MessageFormat;
 import java.time.Instant;
 import java.time.ZoneId;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Stream;
 
 public class CommonTest {
 
-    @Test
-    public void testImg() throws IOException {
-        ImageIO.write(ImageUtils.makeMarker("user", "https://ws1.sinaimg.cn/large/0065oQSqgy1fze94uew3jj30qo10cdka.jpg"), "png", new File("image1.png"));
-        ImageIO.write(ImageUtils.makeMarker("location", "https://ws1.sinaimg.cn/large/0065oQSqgy1fze94uew3jj30qo10cdka.jpg"), "png", new File("image2.png"));
-    }
-
     @Test
     public void testStringFmt() {
         String string = String.format("name=%s, age=%d %s", "huhx", 25, 1.1);
@@ -215,4 +202,34 @@ public class CommonTest {
         System.out.println(b ? 1 : 2);
     }
 
+    @Test
+    public void testPngquant() throws IOException {
+        ProcessBuilder builder = new ProcessBuilder("pngquant");
+
+        // builder.redirectOutput(new File("/Users/drew/Downloads/1.png"));
+        // builder.redirectInput(new File("/Users/drew/Desktop/3716.png"));
+
+        Process process = builder.start();
+        OutputStream stdin = process.getOutputStream();
+        FileInputStream fin = new FileInputStream(new File("/Users/drew/Desktop/3716.png"));
+        int n;
+        byte[] bytes = new byte[1024];
+        while ((n = fin.read(bytes)) > 0) {
+            stdin.write(bytes, 0, n);
+        }
+        stdin.close();
+
+        InputStream stdout = process.getInputStream();
+        InputStream err = process.getErrorStream();
+
+        Scanner scanner = new Scanner(stdout);
+        while (scanner.hasNextLine()) {
+            System.out.println(scanner.nextLine());
+        }
+
+        Scanner errScanner = new Scanner(err);
+        while (errScanner.hasNextLine()) {
+            System.out.println(errScanner.nextLine());
+        }
+    }
 }

+ 19 - 4
src/test/java/com/izouma/walkchina/service/UserInfoServiceTest.java

@@ -1,6 +1,7 @@
 package com.izouma.walkchina.service;
 
 import com.izouma.walkchina.domain.UserInfo;
+import com.izouma.walkchina.event.UpdatePriceEvent;
 import com.izouma.walkchina.repo.AuthorityRepository;
 import com.izouma.walkchina.repo.UserInfoRepository;
 import com.izouma.walkchina.security.Authority;
@@ -10,14 +11,18 @@ import com.izouma.walkchina.utils.ImageUtils;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
 import org.springframework.test.context.junit4.SpringRunner;
 
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.util.List;
 
 @RunWith(SpringRunner.class)
 @SpringBootTest
+@AutoConfigureMockMvc
 public class UserInfoServiceTest {
     @Autowired
     private UserInfoRepository  userInfoRepository;
@@ -27,6 +32,8 @@ public class UserInfoServiceTest {
     private UserInfoService     userInfoService;
     @Autowired
     private AuthorityRepository authorityRepository;
+    @Autowired
+    private ApplicationContext  applicationContext;
 
     @Test
     public void loadUserByUsername() {
@@ -45,17 +52,17 @@ public class UserInfoServiceTest {
     }
 
     @Test
-    public void addMarker() throws IOException {
+    public void addMarker() throws IOException, InterruptedException {
         List<UserInfo> userInfoList = userInfoRepository.findAll();
         for (UserInfo userInfo : userInfoList) {
-            storageService.uploadFromInputStream(ImageUtils.getInputStream(ImageUtils.makeMarker("user", userInfo.getAvatar()), "png"), "marker/user/" + userInfo.getId() + ".png");
-            storageService.uploadFromInputStream(ImageUtils.getInputStream(ImageUtils.makeMarker("location", userInfo.getAvatar()), "png"), "marker/location/" + userInfo.getId() + ".png");
+            storageService.uploadFromInputStream(new FileInputStream(ImageUtils.makeMarker("user", userInfo.getAvatar())), "marker/user/" + userInfo.getId() + ".png");
+            storageService.uploadFromInputStream(new FileInputStream(ImageUtils.makeMarker("location", userInfo.getAvatar())), "marker/location/" + userInfo.getId() + ".png");
         }
     }
 
     @Test
     public void updateUserPrice() {
-        userInfoService.updateUserPrice(userInfoRepository.findById(2232L).get());
+        applicationContext.publishEvent(new UpdatePriceEvent(this, userInfoRepository.findById(2232L).get().getId(), null));
     }
 
     @Test
@@ -63,4 +70,12 @@ public class UserInfoServiceTest {
         authorityRepository.save(Authority.builder().name(AuthorityName.ROLE_ADMIN).build());
         authorityRepository.save(Authority.builder().name(AuthorityName.ROLE_USER).build());
     }
+
+    @Test
+    public void testMarker() throws IOException, InterruptedException {
+        UserInfo userInfo = userInfoRepository.findById(5351L).get();
+        String path = ImageUtils.makeMarker("location", userInfo.getAvatar());
+        Process process = new ProcessBuilder("open", path).start();
+        process.waitFor();
+    }
 }