Ver código fonte

天天企赋api

xx 1 ano atrás
pai
commit
4b2224609a
34 arquivos alterados com 1787 adições e 1 exclusões
  1. 10 0
      pom.xml
  2. 73 0
      sql/Online.sql
  3. 3 0
      sql/jar/reeadmind
  4. BIN
      sql/jar/ttqf-api-sdk-1.0.0.jar
  5. 3 0
      src/main/java/com/ydtech/modules/admin/dao/SysUserBankCardMapper.java
  6. 5 0
      src/main/java/com/ydtech/modules/admin/model/SysUser.java
  7. 10 1
      src/main/java/com/ydtech/modules/admin/model/po/SysUserBankCard.java
  8. 53 0
      src/main/java/com/ydtech/modules/ttqf/GenerateOrderNumberUtils.java
  9. 40 0
      src/main/java/com/ydtech/modules/ttqf/LgInformationPush.java
  10. 136 0
      src/main/java/com/ydtech/modules/ttqf/PayConstantStatus.java
  11. 125 0
      src/main/java/com/ydtech/modules/ttqf/QuartzManager.java
  12. 32 0
      src/main/java/com/ydtech/modules/ttqf/QuartzUserSign.java
  13. 77 0
      src/main/java/com/ydtech/modules/ttqf/RegularlyPaymentStatus.java
  14. 71 0
      src/main/java/com/ydtech/modules/ttqf/RegularlyUpdateStatus.java
  15. 355 0
      src/main/java/com/ydtech/modules/ttqf/RetrieveTTQFApi.java
  16. 53 0
      src/main/java/com/ydtech/modules/ttqf/SavePayOrder.java
  17. 32 0
      src/main/java/com/ydtech/modules/ttqf/TTFQConfig.java
  18. 107 0
      src/main/java/com/ydtech/modules/ttqf/controller/TtqfController.java
  19. 7 0
      src/main/java/com/ydtech/modules/ttqf/dao/PaySignCallbackMapper.java
  20. 7 0
      src/main/java/com/ydtech/modules/ttqf/dao/PayTtqfConfirmMapper.java
  21. 36 0
      src/main/java/com/ydtech/modules/ttqf/dao/PayTtqfLogMapper.java
  22. 7 0
      src/main/java/com/ydtech/modules/ttqf/dao/PayUserSignMapper.java
  23. 7 0
      src/main/java/com/ydtech/modules/ttqf/dao/PaymentNoticeMapper.java
  24. 99 0
      src/main/java/com/ydtech/modules/ttqf/decrypt.java
  25. 35 0
      src/main/java/com/ydtech/modules/ttqf/entity/PaySignCallback.java
  26. 36 0
      src/main/java/com/ydtech/modules/ttqf/entity/PayTtqfConfirm.java
  27. 71 0
      src/main/java/com/ydtech/modules/ttqf/entity/PayTtqfLog.java
  28. 33 0
      src/main/java/com/ydtech/modules/ttqf/entity/PayUserSign.java
  29. 38 0
      src/main/java/com/ydtech/modules/ttqf/entity/PaymentNoticeEntity.java
  30. 49 0
      src/main/java/com/ydtech/modules/ttqf/entity/vo/PaySigningInformation.java
  31. 15 0
      src/main/java/com/ydtech/modules/ttqf/service/PayUserSignService.java
  32. 25 0
      src/main/java/com/ydtech/modules/ttqf/service/TtqfService.java
  33. 45 0
      src/main/java/com/ydtech/modules/ttqf/service/impl/PayUserSignServiceImpl.java
  34. 92 0
      src/main/java/com/ydtech/modules/ttqf/service/impl/TtqfServiceImpl.java

+ 10 - 0
pom.xml

@@ -647,6 +647,16 @@
             <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
             <version>3.4.0</version>
         </dependency>
+        <dependency>
+            <groupId>org.quartz-scheduler</groupId>
+            <artifactId>quartz</artifactId>
+            <version>2.3.2</version>
+        </dependency>
+        <dependency>
+            <groupId>ttqf.api.sdk</groupId>
+            <artifactId>ttqf-api-1.1.0</artifactId>
+            <version>1.0.0</version>
+        </dependency>
 
     </dependencies>
 

+ 73 - 0
sql/Online.sql

@@ -77,7 +77,80 @@ ALTER TABLE `agent`.`sys_user`
     ADD COLUMN `dept_type` varchar(30) NULL COMMENT '机构类型(股份,直营,加盟)',
     ADD COLUMN `referrer_id` varchar(30) NULL COMMENT '推荐人id';
 
+-- 2024.11.1 --
+ALTER TABLE `agent`.`sys_user` ADD COLUMN `identity_time` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '身份证有效期' AFTER `identity`;
 
