|
|
@@ -1,18 +1,34 @@
|
|
|
package com.izouma.walkchina.service;
|
|
|
|
|
|
+import cn.binarywang.wx.miniapp.api.WxMaService;
|
|
|
+import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor;
|
|
|
+import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
|
|
|
+import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage;
|
|
|
import com.izouma.walkchina.constant.AppConstants;
|
|
|
import com.izouma.walkchina.constant.Strings;
|
|
|
import com.izouma.walkchina.domain.*;
|
|
|
-import com.izouma.walkchina.dto.UserTeamMember;
|
|
|
+import com.izouma.walkchina.dto.UserDTO;
|
|
|
import com.izouma.walkchina.exception.ServiceException;
|
|
|
import com.izouma.walkchina.repo.*;
|
|
|
+import com.izouma.walkchina.utils.ImageUtils;
|
|
|
+import com.sun.imageio.plugins.common.ImageUtil;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import me.chanjar.weixin.common.error.WxErrorException;
|
|
|
import org.apache.commons.lang3.time.DateUtils;
|
|
|
+import org.joda.time.Days;
|
|
|
+import org.joda.time.LocalDate;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import javax.imageio.ImageIO;
|
|
|
+import java.awt.*;
|
|
|
+import java.awt.image.BufferedImage;
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
+import java.net.URL;
|
|
|
import java.util.Date;
|
|
|
import java.util.List;
|
|
|
import java.util.Optional;
|
|
|
@@ -21,15 +37,19 @@ import java.util.Optional;
|
|
|
@Slf4j
|
|
|
public class TeamService {
|
|
|
@Autowired
|
|
|
- private TeamMemberRepository teamMemberRepository;
|
|
|
+ private TeamMemberRepository teamMemberRepository;
|
|
|
@Autowired
|
|
|
- private UserInfoRepository userInfoRepository;
|
|
|
+ private UserInfoRepository userInfoRepository;
|
|
|
@Autowired
|
|
|
- private UserCoinRecordRepository userCoinRecordRepository;
|
|
|
+ private MessageRepository messageRepository;
|
|
|
@Autowired
|
|
|
- private MessageRepository messageRepository;
|
|
|
+ private WalkDataRepository walkDataRepository;
|
|
|
@Autowired
|
|
|
- private WalkDataRepository walkDataRepository;
|
|
|
+ private FriendInfoRepository friendInfoRepository;
|
|
|
+ @Autowired
|
|
|
+ private CoinService coinService;
|
|
|
+ @Autowired
|
|
|
+ private WxMaService wxMaService;
|
|
|
|
|
|
public void hire(Long userId, Long target) {
|
|
|
Date now = new Date();
|
|
|
@@ -66,9 +86,11 @@ public class TeamService {
|
|
|
throw new ServiceException("雇佣失败,商城币不足");
|
|
|
}
|
|
|
|
|
|
- balance = balance.subtract(price);
|
|
|
- userInfo.setCoin(balance);
|
|
|
- userInfoRepository.save(userInfo);
|
|
|
+ coinService.balanceChange(userInfo, price.negate(), AppConstants.CoinRecordType.HIRE, Strings.REMARK_HIRE,
|
|
|
+ String.format(Strings.MSG_HIRE, price, targetUserInfo.getNickname()));
|
|
|
+
|
|
|
+ coinService.balanceChange(targetUserInfo, price, AppConstants.CoinRecordType.BE_HIRED, Strings.REMARK_BE_HIRED,
|
|
|
+ String.format(Strings.MSG_HIRED, targetUserInfo.getNickname(), price));
|
|
|
|
|
|
TeamMember newTeamMember = TeamMember.builder()
|
|
|
.userId(target)
|
|
|
@@ -79,41 +101,6 @@ public class TeamService {
|
|
|
.active(true)
|
|
|
.build();
|
|
|
teamMemberRepository.save(newTeamMember);
|
|
|
-
|
|
|
- UserCoinRecord hireRecord = UserCoinRecord.builder()
|
|
|
- .userId(userId)
|
|
|
- .modify(price.negate())
|
|
|
- .balance(balance)
|
|
|
- .type(AppConstants.CoinRecordType.HIRE)
|
|
|
- .remark(Strings.REMARK_HIRE)
|
|
|
- .build();
|
|
|
- userCoinRecordRepository.save(hireRecord);
|
|
|
- Message hireMsg = Message.builder()
|
|
|
- .userId(userId)
|
|
|
- .type(AppConstants.MessageType.NORMAL)
|
|
|
- .content(String.format(Strings.MSG_HIRE, price, targetUserInfo.getNickname()))
|
|
|
- .active(true)
|
|
|
- .isRead(false)
|
|
|
- .build();
|
|
|
- messageRepository.save(hireMsg);
|
|
|
-
|
|
|
- BigDecimal targetBalance = Optional.ofNullable(targetUserInfo.getCoin()).orElse(BigDecimal.ZERO).add(price);
|
|
|
- UserCoinRecord beHiredRecord = UserCoinRecord.builder()
|
|
|
- .userId(target)
|
|
|
- .modify(price)
|
|
|
- .balance(targetBalance)
|
|
|
- .type(AppConstants.CoinRecordType.BE_HIRED)
|
|
|
- .remark(Strings.REMARK_BE_HIRED)
|
|
|
- .build();
|
|
|
- userCoinRecordRepository.save(beHiredRecord);
|
|
|
- Message beHireMsg = Message.builder()
|
|
|
- .userId(userId)
|
|
|
- .type(AppConstants.MessageType.NORMAL)
|
|
|
- .content(String.format(Strings.MSG_HIRED, targetUserInfo.getNickname(), price))
|
|
|
- .active(true)
|
|
|
- .isRead(false)
|
|
|
- .build();
|
|
|
- messageRepository.save(beHireMsg);
|
|
|
}
|
|
|
|
|
|
public boolean canHire(Long userId, Long target) {
|
|
|
@@ -128,18 +115,112 @@ public class TeamService {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- public List<UserTeamMember> userTeam(Long userId) {
|
|
|
- List<UserTeamMember> list = teamMemberRepository.findUserTeam(userId);
|
|
|
+ public List<UserDTO> userTeam(Long userId) {
|
|
|
+ List<UserDTO> list = teamMemberRepository.findUserTeam(userId);
|
|
|
Date now = new Date();
|
|
|
- for (UserTeamMember userTeamMember : list) {
|
|
|
- WalkData walkData = walkDataRepository.findByUserIdAndDate(userTeamMember.getUserId(), now);
|
|
|
+ for (UserDTO userDTO : list) {
|
|
|
+ WalkData walkData = walkDataRepository.findByUserIdAndDate(userDTO.getUserId(), now);
|
|
|
if (walkData != null) {
|
|
|
- userTeamMember.setTodaySteps(walkData.getSteps());
|
|
|
+ userDTO.setTodaySteps(walkData.getSteps());
|
|
|
} else {
|
|
|
- userTeamMember.setTodaySteps(0L);
|
|
|
- userTeamMember.setShouldWake(true);
|
|
|
+ userDTO.setTodaySteps(0L);
|
|
|
+ userDTO.setShouldWake(true);
|
|
|
}
|
|
|
}
|
|
|
return list;
|
|
|
}
|
|
|
+
|
|
|
+ public List<UserDTO> userFriend(Long userId) {
|
|
|
+ Date now = new Date();
|
|
|
+ List<UserDTO> list = friendInfoRepository.findUserFriend(userId, now);
|
|
|
+ for (UserDTO userDTO : list) {
|
|
|
+ WalkData walkData = walkDataRepository.findByUserIdAndDate(userDTO.getUserId(), now);
|
|
|
+ if (walkData != null) {
|
|
|
+ userDTO.setTodaySteps(walkData.getSteps());
|
|
|
+ } else {
|
|
|
+ userDTO.setTodaySteps(0L);
|
|
|
+ }
|
|
|
+
|
|
|
+ TeamMember teamMember = teamMemberRepository.findByLeaderAndUserId(userId, userDTO.getUserId(), now);
|
|
|
+ userDTO.setHired(teamMember != null);
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ public UserDTO userLeader(Long userId) {
|
|
|
+ UserDTO userDTO = teamMemberRepository.findLeader(userId, new Date());
|
|
|
+ WalkData walkData = walkDataRepository.findByUserIdAndDate(userDTO.getUserId(), new Date());
|
|
|
+ if (walkData != null) {
|
|
|
+ userDTO.setTodaySteps(walkData.getSteps());
|
|
|
+ } else {
|
|
|
+ userDTO.setTodaySteps(0L);
|
|
|
+ }
|
|
|
+ return userDTO;
|
|
|
+ }
|
|
|
+
|
|
|
+ public BufferedImage recruitImg(Long userId) throws IOException, FontFormatException, WxErrorException {
|
|
|
+ UserInfo userInfo = userInfoRepository.findById(userId).orElseThrow(new ServiceException("用户不存在"));
|
|
|
+
|
|
|
+ Font pingFangRegular = Font.createFont(Font.TRUETYPE_FONT, new File(ClassLoader.getSystemResource("static/PingFangRegular.ttf").getFile()));
|
|
|
+ Font pingFangMedium = Font.createFont(Font.TRUETYPE_FONT, new File(ClassLoader.getSystemResource("static/PingFangMedium.ttf").getFile()));
|
|
|
+ Font robot = Font.createFont(Font.TRUETYPE_FONT, new File(ClassLoader.getSystemResource("static/Roboto-Black.ttf").getFile()));
|
|
|
+ BufferedImage shareImg = ImageIO.read(ClassLoader.getSystemResource("static/share_img.png"));
|
|
|
+ Graphics2D g = shareImg.createGraphics();
|
|
|
+ g.setComposite(AlphaComposite.Src);
|
|
|
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
+ g.setComposite(AlphaComposite.SrcOver);
|
|
|
+ BufferedImage avatarImg = ImageUtils.makeRoundedCorner(ImageUtils
|
|
|
+ .scale(ImageIO.read(new URL(userInfo.getAvatar())),
|
|
|
+ 46 * 3, 46 * 3,
|
|
|
+ ImageUtils.Fit.COVER), 23 * 3);
|
|
|
+ g.drawImage(avatarImg, 145 * 3, 177 * 3, null);
|
|
|
+
|
|
|
+ BufferedImage levelImg = ImageIO.read(ClassLoader.getSystemResource("static/level_" + userInfo.getLevel() + ".png"));
|
|
|
+ g.drawImage(levelImg, (shareImg.getWidth() - levelImg.getWidth()) / 2, 251 * 3, null);
|
|
|
+
|
|
|
+
|
|
|
+ Font nicknameFont = pingFangRegular.deriveFont(14f * 3);
|
|
|
+ g.setColor(Color.BLACK);
|
|
|
+ ImageUtils.drawCenteredString(g, userInfo.getNickname(), new Rectangle(0, 230 * 3, shareImg.getWidth(), 20 * 3), nicknameFont);
|
|
|
+
|
|
|
+ Font walkDataFont = pingFangMedium.deriveFont(17f * 3);
|
|
|
+ ImageUtils.drawCenteredString(g, Days.daysBetween(LocalDate.fromDateFields(userInfo.getCreatedAt()), LocalDate.fromDateFields(new Date())).getDays() + "", new Rectangle(20 * 3, 295 * 3, 295 * 3 / 2, 24 * 3), walkDataFont);
|
|
|
+ ImageUtils.drawCenteredString(g, String.valueOf(userInfo.getWalkCities()), new Rectangle(295 * 3 / 2 + 20 * 3, 295 * 3, 295 * 3 / 2, 24 * 3), walkDataFont);
|
|
|
+ ImageUtils.drawCenteredString(g, String.valueOf(userInfo.getTotalSteps()), new Rectangle(20 * 3, 353 * 3, 295 * 3 / 2, 24 * 3), walkDataFont);
|
|
|
+ ImageUtils.drawCenteredString(g, coinService.totalAward(userId).toString(), new Rectangle(295 * 3 / 2 + 20 * 3, 353 * 3, 295 * 3 / 2, 24 * 3), walkDataFont);
|
|
|
+
|
|
|
+ Font labelFont = pingFangRegular.deriveFont(12f * 3);
|
|
|
+ g.setColor(new Color(128, 128, 128));
|
|
|
+ ImageUtils.drawCenteredString(g, "参赛天数", new Rectangle(20 * 3, 321 * 3, 295 * 3 / 2, 24 * 3), labelFont);
|
|
|
+ ImageUtils.drawCenteredString(g, "途经城市", new Rectangle(295 * 3 / 2 + 20 * 3, 321 * 3, 295 * 3 / 2, 24 * 3), labelFont);
|
|
|
+ ImageUtils.drawCenteredString(g, "总步数", new Rectangle(20 * 3, 376 * 3, 295 * 3 / 2, 24 * 3), labelFont);
|
|
|
+ ImageUtils.drawCenteredString(g, "获得奖金", new Rectangle(295 * 3 / 2 + 20 * 3, 376 * 3, 295 * 3 / 2, 24 * 3), labelFont);
|
|
|
+
|
|
|
+ String userNum = String.valueOf(userInfoRepository.count());
|
|
|
+ Font numberFont = robot.deriveFont(39f * 3);
|
|
|
+ g.setColor(new Color(76, 128, 255));
|
|
|
+ g.setFont(numberFont);
|
|
|
+ g.drawString(userNum, 20 * 3, 505 * 3);
|
|
|
+
|
|
|
+ int numberWidth = g.getFontMetrics(numberFont).stringWidth(userNum);
|
|
|
+ g.setFont(pingFangRegular.deriveFont(14f * 3));
|
|
|
+ g.drawString("位", 20 * 3 + numberWidth, 505 * 3);
|
|
|
+
|
|
|
+// byte[] bytes = wxMaService.getQrcodeService().createWxaCodeUnlimitBytes("recruit", "pages/home/home?from=" + userId, 72 * 3, true, new WxMaCodeLineColor("0", "0", "0"), true);
|
|
|
+// ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
|
|
|
+// BufferedImage codeImg = ImageIO.read(byteArrayInputStream);
|
|
|
+
|
|
|
+ BufferedImage codeImg = ImageIO.read(ClassLoader.getSystemResource("static/wxaqrcode.jpg"));
|
|
|
+
|
|
|
+ g.drawImage(ImageUtils.scale(codeImg, 72 * 3, 72 * 3, ImageUtils.Fit.COVER), 235 * 3, 425 * 3, null);
|
|
|
+
|
|
|
+ return shareImg;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void wake(Long userId, Long target) throws WxErrorException {
|
|
|
+ UserInfo userInfo = userInfoRepository.findById(userId).orElseThrow(new ServiceException("用户不存在"));
|
|
|
+ UserInfo targetUserInfo = userInfoRepository.findById(target).orElseThrow(new ServiceException("用户不存在"));
|
|
|
+ WxMaTemplateMessage msg = new WxMaTemplateMessage();
|
|
|
+ wxMaService.getMsgService().sendTemplateMsg(msg);
|
|
|
+ }
|
|
|
}
|