Administrator
2024-07-29 a053811c774ac07340e46561f5d2ab4d892282a0
渠道功能完善
25个文件已添加
39个文件已修改
3733 ■■■■■ 已修改文件
src/main/java/com/taoke/autopay/aop/AgentLoginValidate.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/config/WebSecurityConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/WebApiController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/admin/AdminAgentController.java 250 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/admin/AdminAgentSettleController.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/admin/AdminOrderController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/agent/AgentController.java 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/dao/KeyOrderMapper.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/dao/agent/ChannelAgentMapper.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/dao/agent/ChannelAgentSettingsMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/dao/agent/ChannelAgentSettleDetailMapper.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/dao/agent/ChannelAgentSettleRecordMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/dto/ChannelOrderStatistic.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/entity/KeyOrder.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/entity/SystemConfigKeyEnum.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/entity/agent/ChannelAgentSettings.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/entity/agent/ChannelAgentSettleDetail.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/entity/agent/ChannelAgentSettleRecord.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/exception/ChannelAgentException.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/exception/ChannelAgentSettleException.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/factory/AgentFactory.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/factory/OrderFactory.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/KeyOrderService.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/agent/ChannelAgentService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/agent/ChannelAgentSettingService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/agent/ChannelAgentSettleService.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/agent/ChannelAgentSharingRatioService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/KeyOrderServiceImpl.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/agent/ChannelAgentServiceImpl.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/agent/ChannelAgentSettingServiceImpl.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/agent/ChannelAgentSettleServiceImpl.java 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/agent/ChannelAgentSharingRatioServiceImpl.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/utils/AgentUtil.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/utils/Constant.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/utils/LogUtil.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/vo/AgentOrderFilter.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/vo/AgentOrderVO.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/vo/SubmitKeyInfo.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/vo/UserInfoVO.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/vo/admin/AdminChannelAgentVO.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/vo/admin/AgentSearchVO.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/logback.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ChannelAgentMapper.xml 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ChannelAgentSettingsMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ChannelAgentSettleDetailMapper.xml 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ChannelAgentSettleRecordMapper.xml 103 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/KeyOrderMapper.xml 153 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/admin/agent-add.html 153 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/admin/agent-list.html 213 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/admin/agent-settle-list.html 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/admin/agent-update.html 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/admin/agent-withdraw-list.html 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/admin/index.html 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/agent/alipay_account_setting.html 49 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/agent/css/index.css 96 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/agent/index.html 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/agent/js/http.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/agent/js/index.js 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/agent/login.html 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/agent/test.html 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/index3.html 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/AgentTest.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/KeyTest.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/MapperTest.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/aop/AgentLoginValidate.java
New file
@@ -0,0 +1,82 @@
package com.taoke.autopay.aop;
import com.taoke.autopay.entity.agent.ChannelAgent;
import com.taoke.autopay.utils.ApiCodeConstant;
import com.taoke.autopay.utils.Constant;
import com.taoke.autopay.utils.JsonUtil;
import com.taoke.autopay.utils.StringUtil;
import com.taoke.autopay.vo.AcceptData;
import net.sf.json.JSONObject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.util.*;
/**
 * @author hxh
 * @description 客户端接口签名验证
 * @date 12:15 2024/6/14
 * @return
 **/
@Component
@Aspect
@Order(2)
public class AgentLoginValidate {
    public static final String EDP = "execution(* com.taoke.autopay.controller.agent..*.*(..))";
    private Logger logger = LoggerFactory.getLogger(AgentLoginValidate.class);
    @Around(EDP)
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        PrintWriter out = null;
        ServletRequestAttributes servletContainer = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        servletContainer.getResponse().setCharacterEncoding("UTF-8");
        HttpServletRequest request = servletContainer.getRequest();
        AcceptData acceptData = null;
        for (Object obj : args) {
            if (obj instanceof AcceptData) {
                acceptData = (AcceptData) obj;
            } else if (obj instanceof HttpServletRequest) {
                request = (HttpServletRequest) obj;
            }
        }
        ChannelAgent agent = (ChannelAgent) request.getSession().getAttribute(Constant.SESSION_KEY_AGENT);
        if (agent == null && !request.getRequestURI().toString().contains("login")) {
            // 没有登录
            out = servletContainer.getResponse().getWriter();
            out.print(JsonUtil.loadFalseResult(Constant.RESULT_CODE_NEED_LOGIN, "尚未登录"));
            return null;
        }
        Object obj = null;
        try {
            long startTime = System.currentTimeMillis();
            obj = joinPoint.proceed(args);
        } catch (Throwable e) {
            e.printStackTrace();
            out = servletContainer.getResponse().getWriter();
            out.print(JsonUtil.loadFalseResult(ApiCodeConstant.CODE_ERROR_IN_SERVER, "服务器内部错误"));
            logger.error("api:{} params:{}", request.getRequestURI(), JsonUtil.getSimpleGson().toJson(request.getParameterMap()), e);
            return null;
        }
        return obj;
    }
}
src/main/java/com/taoke/autopay/config/WebSecurityConfig.java
@@ -198,7 +198,7 @@
        http.headers().frameOptions().disable();
        http.authorizeRequests()
                // 配置不需要鉴权的接口
                .antMatchers("/admin/api/captcha.jpg*", "/api/**", "/webapi/**").permitAll()
                .antMatchers("/admin/api/captcha.jpg*", "/api/**", "/webapi/**","*/agentapi/**").permitAll()
                //配置需要鉴权的接口
                .antMatchers("/admin/api/**", "/admin/index.html").authenticated()
                .and()
src/main/java/com/taoke/autopay/controller/WebApiController.java
@@ -39,8 +39,6 @@
    Logger verifyLogger = LoggerFactory.getLogger("keyVerifyLogger");
    @Resource
    private KeyOrderService keyOrderService;
@@ -118,8 +116,7 @@
                }catch(Exception e){
                }
                throw  ee;
            }
            catch(Exception e){
            } catch (Exception e) {
                throw new KeyVerifyException(KeyVerifyException.CODE_COMMON, e.getMessage());
            }
        }
@@ -198,12 +195,12 @@
    }
    /**
     * @return java.lang.String
     * @author hxh
     * @description 带口令与金额的口令提交接口
     * @date 0:12 2024/7/9
     * @param: keyInfo
     * @param: session
     * @return java.lang.String
     **/
    @ResponseBody
    @RequestMapping(value = "submitKeyV3")
@@ -277,7 +274,7 @@
        if (StringUtil.isNullOrEmpty(keyInfo.getKey())) {
            return JsonUtil.loadFalseResult( "请上传key");
        }
        if(1<0) {
            try {
                verifySubmitKey(keyInfo.getKey());
            } catch (Exception e) {
@@ -294,10 +291,9 @@
            if (Integer.parseInt(now) < Integer.parseInt(startTime) || Integer.parseInt(now) > Integer.parseInt(endTime)) {
                return JsonUtil.loadFalseResult(String.format("口令提交时间段为:%s-%s", timeStr.split(",")[0], timeStr.split(",")[1]));
            }
        }
        if (user == null) {
            // 先保存KEY
//            SESSION_KEY_TEMP_ALIPAY_KEY
            session.setAttribute(Constant.SESSION_KEY_TEMP_ALIPAY_KEY, keyInfo);
            wxLogger.info("微信没有授权:" + session.getId());
            String redictLink = systemConfigService.getValueCache(SystemConfigKeyEnum.WX_REDIRECT_LINK);
@@ -321,7 +317,7 @@
        } catch (WxOrderCountException e) {
            return JsonUtil.loadFalseResult(e.getMessage());
        } catch (KeyVerifyException e) {
            logger.debug("口令校验失败:{}-{}-{}", keyInfo.getKey(), e.getCode(), e.getMessage());
            LogUtil.loggerDebug.debug("口令校验失败:{}-{}-{}", keyInfo.getKey(), e.getCode(), e.getMessage());
            switch (e.getCode()){
                case KeyVerifyException.CODE_KEY_MONEY_NOT_MATCH:
                    return JsonUtil.loadFalseResult("该笔订单有误,不予提交");
src/main/java/com/taoke/autopay/controller/admin/AdminAgentController.java
New file
@@ -0,0 +1,250 @@
package com.taoke.autopay.controller.admin;
import com.alibaba.excel.EasyExcel;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.taoke.autopay.dao.KeyOrderMapper;
import com.taoke.autopay.dao.agent.ChannelAgentMapper;
import com.taoke.autopay.dto.admin.OrderExcelDataDto;
import com.taoke.autopay.entity.ClientInfo;
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.entity.OrderChannelEnum;
import com.taoke.autopay.entity.SystemConfigKeyEnum;
import com.taoke.autopay.entity.agent.ChannelAgent;
import com.taoke.autopay.entity.agent.ChannelAgentSettings;
import com.taoke.autopay.entity.agent.ChannelAgentSharingRatio;
import com.taoke.autopay.exception.ChannelAgentException;
import com.taoke.autopay.factory.AgentFactory;
import com.taoke.autopay.factory.OrderFactory;
import com.taoke.autopay.service.ClientInfoService;
import com.taoke.autopay.service.KeyOrderService;
import com.taoke.autopay.service.SystemConfigService;
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.Constant;
import com.taoke.autopay.utils.TimeUtil;
import com.taoke.autopay.vo.admin.AdminChannelAgentVO;
import com.taoke.autopay.vo.admin.AdminOrderVO;
import com.taoke.autopay.vo.admin.AgentSearchVO;
import com.taoke.autopay.vo.admin.OrderSearchVO;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.yeshi.utils.JsonUtil;
import org.yeshi.utils.NumberUtil;
import org.yeshi.utils.StringUtil;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
@Controller
@RequestMapping("/admin/api/agent")
public class AdminAgentController {
    private Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new TypeAdapter<Date>() {
        @Override
        public void write(JsonWriter out, Date value) throws IOException {
            String desc = "";
            if (value != null) {
                // 判断是否是同一天
                desc = TimeUtil.getGernalTime(value.getTime(), "yyyy-MM-dd HH:mm:ss");
                out.value(desc);
            } else {
                out.value("");
            }
        }
        @Override
        public Date read(JsonReader in) throws IOException {
            return new Date();
        }
    }).create();
    @Resource
    private ChannelAgentService channelAgentService;
    @Resource
    private ChannelAgentSettingService channelAgentSettingService;
    @Resource
    private ChannelAgentSharingRatioService channelAgentSharingRatioService;
    @Resource
    private SystemConfigService systemConfigService;
    @ResponseBody
    @RequestMapping("list")
    public String listAgent(AgentSearchVO search, int page, int limit) {
        //先查询所有的数据
        ChannelAgentMapper.DaoQuery query = new ChannelAgentMapper.DaoQuery();
        query.searchKey = search.getKey();
        query.sortList = Arrays.asList(new String[]{"_create_time desc"});
        query.start = (long) (page - 1) * limit;
        query.count = limit;
        if (!StringUtil.isNullOrEmpty(search.getStartDate())) {
            query.minCreateTime = new Date(TimeUtil.convertToTimeTemp(search.getStartDate(), "yyyy-MM-dd"));
        }
        if (!StringUtil.isNullOrEmpty(search.getEndDate())) {
            query.maxCreateTime = TimeUtil.getNextDay(1, new Date(TimeUtil.convertToTimeTemp(search.getEndDate(), "yyyy-MM-dd")).getTime());
        }
        List<ChannelAgent> agentList = channelAgentService.list(query);
        List<Long> agentIds = new ArrayList<>();
        for (ChannelAgent agent : agentList) {
            agentIds.add(agent.getId());
        }
        List<ChannelAgentSettings> settings = channelAgentSettingService.listByIds(agentIds);
        Map<Long, ChannelAgentSettings> settingsMap = new HashMap<>();
        for (ChannelAgentSettings setting : settings) {
            settingsMap.put(setting.getId(), setting);
        }
        long count = channelAgentService.count(query);
        // 转vo
        List<AdminChannelAgentVO> voList = new ArrayList<>();
        String baseSubmitKeyLink = systemConfigService.getValueCache(SystemConfigKeyEnum.AGENT_SUBMIT_KEY_LINK);
        for (ChannelAgent agent : agentList) {
            voList.add(AgentFactory.create(agent, settingsMap.get(agent.getId()), null, baseSubmitKeyLink));
        }
        JSONObject data = new JSONObject();
        data.put("count", count);
        data.put("list", gson.toJson(voList));
        return JsonUtil.loadTrueResult(data);
    }
    @ResponseBody
    @RequestMapping("add")
    public String addAgent(AdminChannelAgentVO vo) {
        // 创建代理
        ChannelAgent agent = ChannelAgent.builder()
                .name(vo.getName())
                .account(vo.getAccount())
                .pwd(StringUtil.Md5(vo.getPwd()))
                .alipayAccount(StringUtil.isNullOrEmpty(vo.getAlipayAccount()) ? null : vo.getAlipayAccount())
                .alipayName(StringUtil.isNullOrEmpty(vo.getAlipayName()) ? null : vo.getAlipayName())
                .status(ChannelAgent.STATUS_NOMAL)
                .build();
        try {
            agent = channelAgentService.addChannelAgent(agent);
            // 添加设置
            ChannelAgentSettings settings = ChannelAgentSettings.builder()
                    .id(agent.getId())
                    .startSubmitTime(StringUtil.isNullOrEmpty(vo.getStartSubmitTime()) ? null : vo.getStartSubmitTime())
                    .endSubmitTime(StringUtil.isNullOrEmpty(vo.getEndSubmitTime()) ? null : vo.getEndSubmitTime())
                    .maxKeyCountPerDay(StringUtil.isNullOrEmpty(vo.getMaxKeyCountPerDay()) ? null : Long.parseLong(vo.getMaxKeyCountPerDay()))
                    .maxPayMoneyPerDay(StringUtil.isNullOrEmpty(vo.getMaxPayMoneyPerDay()) ? null : new BigDecimal(vo.getMaxPayMoneyPerDay()))
                    .build();
            channelAgentSettingService.add(settings);
            // 添加分成比例设置
            if (!StringUtil.isNullOrEmpty(vo.getShareRatioInfos())) {
                JSONObject shareRatioData = JSONObject.fromObject(vo.getShareRatioInfos());
                for (Object key : shareRatioData.keySet()) {
                    String value = shareRatioData.optString(key.toString());
                    OrderChannelEnum channel = OrderChannelEnum.valueOf(key.toString());
                    if (!StringUtil.isNullOrEmpty(value)) {
                        channelAgentSharingRatioService.setShareRatio(ChannelAgentSharingRatio.builder().agengId(agent.getId()).orderChannel(channel).shareType(ChannelAgentSharingRatio.SHARE_TYPE_MONEY).shareValue(new BigDecimal(value)).build());
                    }
                }
            }
            return JsonUtil.loadTrueResult(agent);
        } catch (ChannelAgentException e) {
            return JsonUtil.loadFalseResult(e.getMessage());
        }
    }
    @ResponseBody
    @RequestMapping("update")
    public String update(AdminChannelAgentVO vo) {
        // 创建代理
        ChannelAgent agent = ChannelAgent.builder()
                .id(vo.getId())
                .name(vo.getName())
                .account(vo.getAccount())
                .pwd(StringUtil.isNullOrEmpty(vo.getPwd()) ? null :StringUtil.Md5(vo.getPwd()))
                .alipayAccount(StringUtil.isNullOrEmpty(vo.getAlipayAccount()) ? null : vo.getAlipayAccount())
                .alipayName(StringUtil.isNullOrEmpty(vo.getAlipayName()) ? null : vo.getAlipayName())
                .build();
            channelAgentService.updateSelective(agent);
            // 添加设置
            ChannelAgentSettings settings = ChannelAgentSettings.builder()
                    .id(agent.getId())
                    .startSubmitTime(StringUtil.isNullOrEmpty(vo.getStartSubmitTime()) ? null : vo.getStartSubmitTime())
                    .endSubmitTime(StringUtil.isNullOrEmpty(vo.getEndSubmitTime()) ? null : vo.getEndSubmitTime())
                    .maxKeyCountPerDay(StringUtil.isNullOrEmpty(vo.getMaxKeyCountPerDay()) ? null : Long.parseLong(vo.getMaxKeyCountPerDay()))
                    .maxPayMoneyPerDay(StringUtil.isNullOrEmpty(vo.getMaxPayMoneyPerDay()) ? null : new BigDecimal(vo.getMaxPayMoneyPerDay()))
                    .build();
            channelAgentSettingService.add(settings);
            // 添加分成比例设置
            if (!StringUtil.isNullOrEmpty(vo.getShareRatioInfos())) {
                JSONObject shareRatioData = JSONObject.fromObject(vo.getShareRatioInfos());
                for (Object key : shareRatioData.keySet()) {
                    String value = shareRatioData.optString(key.toString());
                    OrderChannelEnum channel = OrderChannelEnum.valueOf(key.toString());
                    if (!StringUtil.isNullOrEmpty(value)) {
                        channelAgentSharingRatioService.setShareRatio(ChannelAgentSharingRatio.builder().agengId(agent.getId()).orderChannel(channel).shareType(ChannelAgentSharingRatio.SHARE_TYPE_MONEY).shareValue(new BigDecimal(value)).build());
                    }
                }
            }
            return JsonUtil.loadTrueResult(agent);
    }
    @ResponseBody
    @RequestMapping("delete")
    public String delete(Long id){
        // 删除agent
        channelAgentService.delete(id);
        return JsonUtil.loadTrueResult("");
    }
    @ResponseBody
    @RequestMapping("getDetail")
    public String getDetail(Long id) {
        ChannelAgent agent = channelAgentService.selectByPrimaryKey(id);
        if (agent == null) {
            return JsonUtil.loadFalseResult("代理ID不存在");
        }
        Map<OrderChannelEnum, BigDecimal> shareRatio = channelAgentSharingRatioService.getShareMoneyMap(id);
        ChannelAgentSettings settings = channelAgentSettingService.selectByAgentId(id);
        if(settings.getStartSubmitTime()==null||settings.getEndSubmitTime()==null){
            String timeStr =   systemConfigService.getValueCache(SystemConfigKeyEnum.KEY_SUBMIT_TIME_RANGE);
            settings.setStartSubmitTime(timeStr.split(",")[0]);
            settings.setEndSubmitTime(timeStr.split(",")[1]);
        }
        String baseSubmitKeyLink = systemConfigService.getValueCache(SystemConfigKeyEnum.AGENT_SUBMIT_KEY_LINK);
        AdminChannelAgentVO vo = AgentFactory.create(agent, settings, shareRatio, baseSubmitKeyLink);
        return JsonUtil.loadTrueResult(gson.toJson(vo));
    }
    /**
     * 获取订单所有的渠道
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("getAgentOrderChannels")
    public String getAgentOrderChannels() {
        JSONArray array = new JSONArray();
        for (OrderChannelEnum channel : OrderChannelEnum.values()) {
            JSONObject item = new JSONObject();
            item.put("label", channel.getName());
            item.put("name", channel.name());
            array.add(item);
        }
        return JsonUtil.loadTrueResult(array);
    }
}
src/main/java/com/taoke/autopay/controller/admin/AdminAgentSettleController.java
New file
@@ -0,0 +1,109 @@
package com.taoke.autopay.controller.admin;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.taoke.autopay.dao.agent.ChannelAgentMapper;
import com.taoke.autopay.dao.agent.ChannelAgentSettleRecordMapper;
import com.taoke.autopay.entity.OrderChannelEnum;
import com.taoke.autopay.entity.SystemConfigKeyEnum;
import com.taoke.autopay.entity.agent.ChannelAgent;
import com.taoke.autopay.entity.agent.ChannelAgentSettings;
import com.taoke.autopay.entity.agent.ChannelAgentSettleRecord;
import com.taoke.autopay.entity.agent.ChannelAgentSharingRatio;
import com.taoke.autopay.exception.ChannelAgentException;
import com.taoke.autopay.exception.ChannelAgentSettleException;
import com.taoke.autopay.factory.AgentFactory;
import com.taoke.autopay.service.SystemConfigService;
import com.taoke.autopay.service.agent.ChannelAgentService;
import com.taoke.autopay.service.agent.ChannelAgentSettingService;
import com.taoke.autopay.service.agent.ChannelAgentSettleService;
import com.taoke.autopay.service.agent.ChannelAgentSharingRatioService;
import com.taoke.autopay.utils.TimeUtil;
import com.taoke.autopay.vo.admin.AdminChannelAgentVO;
import com.taoke.autopay.vo.admin.AgentSearchVO;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.yeshi.utils.JsonUtil;
import org.yeshi.utils.StringUtil;
import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
/**
 * 渠道结算
 */
@Controller
@RequestMapping("/admin/api/agentsettle")
public class AdminAgentSettleController {
    private Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new TypeAdapter<Date>() {
        @Override
        public void write(JsonWriter out, Date value) throws IOException {
            String desc = "";
            if (value != null) {
                // 判断是否是同一天
                desc = TimeUtil.getGernalTime(value.getTime(), "yyyy-MM-dd HH:mm:ss");
                out.value(desc);
            } else {
                out.value("");
            }
        }
        @Override
        public Date read(JsonReader in) throws IOException {
            return new Date();
        }
    }).create();
    @Resource
    private ChannelAgentService channelAgentService;
    @Resource
    private ChannelAgentSettleService channelAgentSettleService;
    @ResponseBody
    @RequestMapping("list")
    public String listAgent(String key, String day, int page, int limit) {
        //先查询所有的数据
        ChannelAgentSettleRecordMapper.DaoQuery query = new ChannelAgentSettleRecordMapper.DaoQuery();
        query.settleDay = com.taoke.autopay.utils.StringUtil.isNullOrEmpty(day)?null:day;
        query.sortList = Arrays.asList(new String[]{"_create_time desc"});
        query.start = (long) (page - 1) * limit;
        query.count = limit;
        List<ChannelAgentSettleRecord> recordList = channelAgentSettleService.list(query);
        long count = channelAgentSettleService.count(query);
        JSONObject data = new JSONObject();
        data.put("count", count);
        data.put("list", gson.toJson(recordList));
        return JsonUtil.loadTrueResult(data);
    }
    @ResponseBody
    @RequestMapping("delete")
    public String delete(Long id){
        // 删除agent
        channelAgentSettleService.delete(id);
        return JsonUtil.loadTrueResult("");
    }
    @ResponseBody
    @RequestMapping("startSettle")
    public String startSettle(String  day) {
        try {
           channelAgentSettleService.startSettle(day);
            return JsonUtil.loadTrueResult("");
        } catch (ChannelAgentSettleException e) {
            return JsonUtil.loadFalseResult(e.getMessage());
        }
    }
}
src/main/java/com/taoke/autopay/controller/admin/AdminOrderController.java
@@ -6,10 +6,10 @@
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.sun.org.apache.bcel.internal.generic.BREAKPOINT;
import com.taoke.autopay.dao.KeyOrderMapper;
import com.taoke.autopay.dto.admin.OrderExcelDataDto;
import com.taoke.autopay.entity.*;
import com.taoke.autopay.entity.ClientInfo;
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.factory.OrderFactory;
import com.taoke.autopay.service.ClientInfoService;
import com.taoke.autopay.service.KeyOrderService;
src/main/java/com/taoke/autopay/controller/agent/AgentController.java
New file
@@ -0,0 +1,179 @@
package com.taoke.autopay.controller.agent;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.taoke.autopay.dao.KeyOrderMapper;
import com.taoke.autopay.dao.agent.ChannelAgentMapper;
import com.taoke.autopay.dto.ChannelOrderStatistic;
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.entity.OrderChannelEnum;
import com.taoke.autopay.entity.SystemConfigKeyEnum;
import com.taoke.autopay.entity.agent.ChannelAgent;
import com.taoke.autopay.entity.agent.ChannelAgentSettings;
import com.taoke.autopay.entity.agent.ChannelAgentSharingRatio;
import com.taoke.autopay.exception.ChannelAgentException;
import com.taoke.autopay.factory.AgentFactory;
import com.taoke.autopay.factory.OrderFactory;
import com.taoke.autopay.service.KeyOrderService;
import com.taoke.autopay.service.SystemConfigService;
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.Constant;
import com.taoke.autopay.utils.StringUtil;
import com.taoke.autopay.utils.TimeUtil;
import com.taoke.autopay.vo.AgentOrderFilter;
import com.taoke.autopay.vo.AgentOrderVO;
import com.taoke.autopay.vo.OrderFilter;
import com.taoke.autopay.vo.admin.AdminChannelAgentVO;
import com.taoke.autopay.vo.admin.AgentSearchVO;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.yeshi.utils.JsonUtil;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
@Controller
@RequestMapping("/agentapi/admin")
public class AgentController {
    private Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new TypeAdapter<Date>() {
        @Override
        public void write(JsonWriter out, Date value) throws IOException {
            String desc = "";
            if (value != null) {
                // 判断是否是同一天
                desc = TimeUtil.getGernalTime(value.getTime(), "yyyy-MM-dd HH:mm:ss");
                out.value(desc);
            } else {
                out.value("");
            }
        }
        @Override
        public Date read(JsonReader in) throws IOException {
            return new Date();
        }
    }).create();
    @Resource
    private ChannelAgentService channelAgentService;
    @Resource
    private KeyOrderService keyOrderService;
    @Resource
    private ChannelAgentSharingRatioService channelAgentSharingRatioService;
    @ResponseBody
    @RequestMapping("login")
    public String login(String account, String pwd, HttpSession session) {
        try {
            ChannelAgent agent = channelAgentService.login(account, pwd);
            agent.setPwd(null);
            session.setAttribute(Constant.SESSION_KEY_AGENT, agent);
            return JsonUtil.loadTrueResult(agent);
        } catch (ChannelAgentException e) {
            return JsonUtil.loadFalseResult(e.getMessage());
        }
    }
    @ResponseBody
    @RequestMapping("setAlipayAccount")
    public String setAlipayAccount(String alipayAccount, String alipayName, HttpSession session) {
        ChannelAgent agent = (ChannelAgent) session.getAttribute(Constant.SESSION_KEY_AGENT);
        if (agent == null) {
            return JsonUtil.loadFalseResult("尚未登录");
        }
        try {
            channelAgentService.setAlipayAccount(agent.getId(), alipayName, alipayAccount);
            return JsonUtil.loadTrueResult("");
        } catch (ChannelAgentException e) {
            return JsonUtil.loadFalseResult(e.getMessage());
        }
    }
    @ResponseBody
    @RequestMapping("orderList")
    public String orderList(AgentOrderFilter filter, HttpSession session) {
        ChannelAgent agent = (ChannelAgent) session.getAttribute(Constant.SESSION_KEY_AGENT);
        KeyOrderMapper.DaoQuery query = new KeyOrderMapper.DaoQuery();
        query.agentId = agent.getId();
        if (!StringUtil.isNullOrEmpty(filter.getKey())) {
            query.nickName = filter.getKey().trim();
        }
        query.start = (filter.getPage() - 1) * 20L;
        query.count = 20;
        long now = System.currentTimeMillis();
        String nowDay = TimeUtil.getGernalTime(now, "yyyy-MM-dd");
        switch (filter.getTimeIndex()) {
            case 0:
                query.oMinCreateTime = new Date(TimeUtil.convertToTimeTemp(nowDay, "yyyy-MM-dd"));
                break;
            case 1:
                query.oMaxCreateTime = new Date(TimeUtil.convertToTimeTemp(nowDay, "yyyy-MM-dd"));
                query.oMinCreateTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(now - 24 * 60 * 60 * 1000L, "yyyy-MM-dd"), "yyyy-MM-dd"));
                break;
            case 2:
                query.oMaxCreateTime = new Date(TimeUtil.convertToTimeTemp(nowDay, "yyyy-MM-dd"));
                query.oMinCreateTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(now - 24 * 60 * 60 * 1000L * 3, "yyyy-MM-dd"), "yyyy-MM-dd"));
            case 3:
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(new Date(now));
                int day = calendar.get(Calendar.DAY_OF_WEEK);
                day -= 1;
                if (day == 0) {
                    // 星期天
                    day = 7;
                }
                query.oMinCreateTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(now - 24 * 60 * 60 * 1000L * (day - 1), "yyyy-MM-dd"), "yyyy-MM-dd"));
                break;
        }
        query.sortList = Arrays.asList(new String[]{"o.create_time desc"});
        List<KeyOrder> list = keyOrderService.listWithUser(query);
        long count = keyOrderService.countWithUser(query);
        query.hasPayTime = true;
        ChannelOrderStatistic statistic = keyOrderService.statisticWithUser(query);
        List<AgentOrderVO> voList = new ArrayList<>();
        Map<OrderChannelEnum, BigDecimal> shareMoneyMap = channelAgentSharingRatioService.getShareMoneyMap(agent.getId());
        for (KeyOrder order : list) {
            BigDecimal money = null;
            for (OrderChannelEnum channel : OrderChannelEnum.values()) {
                if (channel.getKey().equalsIgnoreCase(order.getOrderChannel())) {
                    money = shareMoneyMap.get(channel);
                    break;
                }
            }
            if (money == null) {
                money = new BigDecimal(0);
            }
            AgentOrderVO vo = OrderFactory.createAgentOrder(order, money);
            voList.add(vo);
        }
        JSONObject data = new JSONObject();
        data.put("list", voList);
        data.put("count", count);
        data.put("statistic", statistic);
        return JsonUtil.loadTrueResult(data);
    }
}
src/main/java/com/taoke/autopay/dao/KeyOrderMapper.java
@@ -5,6 +5,7 @@
import java.lang.Long;
import java.util.List;
import com.taoke.autopay.dto.ChannelOrderStatistic;
import com.taoke.autopay.entity.OrderDistributeCountInfo;
import org.apache.ibatis.annotations.Param;
@@ -19,7 +20,20 @@
    List<KeyOrder> list(@Param("query") DaoQuery query);
    List<KeyOrder> listWithUser(@Param("query") DaoQuery query);
    long count(@Param("query") DaoQuery query);
    long countWithUser(@Param("query") DaoQuery query);
    // 统计渠道订单金额与数量
    List<ChannelOrderStatistic> statisticChannelOrders(@Param("query") DaoQuery query);
    // 统计用户数量
    long countUser(@Param("query") DaoQuery query);
    List<OrderDistributeCountInfo> listDistributeUids(@Param("minActiveTime") Date minActiveTime, @Param("minKeyOrderCreateTime") Date minKeyOrderCreateTime);
