按照PK记录为PK双方添加积分
This commit is contained in:
BIN
.idea/.cache/.Apifox_Helper/.toolWindow.db
generated
BIN
.idea/.cache/.Apifox_Helper/.toolWindow.db
generated
Binary file not shown.
5
.idea/ApifoxUploaderProjectSetting.xml
generated
5
.idea/ApifoxUploaderProjectSetting.xml
generated
File diff suppressed because one or more lines are too long
@@ -1,5 +1,6 @@
|
|||||||
package vvpkassistant.config;
|
package vvpkassistant.config;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import vvpkassistant.FunctionConfig.mapper.FunctionConfigMapper;
|
import vvpkassistant.FunctionConfig.mapper.FunctionConfigMapper;
|
||||||
@@ -11,9 +12,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
public class FunctionConfigHolder {
|
public class FunctionConfigHolder {
|
||||||
// 线程安全的全局配置容器
|
// 线程安全的全局配置容器
|
||||||
public static final List<FunctionConfigModel> CONFIGS = new CopyOnWriteArrayList<>();
|
public static List<FunctionConfigModel> CONFIGS = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private FunctionConfigMapper configMapper;
|
private FunctionConfigMapper configMapper;
|
||||||
@@ -26,7 +28,7 @@ public class FunctionConfigHolder {
|
|||||||
List<FunctionConfigModel> dbConfigs = configMapper.selectList(null);
|
List<FunctionConfigModel> dbConfigs = configMapper.selectList(null);
|
||||||
CONFIGS.clear();
|
CONFIGS.clear();
|
||||||
CONFIGS.addAll(dbConfigs);
|
CONFIGS.addAll(dbConfigs);
|
||||||
System.out.println("已加载 "+CONFIGS.size()+" 条功能配置");
|
log.info("已加载 {} 条功能配置", CONFIGS.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ public class SaTokenConfigure implements WebMvcConfigurer {
|
|||||||
"/systemMessage/list",
|
"/systemMessage/list",
|
||||||
"/pk/pkListForPython",
|
"/pk/pkListForPython",
|
||||||
"/pk/insertPkDetail",
|
"/pk/insertPkDetail",
|
||||||
"/pk/updatePkRecordInfo"
|
"/pk/updatePkRecordInfo",
|
||||||
|
"/pk/grantPkResultPoints"
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
package vvpkassistant.controller;
|
package vvpkassistant.controller;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import vvpkassistant.CoinRecords.CoinRecordsDao;
|
|
||||||
import vvpkassistant.Data.ResponseData;
|
import vvpkassistant.Data.ResponseData;
|
||||||
import vvpkassistant.Data.ResponseInfo;
|
import vvpkassistant.Data.ResponseInfo;
|
||||||
import vvpkassistant.Tools.VVTools;
|
import vvpkassistant.Tools.VVTools;
|
||||||
import vvpkassistant.User.mapper.UserDao;
|
|
||||||
import vvpkassistant.pk.mapper.PkInfoDao;
|
import vvpkassistant.pk.mapper.PkInfoDao;
|
||||||
import vvpkassistant.pk.mapper.PkRecordDao;
|
import vvpkassistant.pk.mapper.PkRecordDao;
|
||||||
import vvpkassistant.pk.mapper.PkRecordDetailDao;
|
import vvpkassistant.pk.mapper.PkRecordDetailDao;
|
||||||
@@ -15,10 +13,12 @@ import vvpkassistant.pk.model.DTO.PkInfoDetailDTO;
|
|||||||
import vvpkassistant.pk.model.DTO.PkListRequestDTO;
|
import vvpkassistant.pk.model.DTO.PkListRequestDTO;
|
||||||
import vvpkassistant.pk.model.DTO.PkListUninvitedDTO;
|
import vvpkassistant.pk.model.DTO.PkListUninvitedDTO;
|
||||||
import vvpkassistant.pk.model.DTO.PkQueryMyCanUseDTO;
|
import vvpkassistant.pk.model.DTO.PkQueryMyCanUseDTO;
|
||||||
|
import vvpkassistant.pk.model.DTO.PkResultPointsDTO;
|
||||||
import vvpkassistant.pk.model.PkInfoModel;
|
import vvpkassistant.pk.model.PkInfoModel;
|
||||||
import vvpkassistant.pk.model.PkRecord;
|
import vvpkassistant.pk.model.PkRecord;
|
||||||
import vvpkassistant.pk.model.PkRecordDetail;
|
import vvpkassistant.pk.model.PkRecordDetail;
|
||||||
import vvpkassistant.pk.service.PKService;
|
import vvpkassistant.pk.service.PKService;
|
||||||
|
import vvpkassistant.pk.service.PkResultPointService;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -32,6 +32,9 @@ public class PkController {
|
|||||||
@Resource
|
@Resource
|
||||||
private PKService pkService;
|
private PKService pkService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PkResultPointService pkResultPointService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private PkInfoDao pkDao;
|
private PkInfoDao pkDao;
|
||||||
|
|
||||||
@@ -41,12 +44,6 @@ public class PkController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private PkRecordDetailDao detailDao;
|
private PkRecordDetailDao detailDao;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserDao userDao;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private CoinRecordsDao coinRecordsDao;
|
|
||||||
|
|
||||||
// 创建pk数据
|
// 创建pk数据
|
||||||
@PostMapping("addPkData")
|
@PostMapping("addPkData")
|
||||||
public ResponseData<PkInfoModel> addPkData(@RequestBody PkInfoModel pkModel) {
|
public ResponseData<PkInfoModel> addPkData(@RequestBody PkInfoModel pkModel) {
|
||||||
@@ -155,6 +152,12 @@ public class PkController {
|
|||||||
return i == 1 ? ResponseData.success("") : ResponseData.error(ResponseInfo.ERROR.getCode(),null);
|
return i == 1 ? ResponseData.success("") : ResponseData.error(ResponseInfo.ERROR.getCode(),null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 根据PK结果为用户增加积分
|
||||||
|
@PostMapping("grantPkResultPoints")
|
||||||
|
public ResponseData<Object> grantPkResultPoints(@RequestBody PkResultPointsDTO request) {
|
||||||
|
return ResponseData.success(pkResultPointService.grantPkResultPoints(request));
|
||||||
|
}
|
||||||
|
|
||||||
// 插入pk明细表数据
|
// 插入pk明细表数据
|
||||||
@PostMapping("insertPkDetail")
|
@PostMapping("insertPkDetail")
|
||||||
public ResponseData<Object> insert(@RequestBody PkRecordDetail detail) {
|
public ResponseData<Object> insert(@RequestBody PkRecordDetail detail) {
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package vvpkassistant.pk.model.DTO;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PkResultPointsDTO {
|
||||||
|
private Integer winnerUserId;
|
||||||
|
private Integer loserUserId;
|
||||||
|
}
|
||||||
@@ -4,8 +4,6 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import vvpkassistant.CoinRecords.CoinRecords;
|
import vvpkassistant.CoinRecords.CoinRecords;
|
||||||
import vvpkassistant.CoinRecords.CoinRecordsDao;
|
import vvpkassistant.CoinRecords.CoinRecordsDao;
|
||||||
import vvpkassistant.Data.ResponseData;
|
|
||||||
import vvpkassistant.Data.ResponseInfo;
|
|
||||||
import vvpkassistant.Tools.VVTools;
|
import vvpkassistant.Tools.VVTools;
|
||||||
import vvpkassistant.User.mapper.UserDao;
|
import vvpkassistant.User.mapper.UserDao;
|
||||||
import vvpkassistant.User.model.UserModel;
|
import vvpkassistant.User.model.UserModel;
|
||||||
@@ -242,4 +240,5 @@ public class PKServiceImpl extends ServiceImpl<PkInfoDao, PkInfoModel> implement
|
|||||||
return pkInfoModel;
|
return pkInfoModel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package vvpkassistant.pk.service;
|
||||||
|
|
||||||
|
import vvpkassistant.pk.model.DTO.PkResultPointsDTO;
|
||||||
|
|
||||||
|
public interface PkResultPointService {
|
||||||
|
String grantPkResultPoints(PkResultPointsDTO request);
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package vvpkassistant.pk.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import vvpkassistant.CoinRecords.CoinRecords;
|
||||||
|
import vvpkassistant.CoinRecords.CoinRecordsDao;
|
||||||
|
import vvpkassistant.Tools.EpochSecondProvider;
|
||||||
|
import vvpkassistant.User.mapper.UserDao;
|
||||||
|
import vvpkassistant.common.ErrorCode;
|
||||||
|
import vvpkassistant.config.FunctionConfigProvider;
|
||||||
|
import vvpkassistant.exception.BusinessException;
|
||||||
|
import vvpkassistant.pk.model.DTO.PkResultPointsDTO;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class PkResultPointServiceImpl implements PkResultPointService {
|
||||||
|
|
||||||
|
private static final String PK_WIN_COIN_CONFIG_NAME = "PK胜利增加积分";
|
||||||
|
private static final String PK_LOSE_COIN_CONFIG_NAME = "PK失败增加积分";
|
||||||
|
private static final int COIN_RECORD_ADD = 1;
|
||||||
|
|
||||||
|
private final UserDao userDao;
|
||||||
|
private final CoinRecordsDao coinRecordsDao;
|
||||||
|
private final FunctionConfigProvider functionConfigProvider;
|
||||||
|
private final EpochSecondProvider epochSecondProvider;
|
||||||
|
|
||||||
|
public PkResultPointServiceImpl(
|
||||||
|
UserDao userDao,
|
||||||
|
CoinRecordsDao coinRecordsDao,
|
||||||
|
FunctionConfigProvider functionConfigProvider,
|
||||||
|
EpochSecondProvider epochSecondProvider
|
||||||
|
) {
|
||||||
|
this.userDao = userDao;
|
||||||
|
this.coinRecordsDao = coinRecordsDao;
|
||||||
|
this.functionConfigProvider = functionConfigProvider;
|
||||||
|
this.epochSecondProvider = epochSecondProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public String grantPkResultPoints(PkResultPointsDTO request) {
|
||||||
|
validateRequest(request);
|
||||||
|
int now = (int) epochSecondProvider.nowEpochSecond();
|
||||||
|
int winPoints = parsePositivePoints(PK_WIN_COIN_CONFIG_NAME);
|
||||||
|
int losePoints = parsePositivePoints(PK_LOSE_COIN_CONFIG_NAME);
|
||||||
|
|
||||||
|
grantPoints(request.getWinnerUserId(), winPoints, PK_WIN_COIN_CONFIG_NAME, now);
|
||||||
|
grantPoints(request.getLoserUserId(), losePoints, PK_LOSE_COIN_CONFIG_NAME, now);
|
||||||
|
return String.format("操作成功,胜利方增加%d积分,失败方增加%d积分", winPoints, losePoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void validateRequest(PkResultPointsDTO request) {
|
||||||
|
if (request == null || request.getWinnerUserId() == null || request.getLoserUserId() == null) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数不能为空");
|
||||||
|
}
|
||||||
|
if (request.getWinnerUserId().equals(request.getLoserUserId())) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "胜利者和失败者不能是同一用户");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int parsePositivePoints(String configName) {
|
||||||
|
String value = functionConfigProvider.getValue(configName);
|
||||||
|
if (value == null) {
|
||||||
|
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "未配置" + configName);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int points = Integer.parseInt(value);
|
||||||
|
if (points <= 0) {
|
||||||
|
throw new BusinessException(ErrorCode.SYSTEM_ERROR, configName + "配置错误");
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new BusinessException(ErrorCode.SYSTEM_ERROR, configName + "配置错误");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void grantPoints(int userId, int points, String configName, int now) {
|
||||||
|
if (userDao.increasePoints(userId, points) != 1) {
|
||||||
|
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "用户不存在");
|
||||||
|
}
|
||||||
|
CoinRecords coinRecords = new CoinRecords(configName, userId, points, now, COIN_RECORD_ADD);
|
||||||
|
if (coinRecordsDao.insert(coinRecords) != 1) {
|
||||||
|
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "积分记录写入失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package vvpkassistant.pk.service;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import vvpkassistant.CoinRecords.CoinRecords;
|
||||||
|
import vvpkassistant.CoinRecords.CoinRecordsDao;
|
||||||
|
import vvpkassistant.Tools.EpochSecondProvider;
|
||||||
|
import vvpkassistant.User.mapper.UserDao;
|
||||||
|
import vvpkassistant.common.ErrorCode;
|
||||||
|
import vvpkassistant.config.FunctionConfigProvider;
|
||||||
|
import vvpkassistant.exception.BusinessException;
|
||||||
|
import vvpkassistant.pk.model.DTO.PkResultPointsDTO;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
class PkResultPointServiceImplTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldGrantWinAndLosePointsTogether() {
|
||||||
|
UserDao userDao = mock(UserDao.class);
|
||||||
|
CoinRecordsDao coinRecordsDao = mock(CoinRecordsDao.class);
|
||||||
|
FunctionConfigProvider functionConfigProvider = mock(FunctionConfigProvider.class);
|
||||||
|
EpochSecondProvider epochSecondProvider = () -> 1_234L;
|
||||||
|
|
||||||
|
when(functionConfigProvider.getValue("PK胜利增加积分")).thenReturn("8");
|
||||||
|
when(functionConfigProvider.getValue("PK失败增加积分")).thenReturn("3");
|
||||||
|
when(userDao.increasePoints(1001, 8)).thenReturn(1);
|
||||||
|
when(userDao.increasePoints(1002, 3)).thenReturn(1);
|
||||||
|
when(coinRecordsDao.insert(any())).thenReturn(1);
|
||||||
|
|
||||||
|
PkResultPointServiceImpl service = new PkResultPointServiceImpl(
|
||||||
|
userDao, coinRecordsDao, functionConfigProvider, epochSecondProvider
|
||||||
|
);
|
||||||
|
PkResultPointsDTO request = new PkResultPointsDTO();
|
||||||
|
request.setWinnerUserId(1001);
|
||||||
|
request.setLoserUserId(1002);
|
||||||
|
|
||||||
|
String result = service.grantPkResultPoints(request);
|
||||||
|
|
||||||
|
Assertions.assertEquals("操作成功,胜利方增加8积分,失败方增加3积分", result);
|
||||||
|
ArgumentCaptor<CoinRecords> captor = ArgumentCaptor.forClass(CoinRecords.class);
|
||||||
|
verify(coinRecordsDao, times(2)).insert(captor.capture());
|
||||||
|
Assertions.assertEquals("PK胜利增加积分", captor.getAllValues().get(0).getInfo());
|
||||||
|
Assertions.assertEquals(Integer.valueOf(1001), captor.getAllValues().get(0).getUserId());
|
||||||
|
Assertions.assertEquals(Integer.valueOf(8), captor.getAllValues().get(0).getNumber());
|
||||||
|
Assertions.assertEquals("PK失败增加积分", captor.getAllValues().get(1).getInfo());
|
||||||
|
Assertions.assertEquals(Integer.valueOf(1002), captor.getAllValues().get(1).getUserId());
|
||||||
|
Assertions.assertEquals(Integer.valueOf(3), captor.getAllValues().get(1).getNumber());
|
||||||
|
Assertions.assertEquals(Integer.valueOf(1234), captor.getAllValues().get(0).getTime());
|
||||||
|
Assertions.assertEquals(Integer.valueOf(1234), captor.getAllValues().get(1).getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldFailWhenWinnerAndLoserAreSameUser() {
|
||||||
|
UserDao userDao = mock(UserDao.class);
|
||||||
|
CoinRecordsDao coinRecordsDao = mock(CoinRecordsDao.class);
|
||||||
|
FunctionConfigProvider functionConfigProvider = mock(FunctionConfigProvider.class);
|
||||||
|
EpochSecondProvider epochSecondProvider = () -> 1_234L;
|
||||||
|
|
||||||
|
PkResultPointServiceImpl service = new PkResultPointServiceImpl(
|
||||||
|
userDao, coinRecordsDao, functionConfigProvider, epochSecondProvider
|
||||||
|
);
|
||||||
|
PkResultPointsDTO request = new PkResultPointsDTO();
|
||||||
|
request.setWinnerUserId(1001);
|
||||||
|
request.setLoserUserId(1001);
|
||||||
|
|
||||||
|
BusinessException ex = Assertions.assertThrows(BusinessException.class,
|
||||||
|
() -> service.grantPkResultPoints(request));
|
||||||
|
|
||||||
|
Assertions.assertEquals(ErrorCode.PARAMS_ERROR.getCode(), ex.getCode());
|
||||||
|
verifyNoInteractions(functionConfigProvider, coinRecordsDao);
|
||||||
|
verify(userDao, never()).increasePoints(anyInt(), anyInt());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user