package com.ks.goldcorn.service.remote;
|
|
import com.ks.goldcorn.exception.GoldAppException;
|
import com.ks.goldcorn.exception.GoldRecordException;
|
import com.ks.goldcorn.exception.GoldTradeException;
|
import com.ks.goldcorn.exception.GoldUserException;
|
import com.ks.goldcorn.manager.RedisManager;
|
import com.ks.goldcorn.mapper.GoldCornAppInfoMapper;
|
import com.ks.goldcorn.mapper.GoldCornBalanceMapper;
|
import com.ks.goldcorn.mapper.GoldCornConsumeSourceMapper;
|
import com.ks.goldcorn.mapper.GoldCornGetSourceMapper;
|
import com.ks.goldcorn.pojo.DO.*;
|
import com.ks.goldcorn.service.GoldCornBalanceManager;
|
import com.ks.goldcorn.service.GoldCornRecordManager;
|
import org.apache.dubbo.config.annotation.Service;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import javax.annotation.Resource;
|
import java.util.concurrent.TimeUnit;
|
|
@Service(version = "1.0")
|
public class GoldCornTradeServiceImpl implements GoldCornTradeService {
|
|
Logger logger = LoggerFactory.getLogger(GoldCornTradeService.class);
|
|
@Resource
|
private GoldCornAppInfoMapper goldCornAppInfoMapper;
|
|
@Resource
|
private GoldCornBalanceMapper goldCornBalanceMapper;
|
|
@Resource
|
private GoldCornConsumeSourceMapper goldCornConsumeSourceMapper;
|
|
@Resource
|
private GoldCornBalanceManager goldCornBalanceManager;
|
|
@Resource
|
private GoldCornGetSourceMapper goldCornGetSourceMapper;
|
|
@Resource
|
private GoldCornRecordManager goldCornRecordManager;
|
|
@Resource
|
private RedisTemplate<String, Object> redisTemplate;
|
|
@Resource
|
private RedisManager redisManager;
|
|
/**
|
* 验证系统与用户
|
*
|
* @param appCode
|
* @param uid
|
* @return
|
* @throws GoldAppException
|
* @throws GoldUserException
|
*/
|
private Long validateAppAndUser(String appCode, String uid) throws GoldAppException, GoldUserException {
|
GoldCornAppInfo appInfo = goldCornAppInfoMapper.selectByAppCode(appCode);
|
if (appInfo == null) {
|
throw new GoldAppException(GoldAppException.CODE_NOT_EXIST, "app is not exist");
|
}
|
|
GoldCornBalance balance = goldCornBalanceMapper.selectByAppIdAndUid(appInfo.getId(), uid);
|
if (balance == null) {
|
throw new GoldUserException(GoldUserException.CODE_NOT_EXIST, "uid is not exist");
|
}
|
|
return appInfo.getId();
|
}
|
|
@Override
|
public long getNextDoTaskTime(String appCode, String uid, String sourceCode) {
|
long time = redisManager.getCanAddCornExpireTime(appCode, uid, sourceCode);
|
if (time <= 0) {
|
return -1;
|
}
|
|
return System.currentTimeMillis() + 1000 * time;
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
@Override
|
public void addGoldCorn(String appCode, String uid, String sourceCode, Integer goldCornCount, String title, String desc) throws GoldAppException, GoldUserException, GoldTradeException {
|
Long appId = validateAppAndUser(appCode, uid);
|
GoldCornGetSource source = goldCornGetSourceMapper.selectByAppIdAndSourceCode(appId, sourceCode);
|
if (source == null) {
|
throw new GoldUserException(GoldTradeException.CODE_NOT_EXIST, "source is not exist");
|
}
|
|
|
String key = appCode + "-" + uid + "-" + sourceCode;
|
if (!redisTemplate.opsForValue().setIfAbsent(key, 1, 60 * 2, TimeUnit.SECONDS)) {
|
throw new GoldTradeException(GoldTradeException.CODE_FREQUENCY_LIMIT, "请求频率过高,请稍后再试");
|
}
|
try {
|
int count = redisManager.getGoldCornAddRecordCount(appCode, uid, sourceCode);
|
if (count >= source.getMaxDayCount()) {
|
throw new GoldTradeException(GoldTradeException.CODE_COUNT_LIMIT, "添加次数超限,请明日再试");
|
}
|
|
if (!redisManager.canAddCornWithTime(appCode, uid, sourceCode)) {
|
throw new GoldTradeException(GoldTradeException.CODE_FREQUENCY_LIMIT, "添加时间间隔过小");
|
}
|
//加记录
|
GoldCornRecord record = new GoldCornRecord();
|
record.setAppId(appId);
|
record.setGoldCorn(goldCornCount == null ? source.getGoldCorn() : goldCornCount);
|
record.setSourceCode(source.getSourceCode());
|
record.setType(GoldCornRecord.TYPE_GET);
|
record.setUid(uid);
|
if (title != null) {
|
record.setTitle(title);
|
} else {
|
record.setTitle(source.getSourceName());
|
}
|
if (desc != null) {
|
record.setDesc(desc);
|
} else {
|
record.setDesc(source.getSourceDesc());
|
}
|
try {
|
goldCornRecordManager.addRecord(record);
|
} catch (GoldRecordException e) {
|
throw new GoldTradeException(GoldTradeException.CODE_ADD_RECORD_FAIL, "添加记录失败");
|
}
|
//加余额
|
goldCornBalanceManager.addMoney(appId, uid, record.getGoldCorn());
|
|
redisManager.addCornSuccess(appCode, uid, sourceCode, source.getMinTimeSpan());
|
} catch (GoldUserException e) {
|
throw e;
|
} catch (GoldTradeException e) {
|
throw e;
|
} catch (Exception e) {
|
logger.error("添加金币未知异常:{}", e);
|
} finally {
|
redisTemplate.delete(key);
|
}
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
@Override
|
public void consumeGoldCorn(String appCode, String uid, String sourceCode, Integer goldCornCount, String title, String desc) throws GoldAppException, GoldUserException, GoldTradeException {
|
Long appId = validateAppAndUser(appCode, uid);
|
GoldCornConsumeSource source = goldCornConsumeSourceMapper.selectByAppIdAndSourceCode(appId, sourceCode);
|
if (source == null) {
|
throw new GoldUserException(GoldTradeException.CODE_NOT_EXIST, "source is not exist");
|
}
|
|
int goldCorn = goldCornCount == null ? source.getGoldCorn() : goldCornCount;
|
|
//减余额
|
goldCornBalanceManager.subMoney(appId, uid, goldCorn);
|
|
//加记录
|
GoldCornRecord record = new GoldCornRecord();
|
record.setAppId(appId);
|
record.setGoldCorn(goldCorn);
|
record.setSourceCode(source.getSourceCode());
|
record.setType(GoldCornRecord.TYPE_CONSUME);
|
record.setUid(uid);
|
if (title != null) {
|
record.setTitle(title);
|
} else {
|
record.setTitle(source.getSourceName());
|
}
|
if (desc != null) {
|
record.setDesc(desc);
|
} else {
|
record.setDesc(source.getSourceDesc());
|
}
|
try {
|
goldCornRecordManager.addRecord(record);
|
} catch (GoldRecordException e) {
|
throw new GoldTradeException(GoldTradeException.CODE_ADD_RECORD_FAIL, "添加记录失败");
|
}
|
}
|
}
|