答题奖励规则

This commit is contained in:
ronger 2021-02-20 16:55:12 +08:00
parent b4f9074338
commit b7437b01a1
13 changed files with 197 additions and 12 deletions

View File

@ -3,6 +3,9 @@ package com.rymcu.forest;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author ronger
*/
@SpringBootApplication @SpringBootApplication
public class ForestApplication { public class ForestApplication {

View File

@ -3,8 +3,10 @@ package com.rymcu.forest.answer;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.rymcu.forest.core.result.GlobalResult; import com.rymcu.forest.core.result.GlobalResult;
import com.rymcu.forest.core.result.GlobalResultGenerator; import com.rymcu.forest.core.result.GlobalResultGenerator;
import com.rymcu.forest.core.service.log.annotation.TransactionLogger;
import com.rymcu.forest.dto.AnswerDTO; import com.rymcu.forest.dto.AnswerDTO;
import com.rymcu.forest.entity.User; import com.rymcu.forest.entity.User;
import com.rymcu.forest.enumerate.TransactionEnum;
import com.rymcu.forest.util.HttpUtils; import com.rymcu.forest.util.HttpUtils;
import com.rymcu.forest.util.UserUtils; import com.rymcu.forest.util.UserUtils;
import com.rymcu.forest.web.api.exception.BaseApiException; import com.rymcu.forest.web.api.exception.BaseApiException;
@ -30,6 +32,7 @@ public class AnswerController {
} }
@PostMapping("/answer") @PostMapping("/answer")
@TransactionLogger(transactionType = TransactionEnum.Answer)
public GlobalResult answer(@RequestBody AnswerDTO answerDTO) throws BaseApiException { public GlobalResult answer(@RequestBody AnswerDTO answerDTO) throws BaseApiException {
User user = UserUtils.getCurrentUserByToken(); User user = UserUtils.getCurrentUserByToken();
Map params = new HashMap<>(3); Map params = new HashMap<>(3);

View File

@ -7,7 +7,6 @@ import org.apache.ibatis.exceptions.TooManyResultsException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Condition; import tk.mybatis.mapper.entity.Condition;
import javax.annotation.Resource;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.util.List; import java.util.List;

View File

@ -0,0 +1,94 @@
package com.rymcu.forest.core.service.log;
import com.rymcu.forest.core.result.GlobalResult;
import com.rymcu.forest.core.service.log.annotation.TransactionLogger;
import com.rymcu.forest.entity.TransactionRecord;
import com.rymcu.forest.entity.User;
import com.rymcu.forest.enumerate.TransactionEnum;
import com.rymcu.forest.service.TransactionRecordService;
import com.rymcu.forest.util.UserUtils;
import com.rymcu.forest.web.api.exception.BaseApiException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Objects;
/**
* @author ronger
*
*/
@Aspect
@Component
public class TransactionAspect {
Logger logger = LoggerFactory.getLogger(TransactionAspect.class);
@Resource
private TransactionRecordService transactionRecordService;
@Pointcut("@annotation(com.rymcu.forest.core.service.log.annotation.TransactionLogger)")
public void pointCut() {}
/**
* 保存交易操作日志
*
* @param joinPoint 连接点
* @return 方法执行结果
* @throws Throwable 调用出错
*/
@AfterReturning(value = "pointCut()", returning="obj")
public void save(JoinPoint joinPoint, Object obj) throws Exception {
logger.info("保存交易记录 start ...");
/**
* 解析Log注解
*/
String methodName = joinPoint.getSignature().getName();
Method method = currentMethod(joinPoint, methodName);
TransactionLogger log = method.getAnnotation(TransactionLogger.class);
if (Objects.nonNull(log)) {
User user = UserUtils.getCurrentUserByToken();
GlobalResult globalResult = (GlobalResult) obj;
if (globalResult.isSuccess()) {
if (TransactionEnum.Answer.equals(log.transactionType())) {
if (globalResult.getData().equals(true)) {
transactionRecordService.bankTransfer(user.getIdUser(), TransactionEnum.CorrectAnswer);
} else {
transactionRecordService.bankTransfer(user.getIdUser(), TransactionEnum.Answer);
}
}
}
}
logger.info("保存交易记录 end ...");
}
/**
* 获取当前执行的方法
*
* @param joinPoint 连接点
* @param methodName 方法名称
* @return 方法
*/
private Method currentMethod(JoinPoint joinPoint, String methodName) {
/**
* 获取目标类的所有方法找到当前要执行的方法
*/
Method[] methods = joinPoint.getTarget().getClass().getMethods();
Method resultMethod = null;
for (Method method : methods) {
if (method.getName().equals(methodName)) {
resultMethod = method;
break;
}
}
return resultMethod;
}
}

View File

@ -0,0 +1,16 @@
package com.rymcu.forest.core.service.log.annotation;
import com.rymcu.forest.enumerate.TransactionEnum;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* @author ronger
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface TransactionLogger {
TransactionEnum transactionType();
}

View File

@ -7,17 +7,20 @@ import java.util.Arrays;
*/ */
public enum TransactionEnum { public enum TransactionEnum {
ArticleSponsor("0", 20), ArticleSponsor("0", 20, "文章赞赏"),
Answer("1", 30), Answer("1", 30, "答题奖励"),
CorrectAnswer("2", 50); CorrectAnswer("2", 50, "答题奖励");
private String dataType; private String dataType;
private Integer money; private Integer money;
TransactionEnum(String dataType, Integer money) { private String description;
TransactionEnum(String dataType, Integer money, String description) {
this.dataType = dataType; this.dataType = dataType;
this.money = money; this.money = money;
this.description = description;
} }
public static TransactionEnum findTransactionEnum(String dataType) { public static TransactionEnum findTransactionEnum(String dataType) {
@ -32,6 +35,10 @@ public enum TransactionEnum {
return this.money; return this.money;
} }
public String getDescription() {
return this.description;
}
public boolean isArticleSponsor() { public boolean isArticleSponsor() {
return ArticleSponsor.equals(this); return ArticleSponsor.equals(this);
} }

View File

@ -27,4 +27,12 @@ public interface TransactionRecordMapper extends Mapper<TransactionRecord> {
* @return * @return
*/ */
List<TransactionRecordDTO> selectTransactionRecords(@Param("bankAccount") String bankAccount); List<TransactionRecordDTO> selectTransactionRecords(@Param("bankAccount") String bankAccount);
/**
* 校验今日是否已发放答题奖励
* @param bankAccount
* @param funds
* @return
*/
Boolean existsWithBankAccountAndFunds(@Param("bankAccount") String bankAccount, @Param("funds") String funds);
} }

View File

@ -32,4 +32,10 @@ public interface BankAccountService extends Service<BankAccount> {
* @return * @return
*/ */
BankAccount findByBankAccount(String bankAccount); BankAccount findByBankAccount(String bankAccount);
/**
* 查询系统社区银行
* @return
*/
BankAccount findSystemBankAccount();
} }

View File

@ -3,6 +3,7 @@ package com.rymcu.forest.service;
import com.rymcu.forest.core.service.Service; import com.rymcu.forest.core.service.Service;
import com.rymcu.forest.dto.TransactionRecordDTO; import com.rymcu.forest.dto.TransactionRecordDTO;
import com.rymcu.forest.entity.TransactionRecord; import com.rymcu.forest.entity.TransactionRecord;
import com.rymcu.forest.enumerate.TransactionEnum;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
@ -30,9 +31,18 @@ public interface TransactionRecordService extends Service<TransactionRecord> {
* 根据用户主键进行交易 * 根据用户主键进行交易
* @param toUserId * @param toUserId
* @param formUserId * @param formUserId
* @param money * @param transactionType
* @return * @return
* @throws Exception * @throws Exception
*/ */
TransactionRecord transferByUserId(Integer toUserId, Integer formUserId, BigDecimal money) throws Exception; TransactionRecord userTransfer(Integer toUserId, Integer formUserId, TransactionEnum transactionType) throws Exception;
/**
* 社区银行转账/奖励发放
* @param idUser
* @param transactionType
* @return
* @throws Exception
*/
TransactionRecord bankTransfer(Integer idUser, TransactionEnum transactionType) throws Exception;
} }

View File

@ -67,6 +67,15 @@ public class BankAccountServiceImpl extends AbstractService<BankAccount> impleme
return bankAccountMapper.selectOne(searchBankAccount); return bankAccountMapper.selectOne(searchBankAccount);
} }
@Override
public BankAccount findSystemBankAccount() {
BankAccount bankAccount = new BankAccount();
bankAccount.setIdBank(1);
bankAccount.setAccountType("1");
bankAccount.setAccountOwner(2);
return bankAccountMapper.selectOne(bankAccount);
}
private String nextBankAccount() { private String nextBankAccount() {
String bankAccount = "600000001"; String bankAccount = "600000001";
String maxBankAccount = bankAccountMapper.selectMaxBankAccount(); String maxBankAccount = bankAccountMapper.selectMaxBankAccount();

View File

@ -1,5 +1,6 @@
package com.rymcu.forest.service.impl; package com.rymcu.forest.service.impl;
import com.rymcu.forest.core.exception.TransactionException; import com.rymcu.forest.core.exception.TransactionException;
import com.rymcu.forest.core.service.AbstractService; import com.rymcu.forest.core.service.AbstractService;
import com.rymcu.forest.dto.ArticleDTO; import com.rymcu.forest.dto.ArticleDTO;
@ -51,7 +52,7 @@ public class SponsorServiceImpl extends AbstractService<Sponsor> implements Spon
// 赞赏金额划转 // 赞赏金额划转
if (result.isArticleSponsor()) { if (result.isArticleSponsor()) {
ArticleDTO articleDTO = articleService.findArticleDTOById(sponsor.getDataId(), 1); ArticleDTO articleDTO = articleService.findArticleDTOById(sponsor.getDataId(), 1);
TransactionRecord transactionRecord = transactionRecordService.transferByUserId(articleDTO.getArticleAuthorId(), user.getIdUser(), money); TransactionRecord transactionRecord = transactionRecordService.userTransfer(articleDTO.getArticleAuthorId(), user.getIdUser(), result);
if (Objects.isNull(transactionRecord.getIdTransactionRecord())) { if (Objects.isNull(transactionRecord.getIdTransactionRecord())) {
throw new TransactionException(TransactionCode.InsufficientBalance); throw new TransactionException(TransactionCode.InsufficientBalance);
} }

View File

@ -1,6 +1,5 @@
package com.rymcu.forest.service.impl; package com.rymcu.forest.service.impl;
import com.rymcu.forest.core.exception.ServiceException;
import com.rymcu.forest.core.exception.TransactionException; import com.rymcu.forest.core.exception.TransactionException;
import com.rymcu.forest.core.service.AbstractService; import com.rymcu.forest.core.service.AbstractService;
import com.rymcu.forest.core.service.redis.RedisService; import com.rymcu.forest.core.service.redis.RedisService;
@ -9,6 +8,7 @@ import com.rymcu.forest.dto.TransactionRecordDTO;
import com.rymcu.forest.entity.BankAccount; import com.rymcu.forest.entity.BankAccount;
import com.rymcu.forest.entity.TransactionRecord; import com.rymcu.forest.entity.TransactionRecord;
import com.rymcu.forest.enumerate.TransactionCode; import com.rymcu.forest.enumerate.TransactionCode;
import com.rymcu.forest.enumerate.TransactionEnum;
import com.rymcu.forest.mapper.TransactionRecordMapper; import com.rymcu.forest.mapper.TransactionRecordMapper;
import com.rymcu.forest.service.BankAccountService; import com.rymcu.forest.service.BankAccountService;
import com.rymcu.forest.service.TransactionRecordService; import com.rymcu.forest.service.TransactionRecordService;
@ -60,17 +60,42 @@ public class TransactionRecordServiceImpl extends AbstractService<TransactionRec
} }
@Override @Override
public TransactionRecord transferByUserId(Integer toUserId, Integer formUserId, BigDecimal money) throws Exception { public TransactionRecord userTransfer(Integer toUserId, Integer formUserId, TransactionEnum transactionType) throws Exception {
BankAccountDTO toBankAccount = bankAccountService.findBankAccountByIdUser(toUserId); BankAccountDTO toBankAccount = bankAccountService.findBankAccountByIdUser(toUserId);
BankAccountDTO formBankAccount = bankAccountService.findBankAccountByIdUser(formUserId); BankAccountDTO formBankAccount = bankAccountService.findBankAccountByIdUser(formUserId);
TransactionRecord transactionRecord = new TransactionRecord(); TransactionRecord transactionRecord = new TransactionRecord();
transactionRecord.setToBankAccount(toBankAccount.getBankAccount()); transactionRecord.setToBankAccount(toBankAccount.getBankAccount());
transactionRecord.setFormBankAccount(formBankAccount.getBankAccount()); transactionRecord.setFormBankAccount(formBankAccount.getBankAccount());
transactionRecord.setMoney(money); transactionRecord.setMoney(new BigDecimal(transactionType.getMoney()));
transactionRecord.setFunds("赞赏"); transactionRecord.setFunds(transactionType.getDescription());
return transfer(transactionRecord); return transfer(transactionRecord);
} }
@Override
public TransactionRecord bankTransfer(Integer idUser, TransactionEnum transactionType) throws Exception {
BankAccountDTO toBankAccount = bankAccountService.findBankAccountByIdUser(idUser);
Boolean isTrue;
// 校验货币规则
switch (transactionType) {
case Answer:
case CorrectAnswer:
isTrue = transactionRecordMapper.existsWithBankAccountAndFunds(toBankAccount.getBankAccount(), transactionType.getDescription());
break;
default:
isTrue = true;
}
if (isTrue) {
BankAccount formBankAccount = bankAccountService.findSystemBankAccount();
TransactionRecord transactionRecord = new TransactionRecord();
transactionRecord.setToBankAccount(toBankAccount.getBankAccount());
transactionRecord.setFormBankAccount(formBankAccount.getBankAccount());
transactionRecord.setMoney(new BigDecimal(transactionType.getMoney()));
transactionRecord.setFunds(transactionType.getDescription());
return transfer(transactionRecord);
}
return null;
}
private String nextTransactionNo() { private String nextTransactionNo() {
String orderNo = "E"; String orderNo = "E";
String key = "orderId"; String key = "orderId";

View File

@ -18,4 +18,8 @@
<select id="selectTransactionRecords" resultMap="DTOResultMap"> <select id="selectTransactionRecords" resultMap="DTOResultMap">
select * from forest_transaction_record where form_bank_account = #{bankAccount} or to_bank_account = #{bankAccount} select * from forest_transaction_record where form_bank_account = #{bankAccount} or to_bank_account = #{bankAccount}
</select> </select>
<select id="existsWithBankAccountAndFunds" resultType="java.lang.Boolean">
select ifnull((select false from forest_transaction_record where to_bank_account = #{bankAccount}
and funds = #{funds} and transaction_time > str_to_date(date_format(sysdate(),'%Y-%m-%d'),'%Y-%m-%d') limit 1), true)
</select>
</mapper> </mapper>