| | |
| | | package com.yeshi.makemoney.app; |
| | | |
| | | import com.google.gson.Gson; |
| | | import com.ks.lib.common.exception.ParamsException; |
| | | import com.yeshi.makemoney.app.dto.mq.ExtractTransferResultMQMsg; |
| | | import com.yeshi.makemoney.app.dto.mq.GoldCornSettleMQMsg; |
| | |
| | | import com.yeshi.makemoney.app.service.inter.goldcorn.GoldCornSettleService; |
| | | import com.yeshi.makemoney.app.service.inter.money.ExtractService; |
| | | import com.yeshi.makemoney.app.utils.Constant; |
| | | import com.yeshi.makemoney.app.utils.LogUtil; |
| | | import com.yeshi.makemoney.app.utils.mq.CMQManager; |
| | | import org.mybatis.spring.annotation.MapperScan; |
| | | import org.slf4j.Logger; |
| | |
| | | @EnableTransactionManagement |
| | | //@EnableDubbo(scanBasePackages = "com.ks.push.service.remote") |
| | | public class Application implements ApplicationListener<ContextRefreshedEvent> { |
| | | Logger settleLogger= LoggerFactory.getLogger("settleLog"); |
| | | private final static Logger logger = LoggerFactory.getLogger(Application.class); |
| | | |
| | | public static void main(String[] args) { |
| | |
| | | logger.info("容器加载完毕"); |
| | | initMQMsgConsumer(); |
| | | initCOS(); |
| | | LogUtil.settleLogger.info("test123"); |
| | | |
| | | } |
| | | |
| | | @Resource |
| | |
| | | new JobThreadExecutorServiceImpl().run(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | |
| | | Map<String, GoldCornSettleMQMsg> map = CMQManager.getInstance().consumeGoldCornSettleMsg(10); |
| | | if (map != null) { |
| | | for (Iterator<String> its = map.keySet().iterator(); its.hasNext(); ) { |
| | | String key = its.next(); |
| | | GoldCornSettleMQMsg msg = map.get(key); |
| | | try { |
| | | settleLogger.info("消费结算消息开始:{}",new Gson().toJson(msg)); |
| | | goldCornSettleService.settle(msg.getUid(), msg.getDay(),msg.getSettleId()); |
| | | CMQManager.getInstance().deleteGoldCornSettleMsg(key); |
| | | settleLogger.info("消费结算消息成功:{}",new Gson().toJson(msg)); |
| | | } catch (UserInfoException e) { |
| | | e.printStackTrace(); |
| | | settleLogger.error("消费结算消息异常:{} ",new Gson().toJson(msg),e); |
| | | } catch (GoldCornMoneyExchangeRateRecordException e) { |
| | | e.printStackTrace(); |
| | | settleLogger.error("消费结算消息异常:{} ",new Gson().toJson(msg),e); |
| | | } catch (UserMoneyRecordException e) { |
| | | e.printStackTrace(); |
| | | settleLogger.error("消费结算消息异常:{} ",new Gson().toJson(msg),e); |
| | | } catch (GoldCornConsumeRecordException e) { |
| | | e.printStackTrace(); |
| | | settleLogger.error("消费结算消息异常:{} ",new Gson().toJson(msg),e); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | settleLogger.error("消费结算消息异常:{} ",new Gson().toJson(msg),e); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | import com.google.gson.*; |
| | | import com.ks.lib.common.exception.ParamsException; |
| | | import com.yeshi.makemoney.app.dto.mq.GoldCornSettleMQMsg; |
| | | import com.yeshi.makemoney.app.entity.goldcorn.GoldCornConsumeType; |
| | | import com.yeshi.makemoney.app.exception.goldcorn.GoldCornSettleRecordException; |
| | | import com.yeshi.makemoney.app.service.inter.goldcorn.GoldCornConsumeRecordService; |
| | | import com.yeshi.makemoney.app.service.inter.goldcorn.GoldCornGetRecordService; |
| | | import com.yeshi.makemoney.app.service.inter.goldcorn.GoldCornSettleService; |
| | | import com.yeshi.makemoney.app.service.query.goldcorn.GoldCornConsumeRecordQuery; |
| | | import com.yeshi.makemoney.app.utils.goldcorn.GoldCornUtil; |
| | | import com.yeshi.makemoney.app.utils.mq.CMQManager; |
| | | import com.yeshi.makemoney.app.vo.AcceptAdminData; |
| | | import net.sf.json.JSONArray; |
| | | import net.sf.json.JSONObject; |
| | |
| | | |
| | | @Resource |
| | | private GoldCornConsumeRecordService goldCornConsumeRecordService; |
| | | |
| | | @Resource |
| | | private GoldCornGetRecordService goldCornGetRecordService; |
| | | |
| | | private Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new JsonSerializer<Date>() { |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | @ResponseBody |
| | | @RequestMapping("retry") |
| | | public String retry(String id, AcceptAdminData acceptAdminData) { |
| | | if (id == null) { |
| | | return JsonUtil.loadFalseResult("ID不能为空"); |
| | | } |
| | | |
| | | GoldCornSettleRecord record = goldCornSettleRecordService.get(id); |
| | | if (record == null) { |
| | | return JsonUtil.loadFalseResult("记录不存在"); |
| | | } |
| | | |
| | | long count = goldCornGetRecordService.countUidsByDay(record.getDay()); |
| | | int pageSize = 1000; |
| | | int page = (int) (count % pageSize == 0 ? count / pageSize : count / pageSize + 1); |
| | | for (int i = 0; i < page; i++) { |
| | | List<Long> list = goldCornGetRecordService.getUidsByDay(record.getDay(), i + 1, pageSize); |
| | | for (Long uid : list) { |
| | | //加入到CMQ |
| | | CMQManager.getInstance().addGoldCornSettleMsg(new GoldCornSettleMQMsg(record.getId(), uid, record.getDay(), System.currentTimeMillis())); |
| | | } |
| | | } |
| | | |
| | | return JsonUtil.loadTrueResult(gson.toJson(record)); |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | if (bean.getUid() != null) { |
| | | update.set("uid", bean.getUid()); |
| | | } |
| | | if (bean.getEventId() != null) { |
| | | update.set("eventId", bean.getEventId()); |
| | | } |
| | | if (bean.getCornNum() != null) { |
| | | update.set("cornNum", bean.getCornNum()); |
| | | } |
| | |
| | | * @date 2021/11/15 11:17 |
| | | */ |
| | | public enum SystemEnum { |
| | | svmm("椰视赚钱短视频", "com.yeshi.makemoney.video", ""); |
| | | svmm("椰视极速版", "com.yeshi.makemoney.video", ""); |
| | | private String name; |
| | | private String packageName; |
| | | private String bundleId; |
| | |
| | | public final static int CODE_ALREADY_DONE = 401; |
| | | |
| | | |
| | | public final static int CODE_WX_PAY_ACCOUNT_NO_MONEY = 801; |
| | | |
| | | |
| | | public ExtractException(int code, String msg) { |
| | | super(code, msg); |
| | | } |
New file |
| | |
| | | package com.yeshi.makemoney.app.job; |
| | | |
| | | import com.xxl.job.core.biz.model.ReturnT; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yeshi.makemoney.app.entity.SystemEnum; |
| | | import com.yeshi.makemoney.app.entity.money.Extract; |
| | | import com.yeshi.makemoney.app.exception.money.ExtractException; |
| | | import com.yeshi.makemoney.app.service.inter.goldcorn.GoldCornGetRecordService; |
| | | import com.yeshi.makemoney.app.service.inter.money.ExtractService; |
| | | import com.yeshi.makemoney.app.service.manager.PushManager; |
| | | import com.yeshi.makemoney.app.utils.goldcorn.GoldCornUtil; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.stereotype.Component; |
| | | import org.yeshi.utils.StringUtil; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author hxh |
| | | * @title: PushJob |
| | | * @description: 提现任务 |
| | | * @date 2022/5/7 17:44 |
| | | */ |
| | | @Component |
| | | public class ExtractJob { |
| | | |
| | | private Logger logger = LoggerFactory.getLogger(ExtractJob.class); |
| | | |
| | | @Resource |
| | | private ExtractService extractService; |
| | | |
| | | |
| | | /** |
| | | * @return com.xxl.job.core.biz.model.ReturnT<java.lang.String> |
| | | * @author hxh |
| | | * @description 通过提现 |
| | | * @date 14:30 2022/6/20 |
| | | * @param: param |
| | | **/ |
| | | @XxlJob("pass-extract") |
| | | public ReturnT<String> passExtract(String param) throws Exception { |
| | | if (StringUtil.isNullOrEmpty(param)) { |
| | | param = "1"; |
| | | } |
| | | Date minDate = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24L * 2); |
| | | long count = extractService.countNeedPassRecord(new BigDecimal(param), minDate); |
| | | int pageSize = 100; |
| | | int pageCount = (int) (count % 100 == 0 ? count / 100 : count / 100 + 1); |
| | | for (int p = 0; p < pageCount; p++) { |
| | | List<Extract> extractList = extractService.listNeedPassRecord(new BigDecimal(param), minDate, p + 1, pageSize); |
| | | for (Extract extract : extractList) { |
| | | try { |
| | | extractService.passExtract(extract.getId(), "auto_verify_extract"); |
| | | } catch (ExtractException e) { |
| | | e.printStackTrace(); |
| | | logger.error("机器通过提现出错:id-{}", extract.getId(), e); |
| | | } |
| | | } |
| | | } |
| | | return ReturnT.SUCCESS; |
| | | } |
| | | |
| | | } |
| | |
| | | import com.yeshi.makemoney.app.utils.factory.UserMoneyRecordFactory; |
| | | import com.yeshi.makemoney.app.utils.factory.goldcorn.GoldCornConsumeRecordFactory; |
| | | import com.yeshi.makemoney.app.utils.goldcorn.GoldCornUtil; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | |
| | | */ |
| | | @Service |
| | | public class GoldCornMakeServiceImpl implements GoldCornMakeService { |
| | | Logger taskLogger = LoggerFactory.getLogger("taskLog"); |
| | | |
| | | @Resource |
| | | private GoldCornGetFrequencyConfigService goldCornGetFrequencyConfigService; |
| | |
| | | query.setUid(user.getId()); |
| | | query.setType(type); |
| | | |
| | | //间隔判断 |
| | | if (config.getMinSpaceTime() != null) { |
| | | List<GoldCornGetRecord> list = goldCornGetRecordService.list(query, 1, 1); |
| | | if (list != null && list.size() > 0 && time.getTime() - list.get(0).getCreateTime().getTime() < config.getMinSpaceTime() * 1000L) { |
| | | String msg = String.format("需要间隔%s秒以上", config.getMinSpaceTime()); |
| | | throw new GoldCornMakeException(GoldCornMakeException.CODE_GET_FREQUENCY_TIME_LIMIT, msg); |
| | | try { |
| | | //间隔判断 |
| | | if (config.getMinSpaceTime() != null) { |
| | | List<GoldCornGetRecord> list = goldCornGetRecordService.list(query, 1, 1); |
| | | if (list != null && list.size() > 0 && time.getTime() - list.get(0).getCreateTime().getTime() < config.getMinSpaceTime() * 1000L) { |
| | | String msg = String.format("需要间隔%s秒以上", config.getMinSpaceTime()); |
| | | throw new GoldCornMakeException(GoldCornMakeException.CODE_GET_FREQUENCY_TIME_LIMIT, msg); |
| | | } |
| | | } |
| | | |
| | | Date startTime = null; |
| | | Date endTime = time; |
| | | if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.minute) { |
| | | startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd HHmm"), "yyyyMMdd HHmm")); |
| | | } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.hour) { |
| | | startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd HH"), "yyyyMMdd HH")); |
| | | } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.day) { |
| | | startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd"), "yyyyMMdd")); |
| | | } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.week) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTimeInMillis(endTime.getTime()); |
| | | int subDay = (Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 2 + 7) % 7; |
| | | startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime() - 1000 * 60 * 60 * 24L * subDay, "yyyyMMdd"), "yyyyMMdd")); |
| | | } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.month) { |
| | | startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMM"), "yyyyMM")); |
| | | } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.year) { |
| | | startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyy"), "yyyy")); |
| | | } |
| | | query.setFormat("yyyyMMdd HH:mm:ss"); |
| | | query.setStartTime(TimeUtil.getGernalTime(startTime.getTime(), query.getFormat())); |
| | | //service里面有减去1天 |
| | | query.setEndTime(TimeUtil.getGernalTime(endTime.getTime() - 1000 * 60 * 60 * 24L, query.getFormat())); |
| | | |
| | | Map<GoldCornGetType, Long> countMap = goldCornGetRecordService.sumEventCount(query); |
| | | if (countMap.get(type) != null && (countMap.get(type) >= config.getLimitCount())) { |
| | | String msg = String.format("超出%s次/%s的限制", config.getLimitCount(), config.getTimeUnit().getName()); |
| | | throw new GoldCornMakeException(GoldCornMakeException.CODE_GET_FREQUENCY_COUNT_LIMIT, msg); |
| | | } |
| | | |
| | | return config.getLimitCount() - (countMap.get(type) != null ? countMap.get(type) : 0); |
| | | |
| | | } catch (GoldCornMakeException e) { |
| | | //频率限制 |
| | | taskLogger.error("#频率受限# uid:{} type:{} time:{} msg:{}", user.getId(), type.name(), TimeUtil.getGernalTime(time.getTime(), "yyyy-MM-dd HH:mm:ss SSS"), e.getMsg()); |
| | | throw e; |
| | | } |
| | | |
| | | Date startTime = null; |
| | | Date endTime = time; |
| | | if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.minute) { |
| | | startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd HHmm"), "yyyyMMdd HHmm")); |
| | | } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.hour) { |
| | | startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd HH"), "yyyyMMdd HH")); |
| | | } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.day) { |
| | | startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd"), "yyyyMMdd")); |
| | | } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.week) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTimeInMillis(endTime.getTime()); |
| | | int subDay = (Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 2 + 7) % 7; |
| | | startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime() - 1000 * 60 * 60 * 24L * subDay, "yyyyMMdd"), "yyyyMMdd")); |
| | | } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.month) { |
| | | startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMM"), "yyyyMM")); |
| | | } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.year) { |
| | | startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyy"), "yyyy")); |
| | | } |
| | | query.setFormat("yyyyMMdd HH:mm:ss"); |
| | | query.setStartTime(TimeUtil.getGernalTime(startTime.getTime(), query.getFormat())); |
| | | //service里面有减去1天 |
| | | query.setEndTime(TimeUtil.getGernalTime(endTime.getTime() - 1000 * 60 * 60 * 24L, query.getFormat())); |
| | | |
| | | Map<GoldCornGetType, Long> countMap = goldCornGetRecordService.sumEventCount(query); |
| | | if (countMap.get(type) != null && (countMap.get(type) >= config.getLimitCount())) { |
| | | String msg = String.format("超出%s次/%s的限制", config.getLimitCount(), config.getTimeUnit().getName()); |
| | | throw new GoldCornMakeException(GoldCornMakeException.CODE_GET_FREQUENCY_COUNT_LIMIT, msg); |
| | | } |
| | | return config.getLimitCount() - (countMap.get(type) != null ? countMap.get(type) : 0); |
| | | } |
| | | |
| | | |
| | |
| | | continue; |
| | | } |
| | | //获取兑换记录的主键ID,不需要多余的数据 |
| | | GoldCornConsumeRecord record = GoldCornConsumeRecordFactory.createExchange(uid, GoldCornUtil.getFormatDay(date), 0, new BigDecimal(0.1),null); |
| | | GoldCornConsumeRecord record = GoldCornConsumeRecordFactory.createExchange(uid, GoldCornUtil.getFormatDay(date), 0, new BigDecimal(0.1), null); |
| | | //查询资金记录是否有该记录 |
| | | try { |
| | | UserMoneyRecord userMoneyRecord = UserMoneyRecordFactory.createGoldCornExchange(record); |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Override |
| | | public GoldCornMakeResultDTO scanNews(Long uid, boolean isDouble, Date time, int num) throws GoldCornGetPriceException, UserInfoException, GoldCornMakeException, GoldCornGetFrequencyConfigException { |
| | | //防刷机制 |
| | | if (num < 0) { |
| | | num = 0; |
| | | } |
| | | |
| | | //1个很大的数 |
| | | if (num > 20) { |
| | | num = 1; |
| | | } |
| | | |
| | | |
| | | UserInfo user = userInfoService.get(uid); |
| | | if (user == null) { |
| | | throw new UserInfoException(UserInfoException.CODE_NOT_EXIST, "用户不存在"); |
| | |
| | | package com.yeshi.makemoney.app.service.impl.goldcorn; |
| | | |
| | | import com.google.gson.Gson; |
| | | import com.ks.lib.common.exception.ParamsException; |
| | | import com.ks.push.exception.BPushTaskException; |
| | | import com.yeshi.makemoney.app.dto.mq.GoldCornSettleMQMsg; |
| | |
| | | import com.yeshi.makemoney.app.utils.factory.msg.UserMsgFactory; |
| | | import com.yeshi.makemoney.app.utils.goldcorn.GoldCornUtil; |
| | | import com.yeshi.makemoney.app.utils.mq.CMQManager; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.yeshi.utils.ThreadUtil; |
| | |
| | | */ |
| | | @Service |
| | | public class GoldCornSettleServiceImpl implements GoldCornSettleService { |
| | | Logger settleLogger= LoggerFactory.getLogger("settleLog"); |
| | | |
| | | @Resource |
| | | private GoldCornGetRecordService goldCornGetRecordService; |
| | |
| | | List<Long> list = goldCornGetRecordService.getUidsByDay(day, i + 1, pageSize); |
| | | for (Long uid : list) { |
| | | //加入到CMQ |
| | | CMQManager.getInstance().addGoldCornSettleMsg(new GoldCornSettleMQMsg(record.getId(), uid, day, System.currentTimeMillis())); |
| | | GoldCornSettleMQMsg msg= new GoldCornSettleMQMsg(record.getId(), uid, day, System.currentTimeMillis()); |
| | | settleLogger.info("加入结算队列:{}",new Gson().toJson(msg)); |
| | | CMQManager.getInstance().addGoldCornSettleMsg(msg); |
| | | } |
| | | } |
| | | |
| | |
| | | long cornNum = goldCornGetRecordService.getGoldCornByDay(uid, GoldCornUtil.convertFormatDay(day)); |
| | | //金币数量 |
| | | GoldCornConsumeRecord record = GoldCornConsumeRecordFactory.createExchange(uid, day, (int) cornNum, rate, settleId); |
| | | if(goldCornConsumeRecordService.get(record.getId())!=null){ |
| | | //已经结算过了 |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | UserMoneyRecord moneyRecord = UserMoneyRecordFactory.createGoldCornExchange(record); |
| | | userMoneyService.addUserMoney(moneyRecord); |
| | |
| | | return new Gson().fromJson(value, ExtractConfig.class); |
| | | } |
| | | |
| | | @Override |
| | | public List<Extract> listNeedPassRecord(BigDecimal maxMoney, Date minCreateTime, int page, int pageSize) { |
| | | DaoQuery daoQuery = new DaoQuery(); |
| | | daoQuery.state = Extract.STATE_NOT_PROCESS; |
| | | daoQuery.minCreateTime = minCreateTime; |
| | | daoQuery.maxMoney = maxMoney; |
| | | daoQuery.sortList = Arrays.asList(new String[]{"create_time asc"}); |
| | | daoQuery.start = (page - 1) * pageSize; |
| | | daoQuery.count = pageSize; |
| | | return extractMapper.list(daoQuery); |
| | | } |
| | | |
| | | @Override |
| | | public long countNeedPassRecord(BigDecimal maxMoney, Date minCreateTime) { |
| | | DaoQuery daoQuery = new DaoQuery(); |
| | | daoQuery.state = Extract.STATE_NOT_PROCESS; |
| | | daoQuery.minCreateTime = minCreateTime; |
| | | daoQuery.maxMoney = maxMoney; |
| | | return extractMapper.count(daoQuery); |
| | | } |
| | | |
| | | private void validateExtract(BigDecimal money, UserInfo user) throws ExtractException { |
| | | ExtractConfig config = getExtractConfig(user.getSystem()); |
| | | if (config == null) { |
| | |
| | | if (extract.getType() == ExtractPayType.alipay) { |
| | | transferByAlipay(extract, adminId); |
| | | } else { |
| | | transferByWX(extract, adminId, systemConfigService.getValueCache(user.getSystem(), SystemConfigKey.wxAppId)); |
| | | String result = transferByWX(extract, adminId, systemConfigService.getValueCache(user.getSystem(), SystemConfigKey.wxAppId)); |
| | | Map<String, String> resultMap = WXUtil.parseXML(result); |
| | | if ("SUCCESS".equalsIgnoreCase(resultMap.get("return_code")) && "SUCCESS".equalsIgnoreCase(resultMap.get("result_code"))) { |
| | | ; |
| | | } else { |
| | | |
| | | String errCode = resultMap.get("err_code"); |
| | | String errMsg = resultMap.get("err_code_des"); |
| | | boolean noMoney = "NOTENOUGH".equalsIgnoreCase(errCode); |
| | | if(noMoney) { |
| | | throw new ExtractException(ExtractException.CODE_WX_PAY_ACCOUNT_NO_MONEY,"微信支付账户余额不足"); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | } |
| | | } |
| | | |
| | | private void transferByWX(Extract extract, String adminId, String wxAPPId) { |
| | | private String transferByWX(Extract extract, String adminId, String wxAPPId) { |
| | | //获取用户的系统 |
| | | UserInfo user = userInfoService.get(extract.getUser().getId()); |
| | | String appName = user.getSystem().getName(); |
| | | //理由 |
| | | String result = WXPayUtil.payToOpenId(wxAPPId, extract.getAccount(), Constant.wxTransferConfig.getMchId(), Constant.wxTransferConfig.getKey(), Constant.wxTransferConfig.getCertPwd(), this.getClass().getClassLoader().getResourceAsStream(Constant.wxTransferConfig.getCertPath()), "makemoney" + extract.getId(), extract.getMoney(), "提现", extract.getIp()); |
| | | String result = WXPayUtil.payToOpenId(wxAPPId, extract.getAccount(), Constant.wxTransferConfig.getMchId(), Constant.wxTransferConfig.getKey(), Constant.wxTransferConfig.getCertPwd(), this.getClass().getClassLoader().getResourceAsStream(Constant.wxTransferConfig.getCertPath()), "makemoney" + extract.getId(), extract.getMoney(), String.format("来自%s的提现",appName), extract.getIp()); |
| | | try { |
| | | CMQManager.getInstance().addExtractResultMsg(new ExtractTransferResultMQMsg(extract.getId(), result, adminId)); |
| | | logger.info("提现:添加处理队列成功-" + extract.getId()); |
| | | } catch (Exception e) { |
| | | logger.error("提现:微信提现CMQ异常:{}", result + ",提现信息" + GsonUtil.toJson(extract)); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | |
| | |
| | | if (noMoney) { |
| | | Extract updateExtract = new Extract(); |
| | | updateExtract.setId(extract.getId()); |
| | | updateExtract.setState(Extract.STATE_PROCESSING); |
| | | updateExtract.setState(Extract.STATE_NOT_PROCESS); |
| | | updateExtract.setReason(msg); |
| | | extractMapper.updateByPrimaryKeySelective(updateExtract); |
| | | } else { |
| | |
| | | public ExtractConfig getExtractConfig(SystemEnum system); |
| | | |
| | | |
| | | |
| | | /** |
| | | * @author hxh |
| | | * @description 列举需要通过的记录 |
| | | * @date 14:24 2022/6/20 |
| | | * @param: maxMoney |
| | | * @return java.util.List<com.yeshi.makemoney.app.entity.money.Extract> |
| | | **/ |
| | | public List<Extract> listNeedPassRecord(BigDecimal maxMoney,Date minCreateTime,int page,int pageSize); |
| | | |
| | | /** |
| | | * @author hxh |
| | | * @description 需要通过的记录列表 |
| | | * @date 14:25 2022/6/20 |
| | | * @param: maxMoney |
| | | * @return long |
| | | **/ |
| | | public long countNeedPassRecord(BigDecimal maxMoney,Date minCreateTime); |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | |
| | | public class ExtractQuery extends BaseQuery { |
| | | private Long uid; |
| | | |
| | | private Integer state; |
| | | |
| | | |
| | | |
| | | public Long getUid() { |
| | | return uid; |
New file |
| | |
| | | package com.yeshi.makemoney.app.utils; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | /** |
| | | * @author hxh |
| | | * @title: LogUtil |
| | | * @description: 日志 |
| | | * @date 2022/9/9 10:22 |
| | | */ |
| | | public class LogUtil { |
| | | public static Logger settleLogger= LoggerFactory.getLogger("settleLog"); |
| | | } |
| | |
| | | import com.yeshi.makemoney.app.dto.mq.AddGoldCornMQMsg; |
| | | import com.yeshi.makemoney.app.dto.mq.ExtractTransferResultMQMsg; |
| | | import com.yeshi.makemoney.app.dto.mq.GoldCornSettleMQMsg; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.yeshi.utils.StringUtil; |
| | | import org.yeshi.utils.mq.TDMQUtil; |
| | | |
| | |
| | | * @date 2022/4/1 17:06 |
| | | */ |
| | | public class CMQManager { |
| | | Logger logger= LoggerFactory.getLogger(CMQManager.class); |
| | | private static String secretId = "AKIDTlpgJhLjOozvd6QI2XnpfGbgV4NQJk25"; |
| | | private static String secretKey = "xhCSUHo55oHUQ6XicFcmfIgspX0EEzWo"; |
| | | private static CMQManager cmqManager; |
| | |
| | | |
| | | public void addAddGoldCornMsg(AddGoldCornMQMsg msg) { |
| | | String content = new Gson().toJson(msg); |
| | | |
| | | tdmqUtil.sendMsg(QUEUE_ADD_GOLDCORN, content); |
| | | } |
| | | |
| | |
| | | **/ |
| | | public void addGoldCornSettleMsg(GoldCornSettleMQMsg msg) { |
| | | String content = new Gson().toJson(msg); |
| | | logger.debug("添加结算消息开始:",content); |
| | | TDMQUtil.getInstance().sendMsg(QUEUE_GOLDCORN_SETTLE, content); |
| | | //添加日志 |
| | | logger.debug("添加结算消息结束:{}",content); |
| | | } |
| | | |
| | | public Map<String, GoldCornSettleMQMsg> consumeGoldCornSettleMsg(int count) { |
| | |
| | | <endpoint>ap-guangzhou.cls.tencentcs.com</endpoint> |
| | | <accessKeyId>${tencent.log.accesskey}</accessKeyId> |
| | | <accessKeySecret>${tencent.log.accessKeySecret}</accessKeySecret> |
| | | <topicId>dsp</topicId> |
| | | <topicId>7400eab9-e40c-40aa-a1d3-2084af09a76a</topicId> |
| | | |
| | | <!-- 可选项 详见 '参数说明'--> |
| | | <totalSizeInBytes>104857600</totalSizeInBytes> |
| | | <maxBlockMs>0</maxBlockMs> |
| | | <sendThreadCount>8</sendThreadCount> |
| | | <batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes> |
| | | <batchCountThreshold>4096</batchCountThreshold> |
| | | <lingerMs>2000</lingerMs> |
| | | <retries>10</retries> |
| | | <baseRetryBackoffMs>100</baseRetryBackoffMs> |
| | | <maxRetryBackoffMs>50000</maxRetryBackoffMs> |
| | | |
| | | <!-- 可选项 设置时间格式 --> |
| | | <timeFormat>yyyy-MM-dd'T'HH:mm:ssZ</timeFormat> |
| | | <timeZone>Asia/Shanghai</timeZone> |
| | | <encoder> |
| | | <pattern>${log.pattern}</pattern> |
| | | </encoder> |
| | | <mdcFields>THREAD_ID,MDC_KEY</mdcFields> |
| | | </appender> |
| | | |
| | | |
| | | <appender name="taskLogAppender" class="com.tencentcloudapi.cls.LoghubAppender"> |
| | | <!--必选项--> |
| | | <endpoint>ap-guangzhou.cls.tencentcs.com</endpoint> |
| | | <accessKeyId>${tencent.log.accesskey}</accessKeyId> |
| | | <accessKeySecret>${tencent.log.accessKeySecret}</accessKeySecret> |
| | | <topicId>dc22b452-1006-46c9-b86f-97baf823a1ee</topicId> |
| | | |
| | | <!-- 可选项 详见 '参数说明'--> |
| | | <totalSizeInBytes>104857600</totalSizeInBytes> |
| | | <maxBlockMs>0</maxBlockMs> |
| | | <sendThreadCount>8</sendThreadCount> |
| | | <batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes> |
| | | <batchCountThreshold>4096</batchCountThreshold> |
| | | <lingerMs>2000</lingerMs> |
| | | <retries>10</retries> |
| | | <baseRetryBackoffMs>100</baseRetryBackoffMs> |
| | | <maxRetryBackoffMs>50000</maxRetryBackoffMs> |
| | | |
| | | <!-- 可选项 设置时间格式 --> |
| | | <timeFormat>yyyy-MM-dd'T'HH:mm:ssZ</timeFormat> |
| | | <timeZone>Asia/Shanghai</timeZone> |
| | | <encoder> |
| | | <pattern>${log.pattern}</pattern> |
| | | </encoder> |
| | | <mdcFields>THREAD_ID,MDC_KEY</mdcFields> |
| | | </appender> |
| | | |
| | | |
| | | <appender name="settleLogAppender" class="com.tencentcloudapi.cls.LoghubAppender"> |
| | | <!--必选项--> |
| | | <endpoint>ap-guangzhou.cls.tencentcs.com</endpoint> |
| | | <accessKeyId>${tencent.log.accesskey}</accessKeyId> |
| | | <accessKeySecret>${tencent.log.accessKeySecret}</accessKeySecret> |
| | | <topicId>9c4583b7-ca4f-4907-af58-ebafe5e67cfe</topicId> |
| | | |
| | | <!-- 可选项 详见 '参数说明'--> |
| | | <totalSizeInBytes>104857600</totalSizeInBytes> |
| | |
| | | <appender-ref ref="tencentLogAppender"></appender-ref> |
| | | </logger> |
| | | |
| | | <logger name="com.yeshi.makemoney.app.utils.mq.CMQManager" level="DEBUG" additivity="false"> |
| | | <appender-ref ref="tencentLogAppender"></appender-ref> |
| | | </logger> |
| | | |
| | | <logger name="com.yeshi.makemoney.app.aop.SignValidate" level="ERROR" additivity="false"> |
| | | <appender-ref ref="tencentLogAppender"></appender-ref> |
| | | </logger> |
| | | |
| | | <logger name="taskLog" level="INFO" additivity="false"> |
| | | <appender-ref ref="taskLogAppender"></appender-ref> |
| | | </logger> |
| | | |
| | | <logger name="settleLog" level="INFO" additivity="false"> |
| | | <appender-ref ref="settleLogAppender"></appender-ref> |
| | | </logger> |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | <!-- 一切logger都会继承自root,root默认的层级level为debug --> |
| | | <root level="INFO"> |
| | | <!--在控制台中输出所在层级对应level(以及大于level)的日志信息,因为这里并没有设置LevelFilter--> |
| | |
| | | <a title="" href="javascript:;" lay-event="refresh"> |
| | | <i class="layui-icon"></i> |
| | | </a> |
| | | |
| | | <a class="layui-btn layui-btn-sm" title="" href="javascript:;" lay-event="retry"> |
| | | 重试 |
| | | </a> |
| | | </div> |
| | | </script> |
| | | |
| | |
| | | app.refreshItem(data.id, function (res) { |
| | | obj.update(res); |
| | | }); |
| | | }else if(obj.event === 'retry'){ |
| | | app.retry(data.id); |
| | | } |
| | | }); |
| | | |
| | |
| | | } |
| | | }, function (e) { |
| | | }); |
| | | }, |
| | | retry: function (id) { |
| | | ksapp.post("/admin/api/goldcorn/settle/retry", {id: id}, function (e) { |
| | | if (e.code == 0) { |
| | | layer.msg("更新成功"); |
| | | } else { |
| | | layer.msg(e.msg); |
| | | } |
| | | }, function (e) { |
| | | }); |
| | | } |
| | | |
| | | |
| | |
| | | </script> |
| | | |
| | | |
| | | <script type="text/html" id="optContainer"> |
| | | |
| | | </script> |
| | | |
| | | <script type="text/html" id="statusContainer"> |
| | | <div class="layui-btn-container"> |
| | | {{# if(d.status==0){ }} |
| | |
| | | <img src="{{d.}}"/> |
| | | <input type="checkbox" name="sex" value="{{d.id}}" lay-skin="switch" lay-text="女|男" lay-filter="sexDemo" {{ d.id== |
| | | 10003 ? 'checked': ''}} > |
| | | </script> |
| | | |
| | | <script type="text/html" id="optContainer"> |
| | | <div class="layui-btn-container"> |
| | | <a class="layui-btn {{d.state==0?'':'layui-btn-disabled'}}" title="通过" onclick="app.passExtract({{d.state}},{{d.id}})" |
| | | href="javascript:;"> |
| | | 通过 |
| | | </a> |
| | | |
| | | <a class="layui-btn layui-btn-danger" title="去处理" onclick="xadmin.open('处理提现记录', 'extract_process.html?id= {{d.id}}', null, null, true)" |
| | | href="javascript:;"> |
| | | 去处理 |
| | | </a> |
| | | </div> |
| | | </script> |
| | | |
| | | <script> |
| | |
| | | toolbar: "#toolbar", |
| | | totalRow: true, |
| | | cols: [[{type: 'checkbox', title: "ID"}, |
| | | |
| | | {field: 'id', width: 80, sort: false, title: "ID"}, |
| | | {field: 'money', width: 80, sort: false, title: "提现金额"}, |
| | | { |
| | | field: 'user', width: 80, sort: false, title: "用户ID", templet: function (res) { |
| | | |
| | | return res.user.id; |
| | | } |
| | | }, |
| | | {field: 'money', width: 80, sort: false, title: "提现金额"}, |
| | | |
| | | {field: 'type', width: 80, sort: false, title: "付款渠道"}, |
| | | {field: 'name', width: 80, sort: false, title: "姓名(支付宝)"}, |
| | | {field: 'account', width: 120, sort: false, title: "账号/OpenId"}, |
| | |
| | | {field: 'reason', width: 200, sort: false, title: "原因"}, |
| | | {field: 'successTime', width: 150, sort: false, title: "通过时间"}, |
| | | {field: 'createTime', width: 150, sort: false, title: "创建时间"}, |
| | | {fixed: 'right', width: 150, title: "操作", toolbar: '#optContainer'} |
| | | ]], |
| | | page: true, |
| | | parseData: function (res) { //res 即为原始返回的数据 |
| | |
| | | curr: 1 //重新从第 1 页开始 |
| | | } |
| | | }); |
| | | }, |
| | | passExtract: function (state,id) { |
| | | if(state!=0){ |
| | | return; |
| | | } |
| | | layer.confirm('是否通过提现申请?', {icon: 3, title: '提示'}, function (index) { |
| | | layer.close(index); |
| | | //确定 |
| | | ksapp.post('/admin/api/money/extract/passExtract', {id: id}, function (res) { |
| | | if (res.code == 0) { |
| | | layer.msg("成功"); |
| | | } else if (res.code == 50002) { |
| | | app.openVerifyDialog(); |
| | | } else { |
| | | layer.msg(res.msg); |
| | | } |
| | | }, function (res) { |
| | | }); |
| | | }); |
| | | }, |
| | | openVerifyDialog: function () { |
| | | xadmin.open('邮件验证', 'extract_email_code.html', 350, 160); |
| | | } |
| | | } |
| | | }); |
| | |
| | | package test; |
| | | |
| | | import com.yeshi.makemoney.app.Application; |
| | | import com.yeshi.makemoney.app.job.ExtractJob; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.springframework.boot.test.context.SpringBootTest; |
| | | import org.yeshi.utils.wx.WXPayUtil; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.FileNotFoundException; |
| | |
| | | * @description: TODO |
| | | * @date 2022/4/1 10:51 |
| | | */ |
| | | @SpringBootTest(classes = Application.class) |
| | | public class ExtractTest { |
| | | |
| | | @Resource |
| | | private ExtractJob extractJob; |
| | | |
| | | |
| | | public static void main(String[] args) throws FileNotFoundException { |
| | | WXPayUtil.payToOpenId("wx428de66710fac55b", "odx5JwzVHBcEan-TtlGNKPzNuTlI", "1520950211", "XYJkJ2018FAfaodCCx899mLl138rfGVd", "1520950211", new FileInputStream(new File("D:\\项目\\返利券\\商户平台\\1520950211_20220401_cert\\apiclient_cert.p12")), "buwanwithdraw1", new BigDecimal(1.00), "提现", "192.168.3.122"); |
| | | } |
| | | |
| | | @Test |
| | | public void autoVerify() throws Exception { |
| | | //extractJob.passExtract(""); |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | package test; |
| | | |
| | | import com.qcloud.cmq.Account; |
| | | import com.qcloud.cmq.Queue; |
| | | import com.qcloud.cmq.entity.CmqResponse; |
| | | import org.yeshi.utils.FileUtil; |
| | | |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.Date; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | |
| | | public class Test { |
| | | |
| | | public static void main(String[] args) throws IOException { |
| | | String dir = "C:\\Users\\Administrator\\Desktop\\ocr"; |
| | | // if(1>0){ |
| | | // test1(); |
| | | // return; |
| | | // } |
| | | String dir = "C:\\Users\\Administrator\\Desktop\\ocr\\gpcode"; |
| | | File[] fs = new File(dir).listFiles(); |
| | | Set<String> md5Set = new HashSet<>(); |
| | | for (File f : fs) { |
| | |
| | | } |
| | | |
| | | |
| | | private static void test1() throws Exception{ |
| | | |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | |
| | | import com.ks.lib.common.exception.ParamsException; |
| | | import com.yeshi.makemoney.app.Application; |
| | | import com.yeshi.makemoney.app.dto.mq.GoldCornSettleMQMsg; |
| | | import com.yeshi.makemoney.app.entity.SystemEnum; |
| | | import com.yeshi.makemoney.app.entity.goldcorn.*; |
| | | import com.yeshi.makemoney.app.exception.goldcorn.*; |
| | | import com.yeshi.makemoney.app.exception.user.UserInfoException; |
| | | import com.yeshi.makemoney.app.service.inter.goldcorn.*; |
| | | import com.yeshi.makemoney.app.service.query.goldcorn.GoldCornConsumeRecordQuery; |
| | | import com.yeshi.makemoney.app.utils.mq.CMQManager; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.springframework.boot.test.context.SpringBootTest; |
| | | import org.yeshi.utils.TimeUtil; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.math.BigDecimal; |
| | |
| | | @Test |
| | | public void settle() { |
| | | // goldCornSettleService.startSettle(new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 1L)); |
| | | // CMQManager.getInstance().addGoldCornSettleMsg(new GoldCornSettleMQMsg(record.getId(), uid, day, System.currentTimeMillis())); |
| | | //重新结算 |
| | | GoldCornConsumeRecordQuery query = new GoldCornConsumeRecordQuery(); |
| | | query.setType(GoldCornConsumeType.changeMoney); |
| | | query.setEventId("2022-06-22-svmm"); |
| | | query.setType(GoldCornConsumeType.changeMoney); |
| | | List<GoldCornConsumeRecord> list= goldCornConsumeRecordService.list(query,1,1000); |
| | | int count=0; |
| | | for(GoldCornConsumeRecord record:list){ |
| | | if(record.getCreateTime().getTime()> TimeUtil.convertToTimeTemp("2022-06-29","yyyy-MM-dd")){ |
| | | GoldCornConsumeRecord update=new GoldCornConsumeRecord(); |
| | | update.setId(record.getId()); |
| | | update.setEventId("2022-06-28-svmm"); |
| | | goldCornConsumeRecordService.update(update); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | |
| | | <dependency> |
| | | <groupId>com.yeshi</groupId> |
| | | <artifactId>utils</artifactId> |
| | | <version>0.3.8</version> |
| | | <version>0.3.9</version> |
| | | <exclusions> |
| | | <exclusion> |
| | | <groupId>org.springframework.data</groupId> |