package com.taoke.autopay.service.impl;
|
|
import com.google.gson.Gson;
|
import com.taoke.autopay.dao.KeyOrderMapper;
|
import com.taoke.autopay.dao.WxUserSettingsMapper;
|
import com.taoke.autopay.dto.ChannelOrderStatistic;
|
import com.taoke.autopay.dto.DYOrderDto;
|
import com.taoke.autopay.entity.*;
|
import com.taoke.autopay.entity.agent.ChannelAgent;
|
import com.taoke.autopay.entity.agent.ChannelAgentSettings;
|
import com.taoke.autopay.exception.KeyOrderException;
|
import com.taoke.autopay.exception.KeyVerifyException;
|
import com.taoke.autopay.exception.UserCreditException;
|
import com.taoke.autopay.exception.WxOrderCountException;
|
import com.taoke.autopay.factory.OrderFactory;
|
import com.taoke.autopay.manager.UserCreditManager;
|
import com.taoke.autopay.service.*;
|
import com.taoke.autopay.service.agent.ChannelAgentService;
|
import com.taoke.autopay.service.agent.ChannelAgentSettingService;
|
import com.taoke.autopay.service.agent.ChannelAgentSharingRatioService;
|
import com.taoke.autopay.utils.*;
|
import com.taoke.autopay.utils.order.DYOrderApi;
|
import com.taoke.autopay.utils.order.OrderChannelUtil;
|
import com.taoke.autopay.vo.SubmitKeyInfo;
|
import com.taoke.autopay.vo.admin.IgnoreAgentOrderSettingVO;
|
import net.sf.json.JSONArray;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import javax.annotation.Resource;
|
import java.math.BigDecimal;
|
import java.net.URI;
|
import java.util.*;
|
import java.util.regex.Matcher;
|
import java.util.regex.Pattern;
|
|
/**
|
* @author hxh
|
* @title: KeyOrderServiceImpl
|
* @description: TODO
|
* @date 2024/6/14 19:12
|
*/
|
@Service
|
public class KeyOrderServiceImpl implements KeyOrderService {
|
|
private Logger loggerDebug= LoggerFactory.getLogger("debugLogger");
|
|
@Resource
|
private KeyOrderMapper keyOrderMapper;
|
|
@Resource
|
private WxUserSettingService wxUserSettingService;
|
|
@Resource
|
private WxUserOrderCountService wxUserOrderCountService;
|
|
@Resource
|
private SystemConfigService systemConfigService;
|
|
@Resource
|
private ChannelAgentService channelAgentService;
|
|
@Resource
|
private ChannelAgentSharingRatioService channelAgentSharingRatioService;
|
|
@Resource
|
private ChannelAgentSettingService channelAgentSettingService;
|
|
@Resource
|
private ClientInfoService clientInfoService;
|
|
@Resource
|
private PayMoneySettingService payMoneySettingService;
|
|
@Resource
|
private WxUserService wxUserService;
|
|
@Resource
|
private UserCreditManager userCreditManager;
|
|
|
@Override
|
public KeyOrder selectById(String id) {
|
return keyOrderMapper.selectById(id);
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
@Override
|
public KeyOrder selectByIdForUpdate(String id) {
|
return keyOrderMapper.selectByPrimaryKeyForUpdate(id);
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
@Override
|
public KeyOrder addKeyOrder(SubmitKeyInfo keyInfo, Long uid, String day, Integer orderType, DYOrderDto orderDto) throws KeyOrderException, WxOrderCountException {
|
// 判断提交次数是否过量
|
if (uid != null) {
|
WxUserSettings settings = wxUserSettingService.getUserSettings(uid);
|
OrderCountTypeEnum countType = OrderCountTypeEnum.SUBMIT_TOKEN_COUNT;
|
wxUserOrderCountService.addOrderCount(uid, countType, null, day, 1, settings.getTotalOrderCountPerDay());
|
wxUserService.setLatestInfoInfo(uid, keyInfo.getIp(), keyInfo.getIpInfo());
|
}
|
String id = OrderFactory.createId(keyInfo.getKey());
|
KeyOrder order = keyOrderMapper.selectById(id);
|
if (order != null) {
|
throw new KeyOrderException("请勿重复提交口令");
|
}
|
order = new KeyOrder();
|
// 解析referer中的链接
|
if (!StringUtil.isNullOrEmpty(keyInfo.getReferer())) {
|
Map<String, String> paramsMap = HttpUtil.getPramsFromUrl(keyInfo.getReferer());
|
if (paramsMap.containsKey("a")) {
|
String alias = paramsMap.get("a");
|
ChannelAgent agent = channelAgentService.selectByAlias(alias);
|
if (agent == null) {
|
throw new KeyOrderException("渠道不存在");
|
}
|
|
if (agent.getStatus() != ChannelAgent.STATUS_NOMAL) {
|
throw new KeyOrderException("渠道受限");
|
}
|
// 验证渠道时间
|
ChannelAgentSettings settings = channelAgentSettingService.selectByAgentId(agent.getId());
|
if (settings != null && !StringUtil.isNullOrEmpty(settings.getStartSubmitTime()) && !StringUtil.isNullOrEmpty(settings.getEndSubmitTime())) {
|
String now = TimeUtil.getGernalTime(System.currentTimeMillis(), "HHmmss");
|
String startTime = settings.getStartSubmitTime().replace(":", "");
|
String endTime = settings.getEndSubmitTime().replace(":", "");
|
if (Integer.parseInt(now) < Integer.parseInt(startTime) || Integer.parseInt(now) > Integer.parseInt(endTime)) {
|
throw new KeyOrderException(String.format("口令提交时间段为:%s-%s", settings.getStartSubmitTime(), settings.getEndSubmitTime()));
|
}
|
}
|
|
// 获取渠道忽略订单的配置
|
String config = systemConfigService.getValueCache(SystemConfigKeyEnum.IGNORE_AGENT_ORDER_SETTING);
|
if (!StringUtil.isNullOrEmpty(config)) {
|
IgnoreAgentOrderSettingVO ignore = JsonUtil.getSimpleGson().fromJson(config, IgnoreAgentOrderSettingVO.class);
|
if (ignore.getPercent() > 0) {
|
// 获取当前代理今日的订单数量
|
KeyOrderMapper.DaoQuery daoQuery = new KeyOrderMapper.DaoQuery();
|
daoQuery.agentId = agent.getId();
|
daoQuery.minCreateTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyyMMdd"), "yyyyMMdd"));
|
long keyCount = count(daoQuery);
|
if (keyCount > ignore.getBeginCount()) {
|
if ((keyCount - ignore.getBeginCount()) % (100 / ignore.getPercent()) == 0) {
|
order.setIgnore(true);
|
}
|
}
|
}
|
}
|
order.setAgentId(agent.getId());
|
}
|
}
|
|
|
order.setId(id);
|
order.setKey(keyInfo.getKey());
|
if (!StringUtil.isNullOrEmpty(keyInfo.getMoney())) {
|
order.setOrderMoney(new BigDecimal(keyInfo.getMoney()));
|
}
|
order.setUid(uid);
|
order.setState(KeyOrder.STATE_NOT_PROCESS);
|
order.setStateDesc("尚未处理");
|
order.setCreateTime(new Date());
|
if (orderType != Constant.ORDER_TYPE_UNKNOWN) {
|
order.setOrderType(orderType);
|
}
|
if (orderDto != null) {
|
order.setOrderNo(orderDto.getOrder_id());
|
}
|
|
order.setIp(keyInfo.getIp());
|
if (keyInfo.getIpInfo() != null) {
|
order.setIpInfo(new Gson().toJson(keyInfo.getIpInfo()));
|
}
|
keyOrderMapper.insertSelective(order);
|
return order;
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
@Override
|
public void update(KeyOrder keyOrder) {
|
if (keyOrder.getId() == null) {
|
return;
|
}
|
KeyOrder old = keyOrderMapper.selectByPrimaryKeyForUpdate(keyOrder.getId());
|
if (old == null) {
|
return;
|
}
|
if (keyOrder.getUpdateTime() == null) {
|
keyOrder.setUpdateTime(new Date());
|
}
|
keyOrderMapper.updateByPrimaryKeySelective(keyOrder);
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
@Override
|
public void paySuccess(String id, String stateDesc, String day, String payMerchant) throws WxOrderCountException {
|
KeyOrder old = keyOrderMapper.selectByPrimaryKeyForUpdate(id);
|
if (old == null) {
|
return;
|
}
|
if (old.getState() == KeyOrder.STATE_PAY) {
|
return;
|
}
|
if (old.getUid() != null) {
|
Integer orderType = old.getOrderType();
|
wxUserOrderCountService.addOrderCount(old.getUid(), (orderType == null || orderType == Constant.ORDER_TYPE_DY) ? OrderCountTypeEnum.DY_ORDER_PAY : OrderCountTypeEnum.KS_ORDER_PAY, OrderChannelUtil.getChannelByKey(old.getOrderChannel()), day, 1, null);
|
}
|
KeyOrder orderUpdate = new KeyOrder();
|
orderUpdate.setId(id);
|
orderUpdate.setState(KeyOrder.STATE_PAY);
|
orderUpdate.setStateDesc(stateDesc);
|
orderUpdate.setPayMerchant(payMerchant);
|
if (old.getPayTime() == null) {
|
orderUpdate.setPayTime(new Date());
|
}
|
update(orderUpdate);
|
// 增加积分
|
try {
|
boolean creditEnable = true;
|
// 判断代理是否允许增加积分
|
Long agengId = old.getAgentId();
|
if(agengId!=null) {
|
ChannelAgentSettings agentSettings = channelAgentSettingService.selectByAgentId(agengId);
|
if(agentSettings!=null&&agentSettings.getCreditEnable()!=null) {
|
creditEnable =agentSettings.getCreditEnable();
|
}
|
}
|
if(creditEnable) {
|
if (old.getOrderType() == Constant.ORDER_TYPE_DY) {
|
userCreditManager.addDYOrderPayRecord(old.getUid(), id);
|
} else if (old.getOrderType() == Constant.ORDER_TYPE_KS) {
|
userCreditManager.addKSOrderPayRecord(old.getUid(), id);
|
}
|
}
|
|
} catch (UserCreditException e) {
|
loggerDebug.error("增加积分出错:"+id, e);
|
}
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
@Override
|
public void setOrderInfo(String id, String orderNo, int orderState) throws KeyOrderException {
|
KeyOrder old = keyOrderMapper.selectByPrimaryKeyForUpdate(id);
|
if (old == null) {
|
throw new KeyOrderException("口令不存在");
|
}
|
KeyOrder keyOrder = new KeyOrder();
|
keyOrder.setId(id);
|
// 默认1抖音
|
keyOrder.setOrderType(1);
|
keyOrder.setOrderNo(orderNo);
|
if (keyOrder.getUpdateTime() == null) {
|
keyOrder.setUpdateTime(new Date());
|
}
|
keyOrder.setOrderState(orderState);
|
keyOrderMapper.updateByPrimaryKeySelective(keyOrder);
|
}
|
|
@Override
|
public List<KeyOrder> list(KeyOrderMapper.DaoQuery query) {
|
return keyOrderMapper.list(query);
|
}
|
|
@Override
|
public long count(KeyOrderMapper.DaoQuery query) {
|
return keyOrderMapper.count(query);
|
}
|
|
@Override
|
public List<KeyOrder> listWithUser(KeyOrderMapper.DaoQuery query) {
|
return keyOrderMapper.listWithUser(query);
|
}
|
|
@Override
|
public long countWithUser(KeyOrderMapper.DaoQuery query) {
|
return keyOrderMapper.countWithUser(query);
|
}
|
|
@Override
|
public ChannelOrderStatistic statisticWithUser(KeyOrderMapper.DaoQuery query) {
|
Map<OrderChannelEnum, BigDecimal> shareMoneyMap = channelAgentSharingRatioService.getShareMoneyMap(query.agentId);
|
List<ChannelOrderStatistic> channelOrderStatisticList = keyOrderMapper.statisticChannelOrders(query);
|
BigDecimal totalMoney = new BigDecimal(0);
|
long totalOrderCount = 0;
|
for (ChannelOrderStatistic s : channelOrderStatisticList) {
|
|
for (OrderChannelEnum channel : OrderChannelEnum.values()) {
|
if (channel.getKey().equalsIgnoreCase(s.getOrderChannel())) {
|
|
if (shareMoneyMap.containsKey(channel)) {
|
totalMoney = totalMoney.add(shareMoneyMap.get(channel).multiply(new BigDecimal(s.getCount())));
|
}
|
break;
|
}
|
}
|
totalOrderCount += s.getCount();
|
}
|
long userCount = keyOrderMapper.countUser(query);
|
ChannelOrderStatistic statistic = new ChannelOrderStatistic();
|
statistic.setUserCount(userCount);
|
statistic.setMoney(totalMoney);
|
statistic.setCount(totalOrderCount);
|
return statistic;
|
}
|
|
@Override
|
public List<ChannelOrderStatistic> statisticChannelOrders(Long agentId, Date startTime, Date endTime) {
|
KeyOrderMapper.DaoQuery daoQuery = new KeyOrderMapper.DaoQuery();
|
daoQuery.minCreateTime = startTime;
|
daoQuery.maxCreateTime = endTime;
|
daoQuery.agentId = agentId;
|
daoQuery.state = KeyOrder.STATE_PAY;
|
daoQuery.hasPayTime = true;
|
// 将数据拉出来
|
long count = keyOrderMapper.count(daoQuery);
|
daoQuery.count = (int) count;
|
List<KeyOrder> orderList = keyOrderMapper.list(daoQuery);
|
Map<String, Set<Long>> uidsMap = new HashMap<>();
|
Map<String, Integer> countMap = new HashMap<>();
|
Map<String, BigDecimal> moneyMap = new HashMap<>();
|
|
Set<String> orderIds = new HashSet<>();
|
for (KeyOrder order : orderList) {
|
String orderId = order.getOrderType() + "#" + order.getOrderNo();
|
if (!StringUtil.isNullOrEmpty(order.getOrderNo())) {
|
if (orderIds.contains(orderId)) {
|
continue;
|
}
|
orderIds.add(orderId);
|
}
|
String orderChannel = order.getOrderChannel();
|
|
if (!uidsMap.containsKey(orderChannel)) {
|
uidsMap.put(orderChannel, new HashSet<>());
|
}
|
uidsMap.get(orderChannel).add(order.getUid());
|
|
if (!countMap.containsKey(orderChannel)) {
|
countMap.put(orderChannel, 0);
|
}
|
countMap.put(orderChannel, countMap.get(orderChannel) + 1);
|
|
|
if (!moneyMap.containsKey(orderChannel)) {
|
moneyMap.put(orderChannel, new BigDecimal(0));
|
}
|
moneyMap.put(orderChannel, moneyMap.get(orderChannel).add(order.getOrderMoney()));
|
}
|
|
List<ChannelOrderStatistic> results = new ArrayList<>();
|
for (String orderChannel : moneyMap.keySet()) {
|
ChannelOrderStatistic statistic = new ChannelOrderStatistic();
|
statistic.setCount(countMap.get(orderChannel));
|
statistic.setMoney(moneyMap.get(orderChannel));
|
statistic.setUserCount(uidsMap.get(orderChannel).size());
|
statistic.setOrderChannel(orderChannel);
|
results.add(statistic);
|
}
|
return results;
|
}
|
|
|
@Override
|
public Long getCanDistributeUid(int maxQueueSize) {
|
// 最近1小时有活跃,且不算12以上未执行的数据
|
List<OrderDistributeCountInfo> list = keyOrderMapper.listDistributeUids(new Date(System.currentTimeMillis() - 1000 * 60 * 31L), new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 12L));
|
if (list == null || list.size() == 0) {
|
return null;
|
}
|
// 排除重新分配的设备
|
List<Long> excludeIds = clientInfoService.getRePayClientIds();
|
for (int i = 0; i < list.size(); i++) {
|
if (excludeIds.contains(list.get(i).getUid())) {
|
list.remove(i);
|
i--;
|
}
|
}
|
List<OrderDistributeCountInfo> filterList = new ArrayList<>();
|
// count小于2直接视为0
|
for (OrderDistributeCountInfo info : list) {
|
if (info.getCount() >= maxQueueSize) {
|
continue;
|
}
|
filterList.add(info);
|
}
|
if (filterList.size() <= 0) {
|
return null;
|
}
|
|
return ClientDistributeUtil.computeDistributeClient(filterList);
|
}
|
|
@Override
|
public List<KeyOrder> listNotDistributed(int page, int pageSize) {
|
return keyOrderMapper.listNotDistributed((page - 1) * pageSize, pageSize);
|
}
|
|
@Override
|
public void deleteAll(Date maxCreateTime) {
|
keyOrderMapper.deleteAll(maxCreateTime);
|
}
|
|
@Override
|
public DYOrderDto verifyKey(String orderNoDesc, String orderStatus, String money, Long uid, String keyId) throws KeyVerifyException {
|
int orderType = AlipayOrderUtil.getOrderType(orderNoDesc);
|
if (uid != null) {
|
WxUserSettings settings = wxUserSettingService.getUserSettings(uid);
|
OrderCountTypeEnum orderCountType = OrderCountTypeEnum.SUBMIT_TOKEN_COUNT;
|
int maxCount = settings.getTotalOrderCountPerDay();
|
switch (orderType) {
|
case Constant.ORDER_TYPE_DY:
|
orderCountType = OrderCountTypeEnum.DY_ORDER_PAY;
|
maxCount = settings.getDyOrderCountPerDay();
|
break;
|
case Constant.ORDER_TYPE_KS:
|
orderCountType = OrderCountTypeEnum.KS_ORDER_PAY;
|
maxCount = settings.getKsOrderCountPerDay();
|
break;
|
}
|
}
|
|
|
String orderNo = "";
|
// 匹配连续的数字
|
Pattern pattern = Pattern.compile("\\d+");
|
Matcher matcher = pattern.matcher(orderNoDesc);
|
while (matcher.find()) {
|
// 获取匹配到的数字字符串
|
String number = matcher.group();
|
if (number.length() > 10) {
|
orderNo = number;
|
break;
|
}
|
}
|
|
if (orderType == Constant.ORDER_TYPE_UNKNOWN) {
|
throw new KeyVerifyException(KeyVerifyException.CODE_ORDER_TYPE_ERROR, "未定义的订单类型");
|
}
|
|
if (!StringUtil.isNullOrEmpty(orderStatus) && !orderStatus.contains("未支付")) {
|
throw new KeyVerifyException(KeyVerifyException.CODE_ORDER_STATUS_ERROR, "订单状态:" + orderStatus);
|
}
|
DYOrderDto dyOrderDto = null;
|
// 先匹配订单
|
try {
|
if (orderType == Constant.ORDER_TYPE_DY && !StringUtil.isNullOrEmpty(orderNo)) {
|
dyOrderDto = DYOrderApi.getOrderDetail(orderNo);
|
if (dyOrderDto != null && false) {
|
// 验证金额
|
if (dyOrderDto.getPay_amount().intValue() != new BigDecimal(money).multiply(new BigDecimal(100)).setScale(0).intValue()) {
|
throw new KeyVerifyException(KeyVerifyException.CODE_ORDER_MONEY_NOT_MATCH, String.format("支付金额与订单金额不一致:%s-%d", money, dyOrderDto.getPay_amount()));
|
}
|
// 验证订单号是否已经存在
|
KeyOrderMapper.DaoQuery query = new KeyOrderMapper.DaoQuery();
|
query.orderNo = orderNo;
|
query.orderType = orderType;
|
if (count(query) > 1) {
|
throw new KeyVerifyException(KeyVerifyException.CODE_ORDER_NO_REPEAT, "订单号重复提交");
|
}
|
}
|
} else {
|
throw new KeyOrderException("抖音订单获取失败");
|
}
|
} catch (KeyOrderException e) {
|
// 抖音订单未验证通过,匹配金额
|
// 验证提交的金额是否正确
|
Set<String> moneySet = payMoneySettingService.listAllMoneyAsStr();
|
// 匹配金额
|
if (!moneySet.contains(money)) {
|
throw new KeyVerifyException(KeyVerifyException.CODE_KEY_MONEY_NOT_MATCH, String.format("金额未在系统设置中:%s", money));
|
}
|
}
|
|
return dyOrderDto;
|
}
|
|
@Override
|
public void removeDistributedClient(String id) {
|
keyOrderMapper.removeDistributedClient(id);
|
}
|
|
@Override
|
public List<Long> listAgentId(KeyOrderMapper.DaoQuery query) {
|
return keyOrderMapper.listAgentId(query);
|
}
|
|
@Override
|
public long countAgentId(KeyOrderMapper.DaoQuery query) {
|
return keyOrderMapper.countAgentId(query);
|
}
|
|
@Override
|
public long countUserNotDoOrder(Long uid, Date minCreateTime) {
|
KeyOrderMapper.DaoQuery daoQuery = new KeyOrderMapper.DaoQuery();
|
daoQuery.uid = uid;
|
daoQuery.stateList = Arrays.asList(new Integer[]{KeyOrder.STATE_NOT_PROCESS, KeyOrder.STATE_NOT_PAY});
|
daoQuery.minCreateTime = minCreateTime;
|
return keyOrderMapper.count(daoQuery);
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
@Override
|
public void rejectPay(String id, String rejectMsg) {
|
KeyOrder keyOrder = new KeyOrder();
|
keyOrder.setId(id);
|
keyOrder.setState(KeyOrder.STATE_REJECT_PAY);
|
keyOrder.setStateDesc(rejectMsg);
|
update(keyOrder);
|
}
|
}
|