@@ -29,6 +43,11 @@
    int  removeDistributedClient(String id);
    List<Long> listAgentId(@Param("query") KeyOrderMapper.DaoQuery query);
    long countAgentId(@Param("query") KeyOrderMapper.DaoQuery query);
    public static class DaoQuery{
        public String id;
        public String key;
@@ -37,6 +56,8 @@
        public Long uid;
        public Integer orderState;
        public Integer state;
        public Boolean hasPayTime;
        public Boolean hasAgentId;
        public Long agentId;
        public List<Integer> stateList;
        public String stateDesc;
@@ -47,6 +68,10 @@
        public Date maxCreateTime;
        public Date minUpdateTime;
        public Date maxUpdateTime;
        public Date oMinCreateTime;
        public Date oMaxCreateTime;
        public String nickName;
        public long start;
        public int count;
        public List<String> sortList;
src/main/java/com/taoke/autopay/dao/agent/ChannelAgentMapper.java
@@ -19,6 +19,7 @@
    long count(@Param("query") DaoQuery query);
    public static class DaoQuery{
        public String searchKey;
        public Long id;
        public String name;
        public String alias;
src/main/java/com/taoke/autopay/dao/agent/ChannelAgentSettingsMapper.java
@@ -15,6 +15,8 @@
    List<ChannelAgentSettings> list(@Param("query") DaoQuery query);
    List<ChannelAgentSettings> listByIds(@Param("agentIds") List<Long> agentIds);
    long count(@Param("query") DaoQuery query);
    public static class DaoQuery{
src/main/java/com/taoke/autopay/dao/agent/ChannelAgentSettleDetailMapper.java
New file
@@ -0,0 +1,37 @@
package com.taoke.autopay.dao.agent;
import com.taoke.autopay.entity.OrderChannelEnum;
import java.util.Date;
import java.lang.Long;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List;
import com.taoke.autopay.entity.agent.ChannelAgentSettleDetail;
import org.yeshi.utils.mybatis.BaseMapper;
public interface ChannelAgentSettleDetailMapper extends BaseMapper<ChannelAgentSettleDetail> {
    ChannelAgentSettleDetail selectByPrimaryKeyForUpdate(@Param("id") Long id);
    List<ChannelAgentSettleDetail> list(@Param("query") DaoQuery query);
    long count(@Param("query") DaoQuery query);
    List<ChannelAgentSettleDetail> listBySettleId(Long settleId);
    public static class DaoQuery{
        public Long id;
        public Long settleId;
        public OrderChannelEnum orderChannel;
        public Long payOrderCount;
        public BigDecimal payMoney;
        public BigDecimal money;
        public Date minCreateTime;
        public Date maxCreateTime;
        public Date minUpdateTime;
        public Date maxUpdateTime;
        public long start;
        public int count;
        public List<String> sortList;
    }
}
src/main/java/com/taoke/autopay/dao/agent/ChannelAgentSettleRecordMapper.java
@@ -19,11 +19,6 @@
    long count(@Param("query") DaoQuery query);
    public static class DaoQuery{
        public int STATUS_NOT_SETTLE;
        public int STATUS_SETTLED;
        public int STATUS_WITHDRAWING;
        public int STATUS_WITHDRAW_SUCCESS;
        public int STATUS_WITHDRAW_REJECTED;
        public Long id;
        public Long agentId;
        public String settleDay;
src/main/java/com/taoke/autopay/dto/ChannelOrderStatistic.java
New file
@@ -0,0 +1,12 @@
package com.taoke.autopay.dto;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class ChannelOrderStatistic {
    private String orderChannel;
    private long count;
    private BigDecimal money;
}
src/main/java/com/taoke/autopay/entity/KeyOrder.java
@@ -67,4 +67,6 @@
     **/
    @Column(name = "agent_id")
    private Long agentId;
    private WxUserInfo user;
}
src/main/java/com/taoke/autopay/entity/SystemConfigKeyEnum.java
@@ -18,7 +18,8 @@
    KEY_SUBMIT_TIME_RANGE("order_key_submit_time_range","订单口令提交时间段"),
    PAY_MONEY_LIST("pay_money_list","可支付金额列表"),
    ALIPAY_KEY_VERIFY("alipay_key_verify_state","是否需要提前验证支付宝口令"),
    AGENT_SUBMIT_KEY_LINK("agent_submit_key_link", "代理口令提交链接"),
    AGENT_ORDER_CHANNEL_SHARE_RATIO("agent_order_channel_share_ratio", "代理订单渠道分成比例"),
    ;
src/main/java/com/taoke/autopay/entity/agent/ChannelAgentSettings.java
@@ -1,5 +1,6 @@
package com.taoke.autopay.entity.agent;
import lombok.Builder;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.yeshi.utils.generater.mybatis.Column;
@@ -14,6 +15,7 @@
 * @description: 渠道设置
 * @date 2024/7/20 22:23
 */
@Builder
@Data
@Table(value = "table_agent_settings")
public class ChannelAgentSettings {
src/main/java/com/taoke/autopay/entity/agent/ChannelAgentSettleDetail.java
New file
@@ -0,0 +1,57 @@
package com.taoke.autopay.entity.agent;
import com.taoke.autopay.entity.OrderChannelEnum;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Tolerate;
import org.springframework.data.annotation.Id;
import org.yeshi.utils.generater.mybatis.Column;
import org.yeshi.utils.generater.mybatis.Table;
import java.math.BigDecimal;
import java.util.Date;
/**
 * @author hxh
 * @title: ChannelAgentSettleDetail
 * @description: 结算详情
 * @date 2024/7/20 22:06
 */
@Builder
@Data
@Table(value="table_agent_settle_detail")
public class ChannelAgentSettleDetail {
    @Tolerate
    public ChannelAgentSettleDetail(){
    }
    @Id
    @Column(name="_id")
    private Long id;
    /**
     * 结算ID
     */
    @Column(name="_settle_id")
    private Long settleId;
    @Column(name="_order_channel")
    private OrderChannelEnum orderChannel;
    @Column(name="_pay_order_count")
    private Long payOrderCount;
    @Column(name="_pay_money")
    private BigDecimal payMoney;
    @Column(name="_money")
    private BigDecimal money;
    @Column(name="_create_time")
    private Date createTime;
    @Column(name="_update_time")
    private Date updateTime;
}
src/main/java/com/taoke/autopay/entity/agent/ChannelAgentSettleRecord.java
@@ -1,12 +1,15 @@
package com.taoke.autopay.entity.agent;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Tolerate;
import org.springframework.data.annotation.Id;
import org.yeshi.utils.generater.mybatis.Column;
import org.yeshi.utils.generater.mybatis.Table;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
 * @author hxh
@@ -14,6 +17,7 @@
 * @description: 渠道结算记录
 * @date 2024/7/20 22:06
 */
@Builder
@Data
@Table(value="table_agent_settle_record")
public class ChannelAgentSettleRecord {
@@ -27,6 +31,11 @@
    public final static int STATUS_WITHDRAW_SUCCESS= 3;
    // 提现被驳回
    public final static int STATUS_WITHDRAW_REJECTED= 4;
    @Tolerate
    public ChannelAgentSettleRecord() {
    }
    @Id
@@ -63,7 +72,7 @@
    private Integer status;
    @Column(name="_status_desc")
    private Integer statusDesc;
    private String statusDesc;
    /**
     * 结算时间
@@ -95,5 +104,9 @@
    @Column(name="_update_time")
    private Date updateTime;
    private ChannelAgent agent;
    private List<ChannelAgentSettleDetail> detailList;
}
src/main/java/com/taoke/autopay/exception/ChannelAgentException.java
@@ -2,7 +2,7 @@
/**
 * @author hxh
 * @title: LoginException
 * @title: ChannelAgentException
 * @description: 登录异常
 * @date 2024/6/14 18:46
 */
src/main/java/com/taoke/autopay/exception/ChannelAgentSettleException.java
New file
@@ -0,0 +1,15 @@
package com.taoke.autopay.exception;
/**
 * @author hxh
 * @title: ChannelAgentSettleException
 * @description: 登录异常
 * @date 2024/6/14 18:46
 */
public class ChannelAgentSettleException extends  Exception{
    public ChannelAgentSettleException(String msg){
        super(msg);
    }
}
src/main/java/com/taoke/autopay/factory/AgentFactory.java
New file
@@ -0,0 +1,55 @@
package com.taoke.autopay.factory;
import com.google.gson.Gson;
import com.taoke.autopay.entity.OrderChannelEnum;
import com.taoke.autopay.entity.agent.ChannelAgent;
import com.taoke.autopay.entity.agent.ChannelAgentSettings;
import com.taoke.autopay.utils.AgentUtil;
import com.taoke.autopay.vo.admin.AdminChannelAgentVO;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import java.math.BigDecimal;
import java.util.Map;
public class AgentFactory {
    public static AdminChannelAgentVO create(ChannelAgent agent, ChannelAgentSettings agentSettings, Map<OrderChannelEnum, BigDecimal> shareRatio, String baseSubmitKeyUrl){
        AdminChannelAgentVO vo= AdminChannelAgentVO.builder()
                .id(agent.getId())
                .alias(agent.getAlias())
                .name(agent.getName())
                .alipayAccount(agent.getAlipayAccount())
                .alipayName(agent.getAlipayName())
                .account(agent.getAccount())
                .createTime(agent.getCreateTime())
                .status(agent.getStatus())
                .statusDesc(agent.getStatusDesc())
                .build();
        if(agentSettings!=null){
            vo.setMaxKeyCountPerDay(agentSettings.getMaxKeyCountPerDay()==null?null:agentSettings.getMaxKeyCountPerDay()+"");
            if(agentSettings.getMaxPayMoneyPerDay()!=null) {
                vo.setMaxPayMoneyPerDay(agentSettings.getMaxPayMoneyPerDay().toString());
            }
            vo.setStartSubmitTime(agentSettings.getStartSubmitTime());
            vo.setEndSubmitTime(agentSettings.getEndSubmitTime());
        }
        if(baseSubmitKeyUrl!=null) {
            vo.setSubmitKeyLink(AgentUtil.getSubmitKeyUrl(baseSubmitKeyUrl, agent.getAlias()));
        }
        if(shareRatio!=null){
            JSONArray array=new JSONArray();
            for(OrderChannelEnum key:shareRatio.keySet()){
                JSONObject data=new JSONObject();
                data.put("label",key.getName());
                data.put("name",key.name());
                data.put("money",shareRatio.get(key).toString());
                array.add(data);
            }
            vo.setShareRatioInfos(new Gson().toJson(array));
        }
        return vo;
    }
}
src/main/java/com/taoke/autopay/factory/OrderFactory.java
@@ -2,12 +2,17 @@
import com.taoke.autopay.entity.ClientInfo;
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.entity.OrderChannelEnum;
import com.taoke.autopay.entity.WxUserOrderCount;
import com.taoke.autopay.utils.Constant;
import com.taoke.autopay.utils.StringUtil;
import com.taoke.autopay.utils.TimeUtil;
import com.taoke.autopay.vo.AgentOrderVO;
import com.taoke.autopay.vo.UserInfoVO;
import com.taoke.autopay.vo.admin.AdminOrderVO;
import com.taoke.autopay.vo.KeyOrderVO;
import java.math.BigDecimal;
/**
 * @author hxh
@@ -44,6 +49,19 @@
        return vo;
    }
    public static AgentOrderVO createAgentOrder(KeyOrder order, BigDecimal money) {
        String time=TimeUtil.getGernalTime(order.getCreateTime().getTime(), "yyyy.MM.dd HH:mm:ss");
        time = time.replace(" ","<br>");
        return AgentOrderVO.builder()
                .payMoney(order.getOrderMoney().toString())
                .settleMoney(money.toString())
                .createTime(time)
                .valid(order.getPayTime() != null && order.getState() == KeyOrder.STATE_PAY)
                .user(order.getUser() != null ? UserInfoVO.builder().id(order.getUser().getId()).nickName(order.getUser().getNickName()).portrait(order.getUser().getPortrait()).build() : null)
                .build();
    }
    private static String getOrderStateDesc(Integer orderState, Integer orderType) {
        if (orderState == null || orderType == null) {
src/main/java/com/taoke/autopay/service/KeyOrderService.java
@@ -1,6 +1,7 @@
package com.taoke.autopay.service;
import com.taoke.autopay.dao.KeyOrderMapper;
import com.taoke.autopay.dto.ChannelOrderStatistic;
import com.taoke.autopay.dto.DYOrderDto;
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.exception.KeyOrderException;
@@ -73,6 +74,15 @@
    public long count(KeyOrderMapper.DaoQuery query);
    public List<KeyOrder> listWithUser(KeyOrderMapper.DaoQuery query);
    public long countWithUser(KeyOrderMapper.DaoQuery query);
    public ChannelOrderStatistic statisticWithUser(KeyOrderMapper.DaoQuery query);
    public List<ChannelOrderStatistic> statisticChannelOrders(Long agentId,Date startTime,Date endTime);
    /**
     * @return java.lang.Long
     * @author hxh
@@ -122,4 +132,19 @@
     **/
    public void removeDistributedClient(String id);
    /**
     *  代理ID列表
     * @param query
     * @return
     */
    public List<Long> listAgentId(KeyOrderMapper.DaoQuery query);
    /**
     * 代理ID数量
     * @param query
     * @return
     */
    public long countAgentId(KeyOrderMapper.DaoQuery query);
}
src/main/java/com/taoke/autopay/service/agent/ChannelAgentService.java
@@ -22,7 +22,7 @@
     * @param: agent
     * @return void
     **/
    public void addChannelAgent(ChannelAgent agent) throws ChannelAgentException;
    public ChannelAgent addChannelAgent(ChannelAgent agent) throws ChannelAgentException;
    /**
     * @author hxh
@@ -35,10 +35,19 @@
     **/
    public void setAlipayAccount(Long agengId,String name,String account) throws ChannelAgentException;
    public ChannelAgent selectByPrimaryKey(Long agengId);
    public void updateSelective(ChannelAgent agent);
    public List<ChannelAgent> list(ChannelAgentMapper.DaoQuery query);
    public long count(ChannelAgentMapper.DaoQuery query);
    public void delete(Long id);
    public ChannelAgent login(String account,String pwd) throws  ChannelAgentException;
    public ChannelAgent selectByAlias(String alias);
}
src/main/java/com/taoke/autopay/service/agent/ChannelAgentSettingService.java
New file
@@ -0,0 +1,12 @@
package com.taoke.autopay.service.agent;
import com.taoke.autopay.entity.agent.ChannelAgentSettings;
import java.util.List;
public interface ChannelAgentSettingService {
    public ChannelAgentSettings selectByAgentId(Long agentId);
    public void update(ChannelAgentSettings settings);
    public void add(ChannelAgentSettings settings);
    public List<ChannelAgentSettings> listByIds(List<Long> agentIds);
}
src/main/java/com/taoke/autopay/service/agent/ChannelAgentSettleService.java
New file
@@ -0,0 +1,27 @@
package com.taoke.autopay.service.agent;
import com.taoke.autopay.dao.agent.ChannelAgentSettleRecordMapper;
import com.taoke.autopay.entity.agent.ChannelAgentSettleRecord;
import com.taoke.autopay.exception.ChannelAgentSettleException;
import java.util.List;
public interface ChannelAgentSettleService {
    /**
     * 开始结算
     * @param day
     */
    public void startSettle(String day) throws ChannelAgentSettleException;
    public void settle(ChannelAgentSettleRecord record);
    public List<ChannelAgentSettleRecord> list(ChannelAgentSettleRecordMapper.DaoQuery query);
    public long count(ChannelAgentSettleRecordMapper.DaoQuery query);
    public void delete(Long id);
}
src/main/java/com/taoke/autopay/service/agent/ChannelAgentSharingRatioService.java
@@ -3,7 +3,9 @@
import com.taoke.autopay.entity.OrderChannelEnum;
import com.taoke.autopay.entity.agent.ChannelAgentSharingRatio;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
 * @author hxh
@@ -34,4 +36,26 @@
    public List<ChannelAgentSharingRatio> getShareRatios(Long agengId);
    /**
     * 获取默认的渠道分成比例
     * @return
     */
    public Map<OrderChannelEnum,BigDecimal> getDefaultShareRatio();
    /**
     * 获取每一单的金额
     * @param agengId
     * @return
     */
    public Map<OrderChannelEnum,BigDecimal> getShareMoneyMap(Long agengId);
    /**
     * 设置默认的分成比例
     * @param defaultShareRatio
     */
    public void setDefaultShareRatio(Map<OrderChannelEnum,BigDecimal> defaultShareRatio);
}
src/main/java/com/taoke/autopay/service/impl/KeyOrderServiceImpl.java
@@ -2,8 +2,10 @@
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.exception.KeyOrderException;
import com.taoke.autopay.exception.KeyVerifyException;
import com.taoke.autopay.exception.WxOrderCountException;
@@ -12,6 +14,8 @@
import com.taoke.autopay.service.SystemConfigService;
import com.taoke.autopay.service.WxUserOrderCountService;
import com.taoke.autopay.service.WxUserSettingService;
import com.taoke.autopay.service.agent.ChannelAgentService;
import com.taoke.autopay.service.agent.ChannelAgentSharingRatioService;
import com.taoke.autopay.utils.*;
import com.taoke.autopay.utils.order.DYOrderApi;
import com.taoke.autopay.vo.SubmitKeyInfo;
@@ -21,6 +25,7 @@
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;
@@ -46,6 +51,12 @@
    @Resource
    private SystemConfigService systemConfigService;
    @Resource
    private ChannelAgentService channelAgentService;
    @Resource
    private ChannelAgentSharingRatioService channelAgentSharingRatioService;
    @Override
    public KeyOrder selectById(String id) {
@@ -66,6 +77,24 @@
            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("渠道受限");
                }
                order.setAgentId(agent.getId());
            }
        }
        order.setId(id);
        order.setKey(keyInfo.getKey());
        if(!StringUtil.isNullOrEmpty(keyInfo.getMoney())){
@@ -148,6 +177,53 @@
    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);
        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;
                }
            }
        }
        long userCount = keyOrderMapper.countUser(query);
        ChannelOrderStatistic statistic = new ChannelOrderStatistic();
        statistic.setCount(userCount);
        statistic.setMoney(totalMoney);
        return statistic;
    }
    @Override
    public List<ChannelOrderStatistic> statisticChannelOrders(Long agentId, Date startTime, Date endTime) {
        KeyOrderMapper.DaoQuery daoQuery=new KeyOrderMapper.DaoQuery();
        daoQuery.oMinCreateTime=startTime;
        daoQuery.oMaxCreateTime=endTime;
        daoQuery.agentId = agentId;
        daoQuery.state =KeyOrder.STATE_PAY;
        daoQuery.hasPayTime=true;
        return keyOrderMapper.statisticChannelOrders(daoQuery);
    }
    @Override
    public Long getCanDistributeUid() {
@@ -269,4 +345,14 @@
    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);
    }
}
src/main/java/com/taoke/autopay/service/impl/agent/ChannelAgentServiceImpl.java
@@ -7,6 +7,7 @@
import com.taoke.autopay.utils.AgentAliasUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yeshi.utils.StringUtil;
import javax.annotation.Resource;
import java.util.Date;
@@ -26,7 +27,7 @@
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addChannelAgent(ChannelAgent agent) throws ChannelAgentException {
    public ChannelAgent addChannelAgent(ChannelAgent agent) throws ChannelAgentException {
        ChannelAgentMapper.DaoQuery query=new ChannelAgentMapper.DaoQuery();
        query.account = agent.getAccount();
       long count =  channelAgentMapper.count(query);
@@ -38,7 +39,6 @@
       }
       if(agent.getCreateTime()==null){
           agent.setCreateTime(new Date());
       }
@@ -47,8 +47,11 @@
       // 更新alias
        if(agent.getAlias()==null){
            ChannelAgent update = ChannelAgent.builder().id(agent.getId()).alias(AgentAliasUtil.createAlias(agent.getId())).updateTime(new Date()).build();
            agent.setAlias(update.getAlias());
            channelAgentMapper.updateByPrimaryKeySelective(update);
        }
        return agent;
    }
