| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- package com.izouma.nineth.service;
- import com.alipay.mychain.sdk.vm.abi.datatype.Int;
- import com.izouma.nineth.domain.Rice;
- import com.izouma.nineth.domain.RiceOperationRecord;
- import com.izouma.nineth.domain.RiceUserWaterDropRecord;
- import com.izouma.nineth.domain.User;
- import com.izouma.nineth.dto.PageQuery;
- import com.izouma.nineth.dto.R;
- import com.izouma.nineth.dto.RiceDTO;
- import com.izouma.nineth.enums.RiceOperationType;
- import com.izouma.nineth.exception.BusinessException;
- import com.izouma.nineth.repo.RiceOperationRecordRepo;
- import com.izouma.nineth.repo.RiceRepo;
- import com.izouma.nineth.repo.RiceUserWaterDropRecordRepo;
- import com.izouma.nineth.repo.UserRepo;
- import com.izouma.nineth.utils.JpaUtils;
- import com.izouma.nineth.utils.SecurityUtils;
- import lombok.AllArgsConstructor;
- import org.apache.commons.lang.StringUtils;
- import org.apache.commons.lang.time.DateUtils;
- import org.springframework.beans.BeanUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.domain.Page;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestParam;
- import javax.json.Json;
- import javax.json.JsonArray;
- import javax.json.JsonObject;
- import javax.json.JsonReader;
- import java.io.StringReader;
- import java.time.LocalDateTime;
- import java.util.*;
- @Service
- @AllArgsConstructor
- public class RiceService {
- private static final int MAX_NICKNAME_LENGTH = 6;
- private static final String UPDATE_SUCCESS_MSG = "修改成功";
- private RiceRepo riceRepo;
- private RiceUserWaterDropRecordRepo riceUserWaterDropRecordRepo;
- private RiceOperationRecordRepo riceOperationRecordRepo;
- private UserRepo userRepo;
- private SysConfigService sysConfigService;
- public Page<Rice> all(PageQuery pageQuery) {
- return riceRepo.findAll(JpaUtils.toSpecification(pageQuery, Rice.class), JpaUtils.toPageRequest(pageQuery));
- }
- //点击水稻游戏,进行初始化
- public Rice getCurrentRiceUser(User authenticatedUser) throws BusinessException {
- Long id = authenticatedUser.getId();
- Optional<User> byId = userRepo.findByIdAndDelFalse(id);
- String nickname = null;
- String avatar = null;
- if (byId.isPresent()) {
- User user = byId.get();
- nickname = user.getNickname();
- avatar = user.getAvatar();
- } else {
- throw new BusinessException("用户不存在");
- }
- Optional<Rice> byUserId = riceRepo.findByUserId(id);
- if (byUserId.isPresent()) {
- Rice rice = byUserId.get();
- return rice;
- } else {
- Rice rice = new Rice();
- rice.setUserId(id);
- rice.setAvatar(avatar);
- rice.setNickname(nickname);
- rice.setLevel(0L);
- rice.setWaterDropCount(0L);
- rice.setSignCount(0L);
- rice.setSelfScore(0L);
- rice.setSelfActivityScore(0L);
- rice.setEmpiricalValue(0L);
- riceRepo.save(rice);
- return rice;
- }
- }
- //修改昵称
- public R updateNickName(Long userId, String nickname) {
- String trimmedNickname = StringUtils.trim(nickname);
- if (trimmedNickname.length() > MAX_NICKNAME_LENGTH) {
- return R.error("昵称不能超过" + MAX_NICKNAME_LENGTH + "个字符");
- }
- riceRepo.updateNickName(userId, trimmedNickname);
- return R.success(UPDATE_SUCCESS_MSG);
- }
- /**
- * 获取当前等级
- *
- * @param empiricalValue
- * @return
- */
- public Map<String, Object> getCurrentLevel(Long empiricalValue) {
- String jsonString = sysConfigService.getString("rice_level");
- User authenticatedUser = SecurityUtils.getAuthenticatedUser();
- Long authId = authenticatedUser.getId();
- Optional<Rice> byUserId = riceRepo.findByUserId(authId);
- if (byUserId.isPresent()) {
- Rice rice = byUserId.get();
- empiricalValue = rice.getEmpiricalValue();
- JsonReader jsonReader = Json.createReader(new StringReader(jsonString));
- JsonArray jsonArray = jsonReader.readArray();
- Long currentLevel = null;
- Long currentStart = null;
- Long nextStart = null;
- for (int i = 0; i < jsonArray.size(); i++) {
- JsonObject jsonObject = jsonArray.getJsonObject(i);
- Long start = Long.valueOf(jsonObject.getInt("start"));
- if (empiricalValue >= start && empiricalValue < (i<jsonArray.size()-1?Long.valueOf(jsonArray.getJsonObject(i+1).getInt("start")):Long.MAX_VALUE)) {
- String currentLevelStr = jsonObject.getString("name").replace("Lv", "");
- currentLevel = Long.parseLong(currentLevelStr);
- currentStart = Long.valueOf(jsonObject.getInt("start"));
- if (i < jsonArray.size() - 1) {
- JsonObject nextObject = jsonArray.getJsonObject(i + 1);
- nextStart = nextObject.getJsonNumber("start").longValue();
- }
- break;
- }
- }
- if (currentLevel != null && currentStart != null) {
- Map<String, Object> result = new HashMap<>();
- result.put("currentLevel", currentLevel);
- double levelUpPercentage;
- if (nextStart != null) {
- levelUpPercentage = (double)(empiricalValue - currentStart) / (nextStart - currentStart);
- } else {
- levelUpPercentage = 1.0;
- }
- result.put("levelUpPercentage", levelUpPercentage);
- return result;
- } else {
- throw new BusinessException("没有配置对应的等级对应经验值");
- }
- } else {
- throw new BusinessException("用户不存在");
- }
- }
- /**
- * 任务初始化.显示各个任务能否点击
- *
- * @return R<?>
- */
- public R<?> taskInitialization() {
- User authenticatedUser = SecurityUtils.getAuthenticatedUser();
- Long authId = authenticatedUser.getId();
- Optional<Rice> byUserId = riceRepo.findByUserId(authId);
- if (byUserId.isPresent()) {
- Rice rice = byUserId.get();
- Long lastSignInTime = rice.getLastSignInTime();
- Long currentTime = System.currentTimeMillis();
- // 判断上次签到时间是否为空,如果为空,则默认为从未签到过
- if (lastSignInTime == null) {
- return R.success("未签到").add("isSignedIn", false).add("exchangeCount", rice.getExchangeCount() == null ? 0 : rice.getExchangeCount()).add("waterDropCount", rice.getWaterDropCount());
- }
- // 判断今天是否已经签到过
- if (DateUtils.isSameDay(new Date(lastSignInTime), new Date(currentTime))) {
- return R.success("已签到").add("isSignedIn", true).add("exchangeCount", rice.getExchangeCount() == null ? 0 : rice.getExchangeCount()).add("waterDropCount", rice.getWaterDropCount());
- } else {
- return R.success("未签到").add("isSignedIn", false).add("exchangeCount", rice.getExchangeCount() == null ? 0 : rice.getExchangeCount()).add("waterDropCount", rice.getWaterDropCount());
- }
- }
- return R.error("查询失败");
- }
- /**
- * 获取当前用户积分
- */
- public R<String> getCurrentScore() {
- User authenticatedUser = SecurityUtils.getAuthenticatedUser();
- Long authId = authenticatedUser.getId();
- Optional<Rice> byUserId = riceRepo.findByUserId(authId);
- if (byUserId.isPresent()) {
- Rice rice = byUserId.get();
- Long selfScore = rice.getSelfScore();
- return R.success("获取到当前用户积分").add("selfScore", selfScore);
- }
- return R.error("获取失败");
- }
- //在RiceService中添加一个方法用于更新所有用户的排名。
- public void updateScoreRank() {
- List<Rice> allRices = riceRepo.findAll();
- allRices.sort(Comparator.comparing(Rice::getSelfScore).reversed());
- for (int i = 0; i < allRices.size(); i++) {
- Rice rice = allRices.get(i);
- // rice.setScoreRank(i + 1);
- riceRepo.save(rice);
- }
- }
- public List<RiceDTO> getTop100(Long userId) {
- List<Rice> top100Rices = riceRepo.findTop100OrderByEmpiricalValueDesc();
- List<RiceDTO> result = new ArrayList<>();
- // 计算自己的排名
- int selfRank = 0;
- for (int i = 0; i < top100Rices.size(); i++) {
- if (top100Rices.get(i).getId().equals(userId)) {
- selfRank = i + 1;
- break;
- }
- }
- for (int i = 0; i < top100Rices.size(); i++) {
- Rice rice = top100Rices.get(i);
- RiceDTO riceDTO = new RiceDTO();
- BeanUtils.copyProperties(rice, riceDTO);
- riceDTO.setScoreRank(i + 1);
- // 判断是否上榜
- if (i < 100) {
- riceDTO.setOnTop100(true);
- } else {
- riceDTO.setOnTop100(false);
- }
- // 如果是自己,则设置自己的头像、昵称、等级和离上榜还差多少名
- if (rice.getId().equals(userId)) {
- riceDTO.setAvatar(rice.getAvatar());
- riceDTO.setNickname(rice.getNickname());
- riceDTO.setLevel(rice.getLevel());
- if (i < 100) {
- riceDTO.setRankGap(0);
- } else {
- riceDTO.setRankGap(i + 1 - 100);
- }
- }
- result.add(riceDTO);
- }
- return result;
- }
- //计算自己排名
- public R<RiceDTO> getRiceUserRank(Long userId) {
- Optional<Rice> rice1 = riceRepo.findByUserId(userId);
- if (!rice1.isPresent()) {
- return R.error("用户不存在");
- }
- List<Rice> top100Rices = riceRepo.findByOrderBySelfScoreDesc();
- List<RiceDTO> result = new ArrayList<>();
- RiceDTO dto = new RiceDTO();
- // 计算自己的排名
- int selfRank = 0;
- for (int i = 0; i < top100Rices.size(); i++) {
- if (top100Rices.get(i).getUserId().equals(userId)) {
- selfRank = i + 1;
- break;
- }
- }
- for (int i = 0; i < top100Rices.size(); i++) {
- Rice rice = top100Rices.get(i);
- RiceDTO riceDTO = new RiceDTO();
- BeanUtils.copyProperties(rice, riceDTO);
- riceDTO.setScoreRank(i + 1);
- // 判断是否上榜
- if (i < 100) {
- riceDTO.setOnTop100(true);
- } else {
- riceDTO.setOnTop100(false);
- }
- // 如果是自己,则设置自己的头像、昵称、等级和离上榜还差多少名
- if (rice.getUserId().equals(userId)) {
- riceDTO.setAvatar(rice.getAvatar());
- riceDTO.setNickname(rice.getNickname());
- riceDTO.setLevel(rice.getLevel());
- if (i < 100) {
- riceDTO.setRankGap(0);
- } else {
- riceDTO.setRankGap(i + 1 - 100);
- }
- BeanUtils.copyProperties(riceDTO, dto);
- }
- }
- if (dto == null) {
- return R.error("用户不存在");
- }
- return R.success(dto);
- }
- //浇水
- public R<? extends Object> watering() {
- // 获取当前用户 ID,
- User authenticatedUser = SecurityUtils.getAuthenticatedUser();
- Long authId = authenticatedUser.getId();
- Optional<Rice> byUserId = riceRepo.findByUserId(authId);
- if (byUserId.isPresent()) {
- Rice rice = byUserId.get();
- Long waterDropCount = rice.getWaterDropCount();
- Long beforeWaterDropCount = rice.getWaterDropCount();
- Long beforeEmpiricalValue = rice.getEmpiricalValue();
- // 如果水滴次数为 0,返回不能浇水的提示
- if (waterDropCount == 0) {
- return R.error("水滴次数已用完,无法浇水").add("can", false);
- }
- // 浇水成功,更新水滴次数,经验值加2
- rice.setWaterDropCount(waterDropCount - 1);
- rice.setEmpiricalValue(rice.getEmpiricalValue()+2);
- riceRepo.save(rice);
- createRiceOperationRecord(authId, RiceOperationType.WATER_DROP, 1L,beforeWaterDropCount , rice.getWaterDropCount());
- createRiceOperationRecord(authId, RiceOperationType.EMPIRICAL_VALUE, 2L,beforeEmpiricalValue , rice.getEmpiricalValue());
- // Save watering record
- RiceUserWaterDropRecord record = new RiceUserWaterDropRecord();
- record.setUserId(authId);
- record.setWateringTime(LocalDateTime.now());
- riceUserWaterDropRecordRepo.save(record);
- return R.success("浇水成功").add("can", true).add("time", waterDropCount - 1);
- }
- return R.error("浇水失败").add("can", false);
- }
- //根据用户ID和今日时间获取今日浇水次数的方法
- public Long getTodayWateringCount(Long userId) {
- List<RiceUserWaterDropRecord> records = riceUserWaterDropRecordRepo.findByUserId(userId);
- Long count = records.stream()
- .filter(RiceUserWaterDropRecord::isToday)
- .count();
- return count;
- }
- /**
- * 每浇水一次可获得2经验值,升级所需经验值为下一等级所配置的经验值标准。按照以下方式来计算用户升级所需水滴数
- * @param rice
- * @return
- */
- public Long getWaterDropNeededForLevelUp(Rice rice) {
- Long currentEmpiricalValue = rice.getEmpiricalValue();
- String jsonString = sysConfigService.getString("rice_level");
- JsonReader jsonReader = Json.createReader(new StringReader(jsonString));
- JsonArray jsonArray = jsonReader.readArray();
- for (int i = 0; i < jsonArray.size(); i++) {
- JsonObject jsonObject = jsonArray.getJsonObject(i);
- Long start = Long.valueOf(jsonObject.getInt("start"));
- Long nextStart = 0L;
- if (i + 1 < jsonArray.size()) {
- JsonObject nextJsonObject = jsonArray.getJsonObject(i + 1);
- nextStart = Long.valueOf(nextJsonObject.getInt("start"));
- }
- if (currentEmpiricalValue >= start && currentEmpiricalValue < nextStart) {
- Long levelUpEmpiricalValue = nextStart - currentEmpiricalValue;
- Long waterDropNeededForLevelUp = levelUpEmpiricalValue / 2;
- return waterDropNeededForLevelUp;
- }
- }
- throw new BusinessException("没有配置对应的等级对应经验值");
- }
- //签到
- public R<?> signIn(Long userId) {
- Optional<Rice> byUserId = riceRepo.findByUserId(userId);
- if (byUserId.isPresent()) {
- Rice rice = byUserId.get();
- Long lastSignInTime = rice.getLastSignInTime();
- Long currentTime = System.currentTimeMillis();
- Long beforeWaterDropCount = rice.getWaterDropCount();
- Long beforeEmpiricalValue = rice.getEmpiricalValue();
- // 判断上次签到时间是否为空,如果为空,则默认为从未签到过
- if (lastSignInTime == null) {
- rice.setWaterDropCount(rice.getWaterDropCount() + 1);
- rice.setSignCount(rice.getSignCount() + 1);
- rice.setLastSignInTime(currentTime);
- riceRepo.save(rice);
- createRiceOperationRecord(userId,RiceOperationType.WATER_DROP, (long) 1,beforeWaterDropCount,rice.getWaterDropCount());
- return R.success("签到成功").add("can",true).add("waterDropCount",rice.getWaterDropCount());
- }
- // 判断今天是否已经签到过
- if (DateUtils.isSameDay(new Date(lastSignInTime), new Date(currentTime))) {
- return R.error("今天已经签到过了").add("can",false);
- }
- // 签到成功,水滴数加1,签到次数加1,更新签到时间
- rice.setWaterDropCount(rice.getWaterDropCount() + 1);
- rice.setSignCount(rice.getSignCount() + 1);
- rice.setLastSignInTime(currentTime);
- riceRepo.save(rice);
- createRiceOperationRecord(userId,RiceOperationType.WATER_DROP, (long) 1,beforeWaterDropCount,rice.getWaterDropCount());
- return R.success("签到成功").add("can",true).add("waterDropCount",rice.getWaterDropCount());
- }
- return R.error("签到失败").add("can",false);
- }
- @Transactional
- public R<?> exchangeScoreForWaterDrop(User authenticatedUser) {
- Long authId = authenticatedUser.getId();
- Optional<Rice> byUserId = riceRepo.findByUserId(authId);
- if (byUserId.isPresent()) {
- Rice rice = byUserId.get();
- Long selfScore = rice.getSelfScore();
- Long beforeSelfScore = rice.getSelfScore();
- Integer waterDropCount = Math.toIntExact(rice.getWaterDropCount());
- Long beforeWaterDropCount = rice.getWaterDropCount();
- // 每次兑换需要消耗的积分和最大兑换次数
- int exchangeScore = 2;
- int maxExchangeCount = 10;
- // 计算当前可兑换的次数和消耗的积分
- if(rice.getExchangeCount()==null){
- rice.setExchangeCount(0);
- }
- int exchangeCount = Math.min((int) (selfScore / exchangeScore), maxExchangeCount-rice.getExchangeCount());
- int totalScore = exchangeCount * exchangeScore;
- if (exchangeCount > 0) {
- rice.setSelfScore(selfScore - totalScore);
- rice.setWaterDropCount((long) (waterDropCount + exchangeCount));
- riceRepo.save(rice);
- createRiceOperationRecord(authId,RiceOperationType.WATER_DROP, (long) exchangeCount,beforeWaterDropCount,rice.getWaterDropCount());
- return R.success("兑换成功").add("exchangeCount", exchangeCount).add("waterDropCount", rice.getWaterDropCount());
- } else if(exchangeCount==0){
- return R.error("今天已经兑换满10滴水滴了");
- }
- else {
- return R.error("兑换失败,当前积分不足").add("exchangeCount", 0).add("waterDropCount", rice.getWaterDropCount());
- }
- }
- return R.error("兑换失败,用户不存在");
- }
- private void createRiceOperationRecord(Long userId, RiceOperationType type, Long amount, Long beforeAmount, Long afterAmount) {
- RiceOperationRecord record = new RiceOperationRecord();
- record.setUserId(userId);
- record.setType(type);
- record.setAmount(amount);
- record.setBeforeAmount(beforeAmount);
- record.setAfterAmount(afterAmount);
- riceOperationRecordRepo.save(record);
- }
- //活动积分兑换水滴,无上限.
- public R<?> exchangeActivityScoreForWaterDrop(User authenticatedUser) {
- // 检查用户活动积分是否足够
- Optional<Rice> optionalRice = riceRepo.findById(authenticatedUser.getId());
- if (!optionalRice.isPresent()) {
- return R.error("未找到用户信息");
- }
- Rice rice = optionalRice.get();
- Long currentActivityPoints = rice.getSelfActivityScore();
- Long beforeWaterDropCount = rice.getWaterDropCount();
- // 计算兑换的水滴数量
- Long exchangedWaterDropCount = (long) Math.floor(currentActivityPoints / 2.0);
- if (exchangedWaterDropCount <= 0) {
- return R.error("活动积分不足以兑换水滴").add("times",exchangedWaterDropCount);
- }
- // 更新用户活动积分和水滴数
- rice.setSelfActivityScore(currentActivityPoints - (Long) exchangedWaterDropCount*2);
- rice.setWaterDropCount(rice.getWaterDropCount() + exchangedWaterDropCount);
- riceRepo.save(rice);
- // 记录水滴操作记录
- createRiceOperationRecord(authenticatedUser.getId(), RiceOperationType.WATER_DROP, exchangedWaterDropCount, beforeWaterDropCount, rice.getWaterDropCount());
- createRiceOperationRecord(authenticatedUser.getId(), RiceOperationType.SELF_ACTIVITY_SCORE, (Long) exchangedWaterDropCount*2, currentActivityPoints, rice.getSelfActivityScore());
- return R.success("兑换成功").add("times", exchangedWaterDropCount);
- }
- }
|