✨ 答题奖励规则
This commit is contained in:
parent
b4f9074338
commit
b7437b01a1
@ -3,6 +3,9 @@ package com.rymcu.forest;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* @author ronger
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class ForestApplication {
|
||||
|
||||
|
@ -3,8 +3,10 @@ package com.rymcu.forest.answer;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.rymcu.forest.core.result.GlobalResult;
|
||||
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.entity.User;
|
||||
import com.rymcu.forest.enumerate.TransactionEnum;
|
||||
import com.rymcu.forest.util.HttpUtils;
|
||||
import com.rymcu.forest.util.UserUtils;
|
||||
import com.rymcu.forest.web.api.exception.BaseApiException;
|
||||
@ -30,6 +32,7 @@ public class AnswerController {
|
||||
}
|
||||
|
||||
@PostMapping("/answer")
|
||||
@TransactionLogger(transactionType = TransactionEnum.Answer)
|
||||
public GlobalResult answer(@RequestBody AnswerDTO answerDTO) throws BaseApiException {
|
||||
User user = UserUtils.getCurrentUserByToken();
|
||||
Map params = new HashMap<>(3);
|
||||
|
@ -7,7 +7,6 @@ import org.apache.ibatis.exceptions.TooManyResultsException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import tk.mybatis.mapper.entity.Condition;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.List;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -7,17 +7,20 @@ import java.util.Arrays;
|
||||
*/
|
||||
|
||||
public enum TransactionEnum {
|
||||
ArticleSponsor("0", 20),
|
||||
Answer("1", 30),
|
||||
CorrectAnswer("2", 50);
|
||||
ArticleSponsor("0", 20, "文章赞赏"),
|
||||
Answer("1", 30, "答题奖励"),
|
||||
CorrectAnswer("2", 50, "答题奖励");
|
||||
|
||||
private String dataType;
|
||||
|
||||
private Integer money;
|
||||
|
||||
TransactionEnum(String dataType, Integer money) {
|
||||
private String description;
|
||||
|
||||
TransactionEnum(String dataType, Integer money, String description) {
|
||||
this.dataType = dataType;
|
||||
this.money = money;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public static TransactionEnum findTransactionEnum(String dataType) {
|
||||
@ -32,6 +35,10 @@ public enum TransactionEnum {
|
||||
return this.money;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public boolean isArticleSponsor() {
|
||||
return ArticleSponsor.equals(this);
|
||||
}
|
||||
|
@ -27,4 +27,12 @@ public interface TransactionRecordMapper extends Mapper<TransactionRecord> {
|
||||
* @return
|
||||
*/
|
||||
List<TransactionRecordDTO> selectTransactionRecords(@Param("bankAccount") String bankAccount);
|
||||
|
||||
/**
|
||||
* 校验今日是否已发放答题奖励
|
||||
* @param bankAccount
|
||||
* @param funds
|
||||
* @return
|
||||
*/
|
||||
Boolean existsWithBankAccountAndFunds(@Param("bankAccount") String bankAccount, @Param("funds") String funds);
|
||||
}
|
||||
|
@ -32,4 +32,10 @@ public interface BankAccountService extends Service<BankAccount> {
|
||||
* @return
|
||||
*/
|
||||
BankAccount findByBankAccount(String bankAccount);
|
||||
|
||||
/**
|
||||
* 查询系统社区银行
|
||||
* @return
|
||||
*/
|
||||
BankAccount findSystemBankAccount();
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.rymcu.forest.service;
|
||||
import com.rymcu.forest.core.service.Service;
|
||||
import com.rymcu.forest.dto.TransactionRecordDTO;
|
||||
import com.rymcu.forest.entity.TransactionRecord;
|
||||
import com.rymcu.forest.enumerate.TransactionEnum;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
@ -30,9 +31,18 @@ public interface TransactionRecordService extends Service<TransactionRecord> {
|
||||
* 根据用户主键进行交易
|
||||
* @param toUserId
|
||||
* @param formUserId
|
||||
* @param money
|
||||
* @param transactionType
|
||||
* @return
|
||||
* @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;
|
||||
}
|
||||
|
@ -67,6 +67,15 @@ public class BankAccountServiceImpl extends AbstractService<BankAccount> impleme
|
||||
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() {
|
||||
String bankAccount = "600000001";
|
||||
String maxBankAccount = bankAccountMapper.selectMaxBankAccount();
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.rymcu.forest.service.impl;
|
||||
|
||||
|
||||
import com.rymcu.forest.core.exception.TransactionException;
|
||||
import com.rymcu.forest.core.service.AbstractService;
|
||||
import com.rymcu.forest.dto.ArticleDTO;
|
||||
@ -51,7 +52,7 @@ public class SponsorServiceImpl extends AbstractService<Sponsor> implements Spon
|
||||
// 赞赏金额划转
|
||||
if (result.isArticleSponsor()) {
|
||||
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())) {
|
||||
throw new TransactionException(TransactionCode.InsufficientBalance);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
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.service.AbstractService;
|
||||
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.TransactionRecord;
|
||||
import com.rymcu.forest.enumerate.TransactionCode;
|
||||
import com.rymcu.forest.enumerate.TransactionEnum;
|
||||
import com.rymcu.forest.mapper.TransactionRecordMapper;
|
||||
import com.rymcu.forest.service.BankAccountService;
|
||||
import com.rymcu.forest.service.TransactionRecordService;
|
||||
@ -60,17 +60,42 @@ public class TransactionRecordServiceImpl extends AbstractService<TransactionRec
|
||||
}
|
||||
|
||||
@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 formBankAccount = bankAccountService.findBankAccountByIdUser(formUserId);
|
||||
TransactionRecord transactionRecord = new TransactionRecord();
|
||||
transactionRecord.setToBankAccount(toBankAccount.getBankAccount());
|
||||
transactionRecord.setFormBankAccount(formBankAccount.getBankAccount());
|
||||
transactionRecord.setMoney(money);
|
||||
transactionRecord.setFunds("赞赏");
|
||||
transactionRecord.setMoney(new BigDecimal(transactionType.getMoney()));
|
||||
transactionRecord.setFunds(transactionType.getDescription());
|
||||
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() {
|
||||
String orderNo = "E";
|
||||
String key = "orderId";
|
||||
|
@ -18,4 +18,8 @@
|
||||
<select id="selectTransactionRecords" resultMap="DTOResultMap">
|
||||
select * from forest_transaction_record where form_bank_account = #{bankAccount} or to_bank_account = #{bankAccount}
|
||||
</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>
|
Loading…
Reference in New Issue
Block a user