@@ -61,6 +64,11 @@
        }
        ChannelAgent update= ChannelAgent.builder().id(agentId).alipayAccount(account).alipayName(name).alipayUpdateTime(new Date()).updateTime(new Date()).build();
        updateSelective(update);
    }
    @Override
    public ChannelAgent selectByPrimaryKey(Long agengId) {
        return channelAgentMapper.selectByPrimaryKey(agengId);
    }
    @Override
@@ -80,4 +88,39 @@
    public long count(ChannelAgentMapper.DaoQuery query) {
        return channelAgentMapper.count(query);
    }
    @Override
    public void delete(Long id) {
        channelAgentMapper.deleteByPrimaryKey(id);
    }
    @Override
    public ChannelAgent login(String account, String pwd) throws ChannelAgentException {
        ChannelAgentMapper.DaoQuery query = new ChannelAgentMapper.DaoQuery();
        query.account = account;
        query.count = 1;
        List<ChannelAgent> list = channelAgentMapper.list(query);
        if (list.isEmpty()) {
            throw new ChannelAgentException("账户不存在");
        }
        if (!list.get(0).getPwd().equalsIgnoreCase(StringUtil.Md5(pwd))) {
            throw new ChannelAgentException("密码错误");
        }
        return list.get(0);
    }
    @Override
    public ChannelAgent selectByAlias(String alias) {
        ChannelAgentMapper.DaoQuery query = new ChannelAgentMapper.DaoQuery();
        query.alias = alias;
        query.count = 1;
        List<ChannelAgent> list = channelAgentMapper.list(query);
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }
}
src/main/java/com/taoke/autopay/service/impl/agent/ChannelAgentSettingServiceImpl.java
New file
@@ -0,0 +1,51 @@
package com.taoke.autopay.service.impl.agent;
import com.taoke.autopay.dao.agent.ChannelAgentSettingsMapper;
import com.taoke.autopay.entity.agent.ChannelAgentSettings;
import com.taoke.autopay.service.agent.ChannelAgentSettingService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
@Service
public class ChannelAgentSettingServiceImpl implements ChannelAgentSettingService {
    @Resource
    private ChannelAgentSettingsMapper channelAgentSettingsMapper;
    @Override
    public ChannelAgentSettings selectByAgentId(Long agentId) {
        return channelAgentSettingsMapper.selectByPrimaryKey(agentId);
    }
    @Override
    public void update(ChannelAgentSettings settings) {
        if(settings.getUpdateTime()==null){
            settings.setUpdateTime(new Date());
        }
        channelAgentSettingsMapper.updateByPrimaryKeySelective(settings);
    }
    @Override
    public void add(ChannelAgentSettings settings) {
        // 如果存在就修改
        ChannelAgentSettings old=   selectByAgentId(settings.getId());
        if(old==null){
            if(settings.getCreateTime()==null){
                settings.setCreateTime(new Date());
            }
            channelAgentSettingsMapper.insertSelective(settings);
        }else{
            update(settings);
        }
    }
    @Override
    public List<ChannelAgentSettings> listByIds(List<Long> agentIds) {
        return channelAgentSettingsMapper.listByIds(agentIds);
    }
}
src/main/java/com/taoke/autopay/service/impl/agent/ChannelAgentSettleServiceImpl.java
New file
@@ -0,0 +1,167 @@
package com.taoke.autopay.service.impl.agent;
import com.taoke.autopay.dao.KeyOrderMapper;
import com.taoke.autopay.dao.agent.ChannelAgentSettleDetailMapper;
import com.taoke.autopay.dao.agent.ChannelAgentSettleRecordMapper;
import com.taoke.autopay.dto.ChannelOrderStatistic;
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.entity.OrderChannelEnum;
import com.taoke.autopay.entity.agent.ChannelAgent;
import com.taoke.autopay.entity.agent.ChannelAgentSettleDetail;
import com.taoke.autopay.entity.agent.ChannelAgentSettleRecord;
import com.taoke.autopay.exception.ChannelAgentSettleException;
import com.taoke.autopay.service.KeyOrderService;
import com.taoke.autopay.service.agent.ChannelAgentService;
import com.taoke.autopay.service.agent.ChannelAgentSettleService;
import com.taoke.autopay.service.agent.ChannelAgentSharingRatioService;
import com.taoke.autopay.utils.TimeUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Service
public class ChannelAgentSettleServiceImpl implements ChannelAgentSettleService {
    @Resource
    private ChannelAgentSettleRecordMapper channelAgentSettleRecordMapper;
    @Resource
    private ChannelAgentSettleDetailMapper channelAgentSettleDetailMapper;
    @Resource
    private ChannelAgentSharingRatioService channelAgentSharingRatioService;
    @Resource
    private KeyOrderService keyOrderService;
    @Resource
    private ChannelAgentService channelAgentService;
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void startSettle(String day) throws ChannelAgentSettleException {
        // 查询可结算的代理用户
        Date startTime = new Date(TimeUtil.convertToTimeTemp(day, "yyyy-MM-dd"));
        Date endTime = new Date(startTime.getTime() + 1000 * 60 * 60 * 24L);
        KeyOrderMapper.DaoQuery orderQuery = new KeyOrderMapper.DaoQuery();
        orderQuery.minCreateTime = startTime;
        orderQuery.maxCreateTime = endTime;
        orderQuery.hasAgentId = true;
        orderQuery.hasPayTime = true;
        orderQuery.state = KeyOrder.STATE_PAY;
        orderQuery.count = (int) keyOrderService.countAgentId(orderQuery);
        if (orderQuery.count <= 0) {
            throw new ChannelAgentSettleException("无可结算的代理");
        }
        List<Long> agentList = keyOrderService.listAgentId(orderQuery);
        for (Long agentId : agentList) {
            // 统计订单
            orderQuery = new KeyOrderMapper.DaoQuery();
            orderQuery.oMinCreateTime = startTime;
            orderQuery.oMaxCreateTime = endTime;
            orderQuery.agentId = agentId;
            orderQuery.hasPayTime = true;
            orderQuery.state = KeyOrder.STATE_PAY;
            List<ChannelOrderStatistic> list = keyOrderService.statisticChannelOrders(agentId, startTime, endTime);
            List<ChannelAgentSettleDetail> detailList = new ArrayList<>();
            Map<OrderChannelEnum, BigDecimal> shareMoneyMap = channelAgentSharingRatioService.getShareMoneyMap(agentId);
            for (ChannelOrderStatistic statistic : list) {
                OrderChannelEnum orderChannel = null;
                for (OrderChannelEnum channel : OrderChannelEnum.values()) {
                    if (channel.getKey().equalsIgnoreCase(statistic.getOrderChannel())) {
                        orderChannel = channel;
                        break;
                    }
                }
                if (orderChannel != null) {
                    if (shareMoneyMap.containsKey(orderChannel)) {
                        BigDecimal money = shareMoneyMap.get(orderChannel).multiply(new BigDecimal(statistic.getCount()));
                        // 查询是否已经结算
                        detailList.add(ChannelAgentSettleDetail.builder()
                                .orderChannel(orderChannel)
                                .payOrderCount(statistic.getCount())
                                .payMoney(statistic.getMoney())
                                .money(money)
                                .build());
                    }
                }
            }
            if (detailList.isEmpty()) {
                continue;
            }
            BigDecimal totalMoney = new BigDecimal(0);
            for (ChannelAgentSettleDetail detail : detailList) {
                totalMoney = totalMoney.add(detail.getMoney());
            }
            ChannelAgent agent = channelAgentService.selectByPrimaryKey(agentId);
            settle(ChannelAgentSettleRecord.builder()
                    .agentId(agentId)
                    .settleDay(day)
                    .settleMoney(totalMoney)
                    .alipayAccount(agent.getAlipayAccount())
                    .alipayName(agent.getAlipayName())
                    .detailList(detailList)
                    .build());
        }
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void settle(ChannelAgentSettleRecord record) {
        // 查询是否结算
        ChannelAgentSettleRecordMapper.DaoQuery daoQuery = new ChannelAgentSettleRecordMapper.DaoQuery();
        daoQuery.agentId = record.getAgentId();
        daoQuery.settleDay = record.getSettleDay();
        if (channelAgentSettleRecordMapper.count(daoQuery) > 0) {
            // 已经结算
            return;
        }
        if (record.getCreateTime() == null) {
            record.setCreateTime(new Date());
        }
        if (record.getStatus() == null) {
            record.setStatus(ChannelAgentSettleRecord.STATUS_NOT_SETTLE);
            record.setStatusDesc("已结算,待确认");
        }
        channelAgentSettleRecordMapper.insertSelective(record);
        for (ChannelAgentSettleDetail detail : record.getDetailList()) {
            detail.setSettleId(record.getId());
            if (detail.getCreateTime() == null) {
                detail.setCreateTime(new Date());
            }
            channelAgentSettleDetailMapper.insertSelective(detail);
        }
    }
    @Override
    public List<ChannelAgentSettleRecord> list(ChannelAgentSettleRecordMapper.DaoQuery query) {
        return channelAgentSettleRecordMapper.list(query);
    }
    @Override
    public long count(ChannelAgentSettleRecordMapper.DaoQuery query) {
        return channelAgentSettleRecordMapper.count(query);
    }
    @Override
    public void delete(Long id) {
        ChannelAgentSettleRecord record = channelAgentSettleRecordMapper.selectByPrimaryKey(id);
        if (record != null) {
            channelAgentSettleRecordMapper.deleteByPrimaryKey(id);
            for (ChannelAgentSettleDetail d : record.getDetailList()) {
                channelAgentSettleDetailMapper.deleteByPrimaryKey(d.getId());
            }
        }
    }
}
src/main/java/com/taoke/autopay/service/impl/agent/ChannelAgentSharingRatioServiceImpl.java
@@ -1,11 +1,18 @@
package com.taoke.autopay.service.impl.agent;
import com.taoke.autopay.dao.agent.ChannelAgentSharingRatioMapper;
import com.taoke.autopay.entity.OrderChannelEnum;
import com.taoke.autopay.entity.SystemConfigKeyEnum;
import com.taoke.autopay.entity.agent.ChannelAgentSharingRatio;
import com.taoke.autopay.service.SystemConfigService;
import com.taoke.autopay.service.agent.ChannelAgentSharingRatioService;
import com.taoke.autopay.utils.StringUtil;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Service;
import java.util.List;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
/**
 * @author hxh
@@ -15,18 +22,95 @@
 */
@Service
public class ChannelAgentSharingRatioServiceImpl implements ChannelAgentSharingRatioService {
    @Resource
    private SystemConfigService systemConfigService;
    @Resource
    private ChannelAgentSharingRatioMapper channelAgentSharingRatioMapper;
    @Override
    public void setShareRatio(ChannelAgentSharingRatio shareRatio) {
        ChannelAgentSharingRatio old = getShareRatio(shareRatio.getAgengId(), shareRatio.getOrderChannel());
        if (old != null) {
            if (shareRatio.getUpdateTime() != null) {
                shareRatio.setUpdateTime(new Date());
            }
            channelAgentSharingRatioMapper.updateByPrimaryKeySelective(shareRatio);
        } else {
            if (shareRatio.getCreateTime() == null) {
                shareRatio.setCreateTime(new Date());
            }
            channelAgentSharingRatioMapper.insertSelective(shareRatio);
        }
    }
    @Override
    public ChannelAgentSharingRatio getShareRatio(Long agengId, OrderChannelEnum orderChannel) {
        ChannelAgentSharingRatioMapper.DaoQuery daoQuery = new ChannelAgentSharingRatioMapper.DaoQuery();
        daoQuery.agengId = agengId;
        daoQuery.orderChannel = orderChannel;
        daoQuery.count = 0;
        List<ChannelAgentSharingRatio> list = channelAgentSharingRatioMapper.list(daoQuery);
        if (list.isEmpty()) {
        return null;
        }
        return list.get(0);
    }
    @Override
    public List<ChannelAgentSharingRatio> getShareRatios(Long agengId) {
        return null;
        ChannelAgentSharingRatioMapper.DaoQuery daoQuery = new ChannelAgentSharingRatioMapper.DaoQuery();
        daoQuery.agengId = agengId;
        daoQuery.count = 1000;
        return channelAgentSharingRatioMapper.list(daoQuery);
    }
    @Override
    public Map<OrderChannelEnum, BigDecimal> getDefaultShareRatio() {
        String value = systemConfigService.getValueCache(SystemConfigKeyEnum.AGENT_ORDER_CHANNEL_SHARE_RATIO);
        if (StringUtil.isNullOrEmpty(value)) {
            return new HashMap<>();
        }
        Map<OrderChannelEnum, BigDecimal> map = new HashMap<>();
        JSONObject data = JSONObject.fromObject(value);
        for (OrderChannelEnum channel : OrderChannelEnum.values()) {
            if (data.optString(channel.name()) != null) {
                map.put(channel, new BigDecimal(data.optString(channel.name())));
            }
        }
        return map;
    }
    @Override
    public Map<OrderChannelEnum, BigDecimal> getShareMoneyMap(Long agengId) {
        List<ChannelAgentSharingRatio> list = getShareRatios(agengId);
        Map<OrderChannelEnum, ChannelAgentSharingRatio> listMap = new HashMap<>();
        for (ChannelAgentSharingRatio c : list) {
            listMap.put(c.getOrderChannel(), c);
        }
        Map<OrderChannelEnum, BigDecimal> defaultMap = getDefaultShareRatio();
        Map<OrderChannelEnum, BigDecimal> map = new HashMap<>();
        for (OrderChannelEnum channel : OrderChannelEnum.values()) {
            if (listMap.containsKey(channel)) {
                map.put(channel, listMap.get(channel).getShareValue());
            } else {
                map.put(channel, defaultMap.getOrDefault(channel, null));
            }
        }
        return map;
    }
    @Override
    public void setDefaultShareRatio(Map<OrderChannelEnum, BigDecimal> defaultShareRatio) {
        JSONObject data = new JSONObject();
        for (OrderChannelEnum key : defaultShareRatio.keySet()) {
            if (defaultShareRatio.get(key) != null) {
                data.put(key.name(), defaultShareRatio.get(key));
            }
        }
        systemConfigService.setValue(SystemConfigKeyEnum.AGENT_ORDER_CHANNEL_SHARE_RATIO,data.toString() );
    }
}
src/main/java/com/taoke/autopay/utils/AgentUtil.java
New file
@@ -0,0 +1,9 @@
package com.taoke.autopay.utils;
public class AgentUtil {
    public static String getSubmitKeyUrl(String baseUrl, String alias){
        return baseUrl.replace("{alias}",alias);
    }
}
src/main/java/com/taoke/autopay/utils/Constant.java
@@ -12,6 +12,8 @@
    public final static String SESSION_KEY_USER ="session_user";
    public final static String SESSION_KEY_AGENT ="session_agent";
    public final static String SESSION_KEY_TEMP_ALIPAY_KEY ="session_temp_alipay_key";
    public final static int ORDER_TYPE_UNKNOWN=0;
src/main/java/com/taoke/autopay/utils/LogUtil.java
New file
@@ -0,0 +1,9 @@
package com.taoke.autopay.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogUtil {
    public static Logger loggerDebug= LoggerFactory.getLogger("debugLogger");
}
src/main/java/com/taoke/autopay/vo/AgentOrderFilter.java
New file
@@ -0,0 +1,23 @@
package com.taoke.autopay.vo;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Tolerate;
/**
 * @author hxh
 * @title: AgentOrderFilter
 * @description: TODO
 * @date 2024/6/14 20:04
 */
@Data
@Builder
public class AgentOrderFilter {
    @Tolerate
    public AgentOrderFilter(){
    }
    private int timeIndex;
    private String key;
    private int page;
}
src/main/java/com/taoke/autopay/vo/AgentOrderVO.java
New file
@@ -0,0 +1,14 @@
package com.taoke.autopay.vo;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class AgentOrderVO {
    private UserInfoVO user;
    private String createTime;
    private String settleMoney;
    private String payMoney;
    private boolean valid;
}
src/main/java/com/taoke/autopay/vo/SubmitKeyInfo.java
@@ -13,6 +13,7 @@
    private String key;
    private String money;
    private String referer;
    private String a;
    public SubmitKeyInfo() {
    }
@@ -54,4 +55,12 @@
    public void setReferer(String referer) {
        this.referer = referer;
    }
    public String getA() {
        return a;
    }
    public void setA(String a) {
        this.a = a;
    }
}
src/main/java/com/taoke/autopay/vo/UserInfoVO.java
New file
@@ -0,0 +1,12 @@
package com.taoke.autopay.vo;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class UserInfoVO {
    private Long id;
    private String portrait;
    private String nickName;
}
src/main/java/com/taoke/autopay/vo/admin/AdminChannelAgentVO.java
New file
@@ -0,0 +1,34 @@
package com.taoke.autopay.vo.admin;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Tolerate;
import java.util.Date;
@Builder
@Data
public class AdminChannelAgentVO {
    @Tolerate
    public AdminChannelAgentVO(){
    }
    private Long id;
    private String name;
    private String alias;
    private String account;
    private String pwd;
    private String alipayName;
    private String alipayAccount;
    private Integer status;
    private String statusDesc;
    private String submitKeyLink;
    private String startSubmitTime;
    private String endSubmitTime;
    private String maxKeyCountPerDay;
    private String maxPayMoneyPerDay;
    private Date createTime;
    private String shareRatioInfos;
}
src/main/java/com/taoke/autopay/vo/admin/AgentSearchVO.java
New file
@@ -0,0 +1,16 @@
package com.taoke.autopay.vo.admin;
import lombok.Data;
/**
 * @author hxh
 * @title: OrderSearchVO
 * @description: 订单搜索
 * @date 2024/7/18 22:33
 */
@Data
public class AgentSearchVO {
    private String key;
    private String startDate;
    private String endDate;
}
src/main/resources/logback.xml
@@ -154,6 +154,10 @@
        <appender-ref ref="keyVerifyAppender"></appender-ref>
    </logger>
    <logger name="debugLogger" level="INFO" additivity="false">
        <appender-ref ref="debugAppender"></appender-ref>
    </logger>