+CREATE TABLE `pay_payment_notice` (
+                                      `id` bigint NOT NULL,
+                                      `type` varchar(255) DEFAULT NULL COMMENT '通知类型',
+                                      `mch_order_no` varchar(255) DEFAULT NULL COMMENT '商户订单号',
+                                      `order_no` varchar(255) DEFAULT NULL COMMENT '天天企赋业务订单号',
+                                      `amount` decimal(15,2) DEFAULT NULL COMMENT '打款金额',
+                                      `fee_amount` decimal(15,2) DEFAULT NULL COMMENT '服务费',
+                                      `status` tinyint NOT NULL DEFAULT '0' COMMENT '订单状态',
+                                      `message` varchar(255) DEFAULT NULL COMMENT '状态描述',
+                                      `pay_time` datetime DEFAULT NULL COMMENT '打款时间',
+                                      `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+                                      PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
+CREATE TABLE `pay_sign_callback` (
+                                     `id` int NOT NULL,
+                                     `type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '默认值:PRESIGN',
+                                     `org_req_id` bigint DEFAULT NULL COMMENT '最后一次请求',
+                                     `name` varchar(255) DEFAULT NULL,
+                                     `mobile` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
+                                     `id_card_no` varchar(255) DEFAULT NULL,
+                                     `bank_card_no` varchar(255) DEFAULT NULL,
+                                     `bank_name` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
+                                     `auth_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '认证状态:0-未实名1-已实名',
+                                     `sign_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '签约状态:0-未签约1-已签约',
+                                     `bind_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT ' 绑卡状态:0-未绑定1-已绑定',
+                                     PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户签约回调';
 
+CREATE TABLE `pay_ttqf_confirm` (
+                                    `id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
+                                    `user_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户ID',
+                                    `biz_msg` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '返回信息',
+                                    `biz_code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '业务响应码',
+                                    `batch_no` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '天天企赋业务批次号',
+                                    `mch_batch_no` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '商户批次号',
+                                    `total_mount` decimal(10,2) DEFAULT NULL COMMENT '计划打款总金额',
+                                    `total_fee_amount` decimal(10,2) DEFAULT NULL COMMENT '总服务费服务费',
+                                    `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+                                    PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE `pay_ttqf_log` (
+                                `id` varchar(255) NOT NULL,
+                                `user_id` varchar(255) DEFAULT NULL COMMENT '用户ID',
+                                `sed_status` tinyint NOT NULL DEFAULT '0' COMMENT '是否发送成功0-失败',
+                                `api_url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '请求url',
+                                `request_data` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '请求数据',
+                                `response_data` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '响应数据',
+                                `mch_batch_no` varchar(255) DEFAULT NULL COMMENT '商户批次号',
+                                `mch_order_no` varchar(255) DEFAULT NULL COMMENT '商户订单号',
+                                `amount` decimal(10,2) DEFAULT NULL COMMENT '打款金额',
+                                `fee_amount` decimal(10,2) DEFAULT NULL COMMENT '服务费',
+                                `batch_no` varchar(255) DEFAULT NULL COMMENT '天天企赋业务批次号',
+                                `order_no` varchar(255) DEFAULT NULL COMMENT '天天企赋业务订单号',
+                                `payment_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '打款方式',
+                                `biz_msg` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '返回信息',
+                                `biz_code` varchar(255) DEFAULT NULL,
+                                `confirm` tinyint(1) NOT NULL DEFAULT '0' COMMENT '确认打款1-已确认',
+                                `create_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建者',
+                                `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+                                PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE `pay_user_sign` (
+                                 `id` bigint NOT NULL,
+                                 `user_id` varchar(255) DEFAULT NULL COMMENT '用户ID',
+                                 `sign` tinyint NOT NULL DEFAULT '0' COMMENT '签约1-是',
+                                 `online_payment` tinyint NOT NULL DEFAULT '0' COMMENT '线上支付1-是',
+                                 PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- 2024.11.1  xuqiang --
 

+ 3 - 0
sql/jar/reeadmind

@@ -4,3 +4,6 @@
 mvn install:install-file -Dfile=C:\Users\Administrator\Desktop\jar\csp-iobs-sdk-1.0.5.jar -DgroupId=com.file -DartifactId=sdk-jar-1.0.5 -Dversion=1.0.0 -Dpackaging=jar
 mvn install:install-file -Dfile=C:\Users\Administrator\Desktop\jar\csp-iobs-sdk-1.1.0.jar -DgroupId=com.file -DartifactId=sdk-jar-1.1.0  -Dversion=1.0.0  -Dpackaging=jar
 
+mvn install:install-file -Dfile=E:\data\ttqf\ttqf-api-sdk\ttqf-api-sdk\target\ttqf-api-sdk-1.0.0.jar -DgroupId=ttqf.api.sdk -DartifactId=ttqf-api-1.1.0  -Dversion=1.0.0  -Dpackaging=jar
+
+

BIN
sql/jar/ttqf-api-sdk-1.0.0.jar


+ 3 - 0
src/main/java/com/ydtech/modules/admin/dao/SysUserBankCardMapper.java

@@ -6,6 +6,7 @@ import com.ydtech.modules.admin.model.po.SysUserBankCard;
 import com.ydtech.modules.admin.model.po.SysUserBankCardHistory;
 import com.ydtech.modules.admin.model.vo.SysUserBankCardVO;
 import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 
 import java.util.List;
 
@@ -28,6 +29,8 @@ public interface SysUserBankCardMapper extends BaseMapper<SysUserBankCard> {
 
     List<SysUserBankCardHistory> getUserBankCardHistoryList(@Param("sysUserBankCardHistory") SysUserBankCardHistory sysUserBankCardHistory);
 
+    @Select("SELECT u.mobile, u.identity,u.identity_time, b.user_name,b.user_id, b.bank_number FROM sys_user_bank_card b INNER JOIN sys_user u ON u.id = b.user_id WHERE b.is_default = 1 AND b.user_id = #{userId}")
+    SysUserBankCard selectByIdPay(@Param("userId") String userId);
 }
 
 

+ 5 - 0
src/main/java/com/ydtech/modules/admin/model/SysUser.java

@@ -113,6 +113,11 @@ public class SysUser extends BaseEntity {
     @TableField(value = "identity")
     private String identity;
 
+
+    @ApiModelProperty(value = "身份证有效期")
+    @TableField(value = "identity_time")
+    private String identityTime;
+
     @ApiModelProperty(value = "领导人ID")
     @TableField(value = "leader_id")
     private String leaderId;

+ 10 - 1
src/main/java/com/ydtech/modules/admin/model/po/SysUserBankCard.java

@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.io.Serializable;
@@ -98,4 +97,14 @@ public class SysUserBankCard implements Serializable {
     @TableField(value = "ascription")
     private String ascription;
 
+
+    @TableField(exist = false)
+    private String mobile;
+
+    @TableField(exist = false)
+    private String identity;
+
+    @TableField(exist = false)
+    private String identityTime;
+
 }

+ 53 - 0
src/main/java/com/ydtech/modules/ttqf/GenerateOrderNumberUtils.java

@@ -0,0 +1,53 @@
+package com.ydtech.modules.ttqf;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 生成订单号
+ */
+public class GenerateOrderNumberUtils {
+
+    private GenerateOrderNumberUtils() {}
+    private static GenerateOrderNumberUtils g = null;
+    private static synchronized GenerateOrderNumberUtils getInstance() {
+        if (g == null) {
+            g = new GenerateOrderNumberUtils();
+        }
+        return g;
+    }
+    // 全局自增数
+    private static int count = 0;
+    // 每毫秒秒最多生成多少(最好是像9999这种准备进位的值)
+    private static final int total = 999;
+    // 格式化的时间字符串
+    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+    // 获取当前时间年月日时分秒毫秒字符串
+    private static String getNowDateStr() {
+        return sdf.format(new Date());
+    }
+    // 记录上一次的时间,用来判断是否需要递增全局数
+    private static String now = null;
+    /*
+     * 生成一个时间格式的订单号
+     */
+    public static synchronized String nextNumber() {
+        String dataStr = getNowDateStr();
+        if (dataStr.equals(now)) {
+            count++;
+        } else {
+            count = 1;
+            now = dataStr;
+        }
+        int countInteger = String.valueOf(total).length() - String.valueOf(count).length();
+        String bu = "";
+        for (int i = 0; i < countInteger; i++) {
+            bu += "0";
+        }
+        bu += String.valueOf(count);
+        if (count >= total) {
+            count = 0;
+        }
+        return dataStr + bu;
+    }
+}

+ 40 - 0
src/main/java/com/ydtech/modules/ttqf/LgInformationPush.java

@@ -0,0 +1,40 @@
+package com.ydtech.modules.ttqf;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.ipaynow.jiaxin.domain.PresignModel;
+import com.ydtech.modules.esm.model.vo.EsmUserImageQueryVo;
+import com.ydtech.modules.order.entity.api.bohai.constants.DocumentClass;
+import com.ydtech.modules.ttqf.entity.vo.PaySigningInformation;
+import com.ydtech.utils.HttpUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+@Slf4j
+@Component
+public class LgInformationPush {
+
+    @Resource
+    private TTFQConfig config;
+
+    @Async
+    public void push(String userId,PresignModel model, List<EsmUserImageQueryVo> esmUserImageQueryVo){
+        PaySigningInformation information = JSONObject.parseObject(JSONObject.toJSONString(model), PaySigningInformation.class);
+        information.setZgUserId(userId);
+        for (EsmUserImageQueryVo imageQueryVo : esmUserImageQueryVo) {
+            if (DocumentClass.SFZ_01.getCode().equals(imageQueryVo.getType())){
+                information.setIdCardPicAFileUrl(imageQueryVo.getPath());
+            }else if(DocumentClass.SFZ_02.getCode().equals(imageQueryVo.getType())){
+                information.setIdCardPicBFileId(imageQueryVo.getPath());
+            }
+        }
+        String sendPost = HttpUtil.sendPost(config.getLgUrl(), JSONObject.toJSONString(information));
+        log.info("推送灵工数据+++++++{}",sendPost);
+
+    }
+
+}

+ 136 - 0
src/main/java/com/ydtech/modules/ttqf/PayConstantStatus.java

@@ -0,0 +1,136 @@
+package com.ydtech.modules.ttqf;
+
+import com.ydtech.utils.HttpUtils;
+import com.ydtech.utils.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class PayConstantStatus {
+
+    public static final String BIZ_CODE = "0000";
+
+    public static final Integer[] ORDER_ARRAY = new Integer[]{3,4,5};
+
+    /**
+     *  签约
+     */
+    public static final Integer SIGN_STATUS = 1;
+
+    /**
+     * 已认证
+     */
+    public static final Integer AUTH_STATUS = 1;
+
+
+
+    /**
+     * 订单状态码
+     */
+    public static final Integer ORDER_STATUS_0 = 0;
+
+    /**
+     * 订单状态码 打款中
+     */
+    public static final Integer ORDER_STATUS_2 = 2;
+
+    /**
+     * 订单状态码 已打款
+     */
+    public static final Integer ORDER_STATUS_3 = 3;
+
+    /**
+     * 订单状态码 打款失败
+     */
+    public static final Integer ORDER_STATUS_4 = 4;
+
+    /**
+     * 订单状态码 取消打款
+     */
+    public static final Integer ORDER_STATUS_5 = 5;
+
+
+    /**
+     * 用户签约回调
+     */
+    private static final String USER_SIGN_NOTIFY_URL = "/ttqf/userSign";
+
+
+    /**
+     * 用户签约回调
+     */
+    private static final String PAYMENT_NOTICE_URL = "/ttqf/paymentNotice";
+
+
+    public String getPaymentNoticeUrl(){
+        return getLocalAddr() + PAYMENT_NOTICE_URL;
+    }
+
+    public static String getUserSignNotifyUrl(){
+        return getLocalAddr() + USER_SIGN_NOTIFY_URL;
+    }
+
+    public static String getLocalAddr(){
+        HttpServletRequest request = HttpUtils.getHttpServletRequest();
+        String localAddr = getIpAddr(request);
+        int serverPort = request.getServerPort();
+        return "http://"+localAddr +":"+ serverPort;
+    }
+
+
+    public static String getIpAddr(HttpServletRequest request)
+    {
+        if (request == null)
+        {
+            return "unknown";
+        }
+        String ip = request.getHeader("x-forwarded-for");
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+        {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+        {
+            ip = request.getHeader("X-Forwarded-For");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+        {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+        {
+            ip = request.getHeader("X-Real-IP");
+        }
+
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+        {
+            ip = request.getRemoteAddr();
+        }
+
+        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
+    }
+
+    public static String getMultistageReverseProxyIp(String ip)
+    {
+        // 多级反向代理检测
+        if (ip != null && ip.indexOf(",") > 0)
+        {
+            final String[] ips = ip.trim().split(",");
+            for (String subIp : ips)
+            {
+                if (false == isUnknown(subIp))
+                {
+                    ip = subIp;
+                    break;
+                }
+            }
+        }
+        return StringUtils.substring(ip, 0, 255);
+    }
+    public static boolean isUnknown(String checkString)
+    {
+        return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
+    }
+
+
+
+}

+ 125 - 0
src/main/java/com/ydtech/modules/ttqf/QuartzManager.java

@@ -0,0 +1,125 @@
+package com.ydtech.modules.ttqf;
+
+import org.apache.commons.collections4.MapUtils;
+import org.quartz.*;
+import org.quartz.impl.StdSchedulerFactory;
+
+import java.util.Map;
+
+
+public class QuartzManager {
+
+    /**
+     * 任务调度管理单例对象
+     */
+    private static QuartzManager manager = new QuartzManager();
+
+    /**
+     * 任务调度
+     */
+    private Scheduler scheduler;
+
+    private QuartzManager() {
+        try {
+            scheduler = new StdSchedulerFactory().getScheduler();
+        } catch (SchedulerException e) {
+            throw new RuntimeException("构造调度任务异常...", e);
+        }
+    }
+
+    /**
+     * 获取实例方法
+     *
+     * @return QuartzManager;
+     */
+    public static QuartzManager getInstance() {
+        return manager;
+    }
+
+    /**
+     * 添加任务
+     *
+     * @param name 任务名
+     * @param group 任务组
+     * @param clazz 任务class
+     * @param cronExpression 克隆表达式
+     * @param jobDatalMap 任务附加参数
+     * @throws SchedulerException 添加任务失败抛出该异常
+     */
+    public void addJob(String name, String group, Class<? extends Job> clazz, String cronExpression,
+                       Map<String, ?> jobDatalMap) throws SchedulerException {
+        JobDetail job = JobBuilder.newJob(clazz).withIdentity(name, group).storeDurably().build();
+        if (MapUtils.isNotEmpty(jobDatalMap))
+            job.getJobDataMap().putAll(jobDatalMap);
+
+        Trigger trg = TriggerBuilder.newTrigger().withIdentity(name, group)
+                .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)).build();
+
+        scheduler.scheduleJob(job, trg);
+    }
+
+    /**
+     *
+     *  更新jobDataMap
+     *
+     * @throws SchedulerException
+     */
+    public void updateJobDataMap(String name, String group, Map<String, ?> jobDatalMap) throws SchedulerException {
+        JobKey jobKey = JobKey.jobKey(name, group);
+        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
+        jobDetail.getJobDataMap().putAll(jobDatalMap);
+        scheduler.addJob(jobDetail, true);
+    }
+
+    /**
+     * 删除任务
+     * @param name 任务名
+     * @param group 任务组
+     * @throws SchedulerException
+     *             添加任务失败抛出该异常
+     */
+    public void removeJob(JobExecutionContext jobExecutionContext) throws SchedulerException {
+
+        JobDetail jobDetail = jobExecutionContext.getJobDetail();
+        String group = jobDetail.getKey().getGroup();
+        String name = jobDetail.getKey().getName();
+
+        TriggerKey tk = TriggerKey.triggerKey(name, group);
+        scheduler.pauseTrigger(tk);
+        scheduler.unscheduleJob(tk);
+        JobKey jobKey = JobKey.jobKey(name, group);
+        scheduler.deleteJob(jobKey);
+    }
+
+
+
+    /**
+     * 启动任务
+     */
+    public void start() throws SchedulerException {
+        if (!scheduler.isStarted())
+            scheduler.start();
+    }
+
+    /**
+     * 停止任务
+     */
+    public void shutdown() throws SchedulerException {
+        if (!scheduler.isShutdown())
+            scheduler.shutdown();
+    }
+
+    /**
+     * 获取任务上下文
+     *
+     * @return SchedulerContext
+     * @throws SchedulerException
+     *             获取上下文失败抛出异常
+     */
+    public SchedulerContext getContext() throws SchedulerException {
+        return scheduler.getContext();
+    }
+}
+
+
+

+ 32 - 0
src/main/java/com/ydtech/modules/ttqf/QuartzUserSign.java

@@ -0,0 +1,32 @@
+package com.ydtech.modules.ttqf;
+
+import cn.hutool.extra.spring.SpringUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.*;
+
+
+@Slf4j
+public class QuartzUserSign implements Job {
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        try {
+            if ((boolean) QuartzManager.getInstance().getContext().get("flag")){
+                JobDataMap mergedJobDataMap = jobExecutionContext.getMergedJobDataMap();
+                String idCardNo = String.valueOf(mergedJobDataMap.get("idCardNo"));
+                log.info("用户签约状态查询入参:{}",idCardNo);
+                if (SpringUtil.getBean(RetrieveTTQFApi.class).queryPressing(idCardNo)){
+                    log.info("用户签约状态查询成功");
+                    QuartzManager.getInstance().removeJob(jobExecutionContext);
+                }
+                log.info("当前线程+++++++++++++{}",Thread.currentThread().getId());
+            }else {
+                log.info("获取天天企赋状态退出",jobExecutionContext.getJobDetail().getKey().getName());
+                QuartzManager.getInstance().removeJob(jobExecutionContext);
+            }
+        } catch (SchedulerException e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+}

+ 77 - 0
src/main/java/com/ydtech/modules/ttqf/RegularlyPaymentStatus.java

@@ -0,0 +1,77 @@
+package com.ydtech.modules.ttqf;
+
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.ipaynow.jiaxin.domain.OrderQueryResultModel;
+import com.ipaynow.jiaxin.response.OrderQueryResponse;
+import com.ydtech.modules.ttqf.dao.PaymentNoticeMapper;
+import com.ydtech.modules.ttqf.entity.PaymentNoticeEntity;
+import com.ydtech.utils.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+
+@Component
+@Slf4j
+public class RegularlyPaymentStatus {
+
+
+    @Async
+    public void  updatePaymentStatus(String orderNo){
+        Timer timer = new Timer();
+        final int[] executionCount = {1};
+        TimerTask task = new TimerTask() {
+            @Override
+            public void run() {
+                try {
+                    log.info("打款状态定时任务入参:{}",orderNo);
+                    OrderQueryResponse response = SpringUtil.getBean(RetrieveTTQFApi.class).orderQuery(orderNo);
+                    log.info("打款状态定时返回执行数据:{}", JSONObject.toJSONString(response.getResultModel()));
+                    if (response == null || !StringUtils.equals(response.getBizCode(),"0000")) {
+                        log.info("获取打款状态任务退出{}");
+                        timer.cancel();
+                    }
+                    if (response.isSuccess()) {
+                        if (Arrays.stream(PayConstantStatus.ORDER_ARRAY).anyMatch(i -> Objects.equals(i,response.getResultModel().getStatus()))){
+                            updatePayLog(orderNo,response.getResultModel());
+                            log.info("获取打款状态任务退出");
+                            timer.cancel();
+                        }
+                    }
+                    log.info("当前线程+++++++++++++{}",Thread.currentThread().getId());
+//                    if (executionCount[0] == 20){
+//                        log.info("获取打款状态任务退出{}");
+//                        timer.cancel();
+//                    }
+                }catch (Exception e){
+                    log.error("定时获取打款状态任务异常:{}",e.getMessage());
+                    timer.cancel();
+                }
+                executionCount[0]++;
+            }
+        };
+        timer.schedule(task, 2000, 5000);
+    }
+
+
+    public void updatePayLog(String orderNo, OrderQueryResultModel resultModel){
+        QueryWrapper<PaymentNoticeEntity> wrapper = new QueryWrapper<>();
+        wrapper.eq("order_no",orderNo);
+        PaymentNoticeEntity notice = SpringUtil.getBean(PaymentNoticeMapper.class).selectOne(wrapper);
+        if (null == notice){
+            PaymentNoticeEntity noticeEntity = JSONObject.parseObject(JSONObject.toJSONString(resultModel), PaymentNoticeEntity.class);
+            if (null == noticeEntity.getPayTime()){
+                noticeEntity.setPayTime(new Date());
+            }
+            noticeEntity.setCreateTime(new Date());
+            int update = SpringUtil.getBean(PaymentNoticeMapper.class).insert(noticeEntity);
+            log.info("获取打款状态成功正在保存===========:{}",orderNo ,"+++++", update > 0 ? "保存成功" : "保存失败");
+        }
+    }
+
+
+}

+ 71 - 0
src/main/java/com/ydtech/modules/ttqf/RegularlyUpdateStatus.java

@@ -0,0 +1,71 @@
+package com.ydtech.modules.ttqf;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.ipaynow.jiaxin.domain.OrderQueryResultModel;
+import com.ipaynow.jiaxin.response.OrderQueryResponse;
+import com.ydtech.modules.ttqf.dao.PaymentNoticeMapper;
+import com.ydtech.modules.ttqf.entity.PaymentNoticeEntity;
+import com.ydtech.utils.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.*;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Objects;
+
+
+@Slf4j
+public class RegularlyUpdateStatus implements Job {
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        try {
+            if ((boolean) QuartzManager.getInstance().getContext().get("flag")){
+                JobDataMap mergedJobDataMap = jobExecutionContext.getMergedJobDataMap();
+                String orderNo = String.valueOf(mergedJobDataMap.get("orderNo"));
+                log.info("打款状态定时任务入参:{}",orderNo);
+                OrderQueryResponse response = SpringUtil.getBean(RetrieveTTQFApi.class).orderQuery(orderNo);
+                log.info("打款状态定时返回执行数据:{}", JSONObject.toJSONString(response.getResultModel()));
+                if (response == null || !StringUtils.equals(response.getBizCode(),"0000")) {
+                    log.info("获取打款状态任务退出{}");
+                    QuartzManager.getInstance().removeJob(jobExecutionContext);
+                }
+                if (response.isSuccess()) {
+                    if (Arrays.stream(PayConstantStatus.ORDER_ARRAY).anyMatch(i -> Objects.equals(i,response.getResultModel().getStatus()))){
+                        updatePayLog(orderNo,response.getResultModel());
+                        log.info("获取打款状态任务退出");
+                    }
+                    QuartzManager.getInstance().removeJob(jobExecutionContext);
+                }
+                log.info("当前线程+++++++++++++{}",Thread.currentThread().getId());
+            }else {
+                log.info("获取天天企赋状态退出",jobExecutionContext.getJobDetail().getKey().getName());
+                QuartzManager.getInstance().removeJob(jobExecutionContext);
+            }
+
+        } catch (SchedulerException e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+
+
+    public void updatePayLog(String orderNo, OrderQueryResultModel resultModel){
+        QueryWrapper<PaymentNoticeEntity> wrapper = new QueryWrapper<>();
+        wrapper.eq("order_no",orderNo);
+        PaymentNoticeEntity notice = SpringUtil.getBean(PaymentNoticeMapper.class).selectOne(wrapper);
+        if (null == notice){
+            PaymentNoticeEntity noticeEntity = JSONObject.parseObject(JSONObject.toJSONString(resultModel), PaymentNoticeEntity.class);
+            if (null == noticeEntity.getPayTime()){
+                noticeEntity.setPayTime(new Date());
+            }
+            noticeEntity.setCreateTime(new Date());
+            int update = SpringUtil.getBean(PaymentNoticeMapper.class).insert(noticeEntity);
+            log.info("获取打款状态成功正在保存===========:{}",orderNo ,"+++++", update > 0 ? "保存成功" : "保存失败");
+        }
+    }
+
+
+}

+ 355 - 0
src/main/java/com/ydtech/modules/ttqf/RetrieveTTQFApi.java

@@ -0,0 +1,355 @@
+package com.ydtech.modules.ttqf;
+
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.ipaynow.jiaxin.TangClient;
+import com.ipaynow.jiaxin.domain.*;
+import com.ipaynow.jiaxin.request.*;
+import com.ipaynow.jiaxin.response.*;
+import com.ydtech.exception.SystemException;
+import com.ydtech.modules.admin.dao.SysUserBankCardMapper;
+import com.ydtech.modules.admin.model.po.SysUserBankCard;
+import com.ydtech.modules.esm.model.vo.EsmUserImageQueryVo;
+import com.ydtech.modules.esm.service.EsmUserImageService;
+import com.ydtech.modules.order.entity.api.bohai.constants.DocumentClass;
+import com.ydtech.modules.ttqf.service.PayUserSignService;
+import com.ydtech.utils.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Base64Utils;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
+@Component
+@Slf4j
+public class RetrieveTTQFApi {
+
+
+    private static TangClient tangClient;
+
+    private static SavePayOrder savePayOrder;
+
+    private static PayUserSignService signService;
+
+    private static RegularlyPaymentStatus paymentStatus;
+
+    @Resource
+    private void setSignService(PayUserSignService userSignService){
+        signService = userSignService;
+    }
+
+
+    @Resource
+    private void setPaymentStatus(RegularlyPaymentStatus status){
+        paymentStatus = status;
+    }
+
+
+    @Resource
+    private void setSavePayOrder(SavePayOrder order){
+        savePayOrder = order;
+    }
+
+    @Resource(name = "tangClient")
+    private void setConfig(TangClient client){
+        tangClient = client;
+    }
+    public  static String extractBalance(String userId,String decimal) throws Exception {
+        SysUserBankCard bankCard = SpringUtil.getBean(SysUserBankCardMapper.class).selectByIdPay("9914D1305");
+          signService.saveUserSign(bankCard.getUserId());
+        if (false){
+            //用户已经签约  进行打款操作
+            orderAdd(bankCard,new BigDecimal(decimal),"测试打款");
+            return "0";
+        } else {
+            //  未签约的用户先签约后进行打款
+            return pres(bankCard);
+        }
+    }
+
+    
+    public  static boolean orderAdd(SysUserBankCard bankCard,BigDecimal amount,String remark){
+        OrderAddModel addModel = OrderAddModel.builder()
+                .mchBatchNo(System.currentTimeMillis() + "")
+                .mchOrderNo(GenerateOrderNumberUtils.nextNumber() + "")
+                //收款人姓名
+                .userName(bankCard.getUserName())
+                //收款人手机号
+                .userMobile(bankCard.getMobile())
+                //收款账号
+                .userBankCardNo(bankCard.getBankNumber())
+                //收款人身份证号
+                .userIdCardNo(bankCard.getIdentity())
+                //工作量衡量标准模板
+                .userWorkload("1849326302238785538")
+                //工作量衡量标准
+                .userWorkloadLevel(
+                        "[{\"proj\":\"山西掌柜鼎科技有限公司\",\"std\":\"1\"}]"
+                )
+                //打款金额 Number(15,2)
+                // M 单位为元,风控可调额
+                .amount(amount)
+                .remark(remark)
+                //收款方式非必填:默认0-银行卡枚举:0-银行卡、1-支付宝、2-微信
+                .paymentType(0)
+                //选填项:微信APPID,若填写,以填写项稳准,否则应用预留配置的微信appid;该字段适用于同主体下含有多个公众号或小程序的场景
+                .wechatAppId("")
+                .build();
+        OrderAddResponse response = testOrderAdd(addModel, bankCard.getUserId());
+        if(response.isSuccess()) {
+            log.info("成功 ====>orderAdd {}", response.getResultModel());
+        } else {
+            log.error("失败 ====>orderAdd {}", response.getRespData());
+        }
+        return response.isSuccess();
+
+    }
+
+
+    /**
+     * 打款结果回调
+     */
+    private static void testOrderNotify() {
+        OrderNotifyRequest request = new OrderNotifyRequest();
+        OrderNotifyModel model = OrderNotifyModel.builder().orderId("czhl00000001")
+                .tradeTime(new Date()).tradeStatus("3").cardNo("1234567890").build();
+        request.setBizModel(model);
+        request.setRequestId(System.currentTimeMillis()+"");
+        OrderNotifyResponse response = tangClient.execute(request);
+        System.out.println(response);
+
+        System.out.println(response.getResultModel());
+    }
+
+    /**
+     * 图片上传接口
+     * @throws IOException
+     */
+    private static String testPictureUpload(String encodeBase64) throws IOException {
+        PictureUploadRequest request = new PictureUploadRequest();
+        PictureUploadModel model = PictureUploadModel.builder().picture(encodeBase64).build();
+        request.setBizModel(model);
+        request.setRequestId(System.currentTimeMillis()+"");
+        PictureUploadResponse response = tangClient.execute(request);
+        log.info(JSON.toJSONString(response));
+        return response.getResultModel().getFileId();
+    }
+
+    /**
+     * 账单下载接口
+     */
+    public static BillDownloadResponse billDownload(Integer type,String date) {
+        BillDownloadRequest request = new BillDownloadRequest();
+        BillDownloadModel model = BillDownloadModel.builder().type(type).date(date).build();
+        request.setBizModel(model);
+        request.setRequestId(System.currentTimeMillis()+"");
+        return tangClient.execute(request);
+    }
+
+    /**
+     *电子回执单瞎子啊接口
+     */
+    public static ReceiptlDownloadResponse receiptDownload(String mchOrderNo, String orderNo) {
+        ReceiptDownloadRequest request = new ReceiptDownloadRequest();
+        ReceiptDownloadModel model = ReceiptDownloadModel.builder().mchOrderNo(mchOrderNo).orderNo(orderNo).build();
+        request.setBizModel(model);
+        request.setRequestId(System.currentTimeMillis()+"");
+        return tangClient.execute(request);
+    }
+
+    /**
+     * 用户协议预览地址查询接口
+     */
+    private static void testPreview() {
+        PreviewRequest request = new PreviewRequest();
+        PreviewModel model = PreviewModel.builder().name("杨好晓").idCardNo("150525198909301678").build();
+        request.setBizModel(model);
+        request.setRequestId(System.currentTimeMillis() + "");
+        PreviewResponse response = tangClient.execute(request);
+        if(response.isSuccess()) {
+            log.info("成功 ====>Preview {}", response);
+        } else {
+            log.error("失败 ====>Preview {}", response);
+        }
+    }
+
+    /**
+     * 用户预签约接口
+     */
+    public static String pres(SysUserBankCard bankCard){
+        PresignRequest request = new PresignRequest();
+        List<EsmUserImageQueryVo> esmUserImageQueryVo = SpringUtil.getBean(EsmUserImageService.class).getEsmUserImageQueryVo(bankCard.getUserId());
+        if (CollectionUtils.isEmpty(esmUserImageQueryVo)){
+            throw new SystemException("用户影像资料不存在,请补全后在申请提现");
+        }
+        PresignModel presignModel = new PresignModel();
+        presignModel.setName(bankCard.getUserName());
+        presignModel.setMobile(bankCard.getMobile());
+        presignModel.setIdCardNo(bankCard.getIdentity());
+        presignModel.setBankCardNo(bankCard.getBankNumber());
+        if (bankCard.getIdentityTime().contains(",")){
+            presignModel.setExpiryStart(bankCard.getIdentityTime().split(",")[0]);
+            presignModel.setExpiryEnd(bankCard.getIdentityTime().split(",")[1]);
+        }else {
+            throw new SystemException("用户身份证有效日期不全,请检查");
+        }
+        presignModel.setNotifyUrl("");
+        for (EsmUserImageQueryVo item : esmUserImageQueryVo) {
+            try {
+                if (StringUtils.isEmpty(item.getPath())){
+                    throw new SystemException("用户身份证影像资料不存在,请检查");
+                }
+                String encoded = Base64Utils.encodeToString(FileUtil.readBytes(item.getPath()));
+                if (StringUtils.isEmpty(encoded)){
+                    throw new SystemException("用户身份证影像资料不存在或已删除,请刷新后重试");
+                }
+                if (DocumentClass.SFZ_01.getCode().equals(item.getType())){
+                    presignModel.setIdCardPicAFileId(testPictureUpload(encoded));
+                }else if(DocumentClass.SFZ_02.getCode().equals(item.getType())){
+                    presignModel.setIdCardPicBFileId(testPictureUpload(encoded));
+                }
+            }catch (Exception e){
+                log.error("获取影像信息错误:{}",e.getMessage());
+                e.printStackTrace();
+            }
+        }
+//        PresignModel model = PresignModel.builder().name("杨晓").idCardNo("11010219900131252X").mobile("13092411724")
+//                .bankCardNo("6225880165591124").expiryEnd("2030-03-18" ).expiryStart("2020-03-18").idCardPicAFileId("1362670410277076994").idCardPicBFileId("1362670410277076994").build();
+        request.setBizModel(presignModel);
+        request.setRequestId(System.currentTimeMillis() + "");
+        PresignResponse response = tangClient.execute(request);
+        if(response.isSuccess()) {
+            SpringUtil.getBean(LgInformationPush.class).push(bankCard.getUserId(),presignModel,esmUserImageQueryVo);
+            log.info("成功 ====>Pressing {}", response.getResultModel());
+            return contractH5();
+        } else {
+            log.error("失败{}", response);
+            return "";
+        }
+    }
+
+    /**
+     * 用户预签约结果查询接口
+     */
+    public static boolean queryPressing(String idCardNo) {
+        QueryPresignResponse response = tangClient.execute(QueryPresignRequest.builder().requestId(System.currentTimeMillis() + "")
+                .bizModel(new QueryPresignModel(idCardNo)).build());
+        if(response.isSuccess()) {
+            QueryPresignResultModel resultModel = response.getResultModel();
+            if (Objects.equals(PayConstantStatus.SIGN_STATUS,resultModel.getSignStatus()) &&
+                    Objects.equals(PayConstantStatus.AUTH_STATUS,resultModel.getAuthStatus())){
+                return true;
+            }
+            log.info("成功 ====>QueryPressing {}", resultModel);
+        } else {
+            log.error("失败{}", response);
+        }
+        return false;
+    }
+
+    /**
+     * 合同签约唤起接口
+     */
+    public static String contractH5() {
+        ContractH5Response response = tangClient.execute(ContractH5Request.builder()
+                .requestId(System.currentTimeMillis() + "").bizModel(ContractH5Model.builder()
+                        .idCardNo("11010219900131252X").mchReturnUrl(PayConstantStatus.getUserSignNotifyUrl()).build())
+                .build());
+        if(response.isSuccess()) {
+            //  返回当前签约H5页面
+            String signUrl = response.getResultModel().getSignUrl();
+            log.info("成功 ====>ContractH5 {}", response.getResultModel());
+            return signUrl;
+        } else {
+            log.error("失败");
+        }
+        return "";
+    }
+
+    /**
+     * 打款订单新增接口
+     */
+    public static OrderAddResponse testOrderAdd(OrderAddModel addModel,String userId) {
+        OrderAddRequest addRequest = OrderAddRequest.builder()
+                .requestId(System.currentTimeMillis() + "")
+                .bizModel(addModel)
+                .build();
+        OrderAddResponse response = tangClient.execute(addRequest);
+        boolean confirm = confirm(response.getResultModel().getOrderNo(),response.getResultModel().getBatchNo());
+        savePayOrder.savePayOrder(addRequest.getApiUrl(),response, JSONObject.toJSONString(addModel),JSONObject.toJSONString(response),userId, confirm);
+        return response;
+    }
+
+    /**
+     * 订单取消接口
+     */
+    public static void testOrderCancel() {
+        OrderCancelResponse response = tangClient.execute(OrderCancelRequest.builder()
+                .requestId(System.currentTimeMillis() + "")
+                .bizModel(OrderCancelModel.builder().mchBatchNo("1584671697240")
+                        .mchOrderNo("abc1111111114")
+                        .orderNo("")
+                        .build()).build());
+        if(response.isSuccess()) {
+            System.out.println("成功 ====>OrderCancel " + response.getResultModel());
+        } else {
+            System.out.println("失败 ====>OrderCancel " + response.getRespData());
+        }
+    }
+
+    /**
+     * 打款订单查询接口
+     */
+    public static OrderQueryResponse orderQuery(String orderNo) {
+        OrderQueryResponse response = tangClient.execute(OrderQueryRequest.builder()
+                .requestId(System.currentTimeMillis() + "")
+                .bizModel(OrderQueryModel.builder().mchOrderNo("").orderNo(orderNo).build())
+                .build());
+        if(response.isSuccess()) {
+            log.info("成功 ====>OrderQuery {}", response.getResultModel());
+        } else {
+            log.error("失败 ====>OrderQuery {}", response.getRespData());
+        }
+        return response;
+    }
+
+    /**
+     * \确认打款接口
+     */
+    public static boolean confirm(String orderNo,String batchNo) {
+        ConfirmRequest confirmRequest = ConfirmRequest.builder().requestId(System.currentTimeMillis() + "")
+                .bizModel(ConfirmModel.builder().mchBatchNo("").batchNo(batchNo).build()).build();
+        ConfirmResponse response = tangClient.execute(confirmRequest);
+        if(response.isSuccess()) {
+            log.info("成功 ====>Confirm{}", response.getResultModel());
+            paymentStatus.updatePaymentStatus(orderNo);
+        } else {
+            log.error("失败 ====>Confirm {}", response.getRespData());
+        }
+        savePayOrder.saveConfirm(response);
+        return response.isSuccess();
+    }
+
+    /**
+     * 商户余额查询接口
+     */
+    public static void testBalance() {
+        MerchantBalanceRequest balanceRequest = MerchantBalanceRequest.builder()
+                .requestId(System.currentTimeMillis() + "").bizModel(MerchantBalanceModel.builder().build())
+                .build();
+        MerchantBalanceResponse response = tangClient.execute(balanceRequest);
+        System.out.println(response);
+
+    }
+
+
+}

+ 53 - 0
src/main/java/com/ydtech/modules/ttqf/SavePayOrder.java

@@ -0,0 +1,53 @@
+package com.ydtech.modules.ttqf;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.ipaynow.jiaxin.response.ConfirmResponse;
+import com.ipaynow.jiaxin.response.OrderAddResponse;
+import com.ydtech.modules.ttqf.dao.PayTtqfConfirmMapper;
+import com.ydtech.modules.ttqf.dao.PayTtqfLogMapper;
+import com.ydtech.modules.ttqf.entity.PayTtqfConfirm;
+import com.ydtech.modules.ttqf.entity.PayTtqfLog;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+@Component
+public class SavePayOrder {
+
+    @Async
+    public  void savePayOrder(String url, OrderAddResponse response, String requestData, String responseData, String userId,boolean confirm){
+        PayTtqfLog ttqfLog = new PayTtqfLog();
+        ttqfLog.setSedStatus(response.isSuccess());
+        ttqfLog.setApiUrl(url);
+        ttqfLog.setRequestData(requestData);
+        ttqfLog.setResponseData(responseData);
+        ttqfLog.setCreateBy("");
+        ttqfLog.setCreateTime(new Date());
+        ttqfLog.setBizMsg(response.getBizMsg());
+        ttqfLog.setBizCode(response.getBizCode());
+        ttqfLog.setUserId(userId);
+        ttqfLog.setConfirm(confirm);
+        ttqfLog.setBatchNo(response.getResultModel().getBatchNo());
+        ttqfLog.setOrderNo(response.getResultModel().getOrderNo());
+        ttqfLog.setMchBatchNo(response.getResultModel().getMchBatchNo());
+        ttqfLog.setMchOrderNo(response.getResultModel().getMchOrderNo());
+        ttqfLog.setAmount(response.getResultModel().getAmount());
+        ttqfLog.setFeeAmount(response.getResultModel().getFeeAmount());
+        ttqfLog.setPaymentType(response.getResultModel().getPaymentType());
+        SpringUtil.getBean(PayTtqfLogMapper.class).insert(ttqfLog);
+    }
+
+    @Async
+    public void saveConfirm(ConfirmResponse response) {
+        PayTtqfConfirm confirm = new PayTtqfConfirm();
+        confirm.setBizMsg(response.getBizMsg());
+        confirm.setBizCode(response.getBizCode());
+        confirm.setBatchNo(response.getResultModel().getBatchNo());
+        confirm.setMchBatchNo(response.getResultModel().getMchBatchNo());
+        confirm.setTotalMount(response.getResultModel().getTotalAmount());
+        confirm.setTotalFeeAmount(response.getResultModel().getTotalFeeAmount());
+        confirm.setCreateTime(new Date());
+        SpringUtil.getBean(PayTtqfConfirmMapper.class).insert(confirm);
+    }
+}

+ 32 - 0
src/main/java/com/ydtech/modules/ttqf/TTFQConfig.java

@@ -0,0 +1,32 @@
+package com.ydtech.modules.ttqf;
+
+
+import com.ipaynow.jiaxin.DefaultTangClient;
+import com.ipaynow.jiaxin.TangClient;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConfigurationProperties(prefix = "ttfq")
+@Data
+public class TTFQConfig {
+
+    public  String mchPrivateKey;
+
+    public  String platformPublicKey;
+
+    public  String host;
+
+    public  String mchId;
+
+    private String lgUrl;
+
+
+    @Bean(name = "tangClient")
+    public TangClient getClient() {
+        return new DefaultTangClient(host, mchPrivateKey,  platformPublicKey,mchId);
+    }
+
+}

+ 107 - 0
src/main/java/com/ydtech/modules/ttqf/controller/TtqfController.java

@@ -0,0 +1,107 @@
+package com.ydtech.modules.ttqf.controller;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.ydtech.core.page.HttpResult;
+import com.ydtech.modules.ttqf.QuartzManager;
+import com.ydtech.modules.ttqf.RegularlyPaymentStatus;
+import com.ydtech.modules.ttqf.RegularlyUpdateStatus;
+import com.ydtech.modules.ttqf.RetrieveTTQFApi;
+import com.ydtech.modules.ttqf.service.TtqfService;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import java.util.HashMap;
+
+
+@RestController
+@RequestMapping("ttqf")
+public class TtqfController {
+
+
+    private static RegularlyPaymentStatus paymentStatus;
+
+    @Resource
+    private TtqfService ttqfService;
+
+    @Resource
+    private void setPaymentStatus(RegularlyPaymentStatus regularlyPaymentStatus){
+        paymentStatus = regularlyPaymentStatus;
+    }
+
+
+    /**
+     * 接收打款通知回调
+     * @param obj
+     * @return
+     */
+
+    @PostMapping("paymentNotice")
+    public JSONObject paymentNotice(@RequestBody String obj){
+        return ttqfService.paymentNotice(obj);
+    }
+
+
+
+
+    /**
+     * 接收用户签约回调
+     * @param obj
+     * @return
+     */
+
+    @PostMapping("userSign")
+    public JSONObject userSign(@RequestBody String obj){
+        return ttqfService.userSign(obj);
+    }
+
+
+    /**
+     * 账单下载
+     * @param type 必填,1:日账单2:月账单
+     * @param date 日账单: yyyy-MM-dd 月账单:yyyy-MM
+     * @return
+     */
+    @PostMapping("billDownload")
+    public HttpResult billDownload(@RequestParam("type")Integer type, @RequestParam("date")String date){
+        return ttqfService.billDownload(type,date);
+    }
+
+
+    /**
+     * 电子回执单下载
+     * @param mchOrderNo 商户订单号与天天企赋业务订单号二选一
+     * @param orderNo 商户订单号与天天企赋业务订单号二选一
+     * @return
+     */
+    @PostMapping("receiptDownload")
+    public HttpResult receiptDownload(@RequestParam("mchOrderNo")String mchOrderNo,@RequestParam("orderNo")String orderNo){
+        return ttqfService.receiptDownload(mchOrderNo,orderNo);
+    }
+
+
+    @GetMapping("xx/{de}")
+    public String xx(@PathVariable("de")String de) throws Exception {
+        paymentStatus.updatePaymentStatus(de);
+        return "";
+    }
+
+
+    @GetMapping("aa/{de}")
+    public String getss(@PathVariable("de")String de) throws Exception {
+        RetrieveTTQFApi.extractBalance("",de);
+        return "";
+    }
+
+    @GetMapping("test")
+    public void test() throws Exception {
+        HashMap<String, String> hashMap = new HashMap<>();
+        hashMap.put("userId","11111111111111");
+        QuartzManager manager = QuartzManager.getInstance();
+        manager.getContext().put("flag",true);
+        manager.addJob("jobName","jobGroup", RegularlyUpdateStatus.class,"*/5 * * * * ?",hashMap);
+        manager.start();
+    }
+
+
+
+}

+ 7 - 0
src/main/java/com/ydtech/modules/ttqf/dao/PaySignCallbackMapper.java

@@ -0,0 +1,7 @@
+package com.ydtech.modules.ttqf.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ydtech.modules.ttqf.entity.PaySignCallback;
+
+public interface PaySignCallbackMapper extends BaseMapper<PaySignCallback> {
+}

+ 7 - 0
src/main/java/com/ydtech/modules/ttqf/dao/PayTtqfConfirmMapper.java

@@ -0,0 +1,7 @@
+package com.ydtech.modules.ttqf.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ydtech.modules.ttqf.entity.PayTtqfConfirm;
+
+public interface PayTtqfConfirmMapper extends BaseMapper<PayTtqfConfirm> {
+}

+ 36 - 0
src/main/java/com/ydtech/modules/ttqf/dao/PayTtqfLogMapper.java

@@ -0,0 +1,36 @@
+package com.ydtech.modules.ttqf.dao;
+
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ydtech.modules.ttqf.entity.PayTtqfLog;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.apache.poi.ss.formula.functions.T;
+
+import java.util.List;
+
+/**
+ * 【请填写功能名称】Mapper接口
+ *
+ * @author ruoyi
+ * @date 2024-10-25
+ */
+public interface PayTtqfLogMapper extends BaseMapper<PayTtqfLog> {
+
+
+    @Select("SELECT " +
+            " lo.mch_batch_no, " +
+            " lo.mch_order_no, " +
+            " lo.amount, " +
+            " lo.fee_amount, " +
+            " n.`status`, " +
+            " n.message, " +
+            " n.pay_time  " +
+            "FROM " +
+            " pay_ttqf_log lo " +
+            " LEFT JOIN pay_payment_notice n ON n.mch_order_no = lo.mch_order_no " +
+            "WHERE " +
+            " sed_status = 1  " +
+            " AND user_id = '1111'")
+    List<Object> selectUserPay(@Param("ew") Wrapper<T> ew);
+}

+ 7 - 0
src/main/java/com/ydtech/modules/ttqf/dao/PayUserSignMapper.java

@@ -0,0 +1,7 @@
+package com.ydtech.modules.ttqf.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ydtech.modules.ttqf.entity.PayUserSign;
+
+public interface PayUserSignMapper extends BaseMapper<PayUserSign> {
+}

+ 7 - 0
src/main/java/com/ydtech/modules/ttqf/dao/PaymentNoticeMapper.java

@@ -0,0 +1,7 @@
+package com.ydtech.modules.ttqf.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ydtech.modules.ttqf.entity.PaymentNoticeEntity;
+
+public interface PaymentNoticeMapper extends BaseMapper<PaymentNoticeEntity> {
+}

+ 99 - 0
src/main/java/com/ydtech/modules/ttqf/decrypt.java

@@ -0,0 +1,99 @@
+package com.ydtech.modules.ttqf;
+
+import com.alibaba.fastjson.JSON;
+import com.ipaynow.jiaxin.*;
+import com.ipaynow.jiaxin.domain.ResultModel;
+import com.ipaynow.jiaxin.util.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.ipaynow.jiaxin.TangConstants.CODE_SUCCESS;
+import static com.ipaynow.jiaxin.TangConstants.SECRET_KEY_ERROR;
+
+
+@Slf4j
+public class decrypt {
+
+    private Decryptor decryptor;
+    private SignChecker signChecker;
+
+
+    public TangResponse aa(String response){
+
+        // 返回对象初始化
+        TangResponse rsp = null;
+
+        //解析响应报文
+        Map responseMap = JSON.parseObject(response, Map.class);
+        String code = (String) responseMap.get("code");
+        String msg = (String) responseMap.get("msg");
+        if(!CODE_SUCCESS.equals(code)) {
+            rsp.setCode(code);
+            rsp.setMsg(msg);
+            return  rsp;
+        }
+        // 6. 解密AES
+        String decAES = null;
+        Decryptor aesDecryptor = null;
+        try {
+            decAES = this.decryptor.decrypt((String) responseMap.get("aes"));
+            aesDecryptor = new AESDecryptor(decAES);
+        } catch (Exception e) {
+            log.error("天天企赋API => 秘钥错误,解密失败", e);
+            rsp.setCode(SECRET_KEY_ERROR);
+            rsp.setMsg("解密错误");
+            return rsp;
+        }
+        // 7. 解密业务报文
+        String bizResponse = null;
+        try {
+            bizResponse = aesDecryptor.decrypt((String) responseMap.get("respData"));
+        } catch (Exception e) {
+            log.error("天天企赋API => 秘钥错误,解密业务报文失败", e);
+            rsp.setCode(SECRET_KEY_ERROR);
+            rsp.setMsg("解密响应报文错误");
+            return rsp;
+        }
+        // 8. 构造签名
+        Map<String, String> rtMap = new HashMap<>();
+        rtMap.put("respData", bizResponse);
+        rtMap.put("mchId", (String) responseMap.get("mchId"));
+        rtMap.put("reqId", (String) responseMap.get("reqId"));
+        rtMap.put("respTime", (String) responseMap.get("respTime"));
+        rtMap.put("signType", "RSA");
+        rtMap.put("aes", decAES);
+        rtMap.put("version", "1.0");
+        // 8. 构造待验签字符串
+        String dataForm1 = StringUtils.buildDataForm(rtMap);
+        // 9. 签名结果
+        boolean check = this.signChecker.check(dataForm1, (String) responseMap.get("sign"));
+        if (check) {
+            rsp.setCode(code);
+            rsp.setMsg(msg);
+            // 解析业务报文
+            ResultModel rs = null;
+            try {
+                rs = (ResultModel) rsp.getResultModelClass().newInstance();
+            } catch (InstantiationException e) {
+                throw new SdkException(e);
+            } catch (IllegalAccessException e) {
+                throw new SdkException(e);
+            }
+            rs = JSON.parseObject(bizResponse, rs.getClass());
+            rsp.setResultModel(rs);
+            rsp.setBizCode(rs.getBizCode());
+            rsp.setBizMsg(rs.getBizMsg());
+            rsp.setRespData(bizResponse);
+            return  rsp;
+        } else {
+            rsp.setCode(SECRET_KEY_ERROR);
+            rsp.setMsg("签名错误");
+            return  rsp;
+        }
+    }
+
+
+
+}

+ 35 - 0
src/main/java/com/ydtech/modules/ttqf/entity/PaySignCallback.java

@@ -0,0 +1,35 @@
+package com.ydtech.modules.ttqf.entity;
+
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+@Data
+public class PaySignCallback {
+
+    @TableId(type = IdType.ASSIGN_ID)
+    private String id;
+
+    private String type;
+
+    private Long orgReqId;
+
+    private String name;
+
+    private String mobile;
+
+    private String idCardNo;
+
+    private String bankCardNo;
+
+    private String bankName;
+
+    private int authStatus;
+
+    private int signStatus;
+
+    private int bindStatus;
+
+
+}

+ 36 - 0
src/main/java/com/ydtech/modules/ttqf/entity/PayTtqfConfirm.java

@@ -0,0 +1,36 @@
+package com.ydtech.modules.ttqf.entity;
+
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@TableName("pay_ttqf_confirm")
+public class PayTtqfConfirm {
+
+    /** $column.columnComment */
+    @TableId(type = IdType.ASSIGN_ID)
+    private String id;
+
+    private String userId;
+
+    private String bizMsg;
+
+    private String bizCode;
+
+    private String batchNo;
+
+    private String mchBatchNo;
+
+    private BigDecimal totalMount;
+
+    private BigDecimal totalFeeAmount;
+
+    private Date createTime;
+
+}

+ 71 - 0
src/main/java/com/ydtech/modules/ttqf/entity/PayTtqfLog.java

@@ -0,0 +1,71 @@
+package com.ydtech.modules.ttqf.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 【请填写功能名称】对象 pay_ttqf_log
+ *
+ * @author ruoyi
+ * @date 2024-10-25
+ */
+@Data
+@TableName("pay_ttqf_log")
+public class PayTtqfLog {
+
+private static final long serialVersionUID=1L;
+
+        /** $column.columnComment */
+        @TableId(type = IdType.ASSIGN_ID)
+        private String id;
+
+        /** 是否发送成功0-失败 */
+        private boolean sedStatus;
+
+        private String apiUrl;
+
+        /** 请求数据 */
+        private String requestData;
+
+        /** 响应数据 */
+        private String responseData;
+
+        private String userId;
+
+        private String batchNo;
+
+        private String orderNo;
+
+        private String mchBatchNo;
+
+        private String mchOrderNo;
+
+        private BigDecimal amount;
+
+        private String feeAmount;
+
+        private Integer paymentType;
+
+        private String bizMsg;
+
+        private String bizCode;
+
+        private boolean confirm;
+
+        /**
+         * 创建者
+         */
+        private String createBy;
+        /**
+         * 创建时间
+         */
+        @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+        private Date createTime;
+
+}

+ 33 - 0
src/main/java/com/ydtech/modules/ttqf/entity/PayUserSign.java

@@ -0,0 +1,33 @@
+package com.ydtech.modules.ttqf.entity;
+
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@TableName("pay_user_sign")
+@Builder
+public class PayUserSign {
+
+    @TableId(type = IdType.ASSIGN_ID)
+    private String id;
+
+    /**
+     * 用户ID
+     */
+    private String userId;
+
+    /**
+     * 是否签约
+     */
+    private boolean sign;
+
+    /**
+     * 是否线上支付
+     */
+    private boolean onlinePayment;
+
+}

+ 38 - 0
src/main/java/com/ydtech/modules/ttqf/entity/PaymentNoticeEntity.java

@@ -0,0 +1,38 @@
+package com.ydtech.modules.ttqf.entity;
+
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@TableName("pay_payment_notice")
+public class PaymentNoticeEntity {
+
+    @TableId(type = IdType.ASSIGN_ID)
+    private String id;
+
+    private String type;
+
+    private String mchOrderNo;
+
+    private String orderNo;
+
+    private BigDecimal amount;
+
+    private BigDecimal feeAmount;
+
+    private Integer status;
+
+    private String message;
+
+    private Date payTime;
+
+    private Date createTime;
+
+
+}

+ 49 - 0
src/main/java/com/ydtech/modules/ttqf/entity/vo/PaySigningInformation.java

@@ -0,0 +1,49 @@
+package com.ydtech.modules.ttqf.entity.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class PaySigningInformation {
+
+
+    /** 身份证号 */
+    private String idCardNo;
+
+    /** 手机号 */
+    private String mobile;
+
+    /** 银行卡号 */
+    private String bankCardNo;
+
+    /** 身份证有效日期 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date expiryStart;
+
+    /** 身份证有效日期 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date expiryEnd;
+
+    /** 正面ID */
+    private String idCardPicAFileId;
+
+    /** 反面ID */
+    private String idCardPicBFileId;
+
+    /** 正面url */
+    private String idCardPicAFileUrl;
+
+    /** 反面url */
+    private String idCardPicBFileUrl;
+
+    /** 签约状态 */
+    private Integer signState;
+
+    /** 掌柜用户ID */
+    private String zgUserId;
+
+
+
+}

+ 15 - 0
src/main/java/com/ydtech/modules/ttqf/service/PayUserSignService.java

@@ -0,0 +1,15 @@
+package com.ydtech.modules.ttqf.service;
+
+import com.ydtech.modules.ttqf.entity.PayUserSign;
+
+public interface PayUserSignService {
+
+
+    void saveUserSign(String userId);
+
+
+    PayUserSign selectOne(String userId);
+
+    void updateUserSign(String userId);
+
+}

+ 25 - 0
src/main/java/com/ydtech/modules/ttqf/service/TtqfService.java

@@ -0,0 +1,25 @@
+package com.ydtech.modules.ttqf.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ydtech.core.page.HttpResult;
+
+public interface TtqfService {
+
+
+
+    Object getUserPay(String userId);
+
+
+    JSONObject userSign(String obj);
+
+    JSONObject paymentNotice(String obj);
+
+    HttpResult billDownload(Integer type, String date);
+
+    HttpResult receiptDownload(String mchOrderNo, String orderNo);
+
+
+
+
+
+}

+ 45 - 0
src/main/java/com/ydtech/modules/ttqf/service/impl/PayUserSignServiceImpl.java

@@ -0,0 +1,45 @@
+package com.ydtech.modules.ttqf.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ydtech.modules.ttqf.dao.PayUserSignMapper;
+import com.ydtech.modules.ttqf.entity.PayUserSign;
+import com.ydtech.modules.ttqf.service.PayUserSignService;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Objects;
+
+@Service
+public class PayUserSignServiceImpl implements PayUserSignService {
+
+
+    @Resource
+    private PayUserSignMapper signMapper;
+
+    @Async
+    @Override
+    public void saveUserSign(String userId) {
+
+        if (Objects.isNull(selectOne(userId))){
+            signMapper.insert(PayUserSign.builder().userId(userId).build());
+        }
+    }
+
+    @Override
+    public PayUserSign selectOne(String userId) {
+        LambdaQueryWrapper<PayUserSign> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(PayUserSign::getUserId,userId);
+        return signMapper.selectOne(queryWrapper);
+    }
+
+    @Override
+    public void updateUserSign(String userId) {
+        PayUserSign payUserSign = selectOne(userId);
+        payUserSign.setSign(true);
+        payUserSign.setOnlinePayment(true);
+        signMapper.updateById(payUserSign);
+    }
+
+
+}

+ 92 - 0
src/main/java/com/ydtech/modules/ttqf/service/impl/TtqfServiceImpl.java

@@ -0,0 +1,92 @@
+package com.ydtech.modules.ttqf.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.ipaynow.jiaxin.response.BillDownloadResponse;
+import com.ipaynow.jiaxin.response.ReceiptlDownloadResponse;
+import com.ydtech.core.page.HttpResult;
+import com.ydtech.modules.ttqf.PayConstantStatus;
+import com.ydtech.modules.ttqf.RetrieveTTQFApi;
+import com.ydtech.modules.ttqf.dao.PaySignCallbackMapper;
+import com.ydtech.modules.ttqf.dao.PayTtqfLogMapper;
+import com.ydtech.modules.ttqf.entity.PaySignCallback;
+import com.ydtech.modules.ttqf.entity.PayTtqfLog;
+import com.ydtech.modules.ttqf.service.PayUserSignService;
+import com.ydtech.modules.ttqf.service.TtqfService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+
+@Slf4j
+@Service
+public class TtqfServiceImpl implements TtqfService {
+
+    @Autowired
+    private PayTtqfLogMapper ttqfMapper;
+
+    @Autowired
+    private PayUserSignService userSignService;
+
+
+    @Autowired
+    private PaySignCallbackMapper signCallbackMapper;
+
+    @Override
+    public Object getUserPay(String userId) {
+
+        QueryWrapper<PayTtqfLog> queryWrapper = new QueryWrapper<>();
+        queryWrapper.select("lo.mch_batch_no,\n" +
+                "\tlo.mch_order_no,\n" +
+                "\tlo.amount,\n" +
+                "\tlo.fee_amount,\n" +
+                "\tn.`status`,\n" +
+                "\tn.message,\n" +
+                "\tn.pay_time ").eq("user_id",userId);
+
+
+        return new Object();
+    }
+
+    @Override
+    public JSONObject userSign(String obj) {
+        log.info("接收用户签约回调 + userSign ================={}", obj);
+
+
+
+        //保存签约回调信息
+        signCallbackMapper.insert(JSONObject.parseObject(JSONObject.toJSONString(obj), PaySignCallback.class));
+
+        //用户签约回调成功之后更新为签约状态并支持线上打款  签约成功更新状态
+        if (true){
+            userSignService.updateUserSign("");
+        }
+        return null;
+    }
+
+    @Override
+    public JSONObject paymentNotice(String obj) {
+        log.info("接收打款通知回调 + paymentNotice ================={}", obj);
+        return null;
+    }
+
+    @Override
+    public HttpResult billDownload(Integer type, String date) {
+        BillDownloadResponse response = RetrieveTTQFApi.billDownload(type, date);
+        if (PayConstantStatus.BIZ_CODE.equals(response.getBizCode())){
+            return HttpResult.ok(response.getResultModel().getBillUrl());
+        }
+        return HttpResult.error(response.getBizMsg());
+    }
+
+    @Override
+    public HttpResult receiptDownload(String mchOrderNo, String orderNo) {
+        ReceiptlDownloadResponse response = RetrieveTTQFApi.receiptDownload(mchOrderNo,orderNo);
+        if (PayConstantStatus.BIZ_CODE.equals(response.getBizCode())){
+            return HttpResult.ok(response.getResultModel().getReceiptUrl());
+        }
+        return HttpResult.error(response.getBizMsg());
+    }
+
+
+}