src/main/resources/mapper/ChannelAgentMapper.xml
@@ -16,16 +16,20 @@
    <result column="_create_time" property="createTime" jdbcType="TIMESTAMP"/>
    <result column="_update_time" property="updateTime" jdbcType="TIMESTAMP"/>
  </resultMap>
  <sql id="Base_Column_List">_id,_name,_alias,_account,_pwd,_alipay_name,_alipay_account,_alipay_update_time,_status,_status_desc,_create_time,_update_time</sql>
    <sql id="Base_Column_List">_id
    ,_name,_alias,_account,_pwd,_alipay_name,_alipay_account,_alipay_update_time,_status,_status_desc,_create_time,_update_time</sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long">select
    <include refid="Base_Column_List"/> from table_agent where _id = #{id,jdbcType=BIGINT}
        <include refid="Base_Column_List"/>
        from table_agent where _id = #{id,jdbcType=BIGINT}
  </select>
  <select id="selectByPrimaryKeyForUpdate" resultMap="BaseResultMap" parameterType="java.lang.Long">select
    <include refid="Base_Column_List"/> from table_agent where _id = #{id,jdbcType=BIGINT} for update
        <include refid="Base_Column_List"/>
        from table_agent where _id = #{id,jdbcType=BIGINT} for update
  </select>
  <sql id="listWhereSQL">
    <if test="query.id!=null">AND _id = #{query.id}</if>
    <if test="query.name!=null">AND _name = #{query.name}</if>
        <if test="query.searchKey!=null">AND (_name like '%${query.searchKey}%' or _alias = #{query.searchKey} )</if>
        <if test="query.name!=null">AND _name like '%${query.name}%'</if>
    <if test="query.alias!=null">AND _alias = #{query.alias}</if>
    <if test="query.account!=null">AND _account = #{query.account}</if>
    <if test="query.pwd!=null">AND _pwd = #{query.pwd}</if>
@@ -41,18 +45,32 @@
    <if test="query.maxUpdateTime!=null">AND #{query.maxUpdateTime} > _update_time</if>
  </sql>
  <select id="list" resultMap="BaseResultMap">select
    <include refid="Base_Column_List"/> from table_agent where 1=1
        <include refid="Base_Column_List"/>
        from table_agent where 1=1
    <include refid="listWhereSQL"/>
    <if test="query.sortList!=null">
      <foreach collection="query.sortList" item="item" open=" order by " separator=",">#{item}</foreach>
    </if>limit #{query.start},#{query.count}
            <foreach collection="query.sortList" item="item" open=" order by " separator=",">${item}</foreach>
        </if>
        limit #{query.start},#{query.count}
  </select>
  <select id="count" resultType="java.lang.Long">select count(*) from table_agent where 1=1
    <include refid="listWhereSQL"/>
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">delete from table_agent where _id = #{id,jdbcType=BIGINT}</delete>
  <insert id="insert" parameterType="com.taoke.autopay.entity.agent.ChannelAgent" useGeneratedKeys="true" keyProperty="id">insert into table_agent (_id,_name,_alias,_account,_pwd,_alipay_name,_alipay_account,_alipay_update_time,_status,_status_desc,_create_time,_update_time) values (#{id,jdbcType=BIGINT},#{name,jdbcType=VARCHAR},#{alias,jdbcType=VARCHAR},#{account,jdbcType=VARCHAR},#{pwd,jdbcType=VARCHAR},#{alipayName,jdbcType=VARCHAR},#{alipayAccount,jdbcType=VARCHAR},#{alipayUpdateTime,jdbcType=TIMESTAMP},#{status,jdbcType=INTEGER},#{statusDesc,jdbcType=VARCHAR},#{createTime,jdbcType=TIMESTAMP},#{updateTime,jdbcType=TIMESTAMP})</insert>
  <insert id="insertSelective" parameterType="com.taoke.autopay.entity.agent.ChannelAgent" useGeneratedKeys="true" keyProperty="id">insert into table_agent
    <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">delete
                                                                   from table_agent
                                                                   where _id = #{id,jdbcType=BIGINT}</delete>
    <insert id="insert" parameterType="com.taoke.autopay.entity.agent.ChannelAgent" useGeneratedKeys="true"
            keyProperty="id">insert into table_agent (_id, _name, _alias, _account, _pwd, _alipay_name, _alipay_account,
                                                      _alipay_update_time, _status, _status_desc, _create_time,
                                                      _update_time)
                             values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{alias,jdbcType=VARCHAR},
                                     #{account,jdbcType=VARCHAR}, #{pwd,jdbcType=VARCHAR},
                                     #{alipayName,jdbcType=VARCHAR}, #{alipayAccount,jdbcType=VARCHAR},
                                     #{alipayUpdateTime,jdbcType=TIMESTAMP}, #{status,jdbcType=INTEGER},
                                     #{statusDesc,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP},
                                     #{updateTime,jdbcType=TIMESTAMP})</insert>
    <insert id="insertSelective" parameterType="com.taoke.autopay.entity.agent.ChannelAgent" useGeneratedKeys="true"
            keyProperty="id">insert into table_agent
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">_id,</if>
      <if test="name != null">_name,</if>
@@ -66,7 +84,8 @@
      <if test="statusDesc != null">_status_desc,</if>
      <if test="createTime != null">_create_time,</if>
      <if test="updateTime != null">_update_time,</if>
    </trim>values
        </trim>
        values
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">#{id,jdbcType=BIGINT},</if>
      <if test="name != null">#{name,jdbcType=VARCHAR},</if>
@@ -82,8 +101,21 @@
      <if test="updateTime != null">#{updateTime,jdbcType=TIMESTAMP},</if>
    </trim>
  </insert>
  <update id="updateByPrimaryKey" parameterType="com.taoke.autopay.entity.agent.ChannelAgent">update table_agent set _name = #{name,jdbcType=VARCHAR},_alias = #{alias,jdbcType=VARCHAR},_account = #{account,jdbcType=VARCHAR},_pwd = #{pwd,jdbcType=VARCHAR},_alipay_name = #{alipayName,jdbcType=VARCHAR},_alipay_account = #{alipayAccount,jdbcType=VARCHAR},_alipay_update_time = #{alipayUpdateTime,jdbcType=TIMESTAMP},_status = #{status,jdbcType=INTEGER},_status_desc = #{statusDesc,jdbcType=VARCHAR},_create_time = #{createTime,jdbcType=TIMESTAMP},_update_time = #{updateTime,jdbcType=TIMESTAMP} where _id = #{id,jdbcType=BIGINT}</update>
  <update id="updateByPrimaryKeySelective" parameterType="com.taoke.autopay.entity.agent.ChannelAgent">update table_agent
    <update id="updateByPrimaryKey" parameterType="com.taoke.autopay.entity.agent.ChannelAgent">update table_agent
                                                                                                set _name               = #{name,jdbcType=VARCHAR},
                                                                                                    _alias              = #{alias,jdbcType=VARCHAR},
                                                                                                    _account            = #{account,jdbcType=VARCHAR},
                                                                                                    _pwd                = #{pwd,jdbcType=VARCHAR},
                                                                                                    _alipay_name        = #{alipayName,jdbcType=VARCHAR},
                                                                                                    _alipay_account     = #{alipayAccount,jdbcType=VARCHAR},
                                                                                                    _alipay_update_time = #{alipayUpdateTime,jdbcType=TIMESTAMP},
                                                                                                    _status             = #{status,jdbcType=INTEGER},
                                                                                                    _status_desc        = #{statusDesc,jdbcType=VARCHAR},
                                                                                                    _create_time        = #{createTime,jdbcType=TIMESTAMP},
                                                                                                    _update_time        = #{updateTime,jdbcType=TIMESTAMP}
                                                                                                where _id = #{id,jdbcType=BIGINT}</update>
    <update id="updateByPrimaryKeySelective" parameterType="com.taoke.autopay.entity.agent.ChannelAgent">update
        table_agent
    <set>
      <if test="name != null">_name=#{name,jdbcType=VARCHAR},</if>
      <if test="alias != null">_alias=#{alias,jdbcType=VARCHAR},</if>
@@ -96,6 +128,7 @@
      <if test="statusDesc != null">_status_desc=#{statusDesc,jdbcType=VARCHAR},</if>
      <if test="createTime != null">_create_time=#{createTime,jdbcType=TIMESTAMP},</if>
      <if test="updateTime != null">_update_time=#{updateTime,jdbcType=TIMESTAMP},</if>
    </set> where _id = #{id,jdbcType=BIGINT}
        </set>
        where _id = #{id,jdbcType=BIGINT}
  </update>
</mapper>
src/main/resources/mapper/ChannelAgentSettingsMapper.xml
@@ -72,4 +72,10 @@
      <if test="updateTime != null">_update_time=#{updateTime,jdbcType=TIMESTAMP},</if>
    </set> where _id = #{id,jdbcType=BIGINT}
  </update>
  <select id="listByIds" resultMap="BaseResultMap">select
    <include refid="Base_Column_List"/> from table_agent_settings where
    <foreach collection="agentIds" item="item" open="(" separator=" or " close=")">_id = #{item}</foreach>
  </select>
</mapper>
src/main/resources/mapper/ChannelAgentSettleDetailMapper.xml
New file
@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.taoke.autopay.dao.agent.ChannelAgentSettleDetailMapper">
    <resultMap id="BaseResultMap" type="com.taoke.autopay.entity.agent.ChannelAgentSettleDetail">
        <id column="_id" property="id" jdbcType="BIGINT"/>
        <result column="_settle_id" property="settleId" jdbcType="BIGINT"/>
        <result column="_order_channel" property="orderChannel" jdbcType="VARCHAR"/>
        <result column="_pay_order_count" property="payOrderCount" jdbcType="BIGINT"/>
        <result column="_pay_money" property="payMoney" jdbcType="DECIMAL"/>
        <result column="_money" property="money" jdbcType="DECIMAL"/>
        <result column="_create_time" property="createTime" jdbcType="TIMESTAMP"/>
        <result column="_update_time" property="updateTime" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">_id
    ,_settle_id,_order_channel,_pay_order_count,_pay_money,_money,_create_time,_update_time</sql>
    <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long">select
        <include refid="Base_Column_List"/>
        from table_agent_settle_detail where _id = #{id,jdbcType=BIGINT}
    </select>
    <select id="selectByPrimaryKeyForUpdate" resultMap="BaseResultMap" parameterType="java.lang.Long">select
        <include refid="Base_Column_List"/>
        from table_agent_settle_detail where _id = #{id,jdbcType=BIGINT} for update
    </select>
    <sql id="listWhereSQL">
        <if test="query.id!=null">AND _id = #{query.id}</if>
        <if test="query.settleId!=null">AND _settle_id = #{query.settleId}</if>
        <if test="query.orderChannel!=null">AND _order_channel = #{query.orderChannel}</if>
        <if test="query.payOrderCount!=null">AND _pay_order_count = #{query.payOrderCount}</if>
        <if test="query.payMoney!=null">AND _pay_money = #{query.payMoney}</if>
        <if test="query.money!=null">AND _money = #{query.money}</if>
        <if test="query.minCreateTime!=null">AND _create_time >= #{query.minCreateTime}</if>
        <if test="query.maxCreateTime!=null">AND #{query.maxCreateTime} > _create_time</if>
        <if test="query.minUpdateTime!=null">AND _update_time >= #{query.minUpdateTime}</if>
        <if test="query.maxUpdateTime!=null">AND #{query.maxUpdateTime} > _update_time</if>
    </sql>
    <select id="list" resultMap="BaseResultMap">select
        <include refid="Base_Column_List"/>
        from table_agent_settle_detail where 1=1
        <include refid="listWhereSQL"/>
        <if test="query.sortList!=null">
            <foreach collection="query.sortList" item="item" open=" order by " separator=",">#{item}</foreach>
        </if>
        limit #{query.start},#{query.count}
    </select>
    <select id="listBySettleId" resultMap="BaseResultMap" parameterType="java.lang.Long">select
        <include refid="Base_Column_List"/>
        from table_agent_settle_detail where _settle_id=#{0}
    </select>
    <select id="count" resultType="java.lang.Long">select count(*) from table_agent_settle_detail where 1=1
        <include refid="listWhereSQL"/>
    </select>
    <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">delete
                                                                   from table_agent_settle_detail
                                                                   where _id = #{id,jdbcType=BIGINT}</delete>
    <insert id="insert" parameterType="com.taoke.autopay.entity.agent.ChannelAgentSettleDetail" useGeneratedKeys="true"
            keyProperty="id">insert into table_agent_settle_detail (_id, _settle_id, _order_channel, _pay_order_count,
                                                                    _pay_money, _money, _create_time, _update_time)
                             values (#{id,jdbcType=BIGINT}, #{settleId,jdbcType=BIGINT},
                                     #{orderChannel,jdbcType=VARCHAR}, #{payOrderCount,jdbcType=BIGINT},
                                     #{payMoney,jdbcType=DECIMAL}, #{money,jdbcType=DECIMAL},
                                     #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP})</insert>
    <insert id="insertSelective" parameterType="com.taoke.autopay.entity.agent.ChannelAgentSettleDetail"
            useGeneratedKeys="true" keyProperty="id">
        insert into table_agent_settle_detail
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">_id,</if>
            <if test="settleId != null">_settle_id,</if>
            <if test="orderChannel != null">_order_channel,</if>
            <if test="payOrderCount != null">_pay_order_count,</if>
            <if test="payMoney != null">_pay_money,</if>
            <if test="money != null">_money,</if>
            <if test="createTime != null">_create_time,</if>
            <if test="updateTime != null">_update_time,</if>
        </trim>
        values
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">#{id,jdbcType=BIGINT},</if>
            <if test="settleId != null">#{settleId,jdbcType=BIGINT},</if>
            <if test="orderChannel != null">#{orderChannel,jdbcType=VARCHAR},</if>
            <if test="payOrderCount != null">#{payOrderCount,jdbcType=BIGINT},</if>
            <if test="payMoney != null">#{payMoney,jdbcType=DECIMAL},</if>
            <if test="money != null">#{money,jdbcType=DECIMAL},</if>
            <if test="createTime != null">#{createTime,jdbcType=TIMESTAMP},</if>
            <if test="updateTime != null">#{updateTime,jdbcType=TIMESTAMP},</if>
        </trim>
    </insert>
    <update id="updateByPrimaryKey"
            parameterType="com.taoke.autopay.entity.agent.ChannelAgentSettleDetail">update table_agent_settle_detail
                                                                                    set _settle_id       = #{settleId,jdbcType=BIGINT},
                                                                                        _order_channel   = #{orderChannel,jdbcType=VARCHAR},
                                                                                        _pay_order_count = #{payOrderCount,jdbcType=BIGINT},
                                                                                        _pay_money       = #{payMoney,jdbcType=DECIMAL},
                                                                                        _money           = #{money,jdbcType=DECIMAL},
                                                                                        _create_time     = #{createTime,jdbcType=TIMESTAMP},
                                                                                        _update_time     = #{updateTime,jdbcType=TIMESTAMP}
                                                                                    where _id = #{id,jdbcType=BIGINT}</update>
    <update id="updateByPrimaryKeySelective" parameterType="com.taoke.autopay.entity.agent.ChannelAgentSettleDetail">
        update table_agent_settle_detail
        <set>
            <if test="settleId != null">_settle_id=#{settleId,jdbcType=BIGINT},</if>
            <if test="orderChannel != null">_order_channel=#{orderChannel,jdbcType=VARCHAR},</if>
            <if test="payOrderCount != null">_pay_order_count=#{payOrderCount,jdbcType=BIGINT},</if>
            <if test="payMoney != null">_pay_money=#{payMoney,jdbcType=DECIMAL},</if>
            <if test="money != null">_money=#{money,jdbcType=DECIMAL},</if>
            <if test="createTime != null">_create_time=#{createTime,jdbcType=TIMESTAMP},</if>
            <if test="updateTime != null">_update_time=#{updateTime,jdbcType=TIMESTAMP},</if>
        </set>
        where _id = #{id,jdbcType=BIGINT}
    </update>
</mapper>
src/main/resources/mapper/ChannelAgentSettleRecordMapper.xml
@@ -10,28 +10,36 @@
    <result column="_actual_settle_money" property="actualSettleMoney" jdbcType="DECIMAL"/>  
    <result column="_pay_time" property="payTime" jdbcType="TIMESTAMP"/>  
    <result column="_status" property="status" jdbcType="INTEGER"/>  
    <result column="_status_desc" property="statusDesc" jdbcType="INTEGER"/>
        <result column="_status_desc" property="statusDesc" jdbcType="VARCHAR"/>
    <result column="_settle_time" property="settleTime" jdbcType="TIMESTAMP"/>  
    <result column="_withdraw_apply_time" property="withDrawApplyTime" jdbcType="TIMESTAMP"/>  
    <result column="_withdraw_process_time" property="withDrawProcessTime" jdbcType="TIMESTAMP"/>  
    <result column="_create_time" property="createTime" jdbcType="TIMESTAMP"/>
    <result column="_update_time" property="updateTime" jdbcType="TIMESTAMP"/>
    <result column="_alipay_name" property="alipayName" jdbcType="VARCHAR"/>  
    <result column="_alipay_account" property="alipayAccount" jdbcType="VARCHAR"/> 
        <result column="_create_time" property="createTime" jdbcType="TIMESTAMP"/>
        <result column="_update_time" property="updateTime" jdbcType="TIMESTAMP"/>
        <association property="agent" column="_agent_id"
                     select="com.taoke.autopay.dao.agent.ChannelAgentMapper.selectByPrimaryKey">
        </association>
        <collection property="detailList" column="_id" ofType="com.taoke.autopay.entity.agent.ChannelAgentSettleDetail"
                    select="com.taoke.autopay.dao.agent.ChannelAgentSettleDetailMapper.listBySettleId">
        </collection>
  </resultMap>  
  <sql id="Base_Column_List">_id,_agent_id,_settle_day,_settle_money,_actual_settle_money,_pay_time,_status,_status_desc,_settle_time,_withdraw_apply_time,_withdraw_process_time,_create_time,_update_time,_alipay_name,_alipay_account</sql>
    <sql id="Base_Column_List">
        _id,_agent_id,_settle_day,_settle_money,_actual_settle_money,_pay_time,_status,_status_desc,_settle_time,_withdraw_apply_time,_withdraw_process_time,_alipay_name,_alipay_account,_create_time,_update_time
    </sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long">select 
    <include refid="Base_Column_List"/> from table_agent_settle_record where _id = #{id,jdbcType=BIGINT}
        <include refid="Base_Column_List"/>
        from table_agent_settle_record where _id = #{id,jdbcType=BIGINT}
  </select>  
  <select id="selectByPrimaryKeyForUpdate" resultMap="BaseResultMap" parameterType="java.lang.Long">select 
    <include refid="Base_Column_List"/> from table_agent_settle_record where _id = #{id,jdbcType=BIGINT} for update
        <include refid="Base_Column_List"/>
        from table_agent_settle_record where _id = #{id,jdbcType=BIGINT} for update
  </select>  
  <sql id="listWhereSQL"> 
    <if test="query.STATUS_NOT_SETTLE!=null">AND STATUS_NOT_SETTLE = #{query.STATUS_NOT_SETTLE}</if>
    <if test="query.STATUS_SETTLED!=null">AND STATUS_SETTLED = #{query.STATUS_SETTLED}</if>
    <if test="query.STATUS_WITHDRAWING!=null">AND STATUS_WITHDRAWING = #{query.STATUS_WITHDRAWING}</if>
    <if test="query.STATUS_WITHDRAW_SUCCESS!=null">AND STATUS_WITHDRAW_SUCCESS = #{query.STATUS_WITHDRAW_SUCCESS}</if>
    <if test="query.STATUS_WITHDRAW_REJECTED!=null">AND STATUS_WITHDRAW_REJECTED = #{query.STATUS_WITHDRAW_REJECTED}</if>
    <if test="query.id!=null">AND _id = #{query.id}</if>  
    <if test="query.agentId!=null">AND _agent_id = #{query.agentId}</if>  
    <if test="query.settleDay!=null">AND _settle_day = #{query.settleDay}</if>  
@@ -45,26 +53,48 @@
    <if test="query.maxSettleTime!=null">AND #{query.maxSettleTime} &gt; _settle_time</if>  
    <if test="query.minWithDrawApplyTime!=null">AND _withdraw_apply_time &gt;= #{query.minWithDrawApplyTime}</if>  
    <if test="query.maxWithDrawApplyTime!=null">AND #{query.maxWithDrawApplyTime} &gt; _withdraw_apply_time</if>  
    <if test="query.minWithDrawProcessTime!=null">AND _withdraw_process_time &gt;= #{query.minWithDrawProcessTime}</if>
    <if test="query.maxWithDrawProcessTime!=null">AND #{query.maxWithDrawProcessTime} &gt; _withdraw_process_time</if>
        <if test="query.minWithDrawProcessTime!=null">AND _withdraw_process_time &gt;= #{query.minWithDrawProcessTime}
        </if>
        <if test="query.maxWithDrawProcessTime!=null">AND #{query.maxWithDrawProcessTime} &gt; _withdraw_process_time
        </if>
    <if test="query.minCreateTime!=null">AND _create_time &gt;= #{query.minCreateTime}</if>  
    <if test="query.maxCreateTime!=null">AND #{query.maxCreateTime} &gt; _create_time</if>  
    <if test="query.minUpdateTime!=null">AND _update_time &gt;= #{query.minUpdateTime}</if>  
    <if test="query.maxUpdateTime!=null">AND #{query.maxUpdateTime} &gt; _update_time</if> 
  </sql>  
  <select id="list" resultMap="BaseResultMap">select 
    <include refid="Base_Column_List"/> from table_agent_settle_record where 1=1
        <include refid="Base_Column_List"/>
        from table_agent_settle_record where 1=1
    <include refid="listWhereSQL"/>  
    <if test="query.sortList!=null"> 
      <foreach collection="query.sortList" item="item" open=" order by " separator=",">#{item}</foreach>
    </if>limit #{query.start},#{query.count}
            <foreach collection="query.sortList" item="item" open=" order by " separator=",">${item}</foreach>
        </if>
        limit #{query.start},#{query.count}
  </select>  
  <select id="count" resultType="java.lang.Long">select count(*) from table_agent_settle_record where 1=1 
    <include refid="listWhereSQL"/> 
  </select>  
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">delete from table_agent_settle_record where _id = #{id,jdbcType=BIGINT}</delete>
  <insert id="insert" parameterType="com.taoke.autopay.entity.agent.ChannelAgentSettleRecord" useGeneratedKeys="true" keyProperty="id">insert into table_agent_settle_record (_id,_agent_id,_settle_day,_settle_money,_actual_settle_money,_pay_time,_status,_status_desc,_settle_time,_withdraw_apply_time,_withdraw_process_time,_create_time,_update_time,_id,_alipay_name,_alipay_account) values (#{id,jdbcType=BIGINT},#{agentId,jdbcType=BIGINT},#{settleDay,jdbcType=VARCHAR},#{settleMoney,jdbcType=DECIMAL},#{actualSettleMoney,jdbcType=DECIMAL},#{payTime,jdbcType=TIMESTAMP},#{status,jdbcType=INTEGER},#{statusDesc,jdbcType=INTEGER},#{settleTime,jdbcType=TIMESTAMP},#{withDrawApplyTime,jdbcType=TIMESTAMP},#{withDrawProcessTime,jdbcType=TIMESTAMP},#{createTime,jdbcType=TIMESTAMP},#{updateTime,jdbcType=TIMESTAMP},#{id,jdbcType=BIGINT},#{alipayName,jdbcType=VARCHAR},#{alipayAccount,jdbcType=VARCHAR})</insert>
  <insert id="insertSelective" parameterType="com.taoke.autopay.entity.agent.ChannelAgentSettleRecord" useGeneratedKeys="true" keyProperty="id">insert into table_agent_settle_record
    <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">delete
        from table_agent_settle_record
        where _id = #{id,jdbcType=BIGINT}
    </delete>
    <insert id="insert" parameterType="com.taoke.autopay.entity.agent.ChannelAgentSettleRecord" useGeneratedKeys="true"
            keyProperty="id">insert into table_agent_settle_record (_id, _agent_id, _settle_day, _settle_money,
        _actual_settle_money, _pay_time, _status,
        _status_desc, _settle_time, _withdraw_apply_time,
        _withdraw_process_time, _create_time, _update_time,
        _id, _alipay_name, _alipay_account)
        values (#{id,jdbcType=BIGINT}, #{agentId,jdbcType=BIGINT}, #{settleDay,jdbcType=VARCHAR},
        #{settleMoney,jdbcType=DECIMAL}, #{actualSettleMoney,jdbcType=DECIMAL},
        #{payTime,jdbcType=TIMESTAMP}, #{status,jdbcType=INTEGER},
        #{statusDesc,jdbcType=INTEGER}, #{settleTime,jdbcType=TIMESTAMP},
        #{withDrawApplyTime,jdbcType=TIMESTAMP}, #{withDrawProcessTime,jdbcType=TIMESTAMP},
        #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP},
        #{id,jdbcType=BIGINT}, #{alipayName,jdbcType=VARCHAR},
        #{alipayAccount,jdbcType=VARCHAR})
    </insert>
    <insert id="insertSelective" parameterType="com.taoke.autopay.entity.agent.ChannelAgentSettleRecord"
            useGeneratedKeys="true" keyProperty="id">insert into table_agent_settle_record
    <trim prefix="(" suffix=")" suffixOverrides=","> 
      <if test="id != null">_id,</if>  
      <if test="agentId != null">_agent_id,</if>  
@@ -81,7 +111,8 @@
      <if test="updateTime != null">_update_time,</if>  
      <if test="alipayName != null">_alipay_name,</if>  
      <if test="alipayAccount != null">_alipay_account,</if> 
    </trim>values
        </trim>
        values
    <trim prefix="(" suffix=")" suffixOverrides=","> 
      <if test="id != null">#{id,jdbcType=BIGINT},</if>  
      <if test="agentId != null">#{agentId,jdbcType=BIGINT},</if>  
@@ -90,7 +121,7 @@
      <if test="actualSettleMoney != null">#{actualSettleMoney,jdbcType=DECIMAL},</if>  
      <if test="payTime != null">#{payTime,jdbcType=TIMESTAMP},</if>  
      <if test="status != null">#{status,jdbcType=INTEGER},</if>  
      <if test="statusDesc != null">#{statusDesc,jdbcType=INTEGER},</if>
            <if test="statusDesc != null">#{statusDesc,jdbcType=VARCHAR},</if>
      <if test="settleTime != null">#{settleTime,jdbcType=TIMESTAMP},</if>  
      <if test="withDrawApplyTime != null">#{withDrawApplyTime,jdbcType=TIMESTAMP},</if>  
      <if test="withDrawProcessTime != null">#{withDrawProcessTime,jdbcType=TIMESTAMP},</if>  
@@ -100,8 +131,26 @@
      <if test="alipayAccount != null">#{alipayAccount,jdbcType=VARCHAR},</if>
    </trim> 
  </insert>  
  <update id="updateByPrimaryKey" parameterType="com.taoke.autopay.entity.agent.ChannelAgentSettleRecord">update table_agent_settle_record set _agent_id = #{agentId,jdbcType=BIGINT},_settle_day = #{settleDay,jdbcType=VARCHAR},_settle_money = #{settleMoney,jdbcType=DECIMAL},_actual_settle_money = #{actualSettleMoney,jdbcType=DECIMAL},_pay_time = #{payTime,jdbcType=TIMESTAMP},_status = #{status,jdbcType=INTEGER},_status_desc = #{statusDesc,jdbcType=INTEGER},_settle_time = #{settleTime,jdbcType=TIMESTAMP},_withdraw_apply_time = #{withDrawApplyTime,jdbcType=TIMESTAMP},_withdraw_process_time = #{withDrawProcessTime,jdbcType=TIMESTAMP},_create_time = #{createTime,jdbcType=TIMESTAMP},_update_time = #{updateTime,jdbcType=TIMESTAMP} ,_alipay_name =#{alipayName,jdbcType=VARCHAR}, _alipay_account =#{alipayAccount,jdbcType=VARCHAR}, where _id = #{id,jdbcType=BIGINT}</update>
  <update id="updateByPrimaryKeySelective" parameterType="com.taoke.autopay.entity.agent.ChannelAgentSettleRecord">update table_agent_settle_record
    <update id="updateByPrimaryKey"
            parameterType="com.taoke.autopay.entity.agent.ChannelAgentSettleRecord">update table_agent_settle_record
        set _agent_id = #{agentId,jdbcType=BIGINT},
        _settle_day = #{settleDay,jdbcType=VARCHAR},
        _settle_money = #{settleMoney,jdbcType=DECIMAL},
        _actual_settle_money = #{actualSettleMoney,jdbcType=DECIMAL},
        _pay_time = #{payTime,jdbcType=TIMESTAMP},
        _status = #{status,jdbcType=INTEGER},
        _status_desc = #{statusDesc,jdbcType=INTEGER},
        _settle_time = #{settleTime,jdbcType=TIMESTAMP},
        _withdraw_apply_time = #{withDrawApplyTime,jdbcType=TIMESTAMP},
        _withdraw_process_time = #{withDrawProcessTime,jdbcType=TIMESTAMP},
        _create_time = #{createTime,jdbcType=TIMESTAMP},
        _update_time = #{updateTime,jdbcType=TIMESTAMP},
        _alipay_name =#{alipayName,jdbcType=VARCHAR},
        _alipay_account =#{alipayAccount,jdbcType=VARCHAR},
        where _id = #{id,jdbcType=BIGINT}
    </update>
    <update id="updateByPrimaryKeySelective" parameterType="com.taoke.autopay.entity.agent.ChannelAgentSettleRecord">
        update table_agent_settle_record
    <set> 
      <if test="agentId != null">_agent_id=#{agentId,jdbcType=BIGINT},</if>  
      <if test="settleDay != null">_settle_day=#{settleDay,jdbcType=VARCHAR},</if>  
@@ -109,14 +158,16 @@
      <if test="actualSettleMoney != null">_actual_settle_money=#{actualSettleMoney,jdbcType=DECIMAL},</if>  
      <if test="payTime != null">_pay_time=#{payTime,jdbcType=TIMESTAMP},</if>  
      <if test="status != null">_status=#{status,jdbcType=INTEGER},</if>  
      <if test="statusDesc != null">_status_desc=#{statusDesc,jdbcType=INTEGER},</if>
            <if test="statusDesc != null">_status_desc=#{statusDesc,jdbcType=VARCHAR},</if>
      <if test="settleTime != null">_settle_time=#{settleTime,jdbcType=TIMESTAMP},</if>  
      <if test="withDrawApplyTime != null">_withdraw_apply_time=#{withDrawApplyTime,jdbcType=TIMESTAMP},</if>  
      <if test="withDrawProcessTime != null">_withdraw_process_time=#{withDrawProcessTime,jdbcType=TIMESTAMP},</if>
            <if test="withDrawProcessTime != null">_withdraw_process_time=#{withDrawProcessTime,jdbcType=TIMESTAMP},
            </if>
      <if test="createTime != null">_create_time=#{createTime,jdbcType=TIMESTAMP},</if>  
      <if test="updateTime != null">_update_time=#{updateTime,jdbcType=TIMESTAMP},</if>  
      <if test="alipayName !=null">_alipay_name =#{alipayName,jdbcType=VARCHAR},</if>  
      <if test="alipayAccount !=null">_alipay_account =#{alipayAccount,jdbcType=VARCHAR},</if> 
    </set> where _id = #{id,jdbcType=BIGINT}
        </set>
        where _id = #{id,jdbcType=BIGINT}
  </update> 
</mapper>
src/main/resources/mapper/KeyOrderMapper.xml
@@ -21,20 +21,34 @@
    <result column="order_channel" property="orderChannel" jdbcType="VARCHAR"/>  
    <result column="pay_type" property="payType" jdbcType="INTEGER"/>
    <result column="agent_id" property="agentId" jdbcType="BIGINT"/>
        <association property="user" javaType="com.taoke.autopay.entity.WxUserInfo">
            <id column="uid" property="id" jdbcType="BIGINT"/>
            <result column="nick_name" property="nickName" jdbcType="VARCHAR"/>
            <result column="portrait" property="portrait" jdbcType="VARCHAR"/>
        </association>
  </resultMap>  
  <resultMap id="DistributeResultMap" type="com.taoke.autopay.entity.OrderDistributeCountInfo"> 
    <result column="uid" property="uid" jdbcType="BIGINT"/>  
    <result column="count" property="count" jdbcType="INTEGER"/> 
  </resultMap>  
  <sql id="Base_Column_List">id,uid,`key`,order_type,order_no,order_state,state,state_desc,distribute_client_uid,distribute_time,create_time,update_time,excute_pay_time,pay_time,order_money,order_channel,pay_type,agent_id</sql>
    <resultMap id="ChannelOrderStatisticMap" type="com.taoke.autopay.dto.ChannelOrderStatistic">
        <result column="order_channel" property="orderChannel" jdbcType="VARCHAR"/>
        <result column="count" property="count" jdbcType="BIGINT"/>
        <result column="money" property="money" jdbcType="DECIMAL"/>
    </resultMap>
    <sql id="Base_Column_List">id
    ,uid,`key`,order_type,order_no,order_state,state,state_desc,distribute_client_uid,distribute_time,create_time,update_time,excute_pay_time,pay_time,order_money,order_channel,pay_type,agent_id</sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long">select 
    <include refid="Base_Column_List"/> from table_order where id = #{id,jdbcType=BIGINT}
        <include refid="Base_Column_List"/>
        from table_order where id = #{id,jdbcType=BIGINT}
  </select>  
  <select id="selectByPrimaryKeyForUpdate" resultMap="BaseResultMap" parameterType="java.lang.String">select 
    <include refid="Base_Column_List"/> from table_order where id = #{id,jdbcType=VARCHAR} for update
        <include refid="Base_Column_List"/>
        from table_order where id = #{id,jdbcType=VARCHAR} for update
  </select>  
  <select id="selectById" resultMap="BaseResultMap" parameterType="java.lang.String">select 
    <include refid="Base_Column_List"/> from table_order where id = #{id,jdbcType=VARCHAR}
        <include refid="Base_Column_List"/>
        from table_order where id = #{id,jdbcType=VARCHAR}
  </select>  
  <sql id="listWhereSQL"> 
    <if test="query.id!=null">AND id = #{query.id}</if>  
@@ -44,9 +58,13 @@
    <if test="query.orderNo!=null">AND order_no = #{query.orderNo}</if>  
    <if test="query.orderState!=null">AND order_state = #{query.orderState}</if>  
    <if test="query.state!=null">AND state = #{query.state}</if>
        <if test="query.hasPayTime!=null">AND pay_time is not null</if>
        <if test="query.hasAgentId!=null">AND agent_id is not null</if>
    <if test="query.agentId!=null">AND agent_id = #{query.agentId}</if>
    <if test="query.stateList!=null"> 
      <foreach collection="query.stateList" item="state" separator=" or " open=" AND (" close=") ">state = #{state}</foreach>
            <foreach collection="query.stateList" item="state" separator=" or " open=" AND (" close=") ">state =
                #{state}
            </foreach>
    </if>  
    <if test="query.stateDesc!=null">AND state_desc = #{query.stateDesc}</if>  
    <if test="query.distributeClientUid!=null">AND distribute_client_uid = #{query.distributeClientUid}</if>  
@@ -54,22 +72,95 @@
    <if test="query.maxDistributeTime!=null">AND #{query.maxDistributeTime} &gt; distribute_time</if>  
    <if test="query.minCreateTime!=null">AND create_time &gt;= #{query.minCreateTime}</if>  
    <if test="query.maxCreateTime!=null">AND #{query.maxCreateTime} &gt; create_time</if>  
        <if test="query.oMinCreateTime!=null">AND o.create_time &gt;= #{query.oMinCreateTime}</if>
        <if test="query.oMaxCreateTime!=null">AND #{query.oMaxCreateTime} &gt; o.create_time</if>
    <if test="query.minUpdateTime!=null">AND update_time &gt;= #{query.minUpdateTime}</if>  
    <if test="query.maxUpdateTime!=null">AND #{query.maxUpdateTime} &gt; update_time</if> 
        <if test="query.nickName!=null">AND nick_name like '%${nickName}%' &gt; update_time</if>
  </sql>  
  <select id="list" resultMap="BaseResultMap">select 
    <include refid="Base_Column_List"/> from table_order where 1=1
        <include refid="Base_Column_List"/>
        from table_order where 1=1
    <include refid="listWhereSQL"/>  
    <if test="query.sortList!=null"> 
      <foreach collection="query.sortList" item="item" open=" order by " separator=",">${item}</foreach> 
    </if>limit #{query.start},#{query.count}
        </if>
        limit #{query.start},#{query.count}
  </select>  
    <select id="listWithUser" resultMap="BaseResultMap">
        select
        o.*, u.portrait, u.nick_name from table_order o left join table_wx_user u on u.id = o.uid where 1=1
        <include refid="listWhereSQL"/>
        <if test="query.sortList!=null">
            <foreach collection="query.sortList" item="item" open=" order by " separator=",">${item}</foreach>
        </if>
        limit #{query.start},#{query.count}
    </select>
  <select id="count" resultType="java.lang.Long">select count(*) from table_order where 1=1 
    <include refid="listWhereSQL"/> 
  </select>  
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">delete from table_order where id = #{id,jdbcType=BIGINT}</delete>
  <insert id="insert" parameterType="com.taoke.autopay.entity.KeyOrder" useGeneratedKeys="true" keyProperty="id">insert into table_order (id,uid,key,order_type,order_no,order_state,state,state_desc,distribute_client_uid,distribute_time,create_time,update_time,id,excute_pay_time,pay_time,order_money,order_channel,pay_type,agent_id) values (#{id,jdbcType=VARCHAR},#{uid,jdbcType=BIGINT},#{key,jdbcType=VARCHAR},#{orderType,jdbcType=INTEGER},#{orderNo,jdbcType=VARCHAR},#{orderState,jdbcType=INTEGER},#{state,jdbcType=INTEGER},#{stateDesc,jdbcType=VARCHAR},#{distributeClientUid,jdbcType=BIGINT},#{distributeTime,jdbcType=TIMESTAMP},#{createTime,jdbcType=TIMESTAMP},#{updateTime,jdbcType=TIMESTAMP},#{id,jdbcType=VARCHAR},#{excutePayTime,jdbcType=TIMESTAMP},#{payTime,jdbcType=TIMESTAMP},#{orderMoney,jdbcType=DECIMAL},#{orderChannel,jdbcType=VARCHAR},#{payType,jdbcType=INTEGER},#{agentId,jdbcType=BIGINT})</insert>
  <insert id="insertSelective" parameterType="com.taoke.autopay.entity.KeyOrder" useGeneratedKeys="true" keyProperty="id">insert into table_order
    <select id="countWithUser" resultType="java.lang.Long">select count(*) from table_order o left join table_wx_user u
        on u.id = o.uid where 1=1
        <include refid="listWhereSQL"/>
    </select>
    <select id="countUser" resultType="java.lang.Long">select count(distinct(u.id)) from table_order o left join
        table_wx_user u on u.id = o.uid where 1=1
        <include refid="listWhereSQL"/>
    </select>
    <select id="statisticChannelOrders" resultMap="ChannelOrderStatisticMap">
        select
        order_channel, count(o.id) as count, sum(order_money) as money from table_order o left join table_wx_user u on u.id =
        o.uid where 1=1
        <include refid="listWhereSQL"/>
        group by order_channel
    </select>
    <select id="listAgentId" resultType="java.lang.Long">
        select
        distinct(agent_id) from table_order o where 1=1
        <include refid="listWhereSQL"/>
        <if test="query.sortList!=null">
            <foreach collection="query.sortList" item="item" open=" order by " separator=",">${item}</foreach>
        </if>
        limit #{query.start},#{query.count}
    </select>
    <select id="countAgentId" resultType="java.lang.Long">
        select
        count(distinct(agent_id)) from table_order o where 1=1
        <include refid="listWhereSQL"/>
        <if test="query.sortList!=null">
            <foreach collection="query.sortList" item="item" open=" order by " separator=",">${item}</foreach>
        </if>
    </select>
    <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">delete
                                                                   from table_order
                                                                   where id = #{id,jdbcType=BIGINT}</delete>
    <insert id="insert" parameterType="com.taoke.autopay.entity.KeyOrder" useGeneratedKeys="true"
            keyProperty="id">insert into table_order (id, uid, key, order_type, order_no, order_state, state,
                                                      state_desc, distribute_client_uid, distribute_time, create_time,
                                                      update_time, id, excute_pay_time, pay_time, order_money,
                                                      order_channel, pay_type, agent_id)
                             values (#{id,jdbcType=VARCHAR}, #{uid,jdbcType=BIGINT}, #{key,jdbcType=VARCHAR},
                                     #{orderType,jdbcType=INTEGER}, #{orderNo,jdbcType=VARCHAR},
                                     #{orderState,jdbcType=INTEGER}, #{state,jdbcType=INTEGER},
                                     #{stateDesc,jdbcType=VARCHAR}, #{distributeClientUid,jdbcType=BIGINT},
                                     #{distributeTime,jdbcType=TIMESTAMP}, #{createTime,jdbcType=TIMESTAMP},
                                     #{updateTime,jdbcType=TIMESTAMP}, #{id,jdbcType=VARCHAR},
                                     #{excutePayTime,jdbcType=TIMESTAMP}, #{payTime,jdbcType=TIMESTAMP},
                                     #{orderMoney,jdbcType=DECIMAL}, #{orderChannel,jdbcType=VARCHAR},
                                     #{payType,jdbcType=INTEGER}, #{agentId,jdbcType=BIGINT})</insert>
    <insert id="insertSelective" parameterType="com.taoke.autopay.entity.KeyOrder" useGeneratedKeys="true"
            keyProperty="id">insert into table_order
    <trim prefix="(" suffix=")" suffixOverrides=","> 
      <if test="id != null">id,</if>  
      <if test="uid != null">uid,</if>  
@@ -89,7 +180,8 @@
      <if test="orderChannel != null">order_channel,</if>  
      <if test="payType != null">pay_type,</if>  
      <if test="agentId != null">agent_id,</if>
    </trim>values
        </trim>
        values
    <trim prefix="(" suffix=")" suffixOverrides=","> 
      <if test="id != null">#{id,jdbcType=VARCHAR},</if>  
      <if test="uid != null">#{uid,jdbcType=BIGINT},</if>  
@@ -111,7 +203,25 @@
      <if test="agentId != null">#{agentId,jdbcType=BIGINT},</if>
    </trim> 
  </insert>  
  <update id="updateByPrimaryKey" parameterType="com.taoke.autopay.entity.KeyOrder">update table_order set uid = #{uid,jdbcType=BIGINT},`key` = #{key,jdbcType=VARCHAR},order_type = #{orderType,jdbcType=INTEGER},order_no = #{orderNo,jdbcType=VARCHAR},order_state = #{orderState,jdbcType=INTEGER},state = #{state,jdbcType=INTEGER},state_desc = #{stateDesc,jdbcType=VARCHAR},distribute_client_uid = #{distributeClientUid,jdbcType=BIGINT},distribute_time = #{distributeTime,jdbcType=TIMESTAMP},create_time = #{createTime,jdbcType=TIMESTAMP},update_time = #{updateTime,jdbcType=TIMESTAMP} ,excute_pay_time =#{excutePayTime,jdbcType=TIMESTAMP}, pay_time =#{payTime,jdbcType=TIMESTAMP} ,order_money =#{orderMoney,jdbcType=DECIMAL}, order_channel =#{orderChannel,jdbcType=VARCHAR}, pay_type =#{payType,jdbcType=INTEGER}, agent_id =#{agentId,jdbcType=BIGINT}, where id = #{id,jdbcType=VARCHAR}</update>
    <update id="updateByPrimaryKey" parameterType="com.taoke.autopay.entity.KeyOrder">update table_order
                                                                                      set uid                   = #{uid,jdbcType=BIGINT},
                                                                                          `key`                 = #{key,jdbcType=VARCHAR},
                                                                                          order_type            = #{orderType,jdbcType=INTEGER},
                                                                                          order_no              = #{orderNo,jdbcType=VARCHAR},
                                                                                          order_state           = #{orderState,jdbcType=INTEGER},
                                                                                          state                 = #{state,jdbcType=INTEGER},
                                                                                          state_desc            = #{stateDesc,jdbcType=VARCHAR},
                                                                                          distribute_client_uid = #{distributeClientUid,jdbcType=BIGINT},
                                                                                          distribute_time       = #{distributeTime,jdbcType=TIMESTAMP},
                                                                                          create_time           = #{createTime,jdbcType=TIMESTAMP},
                                                                                          update_time           = #{updateTime,jdbcType=TIMESTAMP},
                                                                                          excute_pay_time       =#{excutePayTime,jdbcType=TIMESTAMP},
                                                                                          pay_time              =#{payTime,jdbcType=TIMESTAMP},
                                                                                          order_money           =#{orderMoney,jdbcType=DECIMAL},
                                                                                          order_channel         =#{orderChannel,jdbcType=VARCHAR},
                                                                                          pay_type              =#{payType,jdbcType=INTEGER},
                                                                                          agent_id              =#{agentId,jdbcType=BIGINT},
                                                                                          where id = #{id,jdbcType=VARCHAR}</update>
  <update id="updateByPrimaryKeySelective" parameterType="com.taoke.autopay.entity.KeyOrder">update table_order 
    <set> 
      <if test="uid != null">uid=#{uid,jdbcType=BIGINT},</if>  
@@ -131,18 +241,27 @@
      <if test="orderChannel !=null">order_channel =#{orderChannel,jdbcType=VARCHAR},</if>  
      <if test="payType !=null">pay_type =#{payType,jdbcType=INTEGER},</if>  
      <if test="agentId !=null">agent_id =#{agentId,jdbcType=BIGINT},</if>
    </set> where id = #{id,jdbcType=VARCHAR}
        </set>
        where id = #{id,jdbcType=VARCHAR}
  </update>  
  <select id="listDistributeUids" resultMap="DistributeResultMap">SELECT u.`id` as uid, IF( a.count IS NULL,0,a.count) AS `count` FROM `table_user` u LEFT JOIN (SELECT o.`distribute_client_uid` AS uid,COUNT(*) AS `count` FROM `table_order` o WHERE o.`state` = 0 and create_time &gt; #{minKeyOrderCreateTime} GROUP BY o.`distribute_client_uid`) a ON a.uid = u.`id` WHERE rule=0
    <select id="listDistributeUids" resultMap="DistributeResultMap">SELECT u.`id` as uid, IF( a.count IS NULL,0,a.count)
        AS `count` FROM `table_user` u LEFT JOIN (SELECT o.`distribute_client_uid` AS uid,COUNT(*) AS `count` FROM
        `table_order` o WHERE o.`state` = 0 and create_time &gt; #{minKeyOrderCreateTime} GROUP BY
        o.`distribute_client_uid`) a ON a.uid = u.`id` WHERE rule=0
    <if test="minActiveTime!=null">and active_time &gt;=#{minActiveTime}</if> 
  </select>  
  <select id="listNotDistributed" resultMap="BaseResultMap">select 
    <include refid="Base_Column_List"/> from table_order where distribute_client_uid is null and state=0 limit #{start},#{count}
        <include refid="Base_Column_List"/>
        from table_order where distribute_client_uid is null and state=0 limit #{start},#{count}
  </select>  
  <delete id="deleteAll" parameterType="java.util.Date">delete from table_order where #{maxCreateTime} &gt;= create_time</delete>
    <delete id="deleteAll" parameterType="java.util.Date">delete
                                                          from table_order
                                                          where #{maxCreateTime} &gt;= create_time</delete>
  <update id="removeDistributedClient" parameterType="java.lang.String">
    update table_order set distribute_client_uid = null where id=#{0}
        update table_order
        set distribute_client_uid = null
        where id = #{0}
  </update>
</mapper>
src/main/resources/static/admin/agent-add.html
@@ -3,26 +3,50 @@
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
            content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>后台登录</title>
        <link rel="stylesheet" type="text/css" href="layui/css/layui.css" />
        <style>
            body{
                padding: 10px;
            }
            #sure{
                visibility: hidden;
            }
            .layui-form-label{
                width: 200px;
            }
            .layui-input-block{
                margin-left: 240px;
                max-width: 500px;
            }
            .layui-input-block input{
                    max-width: 150px;
            }
             .small{
                max-width: 75px !important;
            }
            .share-ratio {
                display: flex;
                margin-bottom: 10px;
            }
            .share-ratio .layui-form-label {
                width: 50px;
                padding-left: 0;
                font-size: 12px;
                text-align: left;
            }
            .share-ratio input {
                width: 60px;
                margin-right: 10px;
            }
        </style>
    </head>
@@ -33,65 +57,79 @@
             <input type="hidden" name="id" />
             <div class="layui-form-item">
                <label class="layui-form-label">渠道代理名称:</label>
                <div class="layui-input-block">
                 <input type="text" name="dyPayCount" required lay-verify="required|num" placeholder="代理名称"
                     autocomplete="off" class="layui-input">
                <div class="layui-input-inline">
                    <input type="text" name="name" required lay-verify="required" placeholder="代理名称" autocomplete="off" class="layui-input">
                </div>
              </div>
              
              <div class="layui-form-item">
                 <label class="layui-form-label">单日代付总频次限制:</label>
                 <div class="layui-input-block">
                  <input type="text" name="dyPayCount" required lay-verify="required|num" placeholder="口令提交总次数"
                      autocomplete="off" class="layui-input">
                <div class="layui-input-inline">
                    <input type="text" name="maxKeyCountPerDay" required lay-verify="required|num" placeholder="口令提交总次数" autocomplete="off" class="layui-input">
                 </div>
               </div>
               
               <div class="layui-form-item">
                  <label class="layui-form-label">单日代付总金额限制:</label>
                  <div class="layui-input-block">
                   <input type="text" name="dyPayCount" required lay-verify="required|num" placeholder="单位:元"
                       autocomplete="off" class="layui-input">
                <div class="layui-input-inline">
                    <input type="text" name="maxPayMoneyPerDay" required lay-verify="required|money" placeholder="单日代付总额" autocomplete="off" class="layui-input">
                  </div>
                <div class="layui-form-mid layui-word-aux">元</div>
                </div>
                
                <div class="layui-form-item">
                   <label class="layui-form-label">提交口令时段:</label>
                   <div class="layui-input-inline" style="width: 100px;">
                        <input type="text" name="price_min" placeholder="¥" autocomplete="off" class="layui-input">
                    <input type="text" name="startSubmitTime" placeholder="开始时间" autocomplete="off" class="layui-input">
                      </div>
                      <div class="layui-form-mid">-</div>
                      <div class="layui-input-inline" style="width: 100px;">
                        <input type="text" name="price_max" placeholder="¥" autocomplete="off" class="layui-input">
                    <input type="text" name="endSubmitTime" placeholder="结束时间" autocomplete="off" class="layui-input">
                      </div>
                      <div class="layui-form-mid layui-word-aux">如不填写就采用系统默认</div>
                 </div>
              
              <div class="layui-form-item">
                 <label class="layui-form-label">登录渠道代理后台账号:</label>
                 <div class="layui-input-block">
                  <input type="text" name="ksPayCount" required lay-verify="required|num" placeholder="账号"
                      autocomplete="off" class="layui-input">
                <div class="layui-input-inline">
                    <input type="text" name="account" required lay-verify="required" placeholder="账号" autocomplete="off" class="layui-input">
                 </div>
               </div>
               
               <div class="layui-form-item">
                  <label class="layui-form-label">登录渠道代理后台密码:</label>
                  <div class="layui-input-block">
                   <input type="password" name="ksPayCount" required lay-verify="required|num" placeholder="密码"
                       autocomplete="off" class="layui-input">
                <div class="layui-input-inline">
                    <input type="password" name="pwd" required lay-verify="required" placeholder="密码" autocomplete="off" class="layui-input">
                  </div>
                </div>
               
            <div class="layui-form-item">
                <label class="layui-form-label">支付宝信息:</label>
                <div class="layui-input-inline">
                    <input type="text" name="alipayName" required lay-verify="" placeholder="支付宝姓名" autocomplete="off" class="layui-input">
                </div>
                <div class="layui-input-inline">
                    <input type="text" name="alipayAccount" required lay-verify="" placeholder="支付宝账号" autocomplete="off" class="layui-input">
                </div>
            </div>
            
                
                <div class="layui-form-item">
                   <label class="layui-form-label">分成设置</label>
                   <div class="layui-input-block">
                <label class="layui-form-label">分成设置:</label>
                <div class="layui-input-inline">
                    <div id="shareRatioContainer"></div>
                    
                      <div class="layui-form-mid layui-word-aux">如不填写就采用系统默认</div>
                   </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">口令提交页面免单福利入口:</label>
                <div class="layui-input-inline">
                    <input type="checkbox" checked name="open" lay-skin="switch" value="1" lay-filter="switchTest" title="">
                </div>
                 </div>
            <div class="layui-input-block">
@@ -101,8 +139,19 @@
        <script src="layui/layui.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/http_api.js"></script>
        <script type="text/html" id="shareRatioTemplate">
            <div class="share-ratio">
                <label class="layui-form-label">{{ d.label }}</label>
                <input type="text" name="shareRatioInfos.{{d.name}}" required lay-verify="required|money" placeholder="" autocomplete="off" value="" class="layui-input money">
                <div class="layui-form-mid layui-word-aux">元/单</div>
            </div>
        </script>
        <script>
            var listener;
            function submit(callback) {
                //暂存回调方法
                listener = callback;
@@ -110,38 +159,68 @@
                $("#sure").click();
            }
            
            layui.use(['form', 'layedit', 'laydate'], function() {
            function copyLink() {
                try {
                    document.getElementById("submitKeyLink").select();
                    var successful = document.execCommand('copy');
                    if(successful){
                        layer.msg("复制成功");
                    }else{
                        layer.msg("复制失败");
                    }
                } catch (err) {
                    layer.msg("复制出错");
                    console.error('Oops, unable to copy', err);
                }
            }
            layui.use(['form', 'layedit', 'laydate', 'laytpl'], function() {
                var form = layui.form,
                    layer = layui.layer;
                    layer = layui.layer,
                    laydate = layui.laydate,
                    laytpl = layui.laytpl;
                //自定义验证规则
                form.verify({
                    num: [/^\d+$/, "必须为正整数"]
                    num: [/^\d+$/, "必须为正整数"],
                    money: [/^\d+(\.\d{1,2})?$/, "金额最多保留2位小数"]
                });
                var id = http_util.getQueryString("id");
                laydate.render({
                    elem: "input[name=startSubmitTime]",
                    type: "time",
                    value: new Date(),
                    isInitValue: false
                });
                laydate.render({
                    elem: "input[name=endSubmitTime]",
                    type: "time",
                    value: new Date(),
                    isInitValue: false
                });
                // 获取值
                $.post("/admin/api/wxuser/getOrderSettings", {"id":id}, function(response) {
                $.post("/admin/api/agent/getAgentOrderChannels", {
                }, function(response) {
                    if (response.code == 0) {
                        form.val("edit", response.data);
                        for(var i=0;i<response.data.length;i++)
                        {
                            laytpl($('#shareRatioTemplate').html()).render({
                                "index": i + 1,
                                "label": response.data[i]["label"],
                                "name": response.data[i]["name"]
                            }, function(html) {
                                $("#shareRatioContainer").append(html);
                            });
                        }
                    } else {
                        layer.msg(response.msg);
                    }
                }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                    layer.msg("网络请求失败");
                });
                //监听提交
                form.on('submit(sure)', function(data) {
                    listener(data.field);
                    return false;
                });
            });
        </script>
    </body>
src/main/resources/static/admin/agent-list.html
@@ -5,17 +5,14 @@
        <meta charset="UTF-8">
        <meta name="renderer" content="webkit">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="viewport"
            content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>设备列表</title>
        <link rel="stylesheet" type="text/css" href="layui/css/layui.css" />
        <link rel="stylesheet" type="text/css" href="css/admin.css" />
        <style>
            #add_client{
                padding: 10px;
            }
        </style>
    </head>
@@ -25,8 +22,7 @@
                <div class="layui-form-item">
                    <div class="layui-inline">
                        <input type="text" name="key" id="key" placeholder="按渠道ID/名称搜索" autocomplete="off"
                            class="layui-input">
                        <input type="text" name="key" id="key" placeholder="按渠道ID/名称搜索" autocomplete="off" class="layui-input">
                    </div>
                    <button class="layui-btn layui-btn-normal" lay-submit lay-filter="search" id="search"><i class="layui-icon layui-icon-search"></i>搜索</button>
                    <a href="javascript:void();" class="layui-btn layui-btn-warm" onclick="add_agent()"><i class="layui-icon layui-icon-add-circle"></i> 创建代理</a>
@@ -38,7 +34,6 @@
                </table>
            </div>
        </div>
        
        <script src="layui/layui.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
@@ -57,7 +52,10 @@
                        layer.msg("密码不能少于6位数");
                        return;
                    }
                    $.post("/admin/api//setpwd", {"id":id,"pwd":value}, function(response) {
                    $.post("/admin/api//setpwd", {
                        "id": id,
                        "pwd": value
                    }, function(response) {
                        if (response.code == 0) {
                             layer.close(index);
                            layer.msg("密码修改成功");
@@ -71,24 +69,152 @@
            }
            
            function add_agent(){
                // 创建设备
                var index = layer.open({
                    type:1,
                    title:"设备账号创建",
                    content: $("#add_client"),
                    end:function(e){
                        $("#add_client").css("display","none");
                var layerIndex = layer.open({
                    title: "添加代理",
                    type: 2,
                    area: ['800px', '600px'],
                    shade: 0.3,
                    shadeClose: false, //默认开启遮罩关闭
                    resize: false, //默认重设大小是否
                    //如果不让iframe出现滚动条,
                    //可以content: ['http://sentsin.com', 'no']
                    content: 'agent-add.html',
                    btn: ['确定', '取消'],
                    yes: function(index) {
                        //submit方法为弹框内容中的方法
                        window["layui-layer-iframe" + index].submit(function(res) {
                            console.log(res);
                            let fdata = {};
                            for (let key in res) {
                                if (key.indexOf(".") >= 0) {
                                    let k1 = key.split(".")[0];
                                    let k2 = key.split(".")[1];
                                    if (k1 in fdata) {} else {
                                        fdata[k1] = {};
                                    }
                                    fdata[k1][k2] = res[key];
                                } else {
                                    fdata[key] = res[key]
                                }
                            }
                            for (let key in fdata) {
                                console.log(typeof(fdata[key]))
                                if (typeof(fdata[key]) == 'object') {
                                    fdata[key] = JSON.stringify(fdata[key]);
                                }
                            }
                            console.log(fdata);
                            try {
                                var index = layer.load(1);
                                $.post("/admin/api/agent/add", fdata, function(response) {
                                    layer.close(index);
                                    if (response.code == 0) {
                                        layer.close(layerIndex);
                                        layer.msg("添加成功");
                                    } else {
                                        layer.msg(response.msg);
                                    }
                                }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                                    layer.close(index);
                                    layer.msg("网络请求失败");
                                });
                            } catch (e) {
                                console.log(e);
                    }
                });
                    },
                    cancel: function() {}
                });
            }
            function update_agent(id) {
                var layerIndex = layer.open({
                    title: "修改代理",
                    type: 2,
                    area: ['800px', '600px'],
                    shade: 0.3,
                    shadeClose: false, //默认开启遮罩关闭
                    resize: false, //默认重设大小是否
                    //如果不让iframe出现滚动条,
                    //可以content: ['http://sentsin.com', 'no']
                    content: 'agent-update.html?id=' + id,
                    btn: ['确定', '取消'],
                    yes: function(index) {
                        //submit方法为弹框内容中的方法
                        window["layui-layer-iframe" + index].submit(function(res) {
                            console.log(res);
                            let fdata = {
                                id: id
                            };
                            for (let key in res) {
                                if (key.indexOf(".") >= 0) {
                                    let k1 = key.split(".")[0];
                                    let k2 = key.split(".")[1];
                                    if (k1 in fdata) {} else {
                                        fdata[k1] = {};
                                    }
                                    fdata[k1][k2] = res[key];
                                } else {
                                    fdata[key] = res[key]
                                }
                            }
                            for (let key in fdata) {
                                console.log(typeof(fdata[key]))
                                if (typeof(fdata[key]) == 'object') {
                                    fdata[key] = JSON.stringify(fdata[key]);
                                }
                            }
                            console.log(fdata);
                            try {
                                var index = layer.load(1);
                                $.post("/admin/api/agent/update", fdata, function(response) {
                                    layer.close(index);
                                    if (response.code == 0) {
                                        layer.close(layerIndex);
                                        layer.msg("更改成功");
                                    } else {
                                        layer.msg(response.msg);
                                    }
                                }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                                    layer.close(index);
                                    layer.msg("网络请求失败");
                                });
                            } catch (e) {
                                console.log(e);
                            }
                        });
                    },
                    cancel: function() {}
                });
            }
            function delete_agent(id) {
                layer.confirm('您确定要执行此操作吗?', {
                    icon: 3,
                    title: '提示'
                }, function(index) {
                    // 确认操作
                    layer.close(index);
                    $.post("/admin/api/agent/delete", {
                        "id": id
                    }, function(response) {
                        if (response.code == 0) {
                            layer.msg("删除成功");
                            $("#search").click();
                        } else {
                            layer.msg(response.msg);
                        }
                    }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                        layer.close(index);
                        layer.msg("网络请求失败");
                    });
                }.bind(this));
            }
            layui.use(['form', 'jquery', 'layer', 'table','laydate'], function() {
                var table = layui.table;
                var form = layui.form;
                var $ = layui.jquery;
                var  laydate = layui.laydate;
                let table_option = {
                    elem: '#table',
                    url: '/admin/api/agent/list', //数据接口
@@ -130,36 +256,29 @@
                                title: 'ID',
                                width: 100,
                                fixed: 'left'
                            },
                            {
                            }, {
                                field: 'name',
                                title: '名称',
                                width: 120
                            },
                            {
                            }, {
                                field: 'alias',
                                title: '渠道标识',
                                width: 100,
                                sort: false,
                            },
                            {
                                field: 'link',
                            }, {
                                field: 'submitKeyLink',
                                title: '口令提交链接',
                                width: 100,
                                sort: false,
                            },
                            {
                                field: 'rule',
                                title: '类型',
                            }, {
                                field: '',
                                title: '状态',
                                width: 100,
                                sort: false,
                                templet: function(d) {
                                    return d.rule == 1 ? '超级管理员' : '普通'
                                    return d.status == 0 ? '正常' : '封禁'
                                }
                            },
                            {
                            }, {
                                field: 'createTime',
                                title: '创建时间',
                                width: 180,
@@ -168,21 +287,28 @@
                                title: '活跃时间',
                                width: 180,
                                sort: false,
                            },
                            {
                            }, {
                                field: '',
                                title: '设置',
                                sort: false,
                                templet: function(d) {
                                    var html = "";
                                    html += "<div><a href='javascript:void' onclick='update_agent(" + d.id + ")' class='layui-table-link'>设置</a></div>";
                                    return html;
                                }
                            }, {
                                field: '',
                                title: '操作',
                                sort: false,
                                templet:'<div><a href="javascript:void" onclick="updatePwd({{d.id}})" class="layui-table-link">设置密码</a></div>'
                                templet: function(d) {
                                    var html = "";
                                    html += "<div><a href='javascript:void' onclick='delete_agent(" + d.id + ")' class='layui-table-link'>删除</a></div>";
                                    return html;
                            }
                            }
                        ]
                    ]
                };
                var key = http_util.getQueryString("key");
                if (key != null && key != undefined) {
                    form.val("search", {
@@ -193,10 +319,8 @@
                        $("#search").click();
                    }, 100);
                }
                //第一个实例
                let tableIns = table.render(table_option);
                //监听提交
                form.on('submit(search)', function(data) {
                    tableIns.reload({
@@ -217,11 +341,8 @@
                    }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                        layer.msg("网络请求失败");
                    });
                    return false;
                });
            });
        </script>
    </body>
src/main/resources/static/admin/agent-settle-list.html
New file
@@ -0,0 +1,218 @@
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="renderer" content="webkit">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>设备列表</title>
        <link rel="stylesheet" type="text/css" href="layui/css/layui.css" />
        <link rel="stylesheet" type="text/css" href="css/admin.css" />
        <style>
            #add_client {
                padding: 10px;
            }
        </style>
    </head>
    <body>
        <div class="page-content-wrap">
            <form class="layui-form" action="" lay-filter='search'>
                <div class="layui-form-item">
                    <div class="layui-inline">
                        <input type="text" name="key" id="key" placeholder="按渠道ID/名称搜索" autocomplete="off" class="layui-input">
                    </div>
                    <div class="layui-inline">
                        <input type="text" name="day" placeholder="日期" autocomplete="off" class="layui-input">
                    </div>
                    <button class="layui-btn layui-btn-normal" lay-submit lay-filter="search" id="search"><i class="layui-icon layui-icon-search"></i>搜索</button>
                    <a href="javascript:void();" class="layui-btn layui-btn-warm" onclick="add_agent()"><i class="layui-icon layui-icon-add-circle"></i> 开始预结算</a>
                </div>
            </form>
            <div class="layui-form" id="table-list">
                <table class="layui-table" lay-even lay-skin="nob" id="table">
                </table>
            </div>
        </div>
        <script src="layui/layui.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/http_api.js"></script>
        <!-- <script src="js/common.js" type="text/javascript" charset="utf-8"></script> -->
        <script>
            function delete_agent(id) {
                layer.confirm('您确定要执行此操作吗?', {
                    icon: 3,
                    title: '提示'
                }, function(index) {
                    // 确认操作
                    layer.close(index);
                    $.post("/admin/api/agentsettle/delete", {
                        "id": id
                    }, function(response) {
                        if (response.code == 0) {
                            layer.msg("删除成功");
                            $("#search").click();
                        } else {
                            layer.msg(response.msg);
                        }
                    }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                        layer.close(index);
                        layer.msg("网络请求失败");
                    });
                }.bind(this));
            }
            function add_agent(){
                if($("input[name=day]").val().length<1){
                        layer.msg("请选择日期");
                        return false;
                    }
                    $.post("/admin/api/agentsettle/startSettle",$("input[name=day]").val(), function(response) {
                        if (response.code == 0) {
                            layer.msg("预结算成功");
                        } else {
                            layer.msg(response.msg);
                        }
                    }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                        layer.msg("网络请求失败");
                    });
            }
            layui.use(['form', 'jquery', 'layer', 'table', 'laydate'], function() {
                var table = layui.table;
                var form = layui.form;
                var $ = layui.jquery;
                var laydate = layui.laydate;
            laydate.render({
                    elem: "input[name=day]",
                    type: "date",
                    value: new Date(),
                    isInitValue:false
                });
                let table_option = {
                    elem: '#table',
                    url: '/admin/api/agentsettle/list', //数据接口
                    where: {
                        'key': $("#key").val(),
                        'day': $("input[name=day]").val(),
                    },
                    parseData: function(res) { //res 即为原始返回的数据
                        let flist = new Array();
                        res.data.list.forEach(function(e) {
                            var fdata = {}
                            for (let key in e) {
                                // 判断属性是否是对象自身的属性而非继承的属性
                                if (e.hasOwnProperty(key)) {
                                    //console.log(key + ": " + json[key]);
                                    if (typeof e[key] == 'object') {
                                        for (let k1 in e[key]) {
                                            fdata[key + "." + k1] = e[key][k1];
                                        }
                                    } else {
                                        fdata[key] = e[key];
                                    }
                                }
                            }
                            console.log(fdata);
                            flist.push(fdata);
                        });
                        return {
                            "code": res.code, //解析接口状态
                            "msg": res.msg, //解析提示文本
                            "count": res.data.count, //解析数据长度
                            "data": flist //解析数据列表
                        }
                    },
                    page: true, //开启分页
                    cols: [
                        [ //表头
                            {
                                field: 'id',
                                title: 'ID',
                                width: 100,
                                fixed: 'left'
                            },{
                                field: 'agentId',
                                title: '渠道',
                                width: 100,
                                sort: false,
                                templet: function(d) {
                                  return d["agent.name"]+"("+d["agent.id"]+")";
                                }
                            },  {
                                field: 'settleDay',
                                title: '日期',
                                width: 120
                            }, {
                                field: 'settleMoney',
                                title: '预结算金额',
                                width: 100,
                                sort: false,
                            }, {
                                field: 'createTime',
                                title: '预结算时间',
                                width: 180,
                            }, {
                                field: 'actualSettleMoney',
                                title: '实际结算金额',
                                width: 100,
                                sort: false
                            }, {
                                field: 'settleTime',
                                title: '实际结算时间',
                                width: 100,
                                sort: false
                            }, {
                                field: 'statusDesc',
                                title: '状态',
                                width: 100,
                                sort: false
                            },  {
                                field: '',
                                title: '操作',
                                sort: false,
                                templet: function(d) {
                                    var html = "";
                                    html += "<div><a href='javascript:void' onclick='delete_agent(" + d.id + ")' class='layui-table-link'>删除</a></div>";
                                    return html;
                                }
                            }
                        ]
                    ]
                };
                var key = http_util.getQueryString("key");
                if (key != null && key != undefined) {
                    form.val("search", {
                        "key": key
                    });
                    table_option.data = [];
                    setTimeout(function() {
                        $("#search").click();
                    }, 100);
                }
                //第一个实例
                let tableIns = table.render(table_option);
                //监听提交
                form.on('submit(search)', function(data) {
                    tableIns.reload({
                        where: data.field,
                        page: {
                            curr: 1 //重新从第 1 页开始
                        }
                    });
                    return false;
                });
            });
        </script>
    </body>
</html>
src/main/resources/static/admin/agent-update.html
New file
@@ -0,0 +1,235 @@
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>后台登录</title>
        <link rel="stylesheet" type="text/css" href="layui/css/layui.css" />
        <style>
            body {
                padding: 10px;
            }
            #sure {
                visibility: hidden;
            }
            .layui-form-label {
                width: 200px;
            }
            .layui-input-block {
                margin-left: 240px;
                max-width: 500px;
            }
            .layui-input-block input {
                max-width: 150px;
            }
            .small {
                max-width: 75px !important;
            }
            .share-ratio {
                display: flex;
                margin-bottom: 10px;
            }
            .share-ratio .layui-form-label {
                width: 50px;
                padding-left: 0;
                font-size: 12px;
                text-align: left;
            }
            .share-ratio input {
                width: 60px;
                margin-right: 10px;
            }
        </style>
    </head>
    <body>
        <form class="layui-form" lay-filter="edit">
            <input type="hidden" name="id" />
            <div class="layui-form-item">
                <label class="layui-form-label">渠道代理名称:</label>
                <div class="layui-input-inline">
                    <input type="text" name="name" required lay-verify="required" placeholder="代理名称" autocomplete="off" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">单日代付总频次限制:</label>
                <div class="layui-input-inline">
                    <input type="text" name="maxKeyCountPerDay" required lay-verify="required|num" placeholder="口令提交总次数" autocomplete="off" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">单日代付总金额限制:</label>
                <div class="layui-input-inline">
                    <input type="text" name="maxPayMoneyPerDay" required lay-verify="required|money" placeholder="单日代付总额" autocomplete="off" class="layui-input">
                </div>
                <div class="layui-form-mid layui-word-aux">元</div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">提交口令时段:</label>
                <div class="layui-input-inline" style="width: 100px;">
                    <input type="text" name="startSubmitTime" placeholder="开始时间" autocomplete="off" class="layui-input">
                </div>
                <div class="layui-form-mid">-</div>
                <div class="layui-input-inline" style="width: 100px;">
                    <input type="text" name="endSubmitTime" placeholder="结束时间" autocomplete="off" class="layui-input">
                </div>
                <div class="layui-form-mid layui-word-aux">如不填写就采用系统默认</div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">登录渠道代理后台账号:</label>
                <div class="layui-input-inline">
                    <input type="text" name="account" required lay-verify="required" placeholder="账号" autocomplete="off" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">登录渠道代理后台密码:</label>
                <div class="layui-input-inline">
                    <input type="password" name="pwd" required lay-verify="" placeholder="密码" autocomplete="off" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">支付宝信息:</label>
                <div class="layui-input-inline">
                    <input type="text" name="alipayName" required lay-verify="" placeholder="支付宝姓名" autocomplete="off" class="layui-input">
                </div>
                <div class="layui-input-inline">
                    <input type="text" name="alipayAccount" required lay-verify="" placeholder="支付宝账号" autocomplete="off" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">口令提交链接:</label>
                <div class="layui-input-inline">
                    <input type="text" name="submitKeyLink" id="submitKeyLink" readonly="readonly" value="http://www.baidu.com123123123123123123" placeholder="口令提交链接" autocomplete="off" class="layui-input">
                </div>
                <div class="layui-input-inline">
                    <button type="button" class="layui-form-mid layui-btn" onclick="copyLink()">复制</button>
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">分成设置:</label>
                <div class="layui-input-inline">
                    <div id="shareRatioContainer"></div>
                    <div class="layui-form-mid layui-word-aux">如不填写就采用系统默认</div>
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">口令提交页面免单福利入口:</label>
                <div class="layui-input-inline">
                    <input type="checkbox" checked name="open" lay-skin="switch" value="1" lay-filter="switchTest" title="">
                </div>
            </div>
            <div class="layui-input-block">
                <button class="layui-btn layui-btn-normal" lay-submit lay-filter="sure" id="sure">确定</button>
            </div>
        </form>
        <script src="layui/layui.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/http_api.js"></script>
        <script type="text/html" id="shareRatioTemplate">
            <div class="share-ratio">
                <label class="layui-form-label">{{ d.label }}</label>
                <input type="text" name="shareRatioInfos.{{d.name}}" required lay-verify="required|money" placeholder="" autocomplete="off" value="{{d.money}}" class="layui-input money">
                <div class="layui-form-mid layui-word-aux">元/单</div>
            </div>
        </script>
        <script>
            var listener;
            function submit(callback) {
                //暂存回调方法
                listener = callback;
                //表单提交按钮
                $("#sure").click();
            }
            function copyLink() {
                try {
                    document.getElementById("submitKeyLink").select();
                    var successful = document.execCommand('copy');
                    if (successful) {
                        layer.msg("复制成功");
                    } else {
                        layer.msg("复制失败");
                    }
                } catch (err) {
                    layer.msg("复制出错");
                    console.error('Oops, unable to copy', err);
                }
            }
            layui.use(['form', 'layedit', 'laydate', 'laytpl'], function() {
                var form = layui.form,
                    layer = layui.layer,
                    laydate = layui.laydate,
                    laytpl = layui.laytpl;
                //自定义验证规则
                form.verify({
                    num: [/^\d+$/, "必须为正整数"],
                    money: [/^\d+(\.\d{1,2})?$/, "金额最多保留2位小数"]
                });
                laydate.render({
                    elem: "input[name=startSubmitTime]",
                    type: "time",
                    value: new Date(),
                    isInitValue: false
                });
                laydate.render({
                    elem: "input[name=endSubmitTime]",
                    type: "time",
                    value: new Date(),
                    isInitValue: false
                });
                var id = http_util.getQueryString("id");
                // 获取值
                $.post("/admin/api/agent/getDetail", {
                    "id":id
                }, function(response) {
                    if (response.code == 0) {
                        form.val("edit", response.data);
                        let shareRatioInfos = response.data.shareRatioInfos;
                        shareRatioInfos = JSON.parse(shareRatioInfos);
                        for (var i = 0; i < shareRatioInfos.length; i++) {
                            laytpl($('#shareRatioTemplate').html()).render(shareRatioInfos[i], function(html) {
                                $("#shareRatioContainer").append(html);
                            });
                        }
                    } else {
                        layer.msg(response.msg);
                    }
                }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                    layer.msg("网络请求失败");
                });
                //监听提交
                form.on('submit(sure)', function(data) {
                    listener(data.field);
                    return false;
                });
            });
        </script>
    </body>
</html>
src/main/resources/static/admin/agent-withdraw-list.html
New file
@@ -0,0 +1,218 @@
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="renderer" content="webkit">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>设备列表</title>
        <link rel="stylesheet" type="text/css" href="layui/css/layui.css" />
        <link rel="stylesheet" type="text/css" href="css/admin.css" />
        <style>
            #add_client {
                padding: 10px;
            }
        </style>
    </head>
    <body>
        <div class="page-content-wrap">
            <form class="layui-form" action="" lay-filter='search'>
                <div class="layui-form-item">
                    <div class="layui-inline">
                        <input type="text" name="key" id="key" placeholder="按渠道ID/名称搜索" autocomplete="off" class="layui-input">
                    </div>
                    <div class="layui-inline">
                        <input type="text" name="day" placeholder="日期" autocomplete="off" class="layui-input">
                    </div>
                    <button class="layui-btn layui-btn-normal" lay-submit lay-filter="search" id="search"><i class="layui-icon layui-icon-search"></i>搜索</button>
                    <a href="javascript:void();" class="layui-btn layui-btn-warm" onclick="add_agent()"><i class="layui-icon layui-icon-add-circle"></i> 开始预结算</a>
                </div>
            </form>
            <div class="layui-form" id="table-list">
                <table class="layui-table" lay-even lay-skin="nob" id="table">
                </table>
            </div>
        </div>
        <script src="layui/layui.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/http_api.js"></script>
        <!-- <script src="js/common.js" type="text/javascript" charset="utf-8"></script> -->
        <script>
            function delete_agent(id) {
                layer.confirm('您确定要执行此操作吗?', {
                    icon: 3,
                    title: '提示'
                }, function(index) {
                    // 确认操作
                    layer.close(index);
                    $.post("/admin/api/agentsettle/delete", {
                        "id": id
                    }, function(response) {
                        if (response.code == 0) {
                            layer.msg("删除成功");
                            $("#search").click();
                        } else {
                            layer.msg(response.msg);
                        }
                    }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                        layer.close(index);
                        layer.msg("网络请求失败");
                    });
                }.bind(this));
            }
            function add_agent(){
                if($("input[name=day]").val().length<1){
                        layer.msg("请选择日期");
                        return false;
                    }
                    $.post("/admin/api/agentsettle/startSettle",$("input[name=day]").val(), function(response) {
                        if (response.code == 0) {
                            layer.msg("预结算成功");
                        } else {
                            layer.msg(response.msg);
                        }
                    }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                        layer.msg("网络请求失败");
                    });
            }
            layui.use(['form', 'jquery', 'layer', 'table', 'laydate'], function() {
                var table = layui.table;
                var form = layui.form;
                var $ = layui.jquery;
                var laydate = layui.laydate;
            laydate.render({
                    elem: "input[name=day]",
                    type: "date",
                    value: new Date(),
                    isInitValue:false
                });
                let table_option = {
                    elem: '#table',
                    url: '/admin/api/agentsettle/list', //数据接口
                    where: {
                        'key': $("#key").val(),
                        'day': $("input[name=day]").val(),
                    },
                    parseData: function(res) { //res 即为原始返回的数据
                        let flist = new Array();
                        res.data.list.forEach(function(e) {
                            var fdata = {}
                            for (let key in e) {
                                // 判断属性是否是对象自身的属性而非继承的属性
                                if (e.hasOwnProperty(key)) {
                                    //console.log(key + ": " + json[key]);
                                    if (typeof e[key] == 'object') {
                                        for (let k1 in e[key]) {
                                            fdata[key + "." + k1] = e[key][k1];
                                        }
                                    } else {
                                        fdata[key] = e[key];
                                    }
                                }
                            }
                            console.log(fdata);
                            flist.push(fdata);
                        });
                        return {
                            "code": res.code, //解析接口状态
                            "msg": res.msg, //解析提示文本
                            "count": res.data.count, //解析数据长度
                            "data": flist //解析数据列表
                        }
                    },
                    page: true, //开启分页
                    cols: [
                        [ //表头
                            {
                                field: 'id',
                                title: 'ID',
                                width: 100,
                                fixed: 'left'
                            },{
                                field: 'agentId',
                                title: '渠道',
                                width: 100,
                                sort: false,
                                templet: function(d) {
                                  return d["agent.name"]+"("+d["agent.id"]+")";
                                }
                            },  {
                                field: 'settleDay',
                                title: '日期',
                                width: 120
                            }, {
                                field: 'settleMoney',
                                title: '预结算金额',
                                width: 100,
                                sort: false,
                            }, {
                                field: 'createTime',
                                title: '预结算时间',
                                width: 180,
                            }, {
                                field: 'actualSettleMoney',
                                title: '实际结算金额',
                                width: 100,
                                sort: false
                            }, {
                                field: 'settleTime',
                                title: '实际结算时间',
                                width: 100,
                                sort: false
                            }, {
                                field: 'statusDesc',
                                title: '状态',
                                width: 100,
                                sort: false
                            },  {
                                field: '',
                                title: '操作',
                                sort: false,
                                templet: function(d) {
                                    var html = "";
                                    html += "<div><a href='javascript:void' onclick='delete_agent(" + d.id + ")' class='layui-table-link'>删除</a></div>";
                                    return html;
                                }
                            }
                        ]
                    ]
                };
                var key = http_util.getQueryString("key");
                if (key != null && key != undefined) {
                    form.val("search", {
                        "key": key
                    });
                    table_option.data = [];
                    setTimeout(function() {
                        $("#search").click();
                    }, 100);
                }
                //第一个实例
                let tableIns = table.render(table_option);
                //监听提交
                form.on('submit(search)', function(data) {
                    tableIns.reload({
                        where: data.field,
                        page: {
                            curr: 1 //重新从第 1 页开始
                        }
                    });
                    return false;
                });
            });
        </script>
    </body>
</html>
src/main/resources/static/admin/index.html
@@ -34,8 +34,9 @@
                  <li class="layui-nav-item">
                    <a href="javascript:;"><i class="iconfont">&#xe606;</i>代理管理</a>
                    <dl class="layui-nav-child">
                                        <dd><a href="javascript:;" data-url="device-list.html" data-id='5' data-text="渠道代理"><span class="l-line"></span>渠道代理</a></dd>
                                      <dd><a href="javascript:;" data-url="device-list.html" data-id='5' data-text="代理结算"><span class="l-line"></span>代理结算</a></dd>
                                        <dd><a href="javascript:;" data-url="agent-list.html" data-id='10' data-text="渠道代理"><span class="l-line"></span>渠道代理</a></dd>
                                      <dd><a href="javascript:;" data-url="agent-settle-list.html" data-id='11' data-text="代理结算"><span class="l-line"></span>代理结算</a></dd>
                                      <dd><a href="javascript:;" data-url="agent-withdraw-list.html" data-id='11' data-text="代理提现"><span class="l-line"></span>代理提现</a></dd>
                    </dl>
                  </li>
                  <li class="layui-nav-item">
@@ -54,7 +55,7 @@
                  <li class="layui-nav-item">
                    <a href="javascript:;"><i class="iconfont"></i>设备管理</a>
                    <dl class="layui-nav-child">
                                        <dd><a href="javascript:;" data-url="device-list.html" data-id='5' data-text="设备列表"><span class="l-line"></span>设备列表</a></dd>
                                        <dd><a href="javascript:;" data-url="device-list.html" data-id='6' data-text="设备列表"><span class="l-line"></span>设备列表</a></dd>
                    </dl>
                  </li>
                </ul>
src/main/resources/static/agent/alipay_account_setting.html
@@ -1,9 +1,9 @@
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport"
            content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <meta name="viewport" content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>支付宝账号设置</title>
        <script>
            window.onresize = function() {
@@ -16,11 +16,11 @@
        <script src="../js/jquery.min.js"></script>
        <script src="../js/vue.min.js"></script>
        <script src="../layui/layui.js"></script>
        <script src="js/http.js"></script>
        <style>
            body {
                background-color: #E0E0E0;
            }
            .item {
@@ -37,7 +37,6 @@
                color: #000000;
                width: 2rem;
                text-align: left;
            }
            .item input {
@@ -64,6 +63,7 @@
            }
        </style>
    </head>
    <body>
        <div id="container" style="text-align: center;">
            <div class="top-nav">
@@ -75,23 +75,19 @@
            <div class="item">
                <div class="title">姓&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;名</div>
                <input type="text" placeholder="输入你支付宝绑定的姓名" />
                <input type="text" id="alipayName" placeholder="输入你支付宝绑定的姓名" />
            </div>
            <div class="item">
                <div class="title">支付宝帐号</div>
                <input type="text" placeholder="输入支付宝账号" />
                <input type="text" id="alipayAccount" placeholder="输入支付宝账号" />
            </div>
            <button class="btn active">保存并提交</button>
            <button class="btn active" @click="save">保存并提交</button>
        </div>
        <script>
            $(function() {
                var app = new Vue({
                    el: "#container",
                    methods: {
@@ -99,13 +95,40 @@
                            if (window.history.length > 1) {
                                window.history.back();
                            }
                        },
                        save: function() {
                            var account = $("#alipayAccount").val();
                            var name = $("#alipayName").val();
                            if (account.length <= 0) {
                                layer.msg("请输入账号");
                                return;
                            }
                            if (name.length <= 0) {
                                layer.msg("请输入名称");
                                return;
                            }
                            var index = layer.load();
                            http_util.post("/agentapi/admin/setAlipayAccount", {
                                alipayAccount: account,
                                alipayName: name
                            }, function(res) {
                                layer.close(index);
                                if (res.code == 0) {
                                    layer.msg("设置成功");
                                    app.goBack();
                                } else {
                                    layer.msg(res.msg);
                                }
                            }, function(res) {
                                layer.close(index);
                                layer.msg(res);
                            });
                        }
                    }
                });
            });
        </script>
    </body>
</html>
src/main/resources/static/agent/css/index.css
@@ -3,6 +3,10 @@
    background-color: #F3F3F3;
}
[v-cloak] {
  display: none;
}
.nav-container {
    background-color: #FFF;
    display: flex;
@@ -10,7 +14,11 @@
    border-bottom: solid 1px #E0E0E0;
    width: 100%;
    justify-content: center;
    position: fixed;
    z-index: 1000;
    top: 0;
}
.nav-container>div {
    width: 3.75rem;
@@ -18,7 +26,6 @@
    justify-content: center;
    display: flex;
}
.nav {
    font-weight: 400;
@@ -33,6 +40,7 @@
#container{
    display: flex;
    flex-direction: column;
    height: 100%;
}
.nav-container .active {
@@ -50,17 +58,23 @@
    display: flex;
    flex-direction: column;
    flex: 1;
    position: fixed;
    top: 0.9rem;
    height: 100%;
    width: 100%;
}
.content-order .search {
    width: 100%;
    height: 0.6rem;
    display: flex;
    align-items: center;
    justify-content: center;
    padding-top: 0.2rem;
    background-color: #FFF;
    position: absolute;
    top: 0;
}
.content-order .search>div:first-child {
    height: 0.6rem;
@@ -89,20 +103,22 @@
}
.content-order .screen {
    width: 100%;
    display: flex;
    justify-content: space-between;
    color: #888888;
    padding: 0.23rem;
    align-items: flex-end;
    background-color: #FFF;
    position: absolute;
    top: 0.8rem;
    box-sizing: border-box;
}
.content-order .screen>div:first-child {
    color: #888888;
    font-size: 0.28rem;
    align-items: flex-end;
}
.content-order .screen>div:first-child img {
@@ -116,9 +132,10 @@
}
.content-order .list {
    flex: 1;
    overflow: auto;
    margin-top: 1.65rem;
    box-sizing: border-box;
    height: 100%;
}
.content-order .item {
@@ -144,6 +161,7 @@
    color: #888888;
    line-height: 0.39rem;
    text-align: right;
    white-space: pre-wrap;
}
.content-order .item .user {
@@ -223,7 +241,6 @@
    display: flex;
    justify-content: space-between;
    padding: 0 0.35rem 0.35rem 0.35rem;
}
#screen .item {
@@ -252,16 +269,12 @@
    padding: 0.24rem 0 0.34rem 0.35rem;
}
#screen .btn-container {
    display: flex;
    justify-content: space-between;
    padding: 0 0.4rem;
    align-items: center;
    height: 1.16rem;
}
#screen .btn {
@@ -284,16 +297,25 @@
}
.content-withdraw {
    /* position: relative; */
    position: fixed;
    top: 0.9rem;
    bottom: 1.02rem;
    height: 100%;
    overflow: auto;
}
.content-withdraw>div {
.content-withdraw>.list {
    margin-bottom: 1.02rem;
    flex: 1;
}
.content-withdraw>.list>div {
    display: flex;
    flex-direction: column;
    align-items: center;
}
.content-withdraw>div>.item {
.content-withdraw>.list>div>.item {
    width: 7.1rem;
    height: 1.66rem;
    padding: 0 0.3rem;
@@ -305,7 +327,7 @@
    flex-direction: column;
}
.content-withdraw>div>.month {
.content-withdraw>.list>div>.month {
    background: #FFFFFF;
    border-radius: 0.22rem;
    width: 2.60rem;
@@ -318,8 +340,7 @@
    margin-bottom: 0.18rem;
}
.content-withdraw>div>.item>.time {
.content-withdraw>.list>div>.item>.time {
    text-align: center;
    font-size: 0.24rem;
    color: #888888;
@@ -327,30 +348,29 @@
    border-bottom: solid 1px #E0E0E0;
}
.content-withdraw>div>.item>div:last-child {
.content-withdraw>.list>div>.item>div:last-child {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-top: 0.16rem;
}
.content-withdraw>div>.item:last-child>div {
.content-withdraw>.list>div>.item:last-child>div {
    text-align: center;
}
.content-withdraw>div>.item .title {
.content-withdraw>.list>div>.item .title {
    font-size: 0.20rem;
    color: #888888;
    margin-bottom: 0.2rem;
}
.content-withdraw>div>.item: .val {
.content-withdraw>.list>div>.item: .val {
    font-size: 0.30rem;
    color: #000000;
}
.content-withdraw>div>.item>div:last-child>.btn {
.content-withdraw>.list>div>.item>div:last-child>.btn {
    background: #D0D0D0;
    border-radius: 0.22rem;
    font-size: 0.28rem;
@@ -360,19 +380,20 @@
    line-height: 0.46rem;
}
.content-withdraw>div>.item>div:last-child>.active {
.content-withdraw>.list>div>.item>div:last-child>.active {
    background: #E5005C;
}
.content-withdraw .alipay-setting {
    position: absolute;
    position: fixed;
    bottom: 0;
    height: 1.02rem;
    line-height: 1.02rem;
    text-align: center;
    background: #FFF;
    width: 100%;
    display: flex;
    justify-content: center;
}
.content-withdraw .alipay-setting .btn {
@@ -391,5 +412,28 @@
.content-withdraw .alipay-setting .btn img {
    width: 0.29rem;
    height: 0.29rem;
}
.loading{
    text-align: center;
    font-size: 0.3rem;
    line-height: 0.8rem;
    height: 0.8rem;
    color: #333333;
    width: 100%;
}
.loading-no{
    color: #888888;
}
.empty{
    color: #888888;
    height: 100%;
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
}
src/main/resources/static/agent/index.html
@@ -1,9 +1,9 @@
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport"
            content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <meta name="viewport" content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>福利发放</title>
        <script>
            window.onresize = function() {
@@ -20,20 +20,19 @@
        <style>
    
        </style>
    </head>
    <body>
        <div id="container">
        <div id="container" v-cloak>
            <div class="nav-container">
                <div>
                    <div class="nav"  :class="{'active':mode==0}" @click="change_mode(0)"> 对账</div>
                <div @click="change_mode(0)">
                    <div class="nav" :class="{'active':mode==0}" > 对账</div>
                </div>
                <div class="cutline"></div>
                <div>
                    <div class="nav" :class="{'active':mode==1}"  @click="change_mode(1)"> 提现</div>
                <div @click="change_mode(1)">
                    <div class="nav" :class="{'active':mode==1}" > 提现</div>
                </div>
            </div>
@@ -52,15 +51,15 @@
                    </div>
                    <div>
                        <span>共</span>
                        <span class="red">10</span>
                        <span class="red">{{order_statistic.user_count}}</span>
                        <span>个老铁</span>
                        <span>共</span>
                        <span class="red">30</span>
                        <span class="red">{{order_statistic.order_count}}</span>
                        <span>笔</span>
                        <span>共</span>
                        <span class="red">300.00</span>
                        <span class="red">{{order_statistic.total_money}}</span>
                        <span>元</span>
                    </div>
@@ -71,40 +70,50 @@
                    <div class="order-item" v-for="(item,index) in orders">
                        <div>
                            <div class="user">
                                <img />
                                <img :src="item.user.portrait" />
                                <div>
                                    <div class="name">那些年错过的大鱼</div>
                                    <div class="id">ID:12345</div>
                                    <div class="name">{{item.user.nickName}}</div>
                                    <div class="id">ID:{{item.user.id}}</div>
                                </div>
                            </div>
                            <div class="time">
                                2020.06.18<br>
                                17:00:00
                            <div class="time" v-html="item.createTime">
                            </div>
                        </div>
                        <div>
                            <div>
                                <div class="title">代付金额</div>
                                <div class="val">10.00</div>
                                <div class="val">{{item.payMoney}}</div>
                            </div>
                            <div>
                                <div class="title">结算金额</div>
                                <div class="val">0.6</div>
                                <div class="val">{{item.settleMoney}}</div>
                            </div>
                            <div>
                                <div class="title">订单状态</div>
                                <div class="val">有效</div>
                            </div>
                                <div class="val">
                                    <span v-if="item.valid">有效</span>
                                    <span v-else>无效</span>
                        </div>
                    </div>
                        </div>
                    </div>
                    <div class="loading" v-if="orders.length>0" @click="loadOrder" :class="{'loading-no':!hasMore}">
                        <span v-if="hasMore">点击加载更多</span>
                        <span v-else>没有更多了</span>
                    </div>
                    <div class="empty" v-if="orders.length==0">
                        暂无数据
                    </div>
                </div>
            </div>
            <div class="content-withdraw"  v-if="mode==1">
                <div class="list">
                <div v-for="(item,index) in withdraw_records">
                    <div class="month">2024年07月</div>
                    <div class="item">
@@ -125,14 +134,22 @@
                            <div class="btn">提现</div>
                        </div>
                    </div>
                </div>
                    <div class="loading" v-if="withdraw_records.length>0" @click="loadWidthdraw" :class="{'loading-no':!hasMore}">
                        <span v-if="hasMore">点击加载更多</span>
                        <span v-else>没有更多了</span>
                    </div>
                   <div class="empty" v-if="withdraw_records.length==0">
                
                        暂无数据
                    </div>
                    <div style="height: 1.02rem;"></div>
            
                </div>
                <div class="alipay-setting">
                    
                    <div class="btn" @click="setAlipayAccount">
@@ -141,7 +158,6 @@
                        </span>
                        <img src="img/icon_round_in.png"/>
                    </div>
                    
                </div>
@@ -175,13 +191,12 @@
            
        </div>
        <script src="js/index.js"></script>
        <script src="js/http.js"></script>
        <script>
        </script>
    </body>
</html>
src/main/resources/static/agent/js/http.js
@@ -1,9 +1,21 @@
var httputil={
var http_util = {
    post:function(url,params,success_callback,fail_callback){
        $.post(url,params,function(response){
            if (response.code == 1001) {
                window.location.replace("login.html?redirect="+encodeURIComponent(window.location.href));
            } else {
            success_callback(response);
            }
        },'json').fail(function(jqXHR, textStatus, errorThrown){
            fail_callback("网络请求失败");
        });
    },
    getQueryString:function(name) {
        console.log(window.location.search)
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
        var r = window.location.search.substr(1).match(reg);
        if (r != null)
            return unescape(decodeURI(r[2]));
        return null;
    }
};
src/main/resources/static/agent/js/index.js
@@ -4,16 +4,27 @@
        data:{
            mode:0,
            temp_screen_time_index:0,
            current_page: 1,
            screen_time_index:0,
            orders:[1,1,1,1,1,1,1,1],
            withdraw_records:[1,1,1]
            orders: [],
            hasMore: true,
            withdraw_records: [1, 1, 1, 1, 1],
            order_statistic: {
                user_count: 0,
                order_count: 0,
                total_money: 0.00
            }
        },
        mounted: function() {
            this.$nextTick(function() {
                app.search();
            });
        },
        methods:{
            change_mode:function(mode){
                app.mode = mode;
            },
            search:function(){
            },
            open_screen:function(){
                app.temp_screen_time_index = app.screen_time_index;
@@ -45,15 +56,49 @@
            sureScreen:function(){
                app.screen_time_index = app.temp_screen_time_index;
                    layer.closeAll();
                app.search();
            },
            setAlipayAccount:function(){
                window.location.href="alipay_account_setting.html";
            },
            search: function() {
                app.current_page = 1;
                app.orders = [];
                app.order_statistic = {
                    user_count: 0,
                    order_count: 0,
                    total_money: 0.00
                };
                http_util.post("/agentapi/admin/orderList", {
                    key: $("#search_key").val(),
                    timeIndex: app.screen_time_index,
                    page: app.current_page
                }, function(res) {
                    if (res.code == 0) {
                        app.orders = app.orders.concat(res.data.list);
                        app.order_statistic.order_count = res.data.count;
                        app.order_statistic.user_count = res.data.statistic.count;
                        app.order_statistic.total_money = res.data.statistic.money;
                        if (app.orders.length < app.order_statistic.order_count) {
                            app.hasMore = true;
                        } else {
                            app.hasMore = false;
                        }
            }
            
                }, function(res) {
                });
            },
            loadOrder: function() {
            },
            loadWidthdraw: function() {
            }
            
        }
        
    });
    
});
src/main/resources/static/agent/login.html
@@ -1,5 +1,6 @@
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
         <meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -14,6 +15,7 @@
        <link rel="stylesheet" type="text/css" href="css/common.css" />
        <script src="../js/jquery.min.js"></script>
        <script src="../layui/layui.js"></script>
        <script src="js/http.js"></script>
        
        <style>
            .icon{
@@ -21,6 +23,7 @@
                height: auto;
                margin-top: 1rem;
            }
            .title{
                font-family: Microsoft YaHei;
                font-weight: 400;
@@ -28,6 +31,7 @@
                color: #3279F3;
                margin-top: 0.2rem;
            }
            .container{
                display: flex;
                flex-direction: column;
@@ -51,12 +55,13 @@
                margin-top: 0.23rem;
                line-height: 0.9rem;
                padding-left:0.42rem ;
            }
            .login_content img{
                width: 0.37rem;
                margin-right: 0.2rem;
            }
            .login_content input{
                border: none;
                background-color: transparent;
@@ -65,9 +70,9 @@
                line-height: 0.9rem;
                color: #000000;
            }
        </style>
    </head>
    <body>
        
        <div class="container">
@@ -79,12 +84,12 @@
            
            <div class="login_content">
                <img src="img/icon_account.png"/>
                <input type="text" placeholder="请输入账号"/>
                <input type="text" id="account" placeholder="请输入账号" />
            </div>
            
            <div class="login_content">
                <img src="img/icon_pwd.png" style="width: 0.31rem;"/>
                <input type="password" placeholder="请输入密码"/>
                <input type="password" id="pwd" placeholder="请输入密码" />
            </div>
            
            <button class="btn-active btn" >登&nbsp;&nbsp;&nbsp;&nbsp;录</button>
@@ -94,32 +99,41 @@
        <script>
            $(function(){
                $(".btn").click(function(){
                    var text = $(".edit").val();
                    if(text.length<=0){
                        layer.msg("请输入口令");
                    var account = $("#account").val();
                    var pwd = $("#pwd").val();
                    if (account.length <= 0) {
                        layer.msg("请输入账号");
                        return;
                    }
                    if (pwd.length <= 0) {
                        layer.msg("请输入密码");
                        return;
                    }
                    var index = layer.load();
                    // 上传口令
                    $.post("/webapi/submitKey",{"key":text},function(response){
                    http_util.post("/agentapi/admin/login", {
                        account: account,
                        pwd: pwd
                    }, function(res) {
                        layer.close(index);
                        if(response.code==0){
                            layer.msg("提交成功");
                             $(".edit").val("");
                        if (res.code == 0) {
                            layer.msg("登录成功");
                            let redirect = http_util.getQueryString("redirect");
                            if (redirect != null && redirect.length > 0) {
                                window.location.replace(redirect);
                        }else{
                            layer.msg(response.msg);
                                window.location.replace("index.html");
                        }
                    },'json').fail(function(jqXHR, textStatus, errorThrown){
                        } else {
                            layer.msg(res.msg);
                        }
                    }, function(res) {
                        layer.close(index);
                        layer.msg("网络请求失败");
                        layer.msg(res);
                    });
                });
            });
        </script>
        
    </body>
</html>
src/main/resources/static/agent/test.html
New file
@@ -0,0 +1,288 @@
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
        <title>福利发放</title>
        <script>
            window.onresize = function() {
                document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px';
            };
            window.onresize();
        </script>
        <link rel="stylesheet" type="text/css" href="../layui/css/layui.css">
        <link rel="stylesheet" type="text/css" href="css/common.css">
        <link rel="stylesheet" type="text/css" href="css/index.css">
        <script src="../js/jquery.min.js"></script>
        <script src="../js/vue.min.js"></script>
        <script src="../layui/layui.js"></script>
        <link id="layuicss-laydate" rel="stylesheet" href="http://q.izxwl.com/layui/css/modules/laydate/default/laydate.css?v=5.3.1" media="all">
        <link id="layuicss-layer" rel="stylesheet" href="http://q.izxwl.com/layui/css/modules/layer/default/layer.css?v=3.5.1" media="all">
        <link id="layuicss-skincodecss" rel="stylesheet" href="http://q.izxwl.com/layui/css/modules/code.css?v=2" media="all">
        <style>
        </style>
    </head>
    <body>
        <div id="container">
            <div class="nav-container">
                <div>
                    <div class="nav active"> 对账</div>
                </div>
                <div class="cutline"></div>
                <div>
                    <div class="nav"> 提现</div>
                </div>
            </div>
            <div class="content-order">
                <div class="search">
                    <div><img src="img/icon_search.png"> <input id="search_key" type="text" placeholder="请输入要搜索老铁的关键词"></div>
                    <div class="search-btn">搜索</div>
                </div>
                <div class="screen">
                    <div><img src="img/icon_screen.png"> <span>筛选</span></div>
                    <div><span>共</span> <span class="red">0</span> <span>个老铁</span> <span>共</span> <span class="red">3</span> <span>笔</span> <span>共</span> <span class="red">0</span> <span>元</span></div>
                </div>
                <div class="list">
                    <div class="order-item">
                        <div>
                            <div class="user"><img src="">
                                <div>
                                    <div class="name"></div>
                                    <div class="id">ID:4422</div>
                                </div>
                            </div>
                            <div class="time">2024.07.27<br>22:55:38</div>
                        </div>
                        <div>
                            <div>
                                <div class="title">代付金额</div>
                                <div class="val">4.00</div>
                            </div>
                            <div>
                                <div class="title">结算金额</div>
                                <div class="val">0.50</div>
                            </div>
                            <div>
                                <div class="title">订单状态</div>
                                <div class="val"><span>有效</span></div>
                            </div>
                        </div>
                    </div>
                    <div class="order-item">
                        <div>
                            <div class="user"><img src="">
                                <div>
                                    <div class="name"></div>
                                    <div class="id">ID:6357</div>
                                </div>
                            </div>
                            <div class="time">2024.07.27<br>22:53:38</div>
                        </div>
                        <div>
                            <div>
                                <div class="title">代付金额</div>
                                <div class="val">4.00</div>
                            </div>
                            <div>
                                <div class="title">结算金额</div>
                                <div class="val">0.50</div>
                            </div>
                            <div>
                                <div class="title">订单状态</div>
                                <div class="val"><span>有效</span></div>
                            </div>
                        </div>
                    </div>
                    <div class="order-item">
                        <div>
                            <div class="user"><img src="">
                                <div>
                                    <div class="name"></div>
                                    <div class="id">ID:2704</div>
                                </div>
                            </div>
                            <div class="time">2024.07.27<br>22:51:44</div>
                        </div>
                        <div>
                            <div>
                                <div class="title">代付金额</div>
                                <div class="val">4.00</div>
                            </div>
                            <div>
                                <div class="title">结算金额</div>
                                <div class="val">0.50</div>
                            </div>
                            <div>
                                <div class="title">订单状态</div>
                                <div class="val"><span>有效</span></div>
                            </div>
                        </div>
                    </div>
                    <div class="order-item">
                        <div>
                            <div class="user"><img src="">
                                <div>
                                    <div class="name"></div>
                                    <div class="id">ID:2704</div>
                                </div>
                            </div>
                            <div class="time">2024.07.27<br>22:51:44</div>
                        </div>
                        <div>
                            <div>
                                <div class="title">代付金额</div>
                                <div class="val">4.00</div>
                            </div>
                            <div>
                                <div class="title">结算金额</div>
                                <div class="val">0.50</div>
                            </div>
                            <div>
                                <div class="title">订单状态</div>
                                <div class="val"><span>有效</span></div>
                            </div>
                        </div>
                    </div>
                    <div class="order-item">
                        <div>
                            <div class="user"><img src="">
                                <div>
                                    <div class="name"></div>
                                    <div class="id">ID:2704</div>
                                </div>
                            </div>
                            <div class="time">2024.07.27<br>22:51:44</div>
                        </div>
                        <div>
                            <div>
                                <div class="title">代付金额</div>
                                <div class="val">4.00</div>
                            </div>
                            <div>
                                <div class="title">结算金额</div>
                                <div class="val">0.50</div>
                            </div>
                            <div>
                                <div class="title">订单状态</div>
                                <div class="val"><span>有效</span></div>
                            </div>
                        </div>
                    </div>
                    <div class="order-item">
                        <div>
                            <div class="user"><img src="">
                                <div>
                                    <div class="name"></div>
                                    <div class="id">ID:2704</div>
                                </div>
                            </div>
                            <div class="time">2024.07.27<br>22:51:44</div>
                        </div>
                        <div>
                            <div>
                                <div class="title">代付金额</div>
                                <div class="val">4.00</div>
                            </div>
                            <div>
                                <div class="title">结算金额</div>
                                <div class="val">0.50</div>
                            </div>
                            <div>
                                <div class="title">订单状态</div>
                                <div class="val"><span>有效</span></div>
                            </div>
                        </div>
                    </div>
                    <div class="order-item">
                        <div>
                            <div class="user"><img src="">
                                <div>
                                    <div class="name"></div>
                                    <div class="id">ID:2704</div>
                                </div>
                            </div>
                            <div class="time">2024.07.27<br>22:51:44</div>
                        </div>
                        <div>
                            <div>
                                <div class="title">代付金额</div>
                                <div class="val">4.00</div>
                            </div>
                            <div>
                                <div class="title">结算金额</div>
                                <div class="val">0.50</div>
                            </div>
                            <div>
                                <div class="title">订单状态</div>
                                <div class="val"><span>有效</span></div>
                            </div>
                        </div>
                    </div>
                    <div class="order-item">
                        <div>
                            <div class="user"><img src="">
                                <div>
                                    <div class="name"></div>
                                    <div class="id">ID:2704</div>
                                </div>
                            </div>
                            <div class="time">2024.07.27<br>22:51:44</div>
                        </div>
                        <div>
                            <div>
                                <div class="title">代付金额</div>
                                <div class="val">4.00</div>
                            </div>
                            <div>
                                <div class="title">结算金额</div>
                                <div class="val">0.50</div>
                            </div>
                            <div>
                                <div class="title">订单状态</div>
                                <div class="val"><span>有效</span></div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <!---->
            <div id="screen" class="" style="display: none;">
                <div class="title">
                    全部筛选
                </div> <img src="img/icon_close_sm.png" class="close">
                <div>查看时间</div>
                <div class="date">
                    <div class="item">
                        今天
                    </div>
                    <div class="item active">
                        昨天
                    </div>
                    <div class="item">
                        近三天
                    </div>
                    <div class="item">
                        本周
                    </div>
                </div>
                <div class="btn-container">
                    <div class="btn btn-reset">重置</div>
                    <div class="btn btn-sure">确定</div>
                </div>
            </div>
        </div>
        <script src="js/index.js"></script>
        <script src="js/http.js"></script>
        <script>
        </script>
        <div class="layui-layer-move" id="layui-layer-move"></div>
    </body>
</html>
src/main/resources/static/index3.html
@@ -63,6 +63,7 @@
                }
                var state = getQueryString("state");
                var msg = getQueryString("msg");
                var a=getQueryString("a");
                if(state=="SUCCESS"){
                  layer.msg("提交成功");
                }else if(state =="FAIL"){
@@ -80,6 +81,12 @@
                        layer.msg("请输入口令");
                        return;
                    }
                    if(a==null||a==undefined||a.length<=0){
                        layer.msg("非渠道链接");
                        return;
                    }
                    // const moneyRegex = /^\d+(\.\d{1,2})?$/;
                    // if (!moneyRegex.test(money)) {
                    //     layer.msg("付款金额输入错误");
src/test/java/com/taoke/autopay/AgentTest.java
@@ -1,17 +1,23 @@
package com.taoke.autopay;
import com.taoke.autopay.dao.agent.ChannelAgentMapper;
import com.taoke.autopay.dao.agent.ChannelAgentSettleDetailMapper;
import com.taoke.autopay.dao.agent.ChannelAgentSettleRecordMapper;
import com.taoke.autopay.dao.agent.ChannelAgentSharingRatioMapper;
import com.taoke.autopay.entity.OrderChannelEnum;
import com.taoke.autopay.entity.agent.ChannelAgent;
import com.taoke.autopay.entity.agent.ChannelAgentSettleRecord;
import com.taoke.autopay.entity.agent.ChannelAgentSharingRatio;
import com.taoke.autopay.exception.ChannelAgentException;
import com.taoke.autopay.exception.ChannelAgentSettleException;
import com.taoke.autopay.service.agent.ChannelAgentService;
import com.taoke.autopay.service.agent.ChannelAgentSettleService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
/**
 * @author hxh
@@ -27,6 +33,15 @@
    @Resource
    private ChannelAgentSharingRatioMapper channelAgentSharingRatioMapper;
    @Resource
    private ChannelAgentSettleService channelAgentSettleService;
    @Resource
    private ChannelAgentSettleRecordMapper channelAgentSettleRecordMapper;
    @Resource
    private ChannelAgentSettleDetailMapper channelAgentSettleDetailMapper;
    @Test
@@ -39,4 +54,24 @@
//        ChannelAgentSharingRatio
    }
    @Test
    public void testSettle() throws ChannelAgentSettleException {
        channelAgentSettleService.startSettle("2024-07-28");
    }
    @Test
    public void testGetSettle() throws ChannelAgentSettleException {
//        channelAgentSettleDetailMapper.listBySettleId(1L);
//        channelAgentSettleRecordMapper.selectByPrimaryKey(1L);
        ChannelAgentSettleRecordMapper.DaoQuery daoQuery= new  ChannelAgentSettleRecordMapper.DaoQuery();
        daoQuery.count=100;
//
        List<ChannelAgentSettleRecord> records = channelAgentSettleService.list(daoQuery);
        System.out.println(records);
    }
}
src/test/java/com/taoke/autopay/KeyTest.java
@@ -1,5 +1,6 @@
package com.taoke.autopay;
import com.taoke.autopay.dao.KeyOrderMapper;
import com.taoke.autopay.dto.DYOrderDto;
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.entity.SystemConfigKeyEnum;
@@ -73,8 +74,7 @@
                DYOrderDto dto = keyOrderService.verifyKey(tradeInfo.getGoodsTitle(), orderStatus, tradeInfo.getItemRealAmount());
            }catch(KeyVerifyException ee){
                throw  ee;
            }
            catch(Exception e){
            } catch (Exception e) {
                throw new KeyVerifyException(KeyVerifyException.CODE_COMMON, e.getMessage());
            }
        }
@@ -104,4 +104,16 @@
        }
    }
    @Test
    public void statisticAgentId() {
        KeyOrderMapper.DaoQuery query=new KeyOrderMapper.DaoQuery();
        query.hasAgentId=true;
        query.hasPayTime = true;
        query.state =2;
        query.count = 100;
        List<Long> list =   keyOrderService.listAgentId(query);
        System.out.println(list);
    }
}
src/test/java/com/taoke/autopay/MapperTest.java
@@ -32,12 +32,12 @@
//        System.out.println(   MyBatisMapperUtil.createSQL(ChannelAgentOrderStatisticRecord.class));
//        System.out.println(   MyBatisMapperUtil.createSQL(ChannelAgentSettings.class));
//        System.out.println(MyBatisMapperUtil.createSQL(ChannelAgentSettleRecord.class));
        System.out.println(   MyBatisMapperUtil.createSQL(ChannelAgentSharingRatio.class));
        System.out.println(   MyBatisMapperUtil.createSQL(ChannelAgentSettleDetail.class));
//        MyBatisMapperUtil.createMapper(ChannelAgentOrderStatisticRecord.class);
//        MyBatisMapperUtil.createMapper(ChannelAgentSettings.class);
//        MyBatisMapperUtil.createMapper(ChannelAgentSettleRecord.class);
        MyBatisMapperUtil.createMapper(ChannelAgentSharingRatio.class);
        MyBatisMapperUtil.createMapper(ChannelAgentSettleDetail.class);
//      System.out.println(  new BigDecimal("3.26").multiply(new BigDecimal(100)).setScale(0, RoundingMode.FLOOR).intValue());