commit 7e38b8d9714a0c598e10735f5795378059231e03
Author: ran.shang <>
Date: Wed Jun 11 09:42:13 2025 +0800
init
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5eac309
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3817f49
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# alita-bjy-uygur
+
diff --git a/db/聊天功能.sql b/db/聊天功能.sql
new file mode 100644
index 0000000..b82fdd7
--- /dev/null
+++ b/db/聊天功能.sql
@@ -0,0 +1,58 @@
+CREATE TABLE "xs_chat"
+(
+ "id" BIGINT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
+ "org_id" BIGINT,
+ "org_user_id" BIGINT,
+ "person_user_id" BIGINT,
+ "type" VARCHAR(32),
+ "status" TINYINT,
+ "deleted" BIT DEFAULT 0 NOT NULL,
+ "create_by" BIGINT NOT NULL,
+ "create_time" TIMESTAMP(0) NOT NULL,
+ "update_by" BIGINT,
+ "update_time" TIMESTAMP(0),
+ "proxy_by" BIGINT
+ ) ;
+
+COMMENT ON TABLE "xs_chat" IS '聊天表';
+COMMENT ON COLUMN "xs_chat"."org_id" IS '机构id';
+COMMENT ON COLUMN "xs_chat"."org_user_id" IS '机构用户id';
+COMMENT ON COLUMN "xs_chat"."person_user_id" IS '个人用户id';
+COMMENT ON COLUMN "xs_chat"."type" IS '类型(chat_type)';
+COMMENT ON COLUMN "xs_chat"."status" IS '状态:1有效,2关闭';
+COMMENT ON COLUMN "xs_chat"."create_by" IS '创建人';
+COMMENT ON COLUMN "xs_chat"."create_time" IS '创建时间';
+COMMENT ON COLUMN "xs_chat"."deleted" IS '是否逻辑删除';
+COMMENT ON COLUMN "xs_chat"."proxy_by" IS '代理人';
+COMMENT ON COLUMN "xs_chat"."update_by" IS '更新人';
+COMMENT ON COLUMN "xs_chat"."update_time" IS '更新时间';
+
+
+
+CREATE TABLE "xs_chat_msg"
+(
+ "id" BIGINT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
+ "chat_id" BIGINT,
+ "sender_id" BIGINT,
+ "msg_type" VARCHAR(16),
+ "content" VARCHAR(1024),
+ "msg_status" TINYINT,
+ "deleted" BIT DEFAULT 0 NOT NULL,
+ "create_by" BIGINT NOT NULL,
+ "create_time" TIMESTAMP(0) NOT NULL,
+ "update_by" BIGINT,
+ "update_time" TIMESTAMP(0),
+ "proxy_by" BIGINT
+) ;
+COMMENT ON TABLE "xs_chat_msg" IS '聊天消息表';
+COMMENT ON COLUMN "xs_chat_msg"."chat_id" IS '聊天id';
+COMMENT ON COLUMN "xs_chat_msg"."sender_id" IS '发送用户id';
+COMMENT ON COLUMN "xs_chat_msg"."msg_type" IS '消息类型(chat_msg_type):text等';
+COMMENT ON COLUMN "xs_chat_msg"."content" IS '个人用户id';
+COMMENT ON COLUMN "xs_chat_msg"."msg_status" IS '消息状态:1未读,2已读';
+COMMENT ON COLUMN "xs_chat_msg"."create_by" IS '创建人';
+COMMENT ON COLUMN "xs_chat_msg"."create_time" IS '创建时间';
+COMMENT ON COLUMN "xs_chat_msg"."deleted" IS '是否逻辑删除';
+COMMENT ON COLUMN "xs_chat_msg"."proxy_by" IS '代理人';
+COMMENT ON COLUMN "xs_chat_msg"."update_by" IS '更新人';
+COMMENT ON COLUMN "xs_chat_msg"."update_time" IS '更新时间';
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..4c95a07
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,408 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.4.2
+
+
+ com.newyetai
+ alita-bjy-uygur
+ 0.0.1
+ jar
+
+
+ 1.2.0.Final
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+ com.google.guava
+ guava
+ 18.0
+ compile
+
+
+
+
+ commons-io
+ commons-io
+ 2.6
+
+
+ org.apache.commons
+ commons-lang3
+
+
+ commons-collections
+ commons-collections
+ 3.2.2
+
+
+ org.apache.commons
+ commons-collections4
+ 4.2
+
+
+
+ org.mapstruct
+ mapstruct-jdk8
+ ${org.mapstruct.version}
+ provided
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${org.mapstruct.version}
+ provided
+
+
+
+
+ org.springframework.data
+ spring-data-commons
+
+
+
+
+ org.freemarker
+ freemarker
+
+
+
+
+ io.springfox
+ springfox-swagger2
+ 2.7.0
+
+
+ io.springfox
+ springfox-swagger-ui
+ 2.7.0
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
+
+ com.alibaba
+ easyexcel
+ 3.1.1
+
+
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+ 1.55
+
+
+
+
+ com.github.ulisesbocchio
+ jasypt-spring-boot-starter
+ 3.0.2
+
+
+
+
+
+ com.dameng
+ Dm8JdbcDriver18
+ 8.1.1.49
+
+
+
+ com.alibaba
+ druid-spring-boot-starter
+ 1.2.4
+
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ 3.4.0
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 2.1.3
+
+
+
+
+ com.github.pagehelper
+ pagehelper-spring-boot-starter
+ 1.4.6
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+
+
+
+
+ redis.clients
+ jedis
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+ org.redisson
+ redisson-spring-boot-starter
+ 3.15.6
+
+
+ io.netty
+ netty-all
+
+
+
+
+ cn.hutool
+ hutool-all
+ 5.8.16
+
+
+
+
+ org.apache.pdfbox
+ pdfbox
+ 2.0.20
+
+
+ org.apache.pdfbox
+ fontbox
+ 2.0.20
+
+
+
+
+ e-iceblue
+ spire.pdf
+ 3.7.4
+
+
+ com.itextpdf
+ itextpdf
+ 5.5.11
+
+
+ com.itextpdf
+ itext-asian
+ 5.2.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-oauth2-client
+
+
+
+ io.jsonwebtoken
+ jjwt
+ 0.9.0
+
+
+
+ spring-boot-starter-websocket
+ org.springframework.boot
+
+
+
+
+
+ com.aliyun
+ aliyun-java-sdk-core
+ 4.1.0
+
+
+
+ com.tencentcloudapi
+ tencentcloud-sdk-java
+ 3.1.100
+
+
+
+ com.aliyun
+ alibaba-dingtalk-service-sdk
+ 1.0.1
+
+
+
+ com.baidu.aip
+ java-sdk
+ 4.15.3
+
+
+ org.slf4j
+ slf4j-simple
+
+
+
+
+
+
+ io.github.toolgood
+ toolgood-words
+ 3.1.0.0
+
+
+
+ com.spatial4j
+ spatial4j
+ 0.5
+
+
+
+
+ com.squareup.okhttp3
+ okhttp
+ 4.10.0
+
+
+
+
+ com.squareup.okio
+ okio
+ 2.10.0
+
+
+
+ ws.schild
+ jave-core
+ 3.4.0
+
+
+
+
+ ws.schild
+ jave-nativebin-linux64
+ 3.4.0
+
+
+
+
+ ws.schild
+ jave-nativebin-osx64
+ 3.4.0
+
+
+
+
+ ws.schild
+ jave-nativebin-win64
+ 3.4.0
+
+
+
+
+
+
+
+
+ ${project.artifactId}
+
+
+ src/main/resources
+
+
+ src/main/java
+
+
+ **/*.xml
+
+
+
+ src/main/resources
+ true
+
+ application.yml
+ bootstrap.yml
+ ${project.artifactId}-${profile.active}.yaml
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ com.spotify
+ docker-maven-plugin
+ 1.2.1
+
+ ${project.build.finalName}:${project.version}
+ ${project.build.outputDirectory}
+
+ ${project.build.finalName}.jar
+
+
+
+ ${project.build.directory}
+ ${project.build.finalName}.jar
+
+
+
+ ${docker.host}
+ ${docker.certPath}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/AlitaBjyUygurApplication.java b/src/main/java/com/newyetai/AlitaBjyUygurApplication.java
new file mode 100644
index 0000000..2decefe
--- /dev/null
+++ b/src/main/java/com/newyetai/AlitaBjyUygurApplication.java
@@ -0,0 +1,22 @@
+package com.newyetai;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+
+/**
+ * @author sr on 2020-04-16
+ */
+@SpringBootApplication(scanBasePackages = {"com.newyetai"})
+@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
+@EnableScheduling
+public class AlitaBjyUygurApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(AlitaBjyUygurApplication.class, args);
+ }
+
+
+}
diff --git a/src/main/java/com/newyetai/ai/interview/controller/InterviewRecordController.java b/src/main/java/com/newyetai/ai/interview/controller/InterviewRecordController.java
new file mode 100644
index 0000000..4ec7e00
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/interview/controller/InterviewRecordController.java
@@ -0,0 +1,67 @@
+package com.newyetai.ai.interview.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import com.newyetai.common.AlitaResult;
+import com.newyetai.common.util.JsonUtils;
+import com.newyetai.common.validation.Create;
+import com.newyetai.common.validation.Update;
+import com.newyetai.tkmybatis.pojo.Page;
+import com.newyetai.ai.interview.dto.*;
+import com.newyetai.ai.interview.service.InterviewRecordService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import java.util.List;
+
+/**
+ * ai面试记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-11
+ */
+@Api(tags = "ai面试记录")
+@RestController
+@RequestMapping("/ai/interviewRecord")
+public class InterviewRecordController {
+
+ @Autowired
+ private InterviewRecordService interviewRecordService;
+
+ @PostMapping("/create")
+ @ApiOperation("ai面试记录-创建")
+ public AlitaResult create(@RequestBody @Validated(value = Create.class) InterviewRecordOperatorDTO operatorDTO) {
+ return AlitaResult.success(interviewRecordService.create(operatorDTO));
+ }
+
+ @PutMapping("/modify")
+ @ApiOperation("ai面试记录-修改")
+ public AlitaResult modify(@RequestBody @Validated(value = Update.class) InterviewRecordOperatorDTO operatorDTO) {
+ return AlitaResult.success(interviewRecordService.modify(operatorDTO));
+ }
+
+ @DeleteMapping("{id}")
+ @ApiOperation("ai面试记录-删除")
+ public AlitaResult delete(@PathVariable("id") Long id) {
+ return AlitaResult.success(interviewRecordService.delete(id));
+ }
+
+ @GetMapping("{id}")
+ @ApiOperation("ai面试记录-查询单个")
+ public AlitaResult findById(@PathVariable("id") Long id) {
+ return AlitaResult.success(interviewRecordService.findById(id));
+ }
+
+ @GetMapping("list")
+ @ApiOperation("ai面试记录-列表查询")
+ public AlitaResult> list(InterviewRecordQueryDTO queryDTO) {
+ return AlitaResult.success(interviewRecordService.list(queryDTO));
+ }
+
+ @GetMapping("page")
+ @ApiOperation("ai面试记录-分页查询")
+ public AlitaResult> page(InterviewRecordPageQueryDTO queryDTO) {
+ interviewRecordService.page(queryDTO);
+ return AlitaResult.success(queryDTO.getPageResult());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/interview/convert/InterviewRecordConvert.java b/src/main/java/com/newyetai/ai/interview/convert/InterviewRecordConvert.java
new file mode 100644
index 0000000..5676a5f
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/interview/convert/InterviewRecordConvert.java
@@ -0,0 +1,28 @@
+package com.newyetai.ai.interview.convert;
+
+import com.newyetai.ai.interview.entity.InterviewRecord;
+import com.newyetai.ai.interview.dto.InterviewRecordDTO;
+import com.newyetai.ai.interview.dto.InterviewRecordOperatorDTO;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * ai面试记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-11
+ */
+@Mapper
+public interface InterviewRecordConvert {
+ InterviewRecordConvert INSTANCE = Mappers.getMapper(InterviewRecordConvert.class);
+
+ InterviewRecord convert(InterviewRecordDTO dto);
+
+ InterviewRecordDTO convert(InterviewRecord entity);
+
+ InterviewRecord convert(InterviewRecordOperatorDTO dto);
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/interview/dao/InterviewRecordMapper.java b/src/main/java/com/newyetai/ai/interview/dao/InterviewRecordMapper.java
new file mode 100644
index 0000000..a569b0d
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/interview/dao/InterviewRecordMapper.java
@@ -0,0 +1,26 @@
+package com.newyetai.ai.interview.dao;
+
+import com.newyetai.tkmybatis.mybatis.MyMapper;
+import com.newyetai.ai.interview.entity.InterviewRecord;
+import com.newyetai.ai.interview.dto.InterviewRecordDTO;
+import com.newyetai.ai.interview.dto.InterviewRecordQueryDTO;
+import com.newyetai.ai.interview.dto.InterviewRecordPageQueryDTO;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * ai面试记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-11
+ */
+@Mapper
+public interface InterviewRecordMapper extends MyMapper {
+
+ List page(@Param("param") InterviewRecordPageQueryDTO queryDTO);
+
+ List list(@Param("param") InterviewRecordQueryDTO queryDTO);
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/interview/dto/InterviewRecordDTO.java b/src/main/java/com/newyetai/ai/interview/dto/InterviewRecordDTO.java
new file mode 100644
index 0000000..8120bb0
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/interview/dto/InterviewRecordDTO.java
@@ -0,0 +1,45 @@
+package com.newyetai.ai.interview.dto;
+
+import com.newyetai.common.dto.BaseDTO;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.SuperBuilder;
+
+import java.util.Date;
+
+/**
+ * ai面试记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-11
+ */
+@ApiModel("ai面试记录")
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class InterviewRecordDTO extends BaseDTO {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("用户ID(xs_user)")
+ private Long userId;
+
+ @ApiModelProperty("模拟岗位名称")
+ private String positionName;
+
+ @ApiModelProperty("面试状态(1.待开始、2.待继续、3.已完成)")
+ private Integer state;
+
+ @ApiModelProperty("报告出具状态(1.未出具 2.已出具)")
+ private Integer reportStatus;
+
+ private String jsonData;
+
+ @ApiModelProperty("节点")
+ private Integer node;
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/interview/dto/InterviewRecordOperatorDTO.java b/src/main/java/com/newyetai/ai/interview/dto/InterviewRecordOperatorDTO.java
new file mode 100644
index 0000000..17fa561
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/interview/dto/InterviewRecordOperatorDTO.java
@@ -0,0 +1,69 @@
+package com.newyetai.ai.interview.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.newyetai.common.validation.Create;
+import com.newyetai.common.validation.Update;
+
+import org.hibernate.validator.constraints.Length;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+import java.util.Date;
+
+/**
+ * ai面试记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-11
+ */
+@ApiModel("ai面试记录")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class InterviewRecordOperatorDTO implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @NotNull(message = "id不能为空",groups = Update.class)
+ private Long id;
+
+ @ApiModelProperty("用户ID(xs_user)")
+ private Long userId;
+
+
+ @Length(max = 32,message = "模拟岗位名称超长")
+ @NotBlank(message = "模拟岗位名称不能为空",groups = {Create.class})
+ @ApiModelProperty("模拟岗位名称")
+ private String positionName;
+
+ @ApiModelProperty("面试状态(1.待开始、2.待继续、3.已完成)")
+ private Integer state;
+
+ @ApiModelProperty("报告出具状态(1.未出具 2.已出具)")
+ private Integer reportStatus;
+
+ @NotNull(message = "数据不能为空",groups = {Update.class})
+ private String jsonData;
+
+ @NotNull(message = "节点不能为空",groups = {Update.class})
+ @ApiModelProperty("节点")
+ private Integer node;
+
+ //是否评分
+ @Builder.Default
+ private Boolean gradeInterview = Boolean.FALSE;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/interview/dto/InterviewRecordPageQueryDTO.java b/src/main/java/com/newyetai/ai/interview/dto/InterviewRecordPageQueryDTO.java
new file mode 100644
index 0000000..a3b956b
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/interview/dto/InterviewRecordPageQueryDTO.java
@@ -0,0 +1,74 @@
+package com.newyetai.ai.interview.dto;
+
+import com.newyetai.common.dto.PageQueryDTO;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import org.springframework.format.annotation.DateTimeFormat;
+
+
+import java.util.Date;
+
+/**
+ * ai面试记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-11
+ */
+
+@ApiModel("ai面试记录")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class InterviewRecordPageQueryDTO extends PageQueryDTO {
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ @ApiModelProperty("用户ID(xs_user)")
+ private Long userId;
+
+ @ApiModelProperty("模拟岗位名称 (模糊匹配)")
+ private String positionNameLike;
+
+ @ApiModelProperty("面试状态(1.待开始、2.待继续、3.已完成)")
+ private Integer state;
+
+ @ApiModelProperty("报告出具状态(1.未出具 2.已出具)")
+ private Integer reportStatus;
+
+ private String jsonData;
+
+ @ApiModelProperty("节点")
+ private Integer node;
+
+ @ApiModelProperty("创建时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeStart;
+
+ @ApiModelProperty("创建时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeEnd;
+
+ @ApiModelProperty("修改时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeStart;
+
+ @ApiModelProperty("修改时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeEnd;
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/interview/dto/InterviewRecordQueryDTO.java b/src/main/java/com/newyetai/ai/interview/dto/InterviewRecordQueryDTO.java
new file mode 100644
index 0000000..90f003c
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/interview/dto/InterviewRecordQueryDTO.java
@@ -0,0 +1,74 @@
+package com.newyetai.ai.interview.dto;
+
+import com.newyetai.common.dto.BaseDTO;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * ai面试记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-11
+ */
+@ApiModel("ai面试记录")
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class InterviewRecordQueryDTO implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ @ApiModelProperty("用户ID(xs_user)")
+ private Long userId;
+
+ @ApiModelProperty("模拟岗位名称 (模糊匹配)")
+ private String positionNameLike;
+
+ @ApiModelProperty("面试状态(1.待开始、2.待继续、3.已完成)")
+ private Integer state;
+
+ @ApiModelProperty("报告出具状态(1.未出具 2.已出具)")
+ private Integer reportStatus;
+
+ private String jsonData;
+
+ @ApiModelProperty("节点")
+ private Integer node;
+
+ @ApiModelProperty("创建时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeStart;
+
+ @ApiModelProperty("创建时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeEnd;
+
+ @ApiModelProperty("修改时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeStart;
+
+ @ApiModelProperty("修改时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeEnd;
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/interview/entity/InterviewRecord.java b/src/main/java/com/newyetai/ai/interview/entity/InterviewRecord.java
new file mode 100644
index 0000000..776128a
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/interview/entity/InterviewRecord.java
@@ -0,0 +1,53 @@
+package com.newyetai.ai.interview.entity;
+
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.newyetai.common.entity.BaseEntity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * ai面试记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-11
+ */
+@TableName(value = "ai_interview_record")
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class InterviewRecord extends BaseEntity {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户ID(xs_user)
+ */
+ private Long userId;
+ /**
+ * 模拟岗位名称
+ */
+ private String positionName;
+ /**
+ * 面试状态(1.待开始、2.待继续、3.已完成)
+ */
+ private Integer state;
+ /**
+ * 报告出具状态(1.未出具 2.已出具)
+ */
+ private Integer reportStatus;
+ /**
+ *
+ */
+ private String jsonData;
+ /**
+ * 节点
+ */
+ private Integer node;
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/interview/enums/InterviewRecordEnum.java b/src/main/java/com/newyetai/ai/interview/enums/InterviewRecordEnum.java
new file mode 100644
index 0000000..5b72d3f
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/interview/enums/InterviewRecordEnum.java
@@ -0,0 +1,33 @@
+package com.newyetai.ai.interview.enums;
+/**
+ * @description: 面试状态
+ * @return:
+ * @author: guixinman
+ * @param:
+ */
+public enum InterviewRecordEnum {
+ INIT(1,"待开始"),
+ TO_BE_CONTINUED(2,"待继续"),
+ SUCCESS(3,"已完成"),
+ ;
+
+ private Integer status;
+ /**
+ * 类型描述
+ */
+ private String desc;
+
+
+ InterviewRecordEnum(Integer status, String desc) {
+ this.status = status;
+ this.desc = desc;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/src/main/java/com/newyetai/ai/interview/enums/InterviewRecordReportStatusEnum.java b/src/main/java/com/newyetai/ai/interview/enums/InterviewRecordReportStatusEnum.java
new file mode 100644
index 0000000..fbbb346
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/interview/enums/InterviewRecordReportStatusEnum.java
@@ -0,0 +1,33 @@
+package com.newyetai.ai.interview.enums;
+
+/**
+ * @description: 报告出具状态
+ * @return:
+ * @author: guixinman
+ * @param:
+ */
+public enum InterviewRecordReportStatusEnum {
+ INIT(1,"未出具"),
+ SUCCESS(2,"已出具"),
+ ;
+
+ private Integer status;
+ /**
+ * 类型描述
+ */
+ private String desc;
+
+
+ InterviewRecordReportStatusEnum(Integer status, String desc) {
+ this.status = status;
+ this.desc = desc;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/src/main/java/com/newyetai/ai/interview/mapper/InterviewRecordMapper.xml b/src/main/java/com/newyetai/ai/interview/mapper/InterviewRecordMapper.xml
new file mode 100644
index 0000000..0c4bde7
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/interview/mapper/InterviewRecordMapper.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+ FROM
+ ai_interview_record t
+ WHERE t.deleted = 0
+
+ AND t.id = #{param.id}
+
+
+ AND t.user_id = #{param.userId}
+
+
+
+ AND t.position_name like #{positionNameLike}
+
+
+ AND t.state = #{param.state}
+
+
+ AND t.report_status = #{param.reportStatus}
+
+
+ AND t.json_data = #{param.jsonData}
+
+
+ AND t.node = #{param.node}
+
+
+ AND t.create_time >= #{param.createTimeStart}
+
+
+ AND t.create_time <= #{param.createTimeEnd}
+
+
+ AND t.update_time >= #{param.updateTimeStart}
+
+
+ AND t.update_time <= #{param.updateTimeEnd}
+
+ ORDER BY t.id DESC
+
+
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/interview/service/InterviewRecordService.java b/src/main/java/com/newyetai/ai/interview/service/InterviewRecordService.java
new file mode 100644
index 0000000..e7f52a8
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/interview/service/InterviewRecordService.java
@@ -0,0 +1,68 @@
+package com.newyetai.ai.interview.service;
+
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.Valid;
+import javax.validation.groups.Default;
+
+import java.util.List;
+
+import com.newyetai.ai.interview.dto.*;
+
+/**
+ * ai面试记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-11
+ */
+@Validated(Default.class)
+public interface InterviewRecordService {
+
+ /**
+ * ai面试记录 - 创建
+ *
+ * @param operatorDto 操作dto
+ * @return {@link InterviewRecordDTO}
+ */
+ InterviewRecordDTO create(@Valid InterviewRecordOperatorDTO operatorDto);
+
+ /**
+ * ai面试记录 - 修改
+ *
+ * @param operatorDto 操作dto
+ * @return {@link InterviewRecordDTO}
+ */
+ InterviewRecordDTO modify(@Valid InterviewRecordOperatorDTO operatorDto);
+
+ /**
+ * ai面试记录 - 删除
+ *
+ * @param id id
+ * @return {@link InterviewRecordDTO}
+ */
+ InterviewRecordDTO delete(Long id);
+
+ /**
+ * ai面试记录 - 根据ID查询单个
+ *
+ * @param id id
+ * @return {@link InterviewRecordDTO}
+ */
+ InterviewRecordDTO findById(Long id);
+
+ /**
+ * ai面试记录 - 列表查询
+ *
+ * @param queryDTO 列表查询dto
+ * @return {@link List}<{@link InterviewRecordDTO}>
+ */
+ List list(InterviewRecordQueryDTO queryDTO);
+
+ /**
+ * ai面试记录 - 分页查询
+ *
+ * @param queryDTO 分页查询dto
+ * @return {@link InterviewRecordDTO}
+ */
+ List page(InterviewRecordPageQueryDTO queryDTO);
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/interview/service/impl/InterviewRecordServiceImpl.java b/src/main/java/com/newyetai/ai/interview/service/impl/InterviewRecordServiceImpl.java
new file mode 100644
index 0000000..be5f54f
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/interview/service/impl/InterviewRecordServiceImpl.java
@@ -0,0 +1,108 @@
+package com.newyetai.ai.interview.service.impl;
+
+import cn.hutool.json.JSONUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import com.newyetai.ai.interview.convert.InterviewRecordConvert;
+import com.newyetai.ai.interview.entity.InterviewRecord;
+import com.newyetai.ai.interview.dto.*;
+import com.newyetai.ai.interview.dao.InterviewRecordMapper;
+import com.newyetai.ai.interview.enums.InterviewRecordEnum;
+import com.newyetai.ai.interview.enums.InterviewRecordReportStatusEnum;
+import com.newyetai.ai.interview.service.InterviewRecordService;
+
+import org.springframework.stereotype.Service;
+
+import com.newyetai.common.exception.BusinessException;
+import com.newyetai.common.util.JsonUtils;
+import com.newyetai.common.util.UserContextHolder;
+import com.newyetai.sdk.xf.dto.InterviewContentDTO;
+import com.newyetai.sdk.xf.util.XfUtils;
+
+import javax.annotation.Resource;
+
+import java.util.*;
+
+/**
+ * ai面试记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-11
+ */
+@Slf4j
+@Service
+public class InterviewRecordServiceImpl implements InterviewRecordService {
+
+ @Resource
+ private InterviewRecordMapper interviewRecordMapper;
+
+ @Override
+ public InterviewRecordDTO create(InterviewRecordOperatorDTO operatorDto) {
+ InterviewRecord interviewRecord = InterviewRecordConvert.INSTANCE.convert(operatorDto);
+ interviewRecord.setUserId(UserContextHolder.getExistLoginUserId());
+ interviewRecord.setNode(1);
+ interviewRecord.setState(InterviewRecordEnum.INIT.getStatus());
+ interviewRecord.setReportStatus(InterviewRecordReportStatusEnum.INIT.getStatus());
+
+ String data = XfUtils.generateInterviewQuestion(InterviewContentDTO.builder().positionName(operatorDto.getPositionName()).build());
+ interviewRecord.setJsonData(data);
+ interviewRecordMapper.saveEntity(interviewRecord);
+ return InterviewRecordConvert.INSTANCE.convert(interviewRecord);
+ }
+
+ @Override
+ public InterviewRecordDTO modify(InterviewRecordOperatorDTO operatorDto) {
+ InterviewRecordDTO interviewRecordDto = this.findById(operatorDto.getId());
+ if (Objects.isNull(interviewRecordDto)) {
+ return null;
+ }
+ InterviewRecord interviewRecord = InterviewRecordConvert.INSTANCE.convert(operatorDto);
+
+ String jsonData = interviewRecord.getJsonData();
+ InterviewContentDTO interviewContentDTO = JsonUtils.toObject(jsonData, InterviewContentDTO.class);
+
+ if (Boolean.TRUE.equals(operatorDto.getGradeInterview())) {
+ String jsonDataNew = XfUtils.gradeInterview(interviewContentDTO);
+ interviewRecord.setReportStatus(InterviewRecordReportStatusEnum.SUCCESS.getStatus());
+ interviewRecord.setJsonData(jsonDataNew);
+ interviewRecord.setState(InterviewRecordEnum.SUCCESS.getStatus());
+ }else {
+ interviewRecord.setState(InterviewRecordEnum.TO_BE_CONTINUED.getStatus());
+ }
+ interviewRecordMapper.updateEntitySelective(interviewRecord);
+
+ return this.findById(operatorDto.getId());
+ }
+
+ @Override
+ public InterviewRecordDTO delete(Long id) {
+ InterviewRecordDTO interviewRecordDto = this.findById(id);
+ if (Objects.isNull(interviewRecordDto)) {
+ return null;
+ }
+ InterviewRecord interviewRecord = InterviewRecord.builder().build();
+ interviewRecord.setId(id);
+ interviewRecordMapper.deleteEntity(interviewRecord, UserContextHolder.getLoginUserId());
+ return interviewRecordDto;
+ }
+
+ @Override
+ public InterviewRecordDTO findById(Long id) {
+ InterviewRecord interviewRecord = interviewRecordMapper.getById(id);
+ if (Objects.isNull(interviewRecord)) {
+ return null;
+ }
+ return InterviewRecordConvert.INSTANCE.convert(interviewRecord);
+ }
+
+ @Override
+ public List list(InterviewRecordQueryDTO queryDTO) {
+ return interviewRecordMapper.list(queryDTO);
+ }
+
+ @Override
+ public List page(InterviewRecordPageQueryDTO queryDTO) {
+ queryDTO.setUserId(UserContextHolder.getExistLoginUserId());
+ return interviewRecordMapper.page(queryDTO);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/mbti/controller/MbtiRecordController.java b/src/main/java/com/newyetai/ai/mbti/controller/MbtiRecordController.java
new file mode 100644
index 0000000..7def508
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/mbti/controller/MbtiRecordController.java
@@ -0,0 +1,76 @@
+package com.newyetai.ai.mbti.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import com.newyetai.common.AlitaResult;
+import com.newyetai.common.validation.Create;
+import com.newyetai.common.validation.Update;
+import com.newyetai.tkmybatis.pojo.Page;
+import com.newyetai.ai.mbti.dto.*;
+import com.newyetai.ai.mbti.service.MbtiRecordService;
+
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+
+/**
+ * AI测评记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-20
+ */
+@Api(tags = "AI测评记录")
+@RestController
+@RequestMapping("/ai/mbtiRecord")
+public class MbtiRecordController {
+
+ @Autowired
+ private MbtiRecordService mbtiRecordService;
+
+ @PostMapping("/create")
+ @ApiOperation("AI测评记录-创建")
+ public AlitaResult create(@RequestBody @Validated(value = Create.class) MbtiRecordOperatorDTO operatorDTO) {
+ return AlitaResult.success(mbtiRecordService.create(operatorDTO));
+ }
+
+ @PutMapping("/modify")
+ @ApiOperation("AI测评记录-修改")
+ public AlitaResult modify(@RequestBody @Validated(value = Update.class) MbtiRecordOperatorDTO operatorDTO) {
+ return AlitaResult.success(mbtiRecordService.modify(operatorDTO));
+ }
+
+ @ApiOperation("AI测评记录-出具报告")
+ @PostMapping("/report")
+ public AlitaResult report(@RequestParam("id") Long id){
+ mbtiRecordService.report(id);
+ return AlitaResult.success();
+ }
+
+ @DeleteMapping("{id}")
+ @ApiOperation("AI测评记录-删除")
+ public AlitaResult delete(@PathVariable("id") Long id) {
+ return AlitaResult.success(mbtiRecordService.delete(id));
+ }
+
+ @GetMapping("{id}")
+ @ApiOperation("AI测评记录-查询单个")
+ public AlitaResult findById(@PathVariable("id") Long id) {
+ return AlitaResult.success(mbtiRecordService.findById(id));
+ }
+
+ @GetMapping("list")
+ @ApiOperation("AI测评记录-列表查询")
+ public AlitaResult> list(MbtiRecordQueryDTO queryDTO) {
+ return AlitaResult.success(mbtiRecordService.list(queryDTO));
+ }
+
+ @GetMapping("page")
+ @ApiOperation("AI测评记录-分页查询")
+ public AlitaResult> page(MbtiRecordPageQueryDTO queryDTO) {
+ mbtiRecordService.page(queryDTO);
+ return AlitaResult.success(queryDTO.getPageResult());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/mbti/convert/MbtiRecordConvert.java b/src/main/java/com/newyetai/ai/mbti/convert/MbtiRecordConvert.java
new file mode 100644
index 0000000..79c3897
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/mbti/convert/MbtiRecordConvert.java
@@ -0,0 +1,28 @@
+package com.newyetai.ai.mbti.convert;
+
+import com.newyetai.ai.mbti.entity.MbtiRecord;
+import com.newyetai.ai.mbti.dto.MbtiRecordDTO;
+import com.newyetai.ai.mbti.dto.MbtiRecordOperatorDTO;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * AI测评记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-20
+ */
+@Mapper
+public interface MbtiRecordConvert {
+ MbtiRecordConvert INSTANCE = Mappers.getMapper(MbtiRecordConvert.class);
+
+ MbtiRecord convert(MbtiRecordDTO dto);
+
+ MbtiRecordDTO convert(MbtiRecord entity);
+
+ MbtiRecord convert(MbtiRecordOperatorDTO dto);
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/mbti/dao/MbtiRecordMapper.java b/src/main/java/com/newyetai/ai/mbti/dao/MbtiRecordMapper.java
new file mode 100644
index 0000000..70e6e15
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/mbti/dao/MbtiRecordMapper.java
@@ -0,0 +1,26 @@
+package com.newyetai.ai.mbti.dao;
+
+import com.newyetai.tkmybatis.mybatis.MyMapper;
+import com.newyetai.ai.mbti.entity.MbtiRecord;
+import com.newyetai.ai.mbti.dto.MbtiRecordDTO;
+import com.newyetai.ai.mbti.dto.MbtiRecordQueryDTO;
+import com.newyetai.ai.mbti.dto.MbtiRecordPageQueryDTO;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * AI测评记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-20
+ */
+@Mapper
+public interface MbtiRecordMapper extends MyMapper {
+
+ List page(@Param("param") MbtiRecordPageQueryDTO queryDTO);
+
+ List list(@Param("param") MbtiRecordQueryDTO queryDTO);
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/mbti/dto/MbtiRecordDTO.java b/src/main/java/com/newyetai/ai/mbti/dto/MbtiRecordDTO.java
new file mode 100644
index 0000000..d4c380d
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/mbti/dto/MbtiRecordDTO.java
@@ -0,0 +1,51 @@
+package com.newyetai.ai.mbti.dto;
+
+import com.newyetai.common.dto.BaseDTO;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.SuperBuilder;
+
+import java.util.Date;
+
+/**
+ * AI测评记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-20
+ */
+@ApiModel("AI测评记录")
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class MbtiRecordDTO extends BaseDTO {
+ private static final long serialVersionUID = 1L;
+
+ private Long userId;
+
+ private String liangBiaoId;
+
+ @ApiModelProperty("节点")
+ private Integer node;
+
+ private String jsonData;
+
+ private String orderId;
+
+ @ApiModelProperty("状态(1.待开始、2.待继续、3.已完成)")
+ private Integer state;
+
+ @ApiModelProperty("报告出具状态(1.未出具 2.已出具)")
+ private Integer reportStatus;
+
+ private String content;
+
+ private String reportId;
+
+ private String name;
+
+ private String phone;
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/mbti/dto/MbtiRecordOperatorDTO.java b/src/main/java/com/newyetai/ai/mbti/dto/MbtiRecordOperatorDTO.java
new file mode 100644
index 0000000..2b92554
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/mbti/dto/MbtiRecordOperatorDTO.java
@@ -0,0 +1,76 @@
+package com.newyetai.ai.mbti.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.newyetai.common.validation.Create;
+import com.newyetai.common.validation.Update;
+
+import org.springframework.format.annotation.DateTimeFormat;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * AI测评记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-20
+ */
+@ApiModel("AI测评记录")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class MbtiRecordOperatorDTO implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @NotNull(message = "id不能为空",groups = Update.class)
+ private Long id;
+
+ private Long userId;
+
+ @NotBlank(message = "liangBiaoId不能为空",groups = {Create.class, Update.class})
+ private String liangBiaoId;
+
+ @NotNull(message = "节点不能为空",groups = {Update.class})
+ @ApiModelProperty("节点")
+ private Integer node;
+
+ @NotNull(message = "数据不能为空",groups = {Update.class})
+ private Map answers;
+
+ private String orderId;
+
+ @ApiModelProperty("状态(2.待继续、3.已完成)")
+ private Integer state;
+
+ @ApiModelProperty("报告出具状态(1.未出具 2.已出具)")
+ private Integer reportStatus;
+
+
+ @Builder.Default
+ private Boolean submit = Boolean.FALSE;
+
+ private String content;
+
+ private String reportId;
+
+ @NotBlank(message = "name不能为空",groups = {Create.class, Update.class})
+ private String name;
+
+ @NotBlank(message = "phone不能为空",groups = {Create.class, Update.class})
+ private String phone;
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/mbti/dto/MbtiRecordPageQueryDTO.java b/src/main/java/com/newyetai/ai/mbti/dto/MbtiRecordPageQueryDTO.java
new file mode 100644
index 0000000..fd76fd5
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/mbti/dto/MbtiRecordPageQueryDTO.java
@@ -0,0 +1,74 @@
+package com.newyetai.ai.mbti.dto;
+
+import com.newyetai.common.dto.PageQueryDTO;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import org.springframework.format.annotation.DateTimeFormat;
+
+
+import java.util.Date;
+
+/**
+ * AI测评记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-20
+ */
+
+@ApiModel("AI测评记录")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class MbtiRecordPageQueryDTO extends PageQueryDTO {
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ private Long userId;
+
+ private String liangBiaoId;
+
+ @ApiModelProperty("节点")
+ private Integer node;
+
+ private String jsonData;
+
+ private String orderId;
+
+ @ApiModelProperty("状态(1.待开始、2.待继续、3.已完成)")
+ private Integer state;
+
+ @ApiModelProperty("报告出具状态(1.未出具 2.已出具)")
+ private Integer reportStatus;
+
+ @ApiModelProperty("创建时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeStart;
+
+ @ApiModelProperty("创建时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeEnd;
+
+ @ApiModelProperty("更新时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeStart;
+
+ @ApiModelProperty("更新时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeEnd;
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/mbti/dto/MbtiRecordQueryDTO.java b/src/main/java/com/newyetai/ai/mbti/dto/MbtiRecordQueryDTO.java
new file mode 100644
index 0000000..388c72c
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/mbti/dto/MbtiRecordQueryDTO.java
@@ -0,0 +1,74 @@
+package com.newyetai.ai.mbti.dto;
+
+import com.newyetai.common.dto.BaseDTO;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * AI测评记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-20
+ */
+@ApiModel("AI测评记录")
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class MbtiRecordQueryDTO implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ private Long userId;
+
+ private String liangBiaoId;
+
+ @ApiModelProperty("节点")
+ private Integer node;
+
+ private String jsonData;
+
+ private String orderId;
+
+ @ApiModelProperty("状态(1.待开始、2.待继续、3.已完成)")
+ private Integer state;
+
+ @ApiModelProperty("报告出具状态(1.未出具 2.已出具)")
+ private Integer reportStatus;
+
+ @ApiModelProperty("创建时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeStart;
+
+ @ApiModelProperty("创建时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeEnd;
+
+ @ApiModelProperty("更新时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeStart;
+
+ @ApiModelProperty("更新时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeEnd;
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/mbti/entity/MbtiRecord.java b/src/main/java/com/newyetai/ai/mbti/entity/MbtiRecord.java
new file mode 100644
index 0000000..ea11df0
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/mbti/entity/MbtiRecord.java
@@ -0,0 +1,63 @@
+package com.newyetai.ai.mbti.entity;
+
+
+import lombok.*;
+import lombok.experimental.SuperBuilder;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.newyetai.common.entity.BaseEntity;
+
+/**
+ * AI测评记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-20
+ */
+@TableName(value = "ai_mbti_record")
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class MbtiRecord extends BaseEntity {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ *
+ */
+ private Long userId;
+ /**
+ *
+ */
+ private String liangBiaoId;
+ /**
+ * 节点
+ */
+ private Integer node;
+ /**
+ *
+ */
+ private String jsonData;
+ /**
+ *
+ */
+ private String orderId;
+
+ /**
+ * 状态(1.待开始、2.待继续、3.已完成)
+ */
+ private Integer state;
+ /**
+ * 报告出具状态(1.未出具 2.已出具)
+ */
+ private Integer reportStatus;
+
+ private String content;
+
+ private String reportId;
+
+ private String name;
+
+ private String phone;
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/mbti/enums/MbtiRecordEnum.java b/src/main/java/com/newyetai/ai/mbti/enums/MbtiRecordEnum.java
new file mode 100644
index 0000000..bf35f41
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/mbti/enums/MbtiRecordEnum.java
@@ -0,0 +1,32 @@
+package com.newyetai.ai.mbti.enums;
+/**
+ * @description: 状态
+ * @return:
+ * @author: guixinman
+ * @param:
+ */
+public enum MbtiRecordEnum {
+ TO_BE_CONTINUED(2,"待继续"),
+ SUCCESS(3,"已完成"),
+ ;
+
+ private Integer status;
+ /**
+ * 类型描述
+ */
+ private String desc;
+
+
+ MbtiRecordEnum(Integer status, String desc) {
+ this.status = status;
+ this.desc = desc;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/src/main/java/com/newyetai/ai/mbti/enums/MbtiRecordReportStatusEnum.java b/src/main/java/com/newyetai/ai/mbti/enums/MbtiRecordReportStatusEnum.java
new file mode 100644
index 0000000..1d7a4d3
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/mbti/enums/MbtiRecordReportStatusEnum.java
@@ -0,0 +1,33 @@
+package com.newyetai.ai.mbti.enums;
+
+/**
+ * @description: 报告出具状态
+ * @return:
+ * @author: guixinman
+ * @param:
+ */
+public enum MbtiRecordReportStatusEnum {
+ INIT(1,"未出具"),
+ SUCCESS(2,"已出具"),
+ ;
+
+ private Integer status;
+ /**
+ * 类型描述
+ */
+ private String desc;
+
+
+ MbtiRecordReportStatusEnum(Integer status, String desc) {
+ this.status = status;
+ this.desc = desc;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/src/main/java/com/newyetai/ai/mbti/mapper/MbtiRecordMapper.xml b/src/main/java/com/newyetai/ai/mbti/mapper/MbtiRecordMapper.xml
new file mode 100644
index 0000000..001cb85
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/mbti/mapper/MbtiRecordMapper.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+ FROM
+ ai_mbti_record t
+ WHERE t.deleted = 0
+
+ AND t.id = #{param.id}
+
+
+ AND t.user_id = #{param.userId}
+
+
+ AND t.liang_biao_id = #{param.liangBiaoId}
+
+
+ AND t.node = #{param.node}
+
+
+ AND t.json_data = #{param.jsonData}
+
+
+ AND t.order_id = #{param.orderId}
+
+
+ AND t.state = #{param.state}
+
+
+ AND t.report_status = #{param.reportStatus}
+
+
+ AND t.create_time >= #{param.createTimeStart}
+
+
+ AND t.create_time <= #{param.createTimeEnd}
+
+
+ AND t.update_time >= #{param.updateTimeStart}
+
+
+ AND t.update_time <= #{param.updateTimeEnd}
+
+ ORDER BY t.id DESC
+
+
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/mbti/service/MbtiRecordService.java b/src/main/java/com/newyetai/ai/mbti/service/MbtiRecordService.java
new file mode 100644
index 0000000..5088202
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/mbti/service/MbtiRecordService.java
@@ -0,0 +1,76 @@
+package com.newyetai.ai.mbti.service;
+
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.Valid;
+import javax.validation.groups.Default;
+
+import java.util.List;
+
+import com.newyetai.ai.mbti.dto.*;
+
+/**
+ * AI测评记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-20
+ */
+@Validated(Default.class)
+public interface MbtiRecordService {
+
+ /**
+ * AI测评记录 - 创建
+ *
+ * @param operatorDto 操作dto
+ * @return {@link MbtiRecordDTO}
+ */
+ MbtiRecordDTO create(@Valid MbtiRecordOperatorDTO operatorDto);
+
+ /**
+ * AI测评记录 - 修改
+ *
+ * @param operatorDto 操作dto
+ * @return {@link MbtiRecordDTO}
+ */
+ MbtiRecordDTO modify(@Valid MbtiRecordOperatorDTO operatorDto);
+
+ /**
+ * @description: 出具报告
+ * @return:
+ * @author: guixinman
+ * @param:
+ */
+ void report(Long id);
+
+ /**
+ * AI测评记录 - 删除
+ *
+ * @param id id
+ * @return {@link MbtiRecordDTO}
+ */
+ MbtiRecordDTO delete(Long id);
+
+ /**
+ * AI测评记录 - 根据ID查询单个
+ *
+ * @param id id
+ * @return {@link MbtiRecordDTO}
+ */
+ MbtiRecordDTO findById(Long id);
+
+ /**
+ * AI测评记录 - 列表查询
+ *
+ * @param queryDTO 列表查询dto
+ * @return {@link List}<{@link MbtiRecordDTO}>
+ */
+ List list(MbtiRecordQueryDTO queryDTO);
+
+ /**
+ * AI测评记录 - 分页查询
+ *
+ * @param queryDTO 分页查询dto
+ * @return {@link MbtiRecordDTO}
+ */
+ List page(MbtiRecordPageQueryDTO queryDTO);
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/mbti/service/impl/MbtiRecordServiceImpl.java b/src/main/java/com/newyetai/ai/mbti/service/impl/MbtiRecordServiceImpl.java
new file mode 100644
index 0000000..cf6f2d2
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/mbti/service/impl/MbtiRecordServiceImpl.java
@@ -0,0 +1,166 @@
+package com.newyetai.ai.mbti.service.impl;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.newyetai.ai.interview.enums.InterviewRecordEnum;
+import com.newyetai.ai.interview.enums.InterviewRecordReportStatusEnum;
+import com.newyetai.ai.mbti.convert.MbtiRecordConvert;
+import com.newyetai.ai.mbti.entity.MbtiRecord;
+import com.newyetai.ai.mbti.dto.*;
+import com.newyetai.ai.mbti.dao.MbtiRecordMapper;
+import com.newyetai.ai.mbti.enums.MbtiRecordEnum;
+import com.newyetai.ai.mbti.enums.MbtiRecordReportStatusEnum;
+import com.newyetai.ai.mbti.service.MbtiRecordService;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.newyetai.common.AlitaResult;
+import com.newyetai.common.exception.BusinessException;
+import com.newyetai.common.exception.util.Assert;
+import com.newyetai.common.sensitive.SensitiveInfoUtils;
+import com.newyetai.common.util.JsonUtils;
+import com.newyetai.common.util.RandomUtils;
+import com.newyetai.common.util.UserContextHolder;
+import com.newyetai.sdk.mbti.mobel.AnswerReq;
+import com.newyetai.sdk.mbti.mobel.AnswerReqDTO;
+import com.newyetai.sdk.mbti.mobel.AnswerRes;
+import com.newyetai.sdk.mbti.mobel.OrderQueryReq;
+import com.newyetai.sdk.mbti.mobel.OrderQueryRes;
+import com.newyetai.sdk.mbti.mobel.ReportReq;
+import com.newyetai.sdk.mbti.mobel.ReportRes;
+import com.newyetai.sdk.mbti.service.MbtiProvider;
+
+import javax.annotation.Resource;
+
+import java.util.*;
+
+/**
+ * AI测评记录
+ *
+ * @author guixinman
+ * @since 1.0.0 2024-12-20
+ */
+@Slf4j
+@Service
+public class MbtiRecordServiceImpl implements MbtiRecordService {
+
+ @Resource
+ private MbtiRecordMapper mbtiRecordMapper;
+
+ @Autowired
+ private MbtiProvider mbtiProvider;
+
+ @Override
+ public MbtiRecordDTO create(MbtiRecordOperatorDTO operatorDto) {
+ MbtiRecord mbtiRecord = MbtiRecordConvert.INSTANCE.convert(operatorDto);
+ mbtiRecord.setUserId(UserContextHolder.getExistLoginUserId());
+ mbtiRecord.setState(MbtiRecordEnum.TO_BE_CONTINUED.getStatus());
+ mbtiRecord.setReportStatus(MbtiRecordReportStatusEnum.INIT.getStatus());
+ mbtiRecord.setJsonData(JsonUtils.toJsonString(operatorDto.getAnswers()));
+ mbtiRecord.setName(operatorDto.getName());
+ mbtiRecord.setPhone(operatorDto.getPhone());
+
+ if (operatorDto.getSubmit()) {
+ if (Objects.isNull(operatorDto.getAnswers())) {
+ throw new BusinessException("answers不能为空");
+ }
+ AnswerReq answerReq = new AnswerReq();
+ AnswerReqDTO answerData = AnswerReqDTO.builder()
+ .Answers(operatorDto.getAnswers())
+ .test_name(SensitiveInfoUtils.mobilePhone2(operatorDto.getPhone()) + RandomUtils.getRandomString(5))
+ .test_email(RandomUtils.getRandomString(5))
+ .build();
+ answerReq.setLiangbiaoId(operatorDto.getLiangBiaoId());
+ answerReq.setAnswerData(answerData);
+ AlitaResult answerResAlitaResult = mbtiProvider.http(answerReq);
+ Assert.isTrue(answerResAlitaResult.getSuccess(),answerResAlitaResult.getMsg());
+ AnswerRes answerRes = answerResAlitaResult.getData();
+ mbtiRecord.setOrderId(answerRes.getOrderId());
+ mbtiRecord.setState(MbtiRecordEnum.SUCCESS.getStatus());
+ }
+ mbtiRecordMapper.saveEntity(mbtiRecord);
+ return MbtiRecordConvert.INSTANCE.convert(mbtiRecord);
+ }
+
+ @Override
+ public MbtiRecordDTO modify(MbtiRecordOperatorDTO operatorDto) {
+ MbtiRecordDTO mbtiRecordDto = this.findById(operatorDto.getId());
+ if (Objects.isNull(mbtiRecordDto)) {
+ return null;
+ }
+ MbtiRecord mbtiRecord = MbtiRecordConvert.INSTANCE.convert(operatorDto);
+ mbtiRecord.setJsonData(JsonUtils.toJsonString(operatorDto.getAnswers()));
+ mbtiRecord.setName(operatorDto.getName());
+ mbtiRecord.setPhone(operatorDto.getPhone());
+ if (operatorDto.getSubmit()) {
+ AnswerReq answerReq = new AnswerReq();
+ answerReq.setLiangbiaoId(operatorDto.getLiangBiaoId());
+ answerReq.setAnswerData(AnswerReqDTO.builder()
+ .Answers(operatorDto.getAnswers())
+ .test_name(SensitiveInfoUtils.mobilePhone2(operatorDto.getPhone()) + RandomUtils.getRandomString(5))
+ .test_email(RandomUtils.getRandomString(5))
+ .build());
+ AlitaResult answerResAlitaResult = mbtiProvider.http(answerReq);
+ Assert.isTrue(answerResAlitaResult.getSuccess(),answerResAlitaResult.getMsg());
+ AnswerRes answerRes = answerResAlitaResult.getData();
+ mbtiRecord.setOrderId(answerRes.getOrderId());
+ mbtiRecord.setState(MbtiRecordEnum.SUCCESS.getStatus());
+ }
+ mbtiRecordMapper.updateEntitySelective(mbtiRecord);
+ return this.findById(operatorDto.getId());
+ }
+
+ @Override
+ public void report(Long id) {
+ MbtiRecordDTO mbtiRecordDto = this.findById(id);
+ if (Objects.isNull(mbtiRecordDto)) {
+ return;
+ }
+ AlitaResult queryRes = mbtiProvider.http(OrderQueryReq.builder().liangbiaoId(mbtiRecordDto.getLiangBiaoId()).orderId(mbtiRecordDto.getOrderId()).build());
+ Assert.isTrue(queryRes.getSuccess(),queryRes.getMsg());
+
+ AlitaResult reportRes = mbtiProvider.http(ReportReq.builder().liangbiaoId(mbtiRecordDto.getLiangBiaoId()).reportId(queryRes.getData().getReportId()).build());
+ Assert.isTrue(reportRes.getSuccess(),reportRes.getMsg());
+
+ MbtiRecord mbtiRecord = MbtiRecordConvert.INSTANCE.convert(mbtiRecordDto);
+ mbtiRecord.setReportId(queryRes.getData().getReportId());
+ mbtiRecord.setReportStatus(MbtiRecordReportStatusEnum.SUCCESS.getStatus());
+ mbtiRecord.setContent(reportRes.getData().getContent());
+ mbtiRecordMapper.updateEntitySelective(mbtiRecord);
+ }
+
+ @Override
+ public MbtiRecordDTO delete(Long id) {
+ MbtiRecordDTO mbtiRecordDto = this.findById(id);
+ if (Objects.isNull(mbtiRecordDto)) {
+ return null;
+ }
+ MbtiRecord mbtiRecord = MbtiRecord.builder().build();
+ mbtiRecord.setId(id);
+ mbtiRecordMapper.deleteEntity(mbtiRecord, UserContextHolder.getLoginUserId());
+ return mbtiRecordDto;
+ }
+
+ @Override
+ public MbtiRecordDTO findById(Long id) {
+ MbtiRecord mbtiRecord = mbtiRecordMapper.getById(id);
+ if (Objects.isNull(mbtiRecord)) {
+ return null;
+ }
+ return MbtiRecordConvert.INSTANCE.convert(mbtiRecord);
+ }
+
+ @Override
+ public List list(MbtiRecordQueryDTO queryDTO) {
+ return mbtiRecordMapper.list(queryDTO);
+ }
+
+ @Override
+ public List page(MbtiRecordPageQueryDTO queryDTO) {
+ queryDTO.setUserId(UserContextHolder.getExistLoginUserId());
+ return mbtiRecordMapper.page(queryDTO);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/ai/resume/controller/AiResumeController.java b/src/main/java/com/newyetai/ai/resume/controller/AiResumeController.java
new file mode 100644
index 0000000..2d0eb61
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/resume/controller/AiResumeController.java
@@ -0,0 +1,73 @@
+package com.newyetai.ai.resume.controller;
+
+import com.newyetai.ai.resume.dto.AiResumeReqDTO;
+import com.newyetai.ai.resume.service.AiResumeService;
+import com.newyetai.common.AlitaResult;
+import com.newyetai.sdk.xf.util.XfUtils;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+import cn.hutool.json.JSONUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * @description:
+ * @author: guixinman
+ * @create: 2024-12-12 10:03
+ **/
+@Api(tags = "AI简历")
+@RestController
+@RequestMapping("/ai/resume")
+public class AiResumeController {
+
+ @Autowired
+ private AiResumeService aiResumeService;
+
+ @PostMapping("/create")
+ @ApiOperation("ai简历-创建")
+ public AlitaResult create(@RequestBody @Validated AiResumeReqDTO reqDto) {
+ aiResumeService.create(reqDto);
+ return AlitaResult.success();
+ }
+
+ @PostMapping("/iat")
+ @ApiOperation("ai简历-语音听写")
+ public AlitaResult iat(@RequestParam("fileCode") String fileCode) {
+ return AlitaResult.success(XfUtils.iat(fileCode));
+ }
+
+ @PostMapping("/tts")
+ @ApiOperation("ai简历-语音合成")
+ public AlitaResult tts(@RequestParam("text") String text) {
+ return AlitaResult.success(XfUtils.tts(text));
+ }
+
+ @PostMapping("/analyseResume")
+ @ApiOperation("分析简历")
+ public AlitaResult analyseResume(@RequestParam("text") String text) {
+ return AlitaResult.success(XfUtils.analyseResume(text));
+ }
+
+ @PostMapping("/generateSelfEvaluate")
+ @ApiOperation("生成自我评价")
+ public AlitaResult generateSelfEvaluate(@RequestBody Map map) {
+ return AlitaResult.success(XfUtils.generateSelfEvaluate(JSONUtil.toJsonStr(map)));
+ }
+
+ @PostMapping("/generateWorkExperience")
+ @ApiOperation("生成工作经历")
+ public AlitaResult generateWorkExperience(@RequestBody Map map) {
+ return AlitaResult.success(XfUtils.generateWorkExperience(JSONUtil.toJsonStr(map)));
+ }
+
+}
diff --git a/src/main/java/com/newyetai/ai/resume/dto/AiResumeReqDTO.java b/src/main/java/com/newyetai/ai/resume/dto/AiResumeReqDTO.java
new file mode 100644
index 0000000..190d087
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/resume/dto/AiResumeReqDTO.java
@@ -0,0 +1,43 @@
+package com.newyetai.ai.resume.dto;
+
+import com.newyetai.common.validation.Create;
+import com.newyetai.common.validation.Update;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @description:
+ * @author: guixinman
+ * @create: 2024-12-12 10:07
+ **/
+@ApiModel("ai面试记录")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class AiResumeReqDTO implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @NotBlank(message = "请输入内容")
+ private String content;
+
+ @ApiModelProperty("岗位类型")
+ private String typeCode;
+
+ @ApiModelProperty("期望城市")
+ private String expectCity;
+
+ @ApiModelProperty("期望月薪")
+ private BigDecimal expectSalary;
+}
diff --git a/src/main/java/com/newyetai/ai/resume/model/AiResumeModel.java b/src/main/java/com/newyetai/ai/resume/model/AiResumeModel.java
new file mode 100644
index 0000000..031d46c
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/resume/model/AiResumeModel.java
@@ -0,0 +1,44 @@
+package com.newyetai.ai.resume.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @description: Ai生成简历返回model
+ * @author: guixinman
+ * @create: 2024-12-12 11:31
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class AiResumeModel implements Serializable {
+
+ private String name;
+ private String birthday;
+ @ApiModelProperty("期望工作地")
+ private String desiredWorkLocation;
+ @ApiModelProperty("期望最低薪资")
+ private String desiredSalaryMin;
+ @ApiModelProperty("期望最高薪资")
+ private String desiredSalaryMax;
+ @ApiModelProperty("期望岗位性质")
+ private String desiredPositionNature;
+ @ApiModelProperty("期望岗位")
+ private String desiredPosition;
+ @ApiModelProperty("最高学历")
+ private String highestDegree;
+ @ApiModelProperty("到岗状态")
+ private String reportStatus;
+ @ApiModelProperty("自我介绍")
+ private String selfIntroduction;
+// @ApiModelProperty("简历标签")
+// private String tags;
+
+}
diff --git a/src/main/java/com/newyetai/ai/resume/service/AiResumeService.java b/src/main/java/com/newyetai/ai/resume/service/AiResumeService.java
new file mode 100644
index 0000000..3fc002c
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/resume/service/AiResumeService.java
@@ -0,0 +1,14 @@
+package com.newyetai.ai.resume.service;
+
+import com.newyetai.ai.resume.dto.AiResumeReqDTO;
+
+/**
+ * @description:
+ * @author: guixinman
+ * @create: 2024-12-12 10:57
+ **/
+public interface AiResumeService {
+
+ void create(AiResumeReqDTO reqDto);
+
+}
diff --git a/src/main/java/com/newyetai/ai/resume/service/impl/AiResumeServiceImpl.java b/src/main/java/com/newyetai/ai/resume/service/impl/AiResumeServiceImpl.java
new file mode 100644
index 0000000..5a0b80a
--- /dev/null
+++ b/src/main/java/com/newyetai/ai/resume/service/impl/AiResumeServiceImpl.java
@@ -0,0 +1,99 @@
+package com.newyetai.ai.resume.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.newyetai.ai.resume.dto.AiResumeReqDTO;
+import com.newyetai.ai.resume.model.AiResumeModel;
+import com.newyetai.ai.resume.service.AiResumeService;
+import com.newyetai.common.constant.CommonConstants;
+import com.newyetai.common.exception.BusinessException;
+import com.newyetai.common.util.JsonUtils;
+import com.newyetai.common.util.UserContextHolder;
+import com.newyetai.component.dict.util.DictUtils;
+import com.newyetai.config.service.ConfigService;
+import com.newyetai.recruit.position.dao.PositionTypeMapper;
+import com.newyetai.recruit.position.entity.PositionType;
+import com.newyetai.recruit.user.dao.JobExpectMapper;
+import com.newyetai.recruit.user.dao.ResumeMapper;
+import com.newyetai.recruit.user.dto.JobExpectOperateDTO;
+import com.newyetai.recruit.user.dto.ResumeDTO;
+import com.newyetai.recruit.user.dto.ResumeOperatorDTO;
+import com.newyetai.recruit.user.entity.Resume;
+import com.newyetai.recruit.user.enums.InductionCycleEnum;
+import com.newyetai.recruit.user.service.JobExpectService;
+import com.newyetai.recruit.user.service.ResumeService;
+import com.newyetai.sdk.xf.util.XfUtils;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Objects;
+
+import javax.annotation.Resource;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @description:
+ * @author: guixinman
+ * @create: 2024-12-12 10:57
+ **/
+@Slf4j
+@Service
+public class AiResumeServiceImpl implements AiResumeService {
+
+ @Autowired
+ private ConfigService configService;
+ @Autowired
+ private ResumeService resumeService;
+ @Resource
+ private ResumeMapper resumeMapper;
+
+ @Autowired
+ private JobExpectService jobExpectService;
+
+ @Autowired
+ private PositionTypeMapper positionTypeMapper;
+
+
+ @Transactional(rollbackFor = Exception.class)
+ @Override
+ public void create(AiResumeReqDTO reqDto) {
+ String errMsg = "抱歉,我无法回答,请告诉我你想找什么样的工作";
+ try {
+ String jsonData = XfUtils.generateResume(reqDto.getContent());
+ if (StringUtils.equalsAny(jsonData, errMsg)) {
+ throw new BusinessException(jsonData);
+ }
+ AiResumeModel aiResumeModel = JsonUtils.toObject(jsonData, AiResumeModel.class);
+
+ if (StringUtils.isBlank(aiResumeModel.getDesiredPosition())) {
+ throw new BusinessException(errMsg);
+ }
+ //学历
+ String education = DictUtils.getNameCodeMap("education").get(StringUtils.isNotBlank(aiResumeModel.getHighestDegree()) ? aiResumeModel.getHighestDegree() : "");
+
+ jobExpectService.removeByUserId();
+ jobExpectService.create(
+ JobExpectOperateDTO.builder()
+ .userId(UserContextHolder.getExistLoginUserId())
+ .typeCode(reqDto.getTypeCode())
+ .expectCity(reqDto.getExpectCity())
+ .expectSalary(reqDto.getExpectSalary())
+ .onDuty(false)
+ .inductionCycle(InductionCycleEnum.findTypeByDesc(aiResumeModel.getReportStatus()))
+ .positionName(aiResumeModel.getDesiredPosition())
+ .build());
+
+ } catch (Exception e) {
+ log.error(e.getMessage());
+ throw new BusinessException(errMsg);
+ }
+ }
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/common/mq/constant/ForwardMqConstants.java b/src/main/java/com/newyetai/alitaforward/common/mq/constant/ForwardMqConstants.java
new file mode 100644
index 0000000..594f78e
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/common/mq/constant/ForwardMqConstants.java
@@ -0,0 +1,15 @@
+package com.newyetai.alitaforward.common.mq.constant;
+
+import com.newyetai.common.constant.CommonConstants;
+import com.newyetai.common.constant.SystemCodeEnum;
+
+/**
+ * mq常量类(routingkey)
+ * @author sr on 2021-08-09
+ */
+public interface ForwardMqConstants {
+
+ /** 用户中心系统mq前缀 **/
+ String MQ_PREFIX = SystemCodeEnum.ALITA_FORWARD.getName() + CommonConstants.POINT;
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/constants/FactorVerificationSourceTypeEnum.java b/src/main/java/com/newyetai/alitaforward/verification/constants/FactorVerificationSourceTypeEnum.java
new file mode 100644
index 0000000..df4dd76
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/constants/FactorVerificationSourceTypeEnum.java
@@ -0,0 +1,29 @@
+package com.newyetai.alitaforward.verification.constants;
+
+/**
+ * @author czy
+ * @date 2021-06-21
+ */
+public enum FactorVerificationSourceTypeEnum {
+
+ FXQ("放心签", 1),
+ CL("创蓝", 2),
+ SYS("系统", 3);
+
+ private final String desc;
+
+ private final Integer type;
+
+ FactorVerificationSourceTypeEnum(String desc, Integer type) {
+ this.desc = desc;
+ this.type = type;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public Integer getType() {
+ return type;
+ }
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/constants/VerificationTypeEnum.java b/src/main/java/com/newyetai/alitaforward/verification/constants/VerificationTypeEnum.java
new file mode 100644
index 0000000..6882019
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/constants/VerificationTypeEnum.java
@@ -0,0 +1,33 @@
+package com.newyetai.alitaforward.verification.constants;
+
+import com.newyetai.alitaforward.common.mq.constant.ForwardMqConstants;
+
+public enum VerificationTypeEnum {
+
+ /** 二要素认证 */
+ TWO("real_name_two_verification"),
+ /** 银行卡三要素认证 */
+ THREE("three_verification"),
+ /** 手机三要素认证 **/
+ PHONE_THREE("phone_three_verification"),
+ /** 银行卡四要素认证 **/
+ FOUR("four_verification");
+
+ private String fullname;
+ VerificationTypeEnum(String fullname){
+ this.fullname = fullname;
+ }
+
+ public String getFullName() {
+ return this.fullname;
+ }
+
+ public String getAsyncKey() {
+ return ForwardMqConstants.MQ_PREFIX + this.fullname ;
+ }
+
+ public String getStatusChangeKey() {
+ return getAsyncKey() + "_status_update";
+ }
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/consumer/providers/SystemFourFactorVerificationProvider.java b/src/main/java/com/newyetai/alitaforward/verification/consumer/providers/SystemFourFactorVerificationProvider.java
new file mode 100644
index 0000000..30c7930
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/consumer/providers/SystemFourFactorVerificationProvider.java
@@ -0,0 +1,64 @@
+package com.newyetai.alitaforward.verification.consumer.providers;
+
+import cn.hutool.json.JSONUtil;
+import com.newyetai.alitaforward.verification.dto.FourFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.PhoneThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.ThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.PhoneThreeVerify;
+import com.newyetai.alitaforward.verification.factor.ThreeVerify;
+import com.newyetai.alitaforward.verification.service.FourFactorVerificationProvider;
+import com.newyetai.common.constant.AuthStatusEnum;
+import com.newyetai.mq.dto.TopicMqMessage;
+import com.newyetai.usercenter.user.consumer.FourFactorVerifyStatusUpdateHandler;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+public class SystemFourFactorVerificationProvider implements FourFactorVerificationProvider {
+ @Autowired
+ private FourFactorVerifyStatusUpdateHandler fourFactorVerifyStatusUpdateHandler;
+
+
+ @Override
+ public void onMessage(TopicMqMessage message) {
+ log.info("系统手机号四要素处理->生成三要素数据 开始,参数:{}", JSONUtil.toJsonStr(message));
+ FourFactorVerificationDTO verificationDTO = message.getData();
+ Integer status = verificationDTO.getStatus();
+ if (!AuthStatusEnum.AUTH_SUCCESS.getType().equals(status)) {
+ return;
+ }
+ fourFactorVerifyStatusUpdateHandler.onMessage(verificationDTO);
+ try {
+ ThreeFactorVerificationDTO threeFactorVerificationDTO = ThreeFactorVerificationDTO.builder()
+ .realName(verificationDTO.getRealName())
+ .cardNo(verificationDTO.getCardNo())
+ .bankAccountNo(verificationDTO.getBankAccountNo())
+ .build();
+ threeFactorVerificationDTO.setStatus(verificationDTO.getStatus());
+ threeVerify.autoVerify(threeFactorVerificationDTO);
+ } catch (Exception e) {
+ log.info("系统手机号四要素处理->生成三要素数据 异常,", e);
+ }
+
+ try {
+ PhoneThreeFactorVerificationDTO phoneThreeFactorVerificationDTO = PhoneThreeFactorVerificationDTO.builder()
+ .realName(verificationDTO.getRealName())
+ .cardNo(verificationDTO.getCardNo())
+ .phone(verificationDTO.getPhone())
+ .build();
+ phoneThreeFactorVerificationDTO.setStatus(verificationDTO.getStatus());
+ phoneThreeVerify.autoVerify(phoneThreeFactorVerificationDTO);
+ } catch (Exception e) {
+ log.info("系统手机号四要素处理->生成手机三要素数据 异常,", e);
+ }
+ }
+
+ @Autowired
+ private PhoneThreeVerify phoneThreeVerify;
+
+ @Autowired
+ private ThreeVerify threeVerify;
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/consumer/providers/SystemPhoneThreeFactorVerificationProvider.java b/src/main/java/com/newyetai/alitaforward/verification/consumer/providers/SystemPhoneThreeFactorVerificationProvider.java
new file mode 100644
index 0000000..cf9c503
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/consumer/providers/SystemPhoneThreeFactorVerificationProvider.java
@@ -0,0 +1,46 @@
+package com.newyetai.alitaforward.verification.consumer.providers;
+
+import cn.hutool.json.JSONUtil;
+import com.newyetai.alitaforward.verification.dto.PhoneThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.RealNameTwoFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.RealNameTwoVerify;
+import com.newyetai.alitaforward.verification.service.PhoneThreeFactorVerificationProvider;
+import com.newyetai.common.constant.AuthStatusEnum;
+import com.newyetai.mq.dto.TopicMqMessage;
+import com.newyetai.usercenter.user.consumer.PhoneThreeFactorVerifyStatusUpdateHandler;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+public class SystemPhoneThreeFactorVerificationProvider implements PhoneThreeFactorVerificationProvider {
+
+ @Autowired
+ private RealNameTwoVerify realNameTwoVerify;
+
+ @Autowired
+ private PhoneThreeFactorVerifyStatusUpdateHandler phoneThreeFactorVerifyStatusUpdateHandler;
+
+ @Override
+ public void onMessage(TopicMqMessage message) {
+ log.info("系统手机号三要素成功处理->生成二要素数据 开始,参数:{}", JSONUtil.toJsonStr(message));
+ PhoneThreeFactorVerificationDTO verificationDTO = message.getData();
+ Integer status = verificationDTO.getStatus();
+ if (!AuthStatusEnum.AUTH_SUCCESS.getType().equals(status)) {
+ return;
+ }
+ phoneThreeFactorVerifyStatusUpdateHandler.onMessage(verificationDTO);
+ try {
+ RealNameTwoFactorVerificationDTO realNameTwoFactorVerificationDTO = RealNameTwoFactorVerificationDTO.builder()
+ .realName(verificationDTO.getRealName())
+ .cardNo(verificationDTO.getCardNo())
+ .build();
+ realNameTwoFactorVerificationDTO.setStatus(status);
+ realNameTwoVerify.autoVerify(realNameTwoFactorVerificationDTO);
+ } catch (Exception e) {
+ log.info("系统手机号三要素处理->生成二要素数据 异常,", e);
+ }
+ }
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/consumer/providers/SystemThreeFactorVerificationProvider.java b/src/main/java/com/newyetai/alitaforward/verification/consumer/providers/SystemThreeFactorVerificationProvider.java
new file mode 100644
index 0000000..6148582
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/consumer/providers/SystemThreeFactorVerificationProvider.java
@@ -0,0 +1,46 @@
+package com.newyetai.alitaforward.verification.consumer.providers;
+
+import cn.hutool.json.JSONUtil;
+import com.newyetai.alitaforward.verification.dto.RealNameTwoFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.ThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.RealNameTwoVerify;
+import com.newyetai.alitaforward.verification.service.ThreeFactorVerificationProvider;
+import com.newyetai.common.constant.AuthStatusEnum;
+import com.newyetai.mq.dto.TopicMqMessage;
+import com.newyetai.usercenter.user.consumer.ThreeFactorVerifyStatusUpdateHandler;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+public class SystemThreeFactorVerificationProvider implements ThreeFactorVerificationProvider {
+
+ @Autowired
+ private RealNameTwoVerify realNameTwoVerify;
+
+ @Autowired
+ private ThreeFactorVerifyStatusUpdateHandler threeFactorVerifyStatusUpdateHandler;
+
+ @Override
+ public void onMessage(TopicMqMessage message) {
+ log.info("系统三要素成功处理->生成二要素数据 开始,参数:{}", JSONUtil.toJsonStr(message));
+ ThreeFactorVerificationDTO verificationDTO = message.getData();
+ Integer status = verificationDTO.getStatus();
+ if (!AuthStatusEnum.AUTH_SUCCESS.getType().equals(status)) {
+ return;
+ }
+ threeFactorVerifyStatusUpdateHandler.onMessage(verificationDTO);
+ try {
+ RealNameTwoFactorVerificationDTO realNameTwoFactorVerificationDTO = RealNameTwoFactorVerificationDTO.builder()
+ .realName(verificationDTO.getRealName())
+ .cardNo(verificationDTO.getCardNo())
+ .build();
+ realNameTwoFactorVerificationDTO.setStatus(verificationDTO.getStatus());
+ realNameTwoVerify.autoVerify(realNameTwoFactorVerificationDTO);
+ } catch (Exception e) {
+ log.info("系统三要素处理->生成二要素数据 异常,", e);
+ }
+ }
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/controller/FactorVerificationContorller.java b/src/main/java/com/newyetai/alitaforward/verification/controller/FactorVerificationContorller.java
new file mode 100644
index 0000000..953a899
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/controller/FactorVerificationContorller.java
@@ -0,0 +1,214 @@
+package com.newyetai.alitaforward.verification.controller;
+
+import com.newyetai.alitaforward.verification.dto.*;
+import com.newyetai.alitaforward.verification.factor.FourVerify;
+import com.newyetai.alitaforward.verification.factor.PhoneThreeVerify;
+import com.newyetai.alitaforward.verification.factor.RealNameTwoVerify;
+import com.newyetai.alitaforward.verification.factor.ThreeVerify;
+import com.newyetai.alitaforward.verification.service.BankCardVerificationService;
+import com.newyetai.common.AlitaResult;
+import com.newyetai.tkmybatis.pojo.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author czy
+ * @date 2021-06-21
+ */
+@Api("要素认证")
+@RestController
+@RequestMapping("factor_verify")
+public class FactorVerificationContorller {
+ @Autowired
+ private FourVerify fourVerify;
+
+ @Autowired
+ private BankCardVerificationService bankCardVerificationService;
+
+ @Autowired
+ private RealNameTwoVerify realNameTwoVerify;
+
+ @Autowired
+ private ThreeVerify threeVerify;
+
+ @Autowired
+ private PhoneThreeVerify phoneThreeVerify;
+
+ @ApiOperation("二要素认证(同步)")
+ @PostMapping("/real_name/two/sync")
+ public AlitaResult syncRealNameTwoAuthenticate(
+ @Validated @RequestBody RealNameTwoFactorVerificationDTO verificationInfo) {
+ return AlitaResult.success(realNameTwoVerify.sync(verificationInfo));
+ }
+
+ @ApiOperation("二要素认证(批量、同步)")
+ @PostMapping("/real_name/two/sync/batch")
+ public AlitaResult> syncRealNameTwoAuthenticate(
+ @Validated @RequestBody List verificationInfoList) {
+ return AlitaResult.success(realNameTwoVerify.sync(verificationInfoList));
+ }
+
+ @ApiOperation("二要素认证(异步)")
+ @PostMapping("/real_name/two/async")
+ public AlitaResult asyncRealNameTwoAuthenticate(
+ @Validated @RequestBody RealNameTwoFactorVerificationDTO verificationInfo) {
+ return AlitaResult.success(realNameTwoVerify.async(verificationInfo));
+ }
+
+ @ApiOperation("二要素认证(批量、异步)")
+ @PostMapping("/real_name/two/async/batch")
+ public AlitaResult> asyncRealNameTwoAuthenticate(
+ @Validated @RequestBody List verificationInfoList) {
+ return AlitaResult.success(realNameTwoVerify.async(verificationInfoList));
+ }
+
+
+ @ApiOperation("手机三要素认证(同步)")
+ @PostMapping("/phone/three/sync")
+ public AlitaResult syncPhoneThreeAuthenticate(
+ @Validated @RequestBody PhoneThreeFactorVerificationDTO verificationInfo) {
+ return AlitaResult.success(phoneThreeVerify.sync(verificationInfo));
+ }
+
+ @ApiOperation("手机三要素认证(批量、同步)")
+ @PostMapping("/phone/three/sync/batch")
+ public AlitaResult> syncPhoneThreeAuthenticate(
+ @Validated @RequestBody List verificationInfoList) {
+ return AlitaResult.success(phoneThreeVerify.sync(verificationInfoList));
+ }
+
+ @ApiOperation("手机三要素认证(异步)")
+ @PostMapping("/phone/three/async")
+ public AlitaResult asyncPhoneThreeAuthenticate(
+ @Validated @RequestBody PhoneThreeFactorVerificationDTO verificationInfo) {
+ return AlitaResult.success(phoneThreeVerify.async(verificationInfo));
+ }
+
+ @ApiOperation("手机三要素认证(批量、异步)")
+ @PostMapping("/phone/three/async/batch")
+ public AlitaResult> asyncPhoneThreeAuthenticate(
+ @Validated @RequestBody List verificationInfoList) {
+ return AlitaResult.success(phoneThreeVerify.async(verificationInfoList));
+ }
+
+ @ApiOperation("三要素认证(同步)")
+ @PostMapping("/three/sync")
+ public AlitaResult syncThreeAuthenticate(
+ @Validated @RequestBody ThreeFactorVerificationDTO verificationInfo) {
+ return AlitaResult.success(threeVerify.sync(verificationInfo));
+ }
+
+ @ApiOperation("三要素认证(批量、同步)")
+ @PostMapping("/three/sync/batch")
+ public AlitaResult> syncThreeAuthenticate(
+ @Validated @RequestBody List verificationInfoList) {
+ return AlitaResult.success(threeVerify.sync(verificationInfoList));
+ }
+
+ @ApiOperation("三要素认证(异步)")
+ @PostMapping("/three/async")
+ public AlitaResult asyncThreeAuthenticate(
+ @Validated @RequestBody ThreeFactorVerificationDTO verificationInfo) {
+ return AlitaResult.success(threeVerify.async(verificationInfo));
+ }
+
+ @ApiOperation("三要素认证(批量、异步)")
+ @PostMapping("/three/async/batch")
+ public AlitaResult> asyncThreeAuthenticate(
+ @Validated @RequestBody List verificationInfoList) {
+ return AlitaResult.success(threeVerify.async(verificationInfoList));
+ }
+
+ @ApiOperation("获取匹配请求内容的三要素认证数据")
+ @PostMapping("/match_three/list")
+ public AlitaResult> queryMatchThreeList(@RequestBody List queryDtoList){
+ return AlitaResult.success(threeVerify.queryListByData(queryDtoList));
+ };
+
+ @ApiOperation("三要素认证根据id获取")
+ @PostMapping("/three/find/id")
+ public AlitaResult threeFindById(@RequestParam("id") Long id){
+ return AlitaResult.success(threeVerify.findById(id));
+ };
+
+ @ApiOperation("三要素认证根据查询条件获取列表")
+ @PostMapping("/three/list")
+ public AlitaResult> threeList(@RequestBody FactorVerificationQueryDTO query){
+ query.setNeedPage(Boolean.FALSE);
+ return AlitaResult.success(threeVerify.list(query));
+ };
+
+ @ApiOperation("三要素认证根据查询条件获取列表(分页)")
+ @PostMapping("/three/page")
+ public AlitaResult> threePage(@RequestBody FactorVerificationQueryDTO query){
+ threeVerify.list(query);
+ return AlitaResult.success(query.getPageResult());
+ };
+
+ @ApiOperation("四要素认证(同步)")
+ @PostMapping("/four/sync")
+ public AlitaResult syncFourAuthenticate(
+ @Validated @RequestBody FourFactorVerificationDTO verificationInfoList) {
+ return AlitaResult.success(fourVerify.sync(verificationInfoList));
+ }
+
+ @ApiOperation("四要素认证(批量、同步)")
+ @PostMapping("/four/sync/batch")
+ public AlitaResult> syncFourAuthenticate(
+ @Validated @RequestBody List verificationInfoList) {
+ return AlitaResult.success(fourVerify.sync(verificationInfoList));
+ }
+
+ @ApiOperation("四要素认证(异步)")
+ @PostMapping("/four/async")
+ public AlitaResult asyncFourAuthenticate(
+ @Validated @RequestBody FourFactorVerificationDTO verificationInfoList) {
+ return AlitaResult.success(fourVerify.async(verificationInfoList));
+ }
+
+ @ApiOperation("四要素认证(批量、异步)")
+ @PostMapping("/four/async/batch")
+ public AlitaResult> asyncFourAuthenticate(
+ @Validated @RequestBody List verificationInfoList) {
+ return AlitaResult.success(fourVerify.async(verificationInfoList));
+ }
+
+ @ApiOperation("四要素认证根据id获取")
+ @PostMapping("/four/find/id")
+ public AlitaResult fourFindById(@RequestParam("id") Long id){
+ return AlitaResult.success(fourVerify.findById(id));
+ };
+
+ @ApiOperation("获取匹配请求内容的四要素认证数据")
+ @PostMapping("/match_four/list")
+ public AlitaResult> queryMatchFourList(@RequestBody List queryDtoList){
+ return AlitaResult.success(fourVerify.queryListByData(queryDtoList));
+ };
+
+ @ApiOperation("四要素认证根据查询条件获取列表")
+ @PostMapping("/four/list")
+ public AlitaResult> fourList(@RequestBody FactorVerificationQueryDTO query){
+ query.setNeedPage(Boolean.FALSE);
+ return AlitaResult.success(fourVerify.list(query));
+ };
+
+ @ApiOperation("四要素认证根据查询条件获取列表(分页)")
+ @PostMapping("/four/page")
+ public AlitaResult> fourPage(@RequestBody FactorVerificationQueryDTO query){
+ fourVerify.list(query);
+ return AlitaResult.success(query.getPageResult());
+ };
+
+
+ @ApiOperation("白名单管理-->三、四要素查询合并为银行卡查询")
+ @PostMapping("/bank_card/page")
+ AlitaResult> bankCardPage(String cardNo,Integer status){
+ return AlitaResult.success(bankCardVerificationService.list(cardNo, status));
+ }
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/dao/BankCardVerificationMapper.java b/src/main/java/com/newyetai/alitaforward/verification/dao/BankCardVerificationMapper.java
new file mode 100644
index 0000000..4f8b194
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/dao/BankCardVerificationMapper.java
@@ -0,0 +1,36 @@
+package com.newyetai.alitaforward.verification.dao;
+
+import com.newyetai.alitaforward.verification.dto.BankCordVerificationResDTO;
+import com.newyetai.alitaforward.verification.factor.four.entity.BankCardFourVerification;
+import com.newyetai.tkmybatis.mybatis.MyMapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ * @author fzp
+ * @date 2021年9月6日13:42:17
+ */
+public interface BankCardVerificationMapper{
+
+ /**
+ * 白名单管理-->三、四要素查询合并为银行卡查询
+ * @param cardNo
+ */
+ @Select("select "
+ + " t.id,t.card_no,t.real_name,t.bank_account_no,'' as phone,'三要素' as `type`, "
+ + " (case t.authentication_source when '1' then '放心签' when '2' then '创蓝' when '3' then '系统' else '' end) as source, "
+ + " t.status,t.fail_reason,t.deleted "
+ + "from bank_card_three_verification t "
+ + "where t.deleted = 0 and t.card_no = #{cardNo} "
+ + "union all "
+ + "select "
+ + " f.id,f.card_no,f.real_name,f.bank_account_no,f.phone,'四要素' as `type`, "
+ + " (case f.authentication_source when '1' then '放心签' when '2' then '创蓝' when '3' then '系统' else '' end) as source, "
+ + " f.status,f.fail_reason,f.deleted "
+ + "from bank_card_four_verification f "
+ + "where f.deleted = 0 and f.card_no = #{cardNo} ")
+ List list(@Param("cardNo") String cardNo);
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/dto/BankCordVerificationResDTO.java b/src/main/java/com/newyetai/alitaforward/verification/dto/BankCordVerificationResDTO.java
new file mode 100644
index 0000000..57c4bf3
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/dto/BankCordVerificationResDTO.java
@@ -0,0 +1,47 @@
+package com.newyetai.alitaforward.verification.dto;
+
+import com.newyetai.common.dto.BaseDTO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author fzp
+ * @date 三、四要素合并银行卡查询
+ */
+@ApiModel("三、四要素合并银行卡查询")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BankCordVerificationResDTO extends BaseDTO {
+
+ private static final long serialVersionUID = 4820612112161649806L;
+ @ApiModelProperty("姓名")
+ private String realName;
+
+ @ApiModelProperty("证件号")
+ private String cardNo;
+
+ @ApiModelProperty("银行卡号")
+ private String bankAccountNo;
+
+ @ApiModelProperty("手机号")
+ private String phone;
+
+ @ApiModelProperty("要素类型")
+ private String type;
+
+ @ApiModelProperty("认证来源 1系统,2放心签,3创蓝")
+ private String source;
+
+ @ApiModelProperty("认证状态(1-未认证 2-认证中 3-认证成功 4-认证失败)")
+ private Integer status;
+
+ @ApiModelProperty("失败原因")
+ private String failReason;
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/dto/FactorVerificationDTO.java b/src/main/java/com/newyetai/alitaforward/verification/dto/FactorVerificationDTO.java
new file mode 100644
index 0000000..9332a5d
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/dto/FactorVerificationDTO.java
@@ -0,0 +1,37 @@
+package com.newyetai.alitaforward.verification.dto;
+
+import com.newyetai.common.dto.BaseDTO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * @author czy
+ * @date 2021-06-17
+ */
+@ApiModel("要素认证DTO")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@SuperBuilder
+public class FactorVerificationDTO extends BaseDTO {
+
+ private static final long serialVersionUID = 2838128328843902963L;
+ @ApiModelProperty("认证状态(1-未认证 2-认证中 3-认证成功 4-认证失败)")
+ private Integer status;
+
+ @ApiModelProperty("认证来源")
+ private Integer authenticationSource;
+
+ @ApiModelProperty("调用数据")
+ private String invokeData;
+
+ @ApiModelProperty("失败原因")
+ private String failReason;
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/dto/FactorVerificationQueryDTO.java b/src/main/java/com/newyetai/alitaforward/verification/dto/FactorVerificationQueryDTO.java
new file mode 100644
index 0000000..0fd2e6e
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/dto/FactorVerificationQueryDTO.java
@@ -0,0 +1,47 @@
+package com.newyetai.alitaforward.verification.dto;
+
+import com.newyetai.common.annotation.trimAndUpper.TrimAndUpper;
+import com.newyetai.common.dto.PageQueryDTO;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+
+import java.util.Set;
+
+/**
+ * @author czy
+ * @date 2021-07-01
+ */
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class FactorVerificationQueryDTO extends PageQueryDTO {
+
+ private static final long serialVersionUID = -2357416347060650749L;
+
+ private Long id;
+
+ private Set ids;
+
+ @ApiModelProperty("姓名")
+ @TrimAndUpper
+ private String realName;
+
+ @ApiModelProperty("证件号")
+ @TrimAndUpper
+ private String cardNo;
+
+ @ApiModelProperty("银行卡号")
+ @TrimAndUpper
+ private String bankAccountNo;
+
+ @ApiModelProperty("手机号")
+ @TrimAndUpper
+ private String phone;
+
+ @ApiModelProperty("认证状态(1-未认证 2-认证中 3-认证成功 4-认证失败)")
+ private Integer status;
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/dto/FourFactorVerificationDTO.java b/src/main/java/com/newyetai/alitaforward/verification/dto/FourFactorVerificationDTO.java
new file mode 100644
index 0000000..1891f30
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/dto/FourFactorVerificationDTO.java
@@ -0,0 +1,45 @@
+package com.newyetai.alitaforward.verification.dto;
+
+import com.newyetai.common.annotation.trimAndUpper.TrimAndUpper;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author czy
+ * @date 2021-06-17
+ */
+@ApiModel("四要素认证DTO")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class FourFactorVerificationDTO extends FactorVerificationDTO {
+
+ private static final long serialVersionUID = -5514764157174505641L;
+ @ApiModelProperty("姓名")
+ @NotBlank(message = "姓名不能为空")
+ @TrimAndUpper
+ private String realName;
+
+ @ApiModelProperty("证件号")
+ @NotBlank(message = "证件号不能为空")
+ @TrimAndUpper
+ private String cardNo;
+
+ @ApiModelProperty("银行卡号")
+ @NotBlank(message = "银行卡号不能为空")
+ @TrimAndUpper
+ private String bankAccountNo;
+
+ @ApiModelProperty("手机号")
+ @NotBlank(message = "手机号不能为空")
+ @TrimAndUpper
+ private String phone;
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/dto/PhoneThreeFactorVerificationDTO.java b/src/main/java/com/newyetai/alitaforward/verification/dto/PhoneThreeFactorVerificationDTO.java
new file mode 100644
index 0000000..dfcd61b
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/dto/PhoneThreeFactorVerificationDTO.java
@@ -0,0 +1,40 @@
+package com.newyetai.alitaforward.verification.dto;
+
+import com.newyetai.common.annotation.trimAndUpper.TrimAndUpper;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.SuperBuilder;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author czy
+ * @date 2021-06-17
+ */
+@EqualsAndHashCode(callSuper = true)
+@ApiModel("手机号三要素认证DTO")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@SuperBuilder
+public class PhoneThreeFactorVerificationDTO extends FactorVerificationDTO {
+
+
+ private static final long serialVersionUID = 1594482919800883278L;
+ @ApiModelProperty("姓名")
+ @NotBlank(message = "姓名不能为空")
+ @TrimAndUpper
+ private String realName;
+
+ @ApiModelProperty("证件号")
+ @NotBlank(message = "证件号不能为空")
+ @TrimAndUpper
+ private String cardNo;
+
+ @ApiModelProperty("手机号")
+ @NotBlank(message = "手机号不能为空")
+ @TrimAndUpper
+ private String phone;
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/dto/RealNameTwoFactorVerificationDTO.java b/src/main/java/com/newyetai/alitaforward/verification/dto/RealNameTwoFactorVerificationDTO.java
new file mode 100644
index 0000000..14865e7
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/dto/RealNameTwoFactorVerificationDTO.java
@@ -0,0 +1,35 @@
+package com.newyetai.alitaforward.verification.dto;
+
+import com.newyetai.common.annotation.trimAndUpper.TrimAndUpper;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.SuperBuilder;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 二要素认证DTO
+ *
+ * @author Administrator
+ * @date 2022/07/22
+ */
+@ApiModel("二要素认证DTO")
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class RealNameTwoFactorVerificationDTO extends FactorVerificationDTO {
+
+ private static final long serialVersionUID = -2114148883543603016L;
+ @ApiModelProperty("姓名")
+ @NotBlank(message = "姓名不能为空")
+ @TrimAndUpper
+ private String realName;
+
+ @ApiModelProperty("证件号")
+ @NotBlank(message = "证件号不能为空")
+ @TrimAndUpper
+ private String cardNo;
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/dto/ThreeFactorVerificationDTO.java b/src/main/java/com/newyetai/alitaforward/verification/dto/ThreeFactorVerificationDTO.java
new file mode 100644
index 0000000..106d7bd
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/dto/ThreeFactorVerificationDTO.java
@@ -0,0 +1,39 @@
+package com.newyetai.alitaforward.verification.dto;
+
+import com.newyetai.common.annotation.trimAndUpper.TrimAndUpper;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.SuperBuilder;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author czy
+ * @date 2021-06-17
+ */
+@ApiModel("三要素认证DTO")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@SuperBuilder
+@EqualsAndHashCode(callSuper = true)
+public class ThreeFactorVerificationDTO extends FactorVerificationDTO {
+
+ private static final long serialVersionUID = 656164023756231640L;
+ @ApiModelProperty("姓名")
+ @NotBlank(message = "姓名不能为空")
+ @TrimAndUpper
+ private String realName;
+
+ @ApiModelProperty("证件号")
+ @NotBlank(message = "证件号不能为空")
+ @TrimAndUpper
+ private String cardNo;
+
+ @ApiModelProperty("银行卡号")
+ @NotBlank(message = "银行卡号不能为空")
+ @TrimAndUpper
+ private String bankAccountNo;
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/AbstractVerify.java b/src/main/java/com/newyetai/alitaforward/verification/factor/AbstractVerify.java
new file mode 100644
index 0000000..a2db1aa
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/AbstractVerify.java
@@ -0,0 +1,240 @@
+package com.newyetai.alitaforward.verification.factor;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.aop.framework.AopContext;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.newyetai.alitaforward.verification.constants.FactorVerificationSourceTypeEnum;
+import com.newyetai.alitaforward.verification.dto.FactorVerificationDTO;
+import com.newyetai.alitaforward.verification.source.FactorVerificationSourceService;
+import com.newyetai.common.constant.AuthStatusEnum;
+import com.newyetai.common.exception.util.Assert;
+import com.newyetai.common.util.EnvironmentUtils;
+import com.newyetai.common.util.JsonUtils;
+import com.newyetai.frame.redis.dto.LockDTO;
+import com.newyetai.frame.redis.redisson.RedissonUtils;
+import com.newyetai.mq.consumer.handler.ITopicMqHandler;
+import com.newyetai.mq.dto.TopicMqMessage;
+import com.newyetai.mq.util.MqSendUtils;
+
+import cn.hutool.json.JSONUtil;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 要素校验顶层接口
+ *
+ * @author cheny
+ * @date 2022/08/11
+ */
+@Slf4j
+@Component
+@SuppressWarnings("rawtypes,unchecked")
+public abstract class AbstractVerify implements IVerify, ITopicMqHandler{
+
+ private static final Integer DEFAULT_TYPE = FactorVerificationSourceTypeEnum.CL.getType();
+
+ static final Map SOURCE_SERVICE_MAP = Maps.newConcurrentMap();
+
+ /**
+ * 终态通知key
+ * @return
+ * @author sr on 2023-11-27
+ */
+ final String statusChangeRoutingKey() {
+ return getType().getStatusChangeKey();
+ }
+
+
+ @Override
+ public final String getRoutingKey() {
+ return getType().getAsyncKey();
+ }
+
+ @Override
+ public final void onMessage(TopicMqMessage message) {
+ T verificationDTO = message.getData();
+ log.info("【MQ】异步处理认证开始,参数:{}", JsonUtils.toJsonString(verificationDTO));
+ if (verificationDTO == null) {
+ return;
+ }
+ try {
+ T sync = this.sync(verificationDTO);
+ log.info("【MQ】异步处理认证结束,参数:{}", JsonUtils.toJsonString(sync));
+ } catch (Exception e) {
+ log.info("【MQ】异步处理认证异常", e);
+ }
+ }
+
+ // 幂等创建
+ abstract T createAndGet(T t);
+
+ /**
+ * 得到锁
+ *
+ * @param t t
+ * @return {@link LockDTO}
+ */
+ abstract LockDTO getLock(T t);
+
+ // 上一级认证创建
+ abstract void autoVerify(T t);
+
+ /**
+ * 同步校验前置hook
+ *
+ * @param t t
+ * @return {@link T}
+ */
+ protected T syncBeforeVerify(T t) {
+ // 认证源根据配置文件不同调用不同SDK 1放心签、2创蓝
+ String source = EnvironmentUtils.getProperty("alita.authenticationSource");
+ int authenticationSource = DEFAULT_TYPE;
+ try {
+ authenticationSource = Integer.parseInt(source);
+ //如果不是这两种认证源,用默认的源
+ if (!(FactorVerificationSourceTypeEnum.CL.getType().equals(authenticationSource)
+ || FactorVerificationSourceTypeEnum.FXQ.getType().equals(authenticationSource))) {
+ authenticationSource = DEFAULT_TYPE;
+ }
+ } catch (NumberFormatException e) {
+ //doNothing
+ }
+ t.setAuthenticationSource(authenticationSource);
+ return t;
+ }
+
+ /**
+ * 真正执行校验逻辑的方法
+ *
+ * @param verifyDto 验证dto
+ * @return {@link T}
+ */
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
+ public T doSyncVerify(T verifyDto) {
+ String failReason = verifyDto.getFailReason();
+ //如果校验失败了 直接返回
+ if (StringUtils.isNotEmpty(failReason)) {
+ return verifyDto;
+ }
+ //拿锁
+ LockDTO lockDTO = getLock(verifyDto);
+ try {
+ Assert.isTrue(RedissonUtils.tryLock(lockDTO), "要素认证正在处理中,请稍后再试");
+ T preVerifyDto = createAndGet(verifyDto);
+ //如果不是待认证的数直接返回
+ if (!AuthStatusEnum.NOT_AUTH.getType().equals(preVerifyDto.getStatus())) {
+ return preVerifyDto;
+ }
+
+ return realVerification(preVerifyDto);
+ } finally {
+ RedissonUtils.unlock(lockDTO);
+ }
+ }
+
+ abstract T realVerification(T verificationDTO);
+
+ T syncVerifyWrapper(T t) {
+ T beforeVerify = syncBeforeVerify(t);
+
+ T doVerify = (T) ((AbstractVerify) AopContext.currentProxy()).doSyncVerify(beforeVerify);
+
+ Integer status = doVerify.getStatus();
+ //如果执行到了终态 发送消息通知
+ if (AuthStatusEnum.AUTH_FAIL.getType().equals(status)
+ || AuthStatusEnum.AUTH_SUCCESS.getType().equals(status)) {
+ log.info("【MQ】通知认证状态变更,参数:{}", JSONUtil.toJsonStr(doVerify));
+ MqSendUtils.send(statusChangeRoutingKey(), doVerify);
+ }
+ return doVerify;
+ }
+
+ /**
+ * 同步校验
+ *
+ * @param list 列表
+ * @return {@link List}<{@link T}>
+ */
+ @Override
+ public List sync(List list) {
+ if (CollectionUtils.isEmpty(list)) {
+ return Lists.newArrayList();
+ }
+ return list.stream().map(this::syncVerifyWrapper).collect(Collectors.toList());
+ }
+
+ // -------------------------------------------------------- async -------------------------------------------------------
+
+ /**
+ * 异步校验前置hook
+ *
+ * @param t t
+ * @return {@link T}
+ */
+ protected T asyncBeforeVerify(T t) {
+ return syncBeforeVerify(t);
+ }
+
+ /**
+ * 真正执行校验逻辑的方法
+ *
+ * @param verifyDto 验证dto
+ * @return {@link T}
+ */
+ protected T doAsyncVerify(T verifyDto) {
+ String failReason = verifyDto.getFailReason();
+ //如果校验失败了 直接返回
+ if (StringUtils.isNotEmpty(failReason)) {
+ return verifyDto;
+ }
+ //拿锁
+ LockDTO lockDTO = getLock(verifyDto);
+ try {
+ Assert.isTrue(RedissonUtils.tryLock(lockDTO), "要素认证正在处理中,请稍后再试");
+ T preVerifyDto = createAndGet(verifyDto);
+ //如果不是待认证的数直接返回
+ if (AuthStatusEnum.NOT_AUTH.getType().equals(preVerifyDto.getStatus())) {
+ //mq异步处理认证
+ log.info("async【MQ】要素认证异步处理,参数:{}", JSONUtil.toJsonStr(preVerifyDto));
+ MqSendUtils.send(getRoutingKey(), preVerifyDto);
+ }
+ return preVerifyDto;
+ } finally {
+ RedissonUtils.unlock(lockDTO);
+ }
+
+ }
+
+
+ T asyncVerifyWrapper(T t) {
+ T beforeVerify = asyncBeforeVerify(t);
+
+ T doVerify = doAsyncVerify(beforeVerify);
+
+ Integer status = doVerify.getStatus();
+ //如果执行到了终态 发送消息通知
+ if (AuthStatusEnum.AUTH_FAIL.getType().equals(status)
+ || AuthStatusEnum.AUTH_SUCCESS.getType().equals(status)) {
+ log.info("【MQ】通知认证状态变更,参数:{}", JSONUtil.toJsonStr(doVerify));
+ MqSendUtils.send(statusChangeRoutingKey(), doVerify);
+ }
+ return doVerify;
+ }
+
+ @Override
+ public List async(List list) {
+ if (CollectionUtils.isEmpty(list)) {
+ return Lists.newArrayList();
+ }
+ return list.stream().map(this::asyncVerifyWrapper).collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/FourVerify.java b/src/main/java/com/newyetai/alitaforward/verification/factor/FourVerify.java
new file mode 100644
index 0000000..2c7cf00
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/FourVerify.java
@@ -0,0 +1,176 @@
+package com.newyetai.alitaforward.verification.factor;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import com.google.common.collect.Lists;
+import com.newyetai.alitaforward.verification.constants.FactorVerificationSourceTypeEnum;
+import com.newyetai.alitaforward.verification.constants.VerificationTypeEnum;
+import com.newyetai.alitaforward.verification.dto.FactorVerificationQueryDTO;
+import com.newyetai.alitaforward.verification.dto.FourFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.four.dao.FourVerificationMapper;
+import com.newyetai.alitaforward.verification.factor.four.entity.BankCardFourVerification;
+import com.newyetai.alitaforward.verification.factor.four.mapstruct.FourVerificationMapMapper;
+import com.newyetai.common.constant.AuthStatusEnum;
+import com.newyetai.common.exception.util.Assert;
+import com.newyetai.common.util.UserContextHolder;
+import com.newyetai.common.validation.util.ValidateUtils;
+import com.newyetai.frame.redis.aop.annotation.AutoUnLock;
+import com.newyetai.frame.redis.dto.LockDTO;
+import com.newyetai.frame.redis.redisson.RedissonUtils;
+import com.newyetai.mq.util.MqSendUtils;
+
+import cn.hutool.json.JSONUtil;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Component
+public class FourVerify extends AbstractVerify implements IQueryVerify {
+
+ @Resource
+ private FourVerificationMapper fourVerificationMapper;
+
+ @Override
+ protected FourFactorVerificationDTO syncBeforeVerify(FourFactorVerificationDTO verificationDTO) {
+ StringJoiner stringJoiner = new StringJoiner("、");
+ if (!ValidateUtils.checkRealName(verificationDTO.getRealName())) {
+ stringJoiner.add("姓名格式有误");
+ }
+ if (!ValidateUtils.isIdCard(verificationDTO.getCardNo())) {
+ stringJoiner.add("证件号格式有误");
+ }
+ if (StringUtils.isBlank(verificationDTO.getBankAccountNo())) {
+ stringJoiner.add("银行卡号为空");
+ }
+ if (StringUtils.isBlank(verificationDTO.getPhone())) {
+ stringJoiner.add("手机号为空");
+ }
+ String failReason = stringJoiner.toString();
+ if (StringUtils.isNotBlank(failReason)) {
+ verificationDTO.setFailReason(failReason);
+ } else {
+ //校验成功调用
+ super.syncBeforeVerify(verificationDTO);
+ }
+ return verificationDTO;
+ }
+
+ @Override
+ FourFactorVerificationDTO createAndGet(FourFactorVerificationDTO verificationDTO) {
+ BankCardFourVerification bankCardFourVerification = fourVerificationMapper.selectInfo(verificationDTO);
+ if (bankCardFourVerification == null) {
+ //认证库不存在,以默认状态入库——"未认证"
+ verificationDTO.setStatus(AuthStatusEnum.NOT_AUTH.getType());
+ bankCardFourVerification = FourVerificationMapMapper.INSTANCE.toEntity(verificationDTO);
+ fourVerificationMapper.saveEntity(bankCardFourVerification);
+ }
+ return FourVerificationMapMapper.INSTANCE.toDto(bankCardFourVerification);
+ }
+
+ @Override
+ LockDTO getLock(FourFactorVerificationDTO verificationDTO) {
+ return LockDTO.builder().methodName("verify:four").tryLockWaitTime(0L)
+ .arg(verificationDTO.getRealName())
+ .arg(verificationDTO.getCardNo())
+ .arg(verificationDTO.getBankAccountNo())
+ .arg(verificationDTO.getPhone())
+ .build();
+ }
+
+ @Override
+ @AutoUnLock
+ public void autoVerify(FourFactorVerificationDTO verificationDTO) {
+ //拿锁
+ LockDTO lockDTO = getLock(verificationDTO);
+ Assert.isTrue(RedissonUtils.tryLockAutomatically(lockDTO), "请勿重复校验四要素");
+
+ BankCardFourVerification verificationEntity = fourVerificationMapper.selectInfo(verificationDTO);
+
+ if (Objects.nonNull(verificationEntity)) {
+ if (AuthStatusEnum.AUTH_SUCCESS.getType().equals(verificationEntity.getStatus())) {
+ return;
+ }
+ verificationEntity.setAuthenticationSource(FactorVerificationSourceTypeEnum.SYS.getType());
+ verificationEntity.setStatus(AuthStatusEnum.AUTH_SUCCESS.getType());
+ fourVerificationMapper.updateEntitySelective(verificationEntity,
+ UserContextHolder.getLoginUserId());
+ } else {
+ verificationEntity =
+ BankCardFourVerification.builder()
+ .realName(verificationDTO.getRealName())
+ .cardNo(verificationDTO.getCardNo())
+ .phone(verificationDTO.getPhone())
+ .bankAccountNo(verificationDTO.getBankAccountNo())
+ .authenticationSource(FactorVerificationSourceTypeEnum.SYS.getType())
+ .status(AuthStatusEnum.AUTH_SUCCESS.getType())
+ .build();
+ fourVerificationMapper.saveEntity(verificationEntity);
+ }
+ log.info("【MQ】通知认证状态变更,参数:{}", JSONUtil.toJsonStr(verificationDTO));
+ MqSendUtils.send(statusChangeRoutingKey(), verificationDTO);
+ }
+
+ @Override
+ public List list(FactorVerificationQueryDTO queryDTO) {
+ return fourVerificationMapper.list(queryDTO);
+ }
+
+ @Override
+ public List queryListByData(List queryDTOList) {
+ List resultList = Lists
+ .newArrayListWithCapacity(queryDTOList.size());
+ if (CollectionUtils.isEmpty(queryDTOList)) {
+ return resultList;
+ }
+ List bankCardThreeVerifications = fourVerificationMapper
+ .findFinishStatusData();
+ Map threeVerificationMap = bankCardThreeVerifications
+ .stream().collect(
+ Collectors.toMap(k -> k.getRealName() + k.getCardNo() + k.getBankAccountNo() + k.getPhone(), v -> v, (v1, v2) -> v1));
+
+ for (FactorVerificationQueryDTO queryDTO : queryDTOList) {
+ FourFactorVerificationDTO FourFactorVerificationDTO = threeVerificationMap
+ .get(queryDTO.getRealName() + queryDTO.getCardNo() + queryDTO.getBankAccountNo() + queryDTO
+ .getPhone());
+ if (FourFactorVerificationDTO != null) {
+ resultList.add(FourFactorVerificationDTO);
+ }
+ }
+ return resultList;
+ }
+
+ @Override
+ public FourFactorVerificationDTO findById(Long id) {
+ FourFactorVerificationDTO fourFactorVerificationDTO = null;
+ BankCardFourVerification entity = fourVerificationMapper.getById(id);
+ if (entity != null) {
+ fourFactorVerificationDTO = FourVerificationMapMapper.INSTANCE.toDto(entity);
+ }
+ return fourFactorVerificationDTO;
+ }
+
+ @Override
+ FourFactorVerificationDTO realVerification(FourFactorVerificationDTO verificationDTO) {
+ Integer authenticationSource = verificationDTO.getAuthenticationSource();
+ SOURCE_SERVICE_MAP.get(authenticationSource).fourVerify(verificationDTO);
+ //更新状态
+ BankCardFourVerification entity = FourVerificationMapMapper.INSTANCE
+ .toEntity(verificationDTO);
+ fourVerificationMapper.updateEntitySelective(entity, UserContextHolder.getLoginUserId());
+ return verificationDTO;
+ }
+
+ @Override
+ public VerificationTypeEnum getType() {
+ return VerificationTypeEnum.FOUR;
+ }
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/IQueryVerify.java b/src/main/java/com/newyetai/alitaforward/verification/factor/IQueryVerify.java
new file mode 100644
index 0000000..1ad4ddc
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/IQueryVerify.java
@@ -0,0 +1,42 @@
+package com.newyetai.alitaforward.verification.factor;
+
+import com.newyetai.alitaforward.verification.dto.FactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.FactorVerificationQueryDTO;
+
+import java.util.List;
+
+/**
+ * 要素查询顶层接口
+ *
+ * @author cheny
+ * @date 2022/08/11
+ */
+public interface IQueryVerify {
+
+
+ /**
+ * 根据参数查list
+ *
+ * @param queryDTO 查询DTO
+ * @return {@link List}<{@link T}>
+ */
+ List list(FactorVerificationQueryDTO queryDTO);
+
+
+ /**
+ * 根据传来的数据,查出认证库中存在的数据
+ *
+ * @param queryDTOList 查询DTO集合
+ * @return {@link List}<{@link T}>
+ */
+ List queryListByData(List queryDTOList);
+
+
+ /**
+ * 根据id获取
+ *
+ * @param id id
+ * @return {@link T}
+ */
+ T findById(Long id);
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/IVerify.java b/src/main/java/com/newyetai/alitaforward/verification/factor/IVerify.java
new file mode 100644
index 0000000..d250333
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/IVerify.java
@@ -0,0 +1,48 @@
+package com.newyetai.alitaforward.verification.factor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.newyetai.alitaforward.verification.constants.VerificationTypeEnum;
+
+/**
+ * 要素校验顶层接口
+ *
+ * @author cheny
+ * @date 2022/08/11
+ */
+public interface IVerify {
+
+ /**
+ * 同步校验
+ *
+ * @param list 列表
+ * @return {@link List}<{@link T}>
+ */
+ List sync(List list);
+
+ /**
+ * 异步校验
+ *
+ * @param list 列表
+ * @return {@link List}<{@link T}>
+ */
+ List async(List list);
+
+ default T sync(T t) {
+ List syncSingle = new ArrayList<>(1);
+ syncSingle.add(t);
+ return sync(syncSingle).get(0);
+ }
+
+ default T async(T t) {
+ List asyncSingle = new ArrayList<>(1);
+ asyncSingle.add(t);
+ return async(asyncSingle).get(0);
+ }
+
+ VerificationTypeEnum getType();
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/PhoneThreeVerify.java b/src/main/java/com/newyetai/alitaforward/verification/factor/PhoneThreeVerify.java
new file mode 100644
index 0000000..daad4c1
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/PhoneThreeVerify.java
@@ -0,0 +1,170 @@
+package com.newyetai.alitaforward.verification.factor;
+
+import cn.hutool.json.JSONUtil;
+import com.google.common.collect.Lists;
+import com.newyetai.alitaforward.common.mq.constant.ForwardMqConstants;
+import com.newyetai.alitaforward.verification.constants.FactorVerificationSourceTypeEnum;
+import com.newyetai.alitaforward.verification.constants.VerificationTypeEnum;
+import com.newyetai.alitaforward.verification.dto.FactorVerificationQueryDTO;
+import com.newyetai.alitaforward.verification.dto.PhoneThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.phoneThree.dao.PhoneThreeVerificationMapper;
+import com.newyetai.alitaforward.verification.factor.phoneThree.entity.PhoneThreeVerification;
+import com.newyetai.alitaforward.verification.factor.phoneThree.mapstruct.PhoneThreeVerificationMapMapper;
+import com.newyetai.common.constant.AuthStatusEnum;
+import com.newyetai.common.exception.util.Assert;
+import com.newyetai.common.util.UserContextHolder;
+import com.newyetai.common.validation.util.ValidateUtils;
+import com.newyetai.frame.redis.aop.annotation.AutoUnLock;
+import com.newyetai.frame.redis.dto.LockDTO;
+import com.newyetai.frame.redis.redisson.RedissonUtils;
+import com.newyetai.mq.util.MqSendUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Component
+public class PhoneThreeVerify extends AbstractVerify implements IQueryVerify {
+
+ @Resource
+ private PhoneThreeVerificationMapper phoneThreeVerificationMapper;
+
+ @Override
+ protected PhoneThreeFactorVerificationDTO syncBeforeVerify(PhoneThreeFactorVerificationDTO verificationDTO) {
+ StringJoiner stringJoiner = new StringJoiner("、");
+ if (!ValidateUtils.checkRealName(verificationDTO.getRealName())) {
+ stringJoiner.add("姓名格式有误");
+ }
+ if (!ValidateUtils.isIdCard(verificationDTO.getCardNo())) {
+ stringJoiner.add("证件号格式有误");
+ }
+ if (StringUtils.isBlank(verificationDTO.getPhone())) {
+ stringJoiner.add("手机号为空");
+ }
+ String failReason = stringJoiner.toString();
+ if (StringUtils.isNotBlank(failReason)) {
+ verificationDTO.setFailReason(failReason);
+ } else {
+ //校验成功调用
+ super.syncBeforeVerify(verificationDTO);
+ }
+ return verificationDTO;
+ }
+
+ @Override
+ PhoneThreeFactorVerificationDTO createAndGet(PhoneThreeFactorVerificationDTO verificationDTO) {
+ PhoneThreeVerification entity = phoneThreeVerificationMapper.find(verificationDTO);
+ if (entity == null) {
+ //认证库不存在,以默认状态入库——"未认证"
+ verificationDTO.setStatus(AuthStatusEnum.NOT_AUTH.getType());
+ entity = PhoneThreeVerificationMapMapper.INSTANCE.exchange(verificationDTO);
+ phoneThreeVerificationMapper.saveEntity(entity);
+ }
+ return PhoneThreeVerificationMapMapper.INSTANCE.exchange(entity);
+ }
+
+ @Override
+ LockDTO getLock(PhoneThreeFactorVerificationDTO verificationDTO) {
+ return LockDTO.builder()
+ .methodName("verify:three:phone")
+ .tryLockWaitTime(0L)
+ .arg(verificationDTO.getRealName())
+ .arg(verificationDTO.getCardNo())
+ .arg(verificationDTO.getPhone())
+ .build();
+ }
+
+ @Override
+ @AutoUnLock
+ public void autoVerify(PhoneThreeFactorVerificationDTO verificationDTO) {
+//拿锁
+ LockDTO lockDTO = getLock(verificationDTO);
+ Assert.isTrue(RedissonUtils.tryLockAutomatically(lockDTO), "请勿重复校验手机三要素");
+
+ PhoneThreeVerification verificationEntity = phoneThreeVerificationMapper.find(verificationDTO);
+
+ if (Objects.nonNull(verificationEntity)) {
+ if (!AuthStatusEnum.NOT_AUTH.getType().equals(verificationEntity.getStatus())) {
+ return;
+ }
+ verificationEntity.setAuthenticationSource(FactorVerificationSourceTypeEnum.SYS.getType());
+ verificationEntity.setStatus(verificationDTO.getStatus());
+ phoneThreeVerificationMapper.updateEntitySelective(verificationEntity,
+ UserContextHolder.getLoginUserId());
+ } else {
+ verificationEntity =
+ PhoneThreeVerification.builder()
+ .realName(verificationDTO.getRealName())
+ .cardNo(verificationDTO.getCardNo())
+ .phone(verificationDTO.getPhone())
+ .authenticationSource(FactorVerificationSourceTypeEnum.SYS.getType())
+ .status(verificationDTO.getStatus())
+ .build();
+ phoneThreeVerificationMapper.saveEntity(verificationEntity);
+ }
+ log.info("【MQ】通知认证状态变更,参数:{}", JSONUtil.toJsonStr(verificationDTO));
+ MqSendUtils.send(statusChangeRoutingKey(), verificationDTO);
+ }
+
+ @Override
+ public List list(FactorVerificationQueryDTO queryDTO) {
+ return phoneThreeVerificationMapper.list(queryDTO);
+ }
+
+ @Override
+ public List queryListByData(List queryDTOList) {
+ List resultList = Lists
+ .newArrayListWithCapacity(queryDTOList.size());
+ if (CollectionUtils.isEmpty(queryDTOList)) {
+ return resultList;
+ }
+ List bankCardThreeVerifications = phoneThreeVerificationMapper
+ .findFinishStatusData();
+ Map threeVerificationMap = bankCardThreeVerifications
+ .stream().collect(
+ Collectors.toMap(k -> k.getRealName() + k.getCardNo() + k.getPhone(), v -> v, (v1, v2) -> v1));
+
+ for (FactorVerificationQueryDTO queryDTO : queryDTOList) {
+ PhoneThreeFactorVerificationDTO PhoneThreeFactorVerificationDTO = threeVerificationMap
+ .get(queryDTO.getRealName() + queryDTO.getCardNo() + queryDTO.getPhone());
+ if (PhoneThreeFactorVerificationDTO != null) {
+ resultList.add(PhoneThreeFactorVerificationDTO);
+ }
+ }
+ return resultList;
+ }
+
+ @Override
+ public PhoneThreeFactorVerificationDTO findById(Long id) {
+ PhoneThreeFactorVerificationDTO threeFactorVerificationDTO = null;
+ PhoneThreeVerification entity = phoneThreeVerificationMapper.getById(id);
+ if (entity != null) {
+ threeFactorVerificationDTO = PhoneThreeVerificationMapMapper.INSTANCE.exchange(entity);
+ }
+ return threeFactorVerificationDTO;
+ }
+
+ @Override
+ PhoneThreeFactorVerificationDTO realVerification(
+ PhoneThreeFactorVerificationDTO verificationDTO) {
+ Integer authenticationSource = verificationDTO.getAuthenticationSource();
+ SOURCE_SERVICE_MAP.get(authenticationSource).phoneThreeVerify(verificationDTO);
+ //更新状态
+ PhoneThreeVerification entity = PhoneThreeVerificationMapMapper.INSTANCE.exchange(verificationDTO);
+ phoneThreeVerificationMapper.updateEntitySelective(entity, UserContextHolder.getLoginUserId());
+ return verificationDTO;
+ }
+
+ @Override
+ public VerificationTypeEnum getType() {
+ return VerificationTypeEnum.PHONE_THREE;
+ }
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/RealNameTwoVerify.java b/src/main/java/com/newyetai/alitaforward/verification/factor/RealNameTwoVerify.java
new file mode 100644
index 0000000..d0fc698
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/RealNameTwoVerify.java
@@ -0,0 +1,165 @@
+package com.newyetai.alitaforward.verification.factor;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import com.google.common.collect.Lists;
+import com.newyetai.alitaforward.verification.constants.FactorVerificationSourceTypeEnum;
+import com.newyetai.alitaforward.verification.constants.VerificationTypeEnum;
+import com.newyetai.alitaforward.verification.dto.FactorVerificationQueryDTO;
+import com.newyetai.alitaforward.verification.dto.RealNameTwoFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.two.convert.RealNameTwoVerificationConvert;
+import com.newyetai.alitaforward.verification.factor.two.dao.RealNameTwoVerificationMapper;
+import com.newyetai.alitaforward.verification.factor.two.entity.RealNameTwoVerification;
+import com.newyetai.common.constant.AuthStatusEnum;
+import com.newyetai.common.exception.util.Assert;
+import com.newyetai.common.util.UserContextHolder;
+import com.newyetai.common.validation.util.ValidateUtils;
+import com.newyetai.frame.redis.aop.annotation.AutoUnLock;
+import com.newyetai.frame.redis.dto.LockDTO;
+import com.newyetai.frame.redis.redisson.RedissonUtils;
+import com.newyetai.mq.util.MqSendUtils;
+
+import cn.hutool.json.JSONUtil;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Component
+public class RealNameTwoVerify extends AbstractVerify implements IQueryVerify {
+
+ @Resource
+ private RealNameTwoVerificationMapper realNameTwoVerificationMapper;
+
+ @Override
+ protected RealNameTwoFactorVerificationDTO syncBeforeVerify(RealNameTwoFactorVerificationDTO verificationDTO) {
+ StringJoiner stringJoiner = new StringJoiner("、");
+ if (!ValidateUtils.checkRealName(verificationDTO.getRealName())) {
+ stringJoiner.add("姓名格式有误");
+ }
+ if (!ValidateUtils.isIdCard(verificationDTO.getCardNo())) {
+ stringJoiner.add("证件号格式有误");
+ }
+ String failReason = stringJoiner.toString();
+ if (StringUtils.isNotBlank(failReason)) {
+ verificationDTO.setFailReason(failReason);
+ } else {
+ //校验成功调用
+ super.syncBeforeVerify(verificationDTO);
+ }
+ return verificationDTO;
+ }
+
+ @Override
+ RealNameTwoFactorVerificationDTO createAndGet(RealNameTwoFactorVerificationDTO verificationDTO) {
+ RealNameTwoVerification entity = realNameTwoVerificationMapper.selectInfo(verificationDTO);
+ if (entity == null) {
+ //认证库不存在,以默认状态入库——"未认证"
+ verificationDTO.setStatus(AuthStatusEnum.NOT_AUTH.getType());
+ entity = RealNameTwoVerificationConvert.INSTANCE.convert(verificationDTO);
+ realNameTwoVerificationMapper.saveEntity(entity);
+ }
+ return RealNameTwoVerificationConvert.INSTANCE.convertDTO(entity);
+ }
+
+ @Override
+ LockDTO getLock(RealNameTwoFactorVerificationDTO verificationDTO) {
+ return LockDTO.builder()
+ .methodName("verify:real_name:two")
+ .tryLockWaitTime(0L)
+ .arg(verificationDTO.getRealName())
+ .arg(verificationDTO.getCardNo())
+ .build();
+ }
+
+ @Override
+ @AutoUnLock
+ public void autoVerify(RealNameTwoFactorVerificationDTO verificationDTO) {
+ //拿锁
+ LockDTO lockDTO = getLock(verificationDTO);
+ Assert.isTrue(RedissonUtils.tryLockAutomatically(lockDTO), "请勿重复校验二要素");
+
+ RealNameTwoVerification realNameTwoVerification = realNameTwoVerificationMapper.selectInfo(verificationDTO);
+
+ if (Objects.nonNull(realNameTwoVerification)) {
+ if (!AuthStatusEnum.NOT_AUTH.getType().equals(realNameTwoVerification.getStatus())) {
+ return;
+ }
+ realNameTwoVerification.setAuthenticationSource(FactorVerificationSourceTypeEnum.SYS.getType());
+ realNameTwoVerification.setStatus(verificationDTO.getStatus());
+ realNameTwoVerificationMapper.updateEntitySelective(realNameTwoVerification,
+ UserContextHolder.getLoginUserId());
+ } else {
+ realNameTwoVerification =
+ RealNameTwoVerification.builder()
+ .realName(verificationDTO.getRealName())
+ .cardNo(verificationDTO.getCardNo())
+ .authenticationSource(FactorVerificationSourceTypeEnum.SYS.getType())
+ .status(verificationDTO.getStatus())
+ .build();
+ realNameTwoVerificationMapper.saveEntity(realNameTwoVerification);
+ }
+ log.info("【MQ】通知认证状态变更,参数:{}", JSONUtil.toJsonStr(verificationDTO));
+ MqSendUtils.send(statusChangeRoutingKey(), verificationDTO);
+ }
+
+ @Override
+ public List list(FactorVerificationQueryDTO queryDTO) {
+ return realNameTwoVerificationMapper.list(queryDTO);
+ }
+
+ @Override
+ public List queryListByData(List queryDTOList) {
+ List resultList = Lists
+ .newArrayListWithCapacity(queryDTOList.size());
+ if (CollectionUtils.isEmpty(queryDTOList)) {
+ return resultList;
+ }
+ List bankCardThreeVerifications = realNameTwoVerificationMapper
+ .findFinishStatusData();
+ Map threeVerificationMap = bankCardThreeVerifications
+ .stream().collect(
+ Collectors.toMap(k -> k.getRealName() + k.getCardNo(), v -> v, (v1, v2) -> v1));
+
+ for (FactorVerificationQueryDTO queryDTO : queryDTOList) {
+ RealNameTwoFactorVerificationDTO RealNameTwoFactorVerificationDTO = threeVerificationMap
+ .get(queryDTO.getRealName() + queryDTO.getCardNo());
+ if (RealNameTwoFactorVerificationDTO != null) {
+ resultList.add(RealNameTwoFactorVerificationDTO);
+ }
+ }
+ return resultList;
+ }
+
+ @Override
+ public RealNameTwoFactorVerificationDTO findById(Long id) {
+ RealNameTwoFactorVerificationDTO threeFactorVerificationDTO = null;
+ RealNameTwoVerification entity = realNameTwoVerificationMapper.getById(id);
+ if (entity != null) {
+ threeFactorVerificationDTO = RealNameTwoVerificationConvert.INSTANCE.convertDTO(entity);
+ }
+ return threeFactorVerificationDTO;
+ }
+
+ @Override
+ RealNameTwoFactorVerificationDTO realVerification(RealNameTwoFactorVerificationDTO verificationDTO) {
+ Integer authenticationSource = verificationDTO.getAuthenticationSource();
+ SOURCE_SERVICE_MAP.get(authenticationSource).twoVerify(verificationDTO);
+ RealNameTwoVerification entity = RealNameTwoVerificationConvert.INSTANCE.convert(verificationDTO);
+ realNameTwoVerificationMapper.updateEntitySelective(entity, UserContextHolder.getLoginUserId());
+ return verificationDTO;
+ }
+
+ @Override
+ public VerificationTypeEnum getType() {
+ return VerificationTypeEnum.TWO;
+ }
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/ThreeVerify.java b/src/main/java/com/newyetai/alitaforward/verification/factor/ThreeVerify.java
new file mode 100644
index 0000000..8308043
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/ThreeVerify.java
@@ -0,0 +1,171 @@
+package com.newyetai.alitaforward.verification.factor;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import com.google.common.collect.Lists;
+import com.newyetai.alitaforward.verification.constants.FactorVerificationSourceTypeEnum;
+import com.newyetai.alitaforward.verification.constants.VerificationTypeEnum;
+import com.newyetai.alitaforward.verification.dto.FactorVerificationQueryDTO;
+import com.newyetai.alitaforward.verification.dto.ThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.three.dao.ThreeVerificationMapper;
+import com.newyetai.alitaforward.verification.factor.three.entity.BankCardThreeVerification;
+import com.newyetai.alitaforward.verification.factor.three.mapstruct.ThreeVerificationMapMapper;
+import com.newyetai.common.constant.AuthStatusEnum;
+import com.newyetai.common.exception.util.Assert;
+import com.newyetai.common.util.UserContextHolder;
+import com.newyetai.common.validation.util.ValidateUtils;
+import com.newyetai.frame.redis.aop.annotation.AutoUnLock;
+import com.newyetai.frame.redis.dto.LockDTO;
+import com.newyetai.frame.redis.redisson.RedissonUtils;
+import com.newyetai.mq.util.MqSendUtils;
+
+import cn.hutool.json.JSONUtil;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Component
+public class ThreeVerify extends AbstractVerify implements IQueryVerify {
+
+ @Resource
+ private ThreeVerificationMapper threeVerificationMapper;
+
+ @Override
+ protected ThreeFactorVerificationDTO syncBeforeVerify(ThreeFactorVerificationDTO verificationDTO) {
+ StringJoiner stringJoiner = new StringJoiner("、");
+ if (!ValidateUtils.checkRealName(verificationDTO.getRealName())) {
+ stringJoiner.add("姓名格式有误");
+ }
+ if (!ValidateUtils.isIdCard(verificationDTO.getCardNo())) {
+ stringJoiner.add("证件号格式有误");
+ }
+ if (StringUtils.isBlank(verificationDTO.getBankAccountNo())) {
+ stringJoiner.add("银行卡号为空");
+ }
+ String failReason = stringJoiner.toString();
+ if (StringUtils.isNotBlank(failReason)) {
+ verificationDTO.setFailReason(failReason);
+ } else {
+ //校验成功调用
+ super.syncBeforeVerify(verificationDTO);
+ }
+ return verificationDTO;
+ }
+
+ @Override
+ ThreeFactorVerificationDTO createAndGet(ThreeFactorVerificationDTO verificationDTO) {
+ BankCardThreeVerification entity = threeVerificationMapper.find(verificationDTO);
+ if (entity == null) {
+ //认证库不存在,以默认状态入库——"未认证"
+ verificationDTO.setStatus(AuthStatusEnum.NOT_AUTH.getType());
+ entity = ThreeVerificationMapMapper.INSTANCE.toEntity(verificationDTO);
+ threeVerificationMapper.saveEntity(entity);
+ }
+ return ThreeVerificationMapMapper.INSTANCE.toDto(entity);
+ }
+
+ @Override
+ @AutoUnLock
+ public void autoVerify(ThreeFactorVerificationDTO verificationDTO) {
+ //拿锁
+ LockDTO lockDTO = getLock(verificationDTO);
+ Assert.isTrue(RedissonUtils.tryLockAutomatically(lockDTO), "请勿重复校验三要素");
+
+ BankCardThreeVerification verificationEntity = threeVerificationMapper.find(verificationDTO);
+
+ if (Objects.nonNull(verificationEntity)) {
+ if (!AuthStatusEnum.NOT_AUTH.getType().equals(verificationEntity.getStatus())) {
+ return;
+ }
+ verificationEntity.setAuthenticationSource(FactorVerificationSourceTypeEnum.SYS.getType());
+ verificationEntity.setStatus(verificationDTO.getStatus());
+ threeVerificationMapper.updateEntitySelective(verificationEntity,
+ UserContextHolder.getLoginUserId());
+ } else {
+ verificationEntity =
+ BankCardThreeVerification.builder()
+ .realName(verificationDTO.getRealName())
+ .cardNo(verificationDTO.getCardNo())
+ .bankAccountNo(verificationDTO.getBankAccountNo())
+ .authenticationSource(FactorVerificationSourceTypeEnum.SYS.getType())
+ .status(verificationDTO.getStatus())
+ .build();
+ threeVerificationMapper.saveEntity(verificationEntity);
+ }
+ log.info("【MQ】通知认证状态变更,参数:{}", JSONUtil.toJsonStr(verificationDTO));
+ MqSendUtils.send(statusChangeRoutingKey(), verificationDTO);
+ }
+
+ @Override
+ LockDTO getLock(ThreeFactorVerificationDTO verificationDTO) {
+ return LockDTO.builder()
+ .methodName("verify:three")
+ .tryLockWaitTime(0L)
+ .arg(verificationDTO.getRealName())
+ .arg(verificationDTO.getCardNo())
+ .arg(verificationDTO.getBankAccountNo())
+ .build();
+ }
+
+ @Override
+ public List list(FactorVerificationQueryDTO queryDTO) {
+ return threeVerificationMapper.list(queryDTO);
+ }
+
+ @Override
+ public List queryListByData(List queryDTOList) {
+ List resultList = Lists
+ .newArrayListWithCapacity(queryDTOList.size());
+ if (CollectionUtils.isEmpty(queryDTOList)) {
+ return resultList;
+ }
+ List bankCardThreeVerifications = threeVerificationMapper
+ .findFinishStatusData();
+ Map threeVerificationMap = bankCardThreeVerifications
+ .stream().collect(
+ Collectors.toMap(k -> k.getRealName() + k.getCardNo() + k.getBankAccountNo(), v -> v, (v1, v2) -> v1));
+
+ for (FactorVerificationQueryDTO queryDTO : queryDTOList) {
+ ThreeFactorVerificationDTO threeFactorVerificationDTO = threeVerificationMap
+ .get(queryDTO.getRealName() + queryDTO.getCardNo() + queryDTO.getBankAccountNo());
+ if (threeFactorVerificationDTO != null) {
+ resultList.add(threeFactorVerificationDTO);
+ }
+ }
+ return resultList;
+ }
+
+ @Override
+ public ThreeFactorVerificationDTO findById(Long id) {
+ ThreeFactorVerificationDTO threeFactorVerificationDTO = null;
+ BankCardThreeVerification entity = threeVerificationMapper.getById(id);
+ if (entity != null) {
+ threeFactorVerificationDTO = ThreeVerificationMapMapper.INSTANCE.toDto(entity);
+ }
+ return threeFactorVerificationDTO;
+ }
+ @Override
+ ThreeFactorVerificationDTO realVerification(ThreeFactorVerificationDTO verificationDTO) {
+ Integer authenticationSource = verificationDTO.getAuthenticationSource();
+ SOURCE_SERVICE_MAP.get(authenticationSource).threeVerify(verificationDTO);
+ //更新状态
+ BankCardThreeVerification entity = ThreeVerificationMapMapper.INSTANCE
+ .toEntity(verificationDTO);
+ threeVerificationMapper.updateEntitySelective(entity, UserContextHolder.getLoginUserId());
+ return verificationDTO;
+ }
+
+ @Override
+ public VerificationTypeEnum getType() {
+ return VerificationTypeEnum.THREE;
+ }
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/VerifyConfig.java b/src/main/java/com/newyetai/alitaforward/verification/factor/VerifyConfig.java
new file mode 100644
index 0000000..92a929b
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/VerifyConfig.java
@@ -0,0 +1,18 @@
+package com.newyetai.alitaforward.verification.factor;
+
+import com.newyetai.alitaforward.verification.source.FactorVerificationSourceService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.List;
+
+@Configuration
+public class VerifyConfig {
+
+ @Autowired
+ private void autowiredFactorVerificationSourceService(List sourceServices) {
+ for (FactorVerificationSourceService sourceService : sourceServices) {
+ AbstractVerify.SOURCE_SERVICE_MAP.put(sourceService.getSourceType().getType(), sourceService);
+ }
+ }
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/four/dao/FourVerificationMapper.java b/src/main/java/com/newyetai/alitaforward/verification/factor/four/dao/FourVerificationMapper.java
new file mode 100644
index 0000000..c5ecf4c
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/four/dao/FourVerificationMapper.java
@@ -0,0 +1,30 @@
+package com.newyetai.alitaforward.verification.factor.four.dao;
+
+import com.newyetai.alitaforward.verification.dto.FactorVerificationQueryDTO;
+import com.newyetai.alitaforward.verification.dto.FourFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.ThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.four.entity.BankCardFourVerification;
+import com.newyetai.tkmybatis.mybatis.MyMapper;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+/**
+ * @author czy
+ * @date 2021-06-17
+ */
+public interface FourVerificationMapper extends MyMapper {
+
+ /**
+ * 根据四要素查询数据
+ * @param params
+ * @return
+ */
+ BankCardFourVerification selectInfo(@Param("params") FourFactorVerificationDTO params);
+
+ @Select("select * from bank_card_four_verification where deleted = false and status in (2,3)")
+ List findFinishStatusData();
+
+ List list(@Param("params") FactorVerificationQueryDTO factorVerificationQueryDTO);
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/four/entity/BankCardFourVerification.java b/src/main/java/com/newyetai/alitaforward/verification/factor/four/entity/BankCardFourVerification.java
new file mode 100644
index 0000000..5e142b7
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/four/entity/BankCardFourVerification.java
@@ -0,0 +1,51 @@
+package com.newyetai.alitaforward.verification.factor.four.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.newyetai.common.entity.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author czy
+ * @date 2021-06-17
+ */
+
+@ApiModel("四要素认证库")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@EqualsAndHashCode(callSuper = true)
+@TableName("bank_card_four_verification")
+public class BankCardFourVerification extends BaseEntity {
+
+ @ApiModelProperty("姓名")
+ private String realName;
+
+ @ApiModelProperty("证件号")
+ private String cardNo;
+
+ @ApiModelProperty("银行卡号")
+ private String bankAccountNo;
+
+ @ApiModelProperty("手机号")
+ private String phone;
+
+ @ApiModelProperty("认证状态(1-未认证 2-认证中 3-认证成功 4-认证失败)")
+ private Integer status;
+
+ @ApiModelProperty("认证来源")
+ private Integer authenticationSource;
+
+ @ApiModelProperty("调用数据")
+ private String invokeData;
+
+ @ApiModelProperty("失败原因")
+ private String failReason;
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/four/mapper/BankCardFourVerificationMapper.xml b/src/main/java/com/newyetai/alitaforward/verification/factor/four/mapper/BankCardFourVerificationMapper.xml
new file mode 100644
index 0000000..2578fd0
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/four/mapper/BankCardFourVerificationMapper.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/four/mapstruct/FourVerificationMapMapper.java b/src/main/java/com/newyetai/alitaforward/verification/factor/four/mapstruct/FourVerificationMapMapper.java
new file mode 100644
index 0000000..760fbb8
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/four/mapstruct/FourVerificationMapMapper.java
@@ -0,0 +1,62 @@
+package com.newyetai.alitaforward.verification.factor.four.mapstruct;
+
+import com.newyetai.alitaforward.verification.dto.FourFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.four.entity.BankCardFourVerification;
+import com.newyetai.sdk.fangxinqian.dto.BankCardFourRequestDTO;
+import com.newyetai.sdk.fangxinqian.dto.BankCardThreeRequestDTO;
+import java.util.List;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author czy
+ * @date 2021-06-17
+ */
+@Mapper
+public interface FourVerificationMapMapper {
+
+ FourVerificationMapMapper INSTANCE = Mappers.getMapper(
+ FourVerificationMapMapper.class);
+
+ /**
+ * dto to entity
+ *
+ * @param fourVerificationDTO
+ * @return
+ * @author czy on 2021-06-17
+ */
+ BankCardFourVerification toEntity(
+ FourFactorVerificationDTO fourVerificationDTO);
+
+ /**
+ * dtoList to entityList
+ *
+ * @param threeVerificationDTOList
+ * @return
+ * @author czy on 2021-06-17
+ */
+ List toEntityList(
+ List threeVerificationDTOList);
+
+ /**
+ * entity to dto
+ *
+ * @param threeVerification
+ * @return
+ * @author czy on 2021-06-17
+ */
+ FourFactorVerificationDTO toDto(
+ BankCardFourVerification threeVerification);
+
+ /**
+ * entityList to dtoList
+ *
+ * @param fourVerificationEntityList
+ * @return
+ * @author czy on 2021-06-17
+ */
+ List toDtoList(
+ List fourVerificationEntityList);
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/phoneThree/dao/PhoneThreeVerificationMapper.java b/src/main/java/com/newyetai/alitaforward/verification/factor/phoneThree/dao/PhoneThreeVerificationMapper.java
new file mode 100644
index 0000000..7f29d70
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/phoneThree/dao/PhoneThreeVerificationMapper.java
@@ -0,0 +1,30 @@
+package com.newyetai.alitaforward.verification.factor.phoneThree.dao;
+
+import com.newyetai.alitaforward.verification.dto.FactorVerificationQueryDTO;
+import com.newyetai.alitaforward.verification.dto.PhoneThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.phoneThree.entity.PhoneThreeVerification;
+import com.newyetai.tkmybatis.mybatis.MyMapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ * @author czy
+ * @date 2021-06-17
+ */
+public interface PhoneThreeVerificationMapper extends MyMapper {
+
+ /**
+ * 根据三要素查询数据
+ * @param params
+ * @return
+ */
+ PhoneThreeVerification find(@Param("params") PhoneThreeFactorVerificationDTO params);
+
+ @Select("select * from phone_three_verification where deleted = false")
+ List findFinishStatusData();
+
+ List list(@Param("params") FactorVerificationQueryDTO factorVerificationQueryDTO);
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/phoneThree/entity/PhoneThreeVerification.java b/src/main/java/com/newyetai/alitaforward/verification/factor/phoneThree/entity/PhoneThreeVerification.java
new file mode 100644
index 0000000..d6be3a8
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/phoneThree/entity/PhoneThreeVerification.java
@@ -0,0 +1,42 @@
+package com.newyetai.alitaforward.verification.factor.phoneThree.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.newyetai.common.entity.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+
+/**
+ * @author czy
+ * @date 2021-06-17
+ */
+
+@ApiModel("手机号三要素认证库")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@EqualsAndHashCode(callSuper = true)
+@TableName("phone_three_verification")
+public class PhoneThreeVerification extends BaseEntity {
+
+ private static final long serialVersionUID = 1033289792676234200L;
+ @ApiModelProperty("姓名")
+ private String realName;
+
+ @ApiModelProperty("证件号")
+ private String cardNo;
+
+ @ApiModelProperty("银行卡号")
+ private String phone;
+
+ @ApiModelProperty("认证状态(1-未认证 2-认证中 3-认证成功 4-认证失败)")
+ private Integer status;
+
+ @ApiModelProperty("认证来源")
+ private Integer authenticationSource;
+
+ @ApiModelProperty("失败原因")
+ private String failReason;
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/phoneThree/mapper/PhoneThreeVerificationMapper.xml b/src/main/java/com/newyetai/alitaforward/verification/factor/phoneThree/mapper/PhoneThreeVerificationMapper.xml
new file mode 100644
index 0000000..ee0e2ee
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/phoneThree/mapper/PhoneThreeVerificationMapper.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/phoneThree/mapstruct/PhoneThreeVerificationMapMapper.java b/src/main/java/com/newyetai/alitaforward/verification/factor/phoneThree/mapstruct/PhoneThreeVerificationMapMapper.java
new file mode 100644
index 0000000..5267e84
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/phoneThree/mapstruct/PhoneThreeVerificationMapMapper.java
@@ -0,0 +1,21 @@
+package com.newyetai.alitaforward.verification.factor.phoneThree.mapstruct;
+
+import com.newyetai.alitaforward.verification.dto.PhoneThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.phoneThree.entity.PhoneThreeVerification;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author czy
+ * @date 2021-06-17
+ */
+@Mapper
+public interface PhoneThreeVerificationMapMapper {
+
+ PhoneThreeVerificationMapMapper INSTANCE = Mappers.getMapper(
+ PhoneThreeVerificationMapMapper.class);
+
+ PhoneThreeFactorVerificationDTO exchange(PhoneThreeVerification verification);
+
+ PhoneThreeVerification exchange(PhoneThreeFactorVerificationDTO verificationDTO);
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/three/dao/ThreeVerificationMapper.java b/src/main/java/com/newyetai/alitaforward/verification/factor/three/dao/ThreeVerificationMapper.java
new file mode 100644
index 0000000..2556718
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/three/dao/ThreeVerificationMapper.java
@@ -0,0 +1,29 @@
+package com.newyetai.alitaforward.verification.factor.three.dao;
+
+import com.newyetai.alitaforward.verification.dto.FactorVerificationQueryDTO;
+import com.newyetai.alitaforward.verification.dto.ThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.three.entity.BankCardThreeVerification;
+import com.newyetai.tkmybatis.mybatis.MyMapper;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+/**
+ * @author czy
+ * @date 2021-06-17
+ */
+public interface ThreeVerificationMapper extends MyMapper {
+
+ /**
+ * 根据三要素查询数据
+ * @param params
+ * @return
+ */
+ BankCardThreeVerification find(@Param("params") ThreeFactorVerificationDTO params);
+
+ @Select("select * from bank_card_three_verification where deleted = false")
+ List findFinishStatusData();
+
+ List list(@Param("params") FactorVerificationQueryDTO factorVerificationQueryDTO);
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/three/entity/BankCardThreeVerification.java b/src/main/java/com/newyetai/alitaforward/verification/factor/three/entity/BankCardThreeVerification.java
new file mode 100644
index 0000000..d48103a
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/three/entity/BankCardThreeVerification.java
@@ -0,0 +1,45 @@
+package com.newyetai.alitaforward.verification.factor.three.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.newyetai.common.entity.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+
+/**
+ * @author czy
+ * @date 2021-06-17
+ */
+
+@ApiModel("三要素认证库")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@EqualsAndHashCode(callSuper = true)
+@TableName("bank_card_three_verification")
+public class BankCardThreeVerification extends BaseEntity {
+
+ private static final long serialVersionUID = 1178897458908696195L;
+ @ApiModelProperty("姓名")
+ private String realName;
+
+ @ApiModelProperty("证件号")
+ private String cardNo;
+
+ @ApiModelProperty("银行卡号")
+ private String bankAccountNo;
+
+ @ApiModelProperty("认证状态(1-未认证 2-认证中 3-认证成功 4-认证失败)")
+ private Integer status;
+
+ @ApiModelProperty("认证来源")
+ private Integer authenticationSource;
+
+ @ApiModelProperty("调用数据")
+ private String invokeData;
+
+ @ApiModelProperty("失败原因")
+ private String failReason;
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/three/mapper/BankCardThreeVerificationMapper.xml b/src/main/java/com/newyetai/alitaforward/verification/factor/three/mapper/BankCardThreeVerificationMapper.xml
new file mode 100644
index 0000000..1b0da1f
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/three/mapper/BankCardThreeVerificationMapper.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/three/mapstruct/ThreeVerificationMapMapper.java b/src/main/java/com/newyetai/alitaforward/verification/factor/three/mapstruct/ThreeVerificationMapMapper.java
new file mode 100644
index 0000000..6cc6418
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/three/mapstruct/ThreeVerificationMapMapper.java
@@ -0,0 +1,60 @@
+package com.newyetai.alitaforward.verification.factor.three.mapstruct;
+
+import com.newyetai.alitaforward.verification.dto.ThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.three.entity.BankCardThreeVerification;
+import java.util.List;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author czy
+ * @date 2021-06-17
+ */
+@Mapper
+public interface ThreeVerificationMapMapper {
+
+ ThreeVerificationMapMapper INSTANCE = Mappers.getMapper(
+ ThreeVerificationMapMapper.class);
+
+ /**
+ * dto to entity
+ *
+ * @param threeVerificationDTO
+ * @return
+ * @author czy on 2021-06-17
+ */
+ BankCardThreeVerification toEntity(
+ ThreeFactorVerificationDTO threeVerificationDTO);
+
+ /**
+ * dtoList to entityList
+ *
+ * @param threeVerificationDTOList
+ * @return
+ * @author czy on 2021-06-17
+ */
+ List toEntityList(
+ List threeVerificationDTOList);
+
+ /**
+ * entity to dto
+ *
+ * @param threeVerification
+ * @return
+ * @author czy on 2021-06-17
+ */
+ ThreeFactorVerificationDTO toDto(
+ BankCardThreeVerification threeVerification);
+
+ /**
+ * entityList to dtoList
+ *
+ * @param threeVerificationEntityList
+ * @return
+ * @author czy on 2021-06-17
+ */
+ List toDtoList(
+ List threeVerificationEntityList);
+
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/two/convert/RealNameTwoVerificationConvert.java b/src/main/java/com/newyetai/alitaforward/verification/factor/two/convert/RealNameTwoVerificationConvert.java
new file mode 100644
index 0000000..3b192e2
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/two/convert/RealNameTwoVerificationConvert.java
@@ -0,0 +1,28 @@
+package com.newyetai.alitaforward.verification.factor.two.convert;
+
+import com.newyetai.alitaforward.verification.dto.RealNameTwoFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.two.dto.RealNameTwoVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.two.dto.RealNameTwoVerificationOperatorDTO;
+import com.newyetai.alitaforward.verification.factor.two.entity.RealNameTwoVerification;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * 二要素认证表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2022-07-22
+ */
+@Mapper
+public interface RealNameTwoVerificationConvert {
+ RealNameTwoVerificationConvert INSTANCE = Mappers.getMapper(RealNameTwoVerificationConvert.class);
+
+ RealNameTwoVerification convert(RealNameTwoVerificationDTO dto);
+
+ RealNameTwoVerificationDTO convert(RealNameTwoVerification entity);
+ RealNameTwoFactorVerificationDTO convertDTO(RealNameTwoVerification entity);
+
+ RealNameTwoVerification convert(RealNameTwoVerificationOperatorDTO dto);
+
+ RealNameTwoVerification convert(RealNameTwoFactorVerificationDTO dto);
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/two/dao/RealNameTwoVerificationMapper.java b/src/main/java/com/newyetai/alitaforward/verification/factor/two/dao/RealNameTwoVerificationMapper.java
new file mode 100644
index 0000000..6606b00
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/two/dao/RealNameTwoVerificationMapper.java
@@ -0,0 +1,39 @@
+package com.newyetai.alitaforward.verification.factor.two.dao;
+
+import com.newyetai.alitaforward.verification.dto.FactorVerificationQueryDTO;
+import com.newyetai.alitaforward.verification.dto.RealNameTwoFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.two.dto.RealNameTwoVerificationDTO;
+import com.newyetai.alitaforward.verification.factor.two.dto.RealNameTwoVerificationPageQueryDTO;
+import com.newyetai.alitaforward.verification.factor.two.entity.RealNameTwoVerification;
+import com.newyetai.tkmybatis.mybatis.MyMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ * 二要素认证表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2022-07-22
+ */
+@Mapper
+public interface RealNameTwoVerificationMapper extends MyMapper {
+
+ /**
+ * 根据二要素查询数据
+ *
+ * @param params
+ * @return
+ */
+ RealNameTwoVerification selectInfo(@Param("param") RealNameTwoFactorVerificationDTO params);
+
+ List page(
+ @Param("param") RealNameTwoVerificationPageQueryDTO queryDTO);
+
+ List list(@Param("param") FactorVerificationQueryDTO queryDTO);
+
+ @Select("select * from real_name_two_verification where deleted = false")
+ List findFinishStatusData();
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/two/dto/RealNameTwoVerificationDTO.java b/src/main/java/com/newyetai/alitaforward/verification/factor/two/dto/RealNameTwoVerificationDTO.java
new file mode 100644
index 0000000..27e39d4
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/two/dto/RealNameTwoVerificationDTO.java
@@ -0,0 +1,41 @@
+package com.newyetai.alitaforward.verification.factor.two.dto;
+
+import com.newyetai.common.dto.BaseDTO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * 二要素认证表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2022-07-22
+ */
+@ApiModel("二要素认证表")
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class RealNameTwoVerificationDTO extends BaseDTO {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("姓名")
+ private String realName;
+
+ @ApiModelProperty("证件号")
+ private String cardNo;
+
+ @ApiModelProperty("状态(1待认证 2认证中 3认证成功 4认证失败)")
+ private Integer status;
+
+ @ApiModelProperty("认证来源(1放心签、2创蓝 3系统)")
+ private Integer authenticationSource;
+
+ @ApiModelProperty("调用数据")
+ private String invokeData;
+
+ @ApiModelProperty("失败原因")
+ private String failReason;
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/two/dto/RealNameTwoVerificationOperatorDTO.java b/src/main/java/com/newyetai/alitaforward/verification/factor/two/dto/RealNameTwoVerificationOperatorDTO.java
new file mode 100644
index 0000000..9d708d4
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/two/dto/RealNameTwoVerificationOperatorDTO.java
@@ -0,0 +1,45 @@
+package com.newyetai.alitaforward.verification.factor.two.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 二要素认证表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2022-07-22
+ */
+@ApiModel("二要素认证表")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class RealNameTwoVerificationOperatorDTO implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ @ApiModelProperty("姓名")
+ private String realName;
+
+ @ApiModelProperty("证件号")
+ private String cardNo;
+
+ @ApiModelProperty("状态(1待认证 2认证中 3认证成功 4认证失败)")
+ private Integer status;
+
+ @ApiModelProperty("认证来源(1放心签、2创蓝 3系统)")
+ private Integer authenticationSource;
+
+ @ApiModelProperty("调用数据")
+ private String invokeData;
+
+ @ApiModelProperty("失败原因")
+ private String failReason;
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/two/dto/RealNameTwoVerificationPageQueryDTO.java b/src/main/java/com/newyetai/alitaforward/verification/factor/two/dto/RealNameTwoVerificationPageQueryDTO.java
new file mode 100644
index 0000000..0b59e8c
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/two/dto/RealNameTwoVerificationPageQueryDTO.java
@@ -0,0 +1,67 @@
+package com.newyetai.alitaforward.verification.factor.two.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.newyetai.common.dto.PageQueryDTO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 二要素认证表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2022-07-22
+ */
+@ApiModel("二要素认证表")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class RealNameTwoVerificationPageQueryDTO extends PageQueryDTO {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("ID")
+ private Long id;
+
+ @ApiModelProperty("姓名 (模糊匹配)")
+ private String realNameLike;
+
+ @ApiModelProperty("证件号")
+ private String cardNo;
+
+ @ApiModelProperty("状态(1待认证 2认证中 3认证成功 4认证失败)")
+ private Integer status;
+
+ @ApiModelProperty("认证来源(1放心签、2创蓝 3系统)")
+ private Integer authenticationSource;
+
+ @ApiModelProperty("调用数据")
+ private String invokeData;
+
+ @ApiModelProperty("失败原因")
+ private String failReason;
+
+ @ApiModelProperty("创建时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeStart;
+
+ @ApiModelProperty("创建时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeEnd;
+
+ @ApiModelProperty("更新时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeStart;
+
+ @ApiModelProperty("更新时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeEnd;
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/two/dto/RealNameTwoVerificationQueryDTO.java b/src/main/java/com/newyetai/alitaforward/verification/factor/two/dto/RealNameTwoVerificationQueryDTO.java
new file mode 100644
index 0000000..f576c59
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/two/dto/RealNameTwoVerificationQueryDTO.java
@@ -0,0 +1,69 @@
+package com.newyetai.alitaforward.verification.factor.two.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 二要素认证表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2022-07-22
+ */
+@ApiModel("二要素认证表")
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class RealNameTwoVerificationQueryDTO implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("ID")
+ private Long id;
+
+ @ApiModelProperty("姓名 (模糊匹配)")
+ private String realNameLike;
+
+ @ApiModelProperty("证件号")
+ private String cardNo;
+
+ @ApiModelProperty("状态(1待认证 2认证中 3认证成功 4认证失败)")
+ private Integer status;
+
+ @ApiModelProperty("认证来源(1放心签、2创蓝 3系统)")
+ private Integer authenticationSource;
+
+ @ApiModelProperty("调用数据")
+ private String invokeData;
+
+ @ApiModelProperty("失败原因")
+ private String failReason;
+
+ @ApiModelProperty("创建时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeStart;
+
+ @ApiModelProperty("创建时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeEnd;
+
+ @ApiModelProperty("更新时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeStart;
+
+ @ApiModelProperty("更新时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeEnd;
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/two/entity/RealNameTwoVerification.java b/src/main/java/com/newyetai/alitaforward/verification/factor/two/entity/RealNameTwoVerification.java
new file mode 100644
index 0000000..5802ab9
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/two/entity/RealNameTwoVerification.java
@@ -0,0 +1,40 @@
+package com.newyetai.alitaforward.verification.factor.two.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.newyetai.common.entity.BaseEntity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 二要素认证表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2022-07-22
+ */
+@TableName("real_name_two_verification")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class RealNameTwoVerification extends BaseEntity {
+
+ private static final long serialVersionUID = 1L;
+
+ /** 姓名 */
+ private String realName;
+ /** 证件号 */
+ private String cardNo;
+ /** 状态(1待认证 2认证中 3认证成功 4认证失败) */
+ private Integer status;
+ /** 认证来源(1放心签、2创蓝 3系统) */
+ private Integer authenticationSource;
+ /** 调用数据 */
+ private String invokeData;
+ /** 失败原因 */
+ private String failReason;
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/factor/two/mapper/RealNameTwoVerificationMapper.xml b/src/main/java/com/newyetai/alitaforward/verification/factor/two/mapper/RealNameTwoVerificationMapper.xml
new file mode 100644
index 0000000..b6cb07e
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/factor/two/mapper/RealNameTwoVerificationMapper.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+ FROM
+ real_name_two_verification t
+ WHERE t.deleted = 0
+
+ AND t.id = #{param.id}
+
+
+
+ AND t.real_name like #{realNameLike}
+
+
+ AND t.card_no = #{param.cardNo}
+
+
+ AND t.status = #{param.status}
+
+
+ AND t.authentication_source = #{param.authenticationSource}
+
+
+ AND t.invoke_data = #{param.invokeData}
+
+
+ AND t.fail_reason = #{param.failReason}
+
+
+ AND t.create_time >= #{param.createTimeStart}
+
+
+ AND t.create_time <= #{param.createTimeEnd}
+
+
+ AND t.update_time >= #{param.updateTimeStart}
+
+
+ AND t.update_time <= #{param.updateTimeEnd}
+
+ ORDER BY t.id DESC
+
+
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/alitaforward/verification/service/BankCardVerificationService.java b/src/main/java/com/newyetai/alitaforward/verification/service/BankCardVerificationService.java
new file mode 100644
index 0000000..d01bfc8
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/service/BankCardVerificationService.java
@@ -0,0 +1,14 @@
+package com.newyetai.alitaforward.verification.service;
+
+import com.newyetai.alitaforward.verification.dto.BankCordVerificationResDTO;
+
+import java.util.List;
+
+public interface BankCardVerificationService {
+
+ /**
+ * 白名单管理-->三、四要素查询合并为银行卡查询
+ * @param cardNo
+ */
+ List list(String cardNo,Integer status);
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/service/FourFactorVerificationProvider.java b/src/main/java/com/newyetai/alitaforward/verification/service/FourFactorVerificationProvider.java
new file mode 100644
index 0000000..612be2e
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/service/FourFactorVerificationProvider.java
@@ -0,0 +1,17 @@
+package com.newyetai.alitaforward.verification.service;
+
+import com.newyetai.alitaforward.verification.constants.VerificationTypeEnum;
+import com.newyetai.alitaforward.verification.dto.FourFactorVerificationDTO;
+import com.newyetai.mq.consumer.handler.ITopicMqHandler;
+
+/**
+ * @author czy
+ * @date 2021-06-22
+ */
+public interface FourFactorVerificationProvider extends ITopicMqHandler {
+
+ default String getRoutingKey(){
+ return VerificationTypeEnum.FOUR.getStatusChangeKey();
+ }
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/service/PhoneThreeFactorVerificationProvider.java b/src/main/java/com/newyetai/alitaforward/verification/service/PhoneThreeFactorVerificationProvider.java
new file mode 100644
index 0000000..69be352
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/service/PhoneThreeFactorVerificationProvider.java
@@ -0,0 +1,17 @@
+package com.newyetai.alitaforward.verification.service;
+
+import com.newyetai.alitaforward.verification.constants.VerificationTypeEnum;
+import com.newyetai.alitaforward.verification.dto.PhoneThreeFactorVerificationDTO;
+import com.newyetai.mq.consumer.handler.ITopicMqHandler;
+
+/**
+ * @author czy
+ * @date 2021-06-22
+ */
+public interface PhoneThreeFactorVerificationProvider extends ITopicMqHandler {
+
+ default String getRoutingKey(){
+ return VerificationTypeEnum.PHONE_THREE.getStatusChangeKey();
+ }
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/service/RealNameTwoFactorVerificationProvider.java b/src/main/java/com/newyetai/alitaforward/verification/service/RealNameTwoFactorVerificationProvider.java
new file mode 100644
index 0000000..324c65a
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/service/RealNameTwoFactorVerificationProvider.java
@@ -0,0 +1,17 @@
+package com.newyetai.alitaforward.verification.service;
+
+import com.newyetai.alitaforward.verification.constants.VerificationTypeEnum;
+import com.newyetai.alitaforward.verification.dto.RealNameTwoFactorVerificationDTO;
+import com.newyetai.mq.consumer.handler.ITopicMqHandler;
+
+/**
+ * @author czy
+ * @date 2021-06-22
+ */
+public interface RealNameTwoFactorVerificationProvider extends ITopicMqHandler {
+
+ default String getRoutingKey(){
+ return VerificationTypeEnum.TWO.getStatusChangeKey();
+ }
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/service/ThreeFactorVerificationProvider.java b/src/main/java/com/newyetai/alitaforward/verification/service/ThreeFactorVerificationProvider.java
new file mode 100644
index 0000000..5d1a76c
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/service/ThreeFactorVerificationProvider.java
@@ -0,0 +1,17 @@
+package com.newyetai.alitaforward.verification.service;
+
+import com.newyetai.alitaforward.verification.constants.VerificationTypeEnum;
+import com.newyetai.alitaforward.verification.dto.ThreeFactorVerificationDTO;
+import com.newyetai.mq.consumer.handler.ITopicMqHandler;
+
+/**
+ * @author czy
+ * @date 2021-06-22
+ */
+public interface ThreeFactorVerificationProvider extends ITopicMqHandler {
+
+ default String getRoutingKey(){
+ return VerificationTypeEnum.THREE.getStatusChangeKey();
+ }
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/service/impl/BankCardVerificationServiceImpl.java b/src/main/java/com/newyetai/alitaforward/verification/service/impl/BankCardVerificationServiceImpl.java
new file mode 100644
index 0000000..ddc75c7
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/service/impl/BankCardVerificationServiceImpl.java
@@ -0,0 +1,35 @@
+package com.newyetai.alitaforward.verification.service.impl;
+
+import com.newyetai.alitaforward.verification.dao.BankCardVerificationMapper;
+import com.newyetai.alitaforward.verification.dto.BankCordVerificationResDTO;
+import com.newyetai.alitaforward.verification.service.BankCardVerificationService;
+import com.newyetai.common.exception.BusinessException;
+import com.newyetai.common.exception.util.Assert;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+public class BankCardVerificationServiceImpl implements BankCardVerificationService {
+
+ @Autowired
+ BankCardVerificationMapper bankCardVerificationMapper;
+ /**
+ * 白名单管理-->三、四要素查询合并为银行卡查询
+ * @param cardNo
+ */
+ public List list(String cardNo,Integer status){
+ if(StringUtils.isBlank(cardNo)){
+ throw new BusinessException("身份证号不能为空");
+ }
+ List bankCordVerificationResDTOList = bankCardVerificationMapper.list(cardNo);
+ if(status != null){
+ return bankCordVerificationResDTOList.stream().
+ filter(f -> f.getStatus() != null && f.getStatus() == status).collect(Collectors.toList());
+ }
+ return bankCordVerificationResDTOList;
+ }
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/source/FactorVerificationSourceService.java b/src/main/java/com/newyetai/alitaforward/verification/source/FactorVerificationSourceService.java
new file mode 100644
index 0000000..489fac2
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/source/FactorVerificationSourceService.java
@@ -0,0 +1,34 @@
+package com.newyetai.alitaforward.verification.source;
+
+import com.newyetai.alitaforward.verification.constants.FactorVerificationSourceTypeEnum;
+import com.newyetai.alitaforward.verification.dto.FourFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.PhoneThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.RealNameTwoFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.ThreeFactorVerificationDTO;
+import com.newyetai.common.exception.BusinessException;
+
+/**
+ * 要素认证源 - 顶层接口
+ *
+ * @author cheny
+ * @date 2022/08/11
+ */
+public interface FactorVerificationSourceService {
+
+ FactorVerificationSourceTypeEnum getSourceType();
+
+ default RealNameTwoFactorVerificationDTO twoVerify(RealNameTwoFactorVerificationDTO verificationDTO) {
+ throw new BusinessException("二要素不支持的该认证源:" + getSourceType());
+ }
+ default ThreeFactorVerificationDTO threeVerify(ThreeFactorVerificationDTO verificationDTO){
+ throw new BusinessException("银行卡三要素不支持的该认证源:" + getSourceType());
+ }
+ default PhoneThreeFactorVerificationDTO phoneThreeVerify(PhoneThreeFactorVerificationDTO verificationDTO){
+ throw new BusinessException("手机号三要素不支持的该认证源:" + getSourceType());
+ }
+ default FourFactorVerificationDTO fourVerify(FourFactorVerificationDTO verificationDTO){
+ throw new BusinessException("银行卡四要素不支持的该认证源:" + getSourceType());
+ }
+
+
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/source/cl/ClAuthenticateSourceServiceImpl.java b/src/main/java/com/newyetai/alitaforward/verification/source/cl/ClAuthenticateSourceServiceImpl.java
new file mode 100644
index 0000000..f81c61b
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/source/cl/ClAuthenticateSourceServiceImpl.java
@@ -0,0 +1,119 @@
+package com.newyetai.alitaforward.verification.source.cl;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.annotation.Resource;
+
+import org.springframework.stereotype.Service;
+
+import com.newyetai.alitaforward.verification.constants.FactorVerificationSourceTypeEnum;
+import com.newyetai.alitaforward.verification.dto.FactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.FourFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.PhoneThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.RealNameTwoFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.ThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.source.FactorVerificationSourceService;
+import com.newyetai.alitaforward.verification.source.cl.mapstruct.ClMapMapper;
+import com.newyetai.common.AlitaResult;
+import com.newyetai.common.constant.AuthStatusEnum;
+import com.newyetai.sdk.chuanglan.dto.BankCardFourRequestDTO;
+import com.newyetai.sdk.chuanglan.dto.BankCardThreeRequestDTO;
+import com.newyetai.sdk.chuanglan.dto.ChuangLanResultDTO;
+import com.newyetai.sdk.chuanglan.dto.PhoneThreeRequestDTO;
+import com.newyetai.sdk.chuanglan.dto.RealNameTwoBaseRequestDTO;
+import com.newyetai.sdk.chuanglan.service.ChuangLanService;
+import com.newyetai.sdk.common.constant.SdkConstants;
+
+import cn.hutool.json.JSONUtil;
+import lombok.extern.slf4j.Slf4j;
+
+
+/**
+ * 创蓝认证源
+ *
+ * @author cheny
+ * @date 2022/08/11
+ */
+@Slf4j
+@Service
+@SuppressWarnings("unchecked")
+public class ClAuthenticateSourceServiceImpl implements FactorVerificationSourceService {
+
+ @Override
+ public RealNameTwoFactorVerificationDTO twoVerify(RealNameTwoFactorVerificationDTO verificationDTO) {
+ RealNameTwoBaseRequestDTO requestDTO = ClMapMapper.INSTANCE.toTwoRequestDTO(verificationDTO);
+ log.info("执行创蓝运营商二要素认证:{}", JSONUtil.toJsonStr(requestDTO));
+ AlitaResult result = chuangLanService.checkRealNameTwoBase(requestDTO);
+ handlerResult(result, verificationDTO);
+ return verificationDTO;
+ }
+
+ @Override
+ public PhoneThreeFactorVerificationDTO phoneThreeVerify(PhoneThreeFactorVerificationDTO verificationDTO) {
+ PhoneThreeRequestDTO phoneThreeRequestDTO = ClMapMapper.INSTANCE
+ .toPhoneThreeRequestDTO(verificationDTO);
+ log.info("执行创蓝运营商三要素认证:{}", JSONUtil.toJsonStr(phoneThreeRequestDTO));
+ AlitaResult result = chuangLanService.checkPhoneThree(phoneThreeRequestDTO);
+ handlerResult(result, verificationDTO);
+ return verificationDTO;
+ }
+
+ @Override
+ public ThreeFactorVerificationDTO threeVerify(
+ ThreeFactorVerificationDTO verificationDTO) {
+ BankCardThreeRequestDTO bankCardThreeRequestDTO = ClMapMapper.INSTANCE
+ .toThreeRequestDTO(verificationDTO);
+ log.info("执行创蓝三要素认证:{}", JSONUtil.toJsonStr(bankCardThreeRequestDTO));
+ AlitaResult result = chuangLanService.checkBankCardThree(bankCardThreeRequestDTO);
+ handlerResult(result, verificationDTO);
+ return verificationDTO;
+ }
+
+ @Override
+ public FourFactorVerificationDTO fourVerify(
+ FourFactorVerificationDTO verificationDTO) {
+ //调用放心签
+ BankCardFourRequestDTO bankCardFourRequestDTO = ClMapMapper.INSTANCE
+ .toFourRequestDTO(verificationDTO);
+ log.info("执行创蓝四要素认证:{}", JSONUtil.toJsonStr(bankCardFourRequestDTO));
+ AlitaResult result = chuangLanService.checkBankCardFour(bankCardFourRequestDTO);
+ handlerResult(result, verificationDTO);
+
+ return verificationDTO;
+ }
+
+ /**
+ * 处理结果
+ *
+ * @param result 结果
+ * @param verificationDTO 验证dto
+ */
+ private void handlerResult(AlitaResult result, FactorVerificationDTO verificationDTO) {
+ verificationDTO.setInvokeData(Optional.ofNullable(result.getData()).map(ChuangLanResultDTO::getJsonData).orElse(""));
+ AuthStatusEnum targetStatus = null;
+ if (SdkConstants.SDK_INVOKE_NOT_REACH_CODE.equals(result.getCode())) {
+ // 接口调起失败,未拿到返回结果,视为未调起
+ verificationDTO.setFailReason("调用异常,未调起第三方");
+ } else {
+ if (Boolean.TRUE.equals(result.getSuccess()) && Boolean.TRUE.equals(result.getData().getStatus())) {
+ targetStatus = AuthStatusEnum.AUTH_SUCCESS;
+ } else {
+ targetStatus = AuthStatusEnum.AUTH_FAIL;
+ verificationDTO.setFailReason(result.getMsg());
+ }
+ }
+ if (Objects.nonNull(targetStatus)) {
+ verificationDTO.setStatus(targetStatus.getType());
+ }
+ }
+
+ @Resource(name = ChuangLanService.BEAN_ID)
+ private ChuangLanService chuangLanService;
+
+
+ @Override
+ public FactorVerificationSourceTypeEnum getSourceType() {
+ return FactorVerificationSourceTypeEnum.CL;
+ }
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/source/cl/mapstruct/ClMapMapper.java b/src/main/java/com/newyetai/alitaforward/verification/source/cl/mapstruct/ClMapMapper.java
new file mode 100644
index 0000000..377111f
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/source/cl/mapstruct/ClMapMapper.java
@@ -0,0 +1,76 @@
+package com.newyetai.alitaforward.verification.source.cl.mapstruct;
+
+import com.newyetai.alitaforward.verification.dto.FourFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.PhoneThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.RealNameTwoFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.ThreeFactorVerificationDTO;
+import com.newyetai.sdk.chuanglan.dto.BankCardFourRequestDTO;
+import com.newyetai.sdk.chuanglan.dto.BankCardThreeRequestDTO;
+import com.newyetai.sdk.chuanglan.dto.PhoneThreeRequestDTO;
+import com.newyetai.sdk.chuanglan.dto.RealNameTwoBaseRequestDTO;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author czy
+ * @date 2021-06-23
+ */
+@Mapper
+public interface ClMapMapper {
+
+ ClMapMapper INSTANCE = Mappers.getMapper(ClMapMapper.class);
+
+ /**
+ * dto转创蓝三要素认证请求对象
+ *
+ * @param dto 验证dto
+ * @return {@link RealNameTwoBaseRequestDTO}
+ */
+ @Mappings(value = {
+ @Mapping(target = "name", source = "dto.realName"),
+ @Mapping(target = "idNum", source = "dto.cardNo")
+ })
+ RealNameTwoBaseRequestDTO toTwoRequestDTO(RealNameTwoFactorVerificationDTO dto);
+
+ /**
+ * dto转创蓝三要素认证请求对象
+ *
+ * @param dto
+ * @return {@link BankCardThreeRequestDTO}
+ */
+ @Mappings(value = {
+ @Mapping(target = "name", source = "dto.realName"),
+ @Mapping(target = "idNum", source = "dto.cardNo"),
+ @Mapping(target = "cardNo", source = "dto.bankAccountNo")
+ })
+ BankCardThreeRequestDTO toThreeRequestDTO(ThreeFactorVerificationDTO dto);
+
+ /**
+ * dto转创蓝三要素认证请求对象
+ *
+ * @param dto dto
+ * @return {@link PhoneThreeRequestDTO}
+ */
+ @Mappings(value = {
+ @Mapping(target = "name", source = "dto.realName"),
+ @Mapping(target = "idNum", source = "dto.cardNo"),
+ @Mapping(target = "mobile", source = "dto.phone")
+ })
+ PhoneThreeRequestDTO toPhoneThreeRequestDTO(PhoneThreeFactorVerificationDTO dto);
+
+ /**
+ * dto转创蓝四要素认证请求对象
+ *
+ * @param dto
+ * @return {@link BankCardFourRequestDTO}
+ */
+ @Mappings(value = {
+ @Mapping(target = "name", source = "dto.realName"),
+ @Mapping(target = "idNum", source = "dto.cardNo"),
+ @Mapping(target = "cardNo", source = "dto.bankAccountNo"),
+ @Mapping(target = "mobile", source = "dto.phone")
+ })
+ BankCardFourRequestDTO toFourRequestDTO(FourFactorVerificationDTO dto);
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/source/fxq/FxqAuthenticateSourceServiceImpl.java b/src/main/java/com/newyetai/alitaforward/verification/source/fxq/FxqAuthenticateSourceServiceImpl.java
new file mode 100644
index 0000000..637106c
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/source/fxq/FxqAuthenticateSourceServiceImpl.java
@@ -0,0 +1,88 @@
+package com.newyetai.alitaforward.verification.source.fxq;
+
+import java.util.Objects;
+
+import javax.annotation.Resource;
+
+import org.springframework.stereotype.Service;
+
+import com.newyetai.alitaforward.verification.constants.FactorVerificationSourceTypeEnum;
+import com.newyetai.alitaforward.verification.dto.FactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.FourFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.ThreeFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.source.FactorVerificationSourceService;
+import com.newyetai.alitaforward.verification.source.fxq.mapstruct.FxqMapMapper;
+import com.newyetai.common.AlitaResult;
+import com.newyetai.common.constant.AuthStatusEnum;
+import com.newyetai.sdk.common.constant.SdkConstants;
+import com.newyetai.sdk.fangxinqian.dto.BankCardFourRequestDTO;
+import com.newyetai.sdk.fangxinqian.dto.BankCardThreeRequestDTO;
+import com.newyetai.sdk.fangxinqian.service.FangXinQianService;
+
+import cn.hutool.json.JSONUtil;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author czy
+ * @date 2021-06-21
+ */
+@Slf4j
+@Service
+public class FxqAuthenticateSourceServiceImpl implements FactorVerificationSourceService {
+
+ @Override
+ public ThreeFactorVerificationDTO threeVerify(
+ ThreeFactorVerificationDTO threeFactorVerificationDTO) {
+ BankCardThreeRequestDTO bankCardThreeRequestDto =
+ FxqMapMapper.INSTANCE.toThreeRequestDTO(threeFactorVerificationDTO);
+ log.info("执行放心签三要素认证:{}", JSONUtil.toJsonStr(bankCardThreeRequestDto));
+ AlitaResult result = fangXinQianService.checkBankCardThree(bankCardThreeRequestDto);
+ handlerResult(result, threeFactorVerificationDTO);
+ return threeFactorVerificationDTO;
+ }
+
+ @Override
+ public FourFactorVerificationDTO fourVerify(
+ FourFactorVerificationDTO fourFactorVerificationDTO) {
+ //调用放心签
+ BankCardFourRequestDTO bankCardFourRequestDTO = FxqMapMapper.INSTANCE
+ .toFourRequestDTO(fourFactorVerificationDTO);
+ log.info("执行放心签四要素认证:{}", JSONUtil.toJsonStr(bankCardFourRequestDTO));
+ AlitaResult result = fangXinQianService.checkBankCardFour(bankCardFourRequestDTO);
+ handlerResult(result, fourFactorVerificationDTO);
+
+ return fourFactorVerificationDTO;
+ }
+
+ /**
+ * 处理结果
+ *
+ * @param result 结果
+ * @param verificationDTO 验证dto
+ */
+ private void handlerResult(AlitaResult result, FactorVerificationDTO verificationDTO) {
+ AuthStatusEnum targetStatus = null;
+ if (SdkConstants.SDK_INVOKE_NOT_REACH_CODE.equals(result.getCode())) {
+ // 接口调起失败,未拿到返回结果,视为未调起
+ verificationDTO.setFailReason("调用异常,未调起第三方");
+ } else {
+ if (Boolean.TRUE.equals(result.getSuccess()) && Boolean.TRUE.equals(result.getData())) {
+ targetStatus = AuthStatusEnum.AUTH_SUCCESS;
+ } else {
+ targetStatus = AuthStatusEnum.AUTH_FAIL;
+ verificationDTO.setFailReason(result.getMsg());
+ }
+ }
+ if (Objects.nonNull(targetStatus)) {
+ verificationDTO.setStatus(targetStatus.getType());
+ }
+ }
+
+ @Resource(name = FangXinQianService.BEAN_ID)
+ private FangXinQianService fangXinQianService;
+
+ @Override
+ public FactorVerificationSourceTypeEnum getSourceType() {
+ return FactorVerificationSourceTypeEnum.FXQ;
+ }
+}
diff --git a/src/main/java/com/newyetai/alitaforward/verification/source/fxq/mapstruct/FxqMapMapper.java b/src/main/java/com/newyetai/alitaforward/verification/source/fxq/mapstruct/FxqMapMapper.java
new file mode 100644
index 0000000..230879f
--- /dev/null
+++ b/src/main/java/com/newyetai/alitaforward/verification/source/fxq/mapstruct/FxqMapMapper.java
@@ -0,0 +1,49 @@
+package com.newyetai.alitaforward.verification.source.fxq.mapstruct;
+
+import com.newyetai.alitaforward.verification.dto.FourFactorVerificationDTO;
+import com.newyetai.alitaforward.verification.dto.ThreeFactorVerificationDTO;
+import com.newyetai.sdk.fangxinqian.dto.BankCardFourRequestDTO;
+import com.newyetai.sdk.fangxinqian.dto.BankCardThreeRequestDTO;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author czy
+ * @date 2021-06-23
+ */
+@Mapper
+public interface FxqMapMapper {
+
+ FxqMapMapper INSTANCE = Mappers.getMapper(
+ FxqMapMapper.class);
+
+
+ /**
+ * dto转放心签三要素认证请求对象
+ *
+ * @param dto
+ * @return {@link BankCardThreeRequestDTO}
+ */
+ @Mappings(value = {
+ @Mapping(target = "name", source = "dto.realName"),
+ @Mapping(target = "identityCode", source = "dto.cardNo"),
+ @Mapping(target = "bankcardNumber", source = "dto.bankAccountNo")
+ })
+ BankCardThreeRequestDTO toThreeRequestDTO(ThreeFactorVerificationDTO dto);
+
+ /**
+ * dto转放心签四要素认证请求对象
+ *
+ * @param dto
+ * @return {@link BankCardFourRequestDTO}
+ */
+ @Mappings(value = {
+ @Mapping(target = "name", source = "dto.realName"),
+ @Mapping(target = "identityCode", source = "dto.cardNo"),
+ @Mapping(target = "bankcardNumber", source = "dto.bankAccountNo"),
+ @Mapping(target = "phoneNumber", source = "dto.phone")
+ })
+ BankCardFourRequestDTO toFourRequestDTO(FourFactorVerificationDTO dto);
+}
diff --git a/src/main/java/com/newyetai/business/ability/enums/ProdTypeEnum.java b/src/main/java/com/newyetai/business/ability/enums/ProdTypeEnum.java
new file mode 100644
index 0000000..a18635b
--- /dev/null
+++ b/src/main/java/com/newyetai/business/ability/enums/ProdTypeEnum.java
@@ -0,0 +1,67 @@
+package com.newyetai.business.ability.enums;
+
+/**
+ * 产品类型
+ *
+ * @author sr on 2021-03-29
+ */
+public enum ProdTypeEnum {
+
+ /**
+ * 新业态-灵活就业
+ **/
+ XYT(10, "新业态产品"),
+ /**
+ * 其他
+ **/
+ OTHER(11, "其他"),
+ /**
+ * 短信
+ **/
+ SMS_COUNT(12, "短信计次"),
+ /**
+ * 三要素
+ **/
+ BANK_CARD_THREE_COUNT(13, "三要素计次"),
+ /**
+ * 电子合同
+ **/
+ ELECTRONIC_CONTRACT_COUNT(14, "合同计次"),
+ /**
+ * 发票
+ **/
+ INVOICE(15, "开票余额"),
+ /**
+ * 工商信息
+ **/
+ COMPANY_INFO(16, "工商信息"),
+ /**
+ * 积分
+ **/
+ POINT(17, "积分"),
+ /**
+ * 通用支付
+ */
+ OPEN_PAY(18, "通用支付"),
+ /**
+ * 无卡发薪
+ */
+ UPAY(19, "无卡发薪"),
+ /**
+ * 平台认证
+ */
+ PLATFORM_VERIFICATION(20, "平台认证");
+
+ ProdTypeEnum(Integer type, String desc) {
+ this.type = type;
+ this.desc = desc;
+ }
+
+ private Integer type;
+ private String desc;
+
+ public Integer getType() {
+ return type;
+ }
+
+}
diff --git a/src/main/java/com/newyetai/codegenerator/config/CodeConfiguration.java b/src/main/java/com/newyetai/codegenerator/config/CodeConfiguration.java
new file mode 100644
index 0000000..34a6c27
--- /dev/null
+++ b/src/main/java/com/newyetai/codegenerator/config/CodeConfiguration.java
@@ -0,0 +1,77 @@
+package com.newyetai.codegenerator.config;
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+import com.newyetai.codegenerator.service.CodeService;
+import com.newyetai.codegenerator.service.SnowflakeIdWorker;
+import com.newyetai.codegenerator.service.generator.SnowFlakeCodeGenerator;
+import com.newyetai.codegenerator.service.impl.CodeServiceImpl;
+import com.newyetai.codegenerator.util.CodeUtils;
+import com.newyetai.common.CommonConfiguration;
+import com.newyetai.common.constant.CommonConstants;
+import com.newyetai.common.util.EnvironmentUtils;
+import com.newyetai.common.util.RequestUtils;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 发号器配置类
+ * @author sr on 2021-03-23
+ */
+@Configuration
+@AutoConfigureAfter(CommonConfiguration.class)
+@Slf4j
+public class CodeConfiguration {
+
+ public static final String PROP_WORID_PREFIX = "code.snowflake.workid";
+
+ /**
+ * 默认编号生成器
+ * @return
+ * @author sr on 2021-03-23
+ */
+ @Bean
+ public SnowFlakeCodeGenerator snowFlakeCodeGenerator() {
+ // 机器id
+ String hostIp = RequestUtils.getHostIp();
+ log.info("hostIp:" + hostIp);
+ String workIdStr = EnvironmentUtils.getProperty(
+ String.join(CommonConstants.POINT, PROP_WORID_PREFIX, hostIp));
+ Long workId = 99l;
+ try {
+ if (StringUtils.isNoneBlank(workIdStr)) {
+ workId = Long.valueOf(workIdStr);
+ }
+ } catch (Exception e) {
+ }
+ SnowflakeIdWorker idWorker = new SnowflakeIdWorker(workId, 0);
+ return new SnowFlakeCodeGenerator(idWorker);
+ }
+
+ /**
+ * 编号service(根据类型分发不同的生成器)
+ * @return
+ * @author sr on 2021-03-23
+ */
+ @Bean
+ public CodeService codeService() {
+ CodeService codeService = new CodeServiceImpl();
+ CodeUtils.setCodeService(codeService);
+ return codeService;
+ }
+
+
+}
diff --git a/src/main/java/com/newyetai/codegenerator/constant/CodeConstants.java b/src/main/java/com/newyetai/codegenerator/constant/CodeConstants.java
new file mode 100644
index 0000000..f336d76
--- /dev/null
+++ b/src/main/java/com/newyetai/codegenerator/constant/CodeConstants.java
@@ -0,0 +1,26 @@
+package com.newyetai.codegenerator.constant;
+
+/**
+ * 编号常量类
+ * @author sr on 2019-09-15
+ */
+public class CodeConstants {
+
+ /** 生成器类型:默认(不可用) **/
+// public static final String GENERATOR_TYPE_DEFAULT = "DEFAULT";
+ public static final String GENERATOR_TYPE_SNOW_FLAKE = "SnowFlake";
+
+ /** id默认长度 **/
+ public static final int ID_DEFAULT_LENGTH = 5;
+
+ /** id默认补位字符 **/
+ public static final char ID_DEFAULT_PAD = '0';
+ /** id默认日期格式化 **/
+ public static final DateFormatterEnum ID_DEFAULT_FORMATTER = DateFormatterEnum.YEAR;
+
+ /** -----异常信息----- **/
+ public static final String CODE_GENERATE_ERROR = "编号生成失败";
+ /** -----异常信息----- **/
+
+
+}
diff --git a/src/main/java/com/newyetai/codegenerator/constant/DateFormatterEnum.java b/src/main/java/com/newyetai/codegenerator/constant/DateFormatterEnum.java
new file mode 100644
index 0000000..4b638f0
--- /dev/null
+++ b/src/main/java/com/newyetai/codegenerator/constant/DateFormatterEnum.java
@@ -0,0 +1,32 @@
+package com.newyetai.codegenerator.constant;
+
+import java.time.format.DateTimeFormatter;
+
+/**
+ * 日期formatter枚举
+ * @author sr on 2019-12-03
+ */
+public enum DateFormatterEnum {
+
+ /** 年:yyyy **/
+ YEAR(DateTimeFormatter.ofPattern("yyyy")),
+ /** 年月:yyyyMM **/
+ YM(DateTimeFormatter.ofPattern("yyyyMM")),
+ /** 年月:yyMM **/
+ YM2(DateTimeFormatter.ofPattern("yyMM")),
+ /** 年月日:yyyyMMdd **/
+ YMD(DateTimeFormatter.ofPattern("yyyyMMdd")),
+ /** 年月日:yyMMdd **/
+ YMD2(DateTimeFormatter.ofPattern("yyMMdd"));
+
+ private DateTimeFormatter formatter;
+
+ private DateFormatterEnum(DateTimeFormatter formatter){
+ this.formatter = formatter;
+ }
+
+ public DateTimeFormatter getDateTimeFormatter() {
+ return this.formatter;
+ }
+
+}
diff --git a/src/main/java/com/newyetai/codegenerator/exception/CodeGeneratorException.java b/src/main/java/com/newyetai/codegenerator/exception/CodeGeneratorException.java
new file mode 100644
index 0000000..70221c5
--- /dev/null
+++ b/src/main/java/com/newyetai/codegenerator/exception/CodeGeneratorException.java
@@ -0,0 +1,26 @@
+package com.newyetai.codegenerator.exception;
+
+/**
+ * 编号生成器异常
+ * @author sr on 2019-12-03
+ */
+public class CodeGeneratorException extends RuntimeException{
+
+ /** **/
+ private static final long serialVersionUID = 3558280270933232655L;
+
+
+ public CodeGeneratorException() {}
+
+ public CodeGeneratorException(String message) {
+ super(message);
+ }
+
+ public CodeGeneratorException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public CodeGeneratorException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/src/main/java/com/newyetai/codegenerator/pojo/CodeParam.java b/src/main/java/com/newyetai/codegenerator/pojo/CodeParam.java
new file mode 100644
index 0000000..ea67bac
--- /dev/null
+++ b/src/main/java/com/newyetai/codegenerator/pojo/CodeParam.java
@@ -0,0 +1,25 @@
+package com.newyetai.codegenerator.pojo;
+
+import com.newyetai.codegenerator.constant.CodeConstants;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.Builder.Default;
+
+/**
+ * 编码生成参数对象
+ * @author sr on 2019-12-05
+ */
+@Data
+@Builder
+public class CodeParam {
+
+ /** 生成器类型 **/
+ @Default
+ private String generatorType = CodeConstants.GENERATOR_TYPE_SNOW_FLAKE;
+
+ /** 编码类型 **/
+ private String type;
+
+
+}
diff --git a/src/main/java/com/newyetai/codegenerator/service/CodeGenerator.java b/src/main/java/com/newyetai/codegenerator/service/CodeGenerator.java
new file mode 100644
index 0000000..c023518
--- /dev/null
+++ b/src/main/java/com/newyetai/codegenerator/service/CodeGenerator.java
@@ -0,0 +1,42 @@
+package com.newyetai.codegenerator.service;
+
+import java.util.List;
+
+import com.newyetai.codegenerator.pojo.CodeParam;
+
+/**
+ * 编号生成器 默认一套实现,如需重定义中间时间format和id长度,重写规则 重写规则,注意去发号器对应的数据库表(leaf_alloc)中添加对应type+时间(biz_tag)的记录
+ *
+ * @author sr on 2019-09-15
+ */
+public interface CodeGenerator {
+
+ /**
+ * 自定义特定业务类型,即前缀
+ *
+ * @return
+ * @author sr on 2019-09-19
+ */
+ String getType();
+
+
+ /**
+ * 根据生成规则获取编号
+ *
+ * @param codeParam
+ * @return
+ * @author sr on 2020-07-13
+ */
+ String getCode(T codeParam);
+
+ /**
+ * 批量根据生成规则获取编号
+ *
+ * @param codeParam
+ * @return
+ * @author sr on 2020-07-13
+ */
+ List batchCode(T codeParam, Integer batchNum);
+
+
+}
diff --git a/src/main/java/com/newyetai/codegenerator/service/CodeService.java b/src/main/java/com/newyetai/codegenerator/service/CodeService.java
new file mode 100644
index 0000000..6fb3649
--- /dev/null
+++ b/src/main/java/com/newyetai/codegenerator/service/CodeService.java
@@ -0,0 +1,33 @@
+package com.newyetai.codegenerator.service;
+
+import java.util.List;
+
+import com.newyetai.codegenerator.pojo.CodeParam;
+
+/**
+ * 编号service(根据类型分发不同的生成器)
+ *
+ * @author sr on 2019-09-15
+ */
+public interface CodeService {
+
+ /**
+ * 根据生成规则获取编号
+ *
+ * @param codeParam
+ * @return
+ * @author sr on 2020-07-13
+ */
+ String getCode(CodeParam codeParam);
+
+ /**
+ * 批量根据生成规则获取编号
+ *
+ * @param codeParam
+ * @param batchNum 批次数(1-1000)
+ * @return
+ * @author sr on 2020-07-13
+ */
+ List batchCode(CodeParam codeParam, Integer batchNum);
+
+}
diff --git a/src/main/java/com/newyetai/codegenerator/service/SnowflakeIdWorker.java b/src/main/java/com/newyetai/codegenerator/service/SnowflakeIdWorker.java
new file mode 100644
index 0000000..434212d
--- /dev/null
+++ b/src/main/java/com/newyetai/codegenerator/service/SnowflakeIdWorker.java
@@ -0,0 +1,160 @@
+package com.newyetai.codegenerator.service;
+
+/**
+ * Twitter_Snowflake
+ * SnowFlake的结构如下(每部分用-分开):
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
+ * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0
+ * 41位时间戳(毫秒级),注意,41位时间戳不是存储当前时间的时间戳,而是存储时间戳的差值(当前时间戳 - 开始时间戳) 得到的值),这里的的开始时间戳,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间戳,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69
+ * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId
+ * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间戳)产生4096个ID序号
+ * 加起来刚好64位,为一个Long型。
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
+ */
+public class SnowflakeIdWorker {
+
+ // ==============================Fields===========================================
+ /** 开始时间戳 (2015-01-01) */
+ private final long twepoch = 1420041600000L;
+
+ /** 能容忍的系统时钟回拨时间(2秒) */
+ private final long timeOffset = 2000L;
+
+ /** 机器id所占的位数 */
+ private final long workerIdBits = 5L;
+
+ /** 数据标识id所占的位数 */
+ private final long datacenterIdBits = 5L;
+
+ /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
+ private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+ /** 支持的最大数据标识id,结果是31 */
+ private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+ /** 序列在id中占的位数 */
+ private final long sequenceBits = 12L;
+
+ /** 机器ID向左移12位 */
+ private final long workerIdShift = sequenceBits;
+
+ /** 数据标识id向左移17位(12+5) */
+ private final long datacenterIdShift = sequenceBits + workerIdBits;
+
+ /** 时间戳向左移22位(5+5+12) */
+ private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+ /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
+ private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+ /** 工作机器ID(0~31) */
+ private long workerId;
+
+ /** 数据中心ID(0~31) */
+ private long datacenterId;
+
+ /** 毫秒内序列(0~4095) */
+ private long sequence = 0L;
+
+ /** 上次生成ID的时间戳 */
+ private long lastTimestamp = -1L;
+
+ // ==============================Constructors=====================================
+ /**
+ * 构造函数
+ * @param workerId 工作ID (0~31)
+ * @param datacenterId 数据中心ID (0~31)
+ */
+ public SnowflakeIdWorker(long workerId, long datacenterId) {
+ if (workerId > maxWorkerId || workerId < 0) {
+ throw new IllegalArgumentException(
+ String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+ }
+ if (datacenterId > maxDatacenterId || datacenterId < 0) {
+ throw new IllegalArgumentException(
+ String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+ }
+ this.workerId = workerId;
+ this.datacenterId = datacenterId;
+ }
+
+ // ==============================Methods==========================================
+ /**
+ * 获得下一个ID (该方法是线程安全的)
+ * @return SnowflakeId
+ */
+ public synchronized long nextId() {
+ long timestamp = timeGen();
+
+ // 当前时间戳小于上一次ID生成的时间戳
+ if (timestamp < lastTimestamp) {
+ long offset = lastTimestamp - timestamp;
+ // 系统时钟回退在容忍范围内,例如出现过闰秒
+ if (offset < timeOffset) {
+ timestamp = lastTimestamp;
+ }
+ // 系统时钟回退超出容忍范围,抛出异常
+ else {
+ throw new RuntimeException(String
+ .format("Clock moved backwards. Refusing to generate id for %d milliseconds", offset));
+ }
+ }
+
+ // 如果是同一时间生成的,则进行毫秒内序列
+ if (lastTimestamp == timestamp) {
+ sequence = (sequence + 1) & sequenceMask;
+ // 毫秒内序列溢出
+ if (sequence == 0) {
+ // 阻塞到下一个毫秒,获得新的时间戳
+ timestamp = tilNextMillis(lastTimestamp);
+ }
+ }
+ // 时间戳改变,毫秒内序列重置
+ else {
+ sequence = 0L;
+ }
+
+ // 上次生成ID的时间戳
+ lastTimestamp = timestamp;
+
+ // 移位并通过或运算拼到一起组成64位的ID
+ return ((timestamp - twepoch) << timestampLeftShift) //
+ | (datacenterId << datacenterIdShift) //
+ | (workerId << workerIdShift) //
+ | sequence;
+ }
+
+ /**
+ * 阻塞到下一个毫秒,直到获得新的时间戳
+ * @param lastTimestamp 上次生成ID的时间戳
+ * @return 当前时间戳
+ */
+ protected long tilNextMillis(long lastTimestamp) {
+ long timestamp = timeGen();
+ while (timestamp <= lastTimestamp) {
+ timestamp = timeGen();
+ }
+ return timestamp;
+ }
+
+ /**
+ * 返回以毫秒为单位的当前时间
+ * @return 当前时间(毫秒)
+ */
+ protected long timeGen() {
+ return System.currentTimeMillis();
+ }
+
+ // ==============================Test=============================================
+ /** 测试 */
+ public static void main(String[] args) {
+
+ System.out.println("1000011111010000000111110011100110011110000000000000000001100".length());
+ // SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0);
+ // for (int i = 0; i < 1000; i++) {
+ // long id = idWorker.nextId();
+ // System.out.println(Long.toBinaryString(id));
+ // System.out.println(id);
+ // }
+ }
+}
diff --git a/src/main/java/com/newyetai/codegenerator/service/generator/SnowFlakeCodeGenerator.java b/src/main/java/com/newyetai/codegenerator/service/generator/SnowFlakeCodeGenerator.java
new file mode 100644
index 0000000..b11beb2
--- /dev/null
+++ b/src/main/java/com/newyetai/codegenerator/service/generator/SnowFlakeCodeGenerator.java
@@ -0,0 +1,47 @@
+package com.newyetai.codegenerator.service.generator;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+import com.newyetai.codegenerator.constant.CodeConstants;
+import com.newyetai.codegenerator.pojo.CodeParam;
+import com.newyetai.codegenerator.service.CodeGenerator;
+import com.newyetai.codegenerator.service.SnowflakeIdWorker;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 默认编号生成器
+ *
+ * @author sr on 2019-09-15
+ */
+@Slf4j
+public class SnowFlakeCodeGenerator implements CodeGenerator {
+
+ private SnowflakeIdWorker snowflakeIdWorker;
+
+ public SnowFlakeCodeGenerator(SnowflakeIdWorker snowflakeIdWorker) {
+ this.snowflakeIdWorker = snowflakeIdWorker;
+ }
+
+
+ @Override
+ public String getType() {
+ return CodeConstants.GENERATOR_TYPE_SNOW_FLAKE;
+ }
+
+ @Override
+ public String getCode(CodeParam codeParam) {
+ return codeParam.getType() + snowflakeIdWorker.nextId();
+ }
+
+ @Override
+ public List batchCode(CodeParam codeParam, Integer batchNum) {
+ List ids = Lists.newArrayListWithCapacity(batchNum);
+ for (int i = 0; i < batchNum; i++) {
+ ids.add(this.getCode(codeParam));
+ }
+ return ids;
+ }
+
+}
diff --git a/src/main/java/com/newyetai/codegenerator/service/impl/CodeServiceImpl.java b/src/main/java/com/newyetai/codegenerator/service/impl/CodeServiceImpl.java
new file mode 100644
index 0000000..6a3e8d1
--- /dev/null
+++ b/src/main/java/com/newyetai/codegenerator/service/impl/CodeServiceImpl.java
@@ -0,0 +1,48 @@
+package com.newyetai.codegenerator.service.impl;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.google.common.collect.Maps;
+import com.newyetai.codegenerator.constant.CodeConstants;
+import com.newyetai.codegenerator.pojo.CodeParam;
+import com.newyetai.codegenerator.service.CodeGenerator;
+import com.newyetai.codegenerator.service.CodeService;
+
+/**
+ * 编号service实现类
+ *
+ * @author sr on 2019-09-15
+ */
+public class CodeServiceImpl implements CodeService {
+
+ private Map> codeGenerators = Maps.newHashMap();
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ @Autowired
+ private void codeGenerateResolver(List resolvers) {
+ resolvers.forEach(resolver -> codeGenerators.put(resolver.getType(), resolver));
+ }
+
+ private CodeGenerator getResolver(String type) {
+ CodeGenerator resolver = codeGenerators.get(type);
+ if (resolver == null) {
+ resolver = codeGenerators.get(CodeConstants.GENERATOR_TYPE_SNOW_FLAKE);
+ }
+ return resolver;
+ }
+
+ @Override
+ public String getCode(CodeParam codeParam) {
+ return getResolver(codeParam.getGeneratorType()).getCode(codeParam);
+ }
+
+ @Override
+ public List batchCode(CodeParam codeParam, Integer batchNum) {
+ return getResolver(codeParam.getGeneratorType()).batchCode(codeParam, batchNum);
+ }
+
+
+}
diff --git a/src/main/java/com/newyetai/codegenerator/util/CodeUtils.java b/src/main/java/com/newyetai/codegenerator/util/CodeUtils.java
new file mode 100644
index 0000000..ffed798
--- /dev/null
+++ b/src/main/java/com/newyetai/codegenerator/util/CodeUtils.java
@@ -0,0 +1,48 @@
+package com.newyetai.codegenerator.util;
+
+import java.util.List;
+
+import com.newyetai.codegenerator.pojo.CodeParam;
+import com.newyetai.codegenerator.service.CodeService;
+import com.newyetai.component.constants.CodeTypeEnum;
+
+/**
+ * 发号器工具类
+ * @author sr on 2021-03-23
+ */
+public abstract class CodeUtils {
+
+ private static CodeService codeService;
+
+ public static void setCodeService(CodeService codeService) {
+ CodeUtils.codeService = codeService;
+ }
+
+ public static String getCode(CodeTypeEnum codeTypeEnum) {
+ return codeService.getCode(codeTypeEnum.getCodeParam());
+ }
+
+ /**
+ * 根据生成规则获取编号
+ *
+ * @param codeParam
+ * @return
+ * @author sr on 2021-03-23
+ */
+ public static String getCode(CodeParam codeParam) {
+ return codeService.getCode(codeParam);
+ }
+
+ /**
+ * 批量根据生成规则获取编号
+ *
+ * @param codeParam
+ * @param batchNum
+ * @return
+ * @author sr on 2021-03-23
+ */
+ public static List batchCode(CodeParam codeParam, Integer batchNum) {
+ return codeService.batchCode(codeParam, batchNum);
+ }
+
+}
diff --git a/src/main/java/com/newyetai/codesetting/constant/CodeSettingConstants.java b/src/main/java/com/newyetai/codesetting/constant/CodeSettingConstants.java
new file mode 100644
index 0000000..006a6ff
--- /dev/null
+++ b/src/main/java/com/newyetai/codesetting/constant/CodeSettingConstants.java
@@ -0,0 +1,37 @@
+package com.newyetai.codesetting.constant;
+
+public interface CodeSettingConstants {
+ /**
+ * 编码配置数据类型
+ */
+ public static final String CODE_SETTING_DATA_TYPE = "code_setting_data_type";
+
+ public class CodeSettingDataType {
+
+ public static final String STRING = "1";
+
+ public static final String NUMBER = "2";
+
+ public static final String DATE = "3";
+
+ public static final String BOOL = "4";
+
+ public static final String RADIO = "5";
+
+ public static final String CHECKBOX = "6";
+
+ public static final String FILE = "7";
+
+ }
+
+ /**
+ * 编码配置模块:机构配置
+ **/
+ public static final String CODE_SETTING_TYPE_CONFIG = "1";
+
+ /**
+ * 编码配置默认级别
+ **/
+ public static final String CODE_SETTING_LEVEL_DEFAULT = "1,2,3,4";
+
+}
diff --git a/src/main/java/com/newyetai/codesetting/controller/CodeSettingController.java b/src/main/java/com/newyetai/codesetting/controller/CodeSettingController.java
new file mode 100644
index 0000000..a05d327
--- /dev/null
+++ b/src/main/java/com/newyetai/codesetting/controller/CodeSettingController.java
@@ -0,0 +1,67 @@
+package com.newyetai.codesetting.controller;
+
+import com.newyetai.codesetting.dto.CodeSettingDTO;
+import com.newyetai.codesetting.dto.CodeSettingOperatorDTO;
+import com.newyetai.codesetting.dto.CodeSettingPageQueryDTO;
+import com.newyetai.codesetting.dto.CodeSettingQueryDTO;
+import com.newyetai.codesetting.service.CodeSettingService;
+import com.newyetai.common.AlitaResult;
+import com.newyetai.tkmybatis.pojo.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 编码表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2023-01-04
+ */
+@Api(tags = "编码表")
+@RestController
+@RequestMapping("code_setting")
+public class CodeSettingController {
+
+ @Autowired
+ private CodeSettingService codeSettingService;
+
+ @PostMapping
+ @ApiOperation("编码表-创建")
+ public AlitaResult create(@RequestBody CodeSettingOperatorDTO operatorDTO) {
+ return AlitaResult.success(codeSettingService.create(operatorDTO));
+ }
+
+ @PutMapping
+ @ApiOperation("编码表-修改")
+ public AlitaResult modify(@RequestBody CodeSettingOperatorDTO operatorDTO) {
+ return AlitaResult.success(codeSettingService.modify(operatorDTO));
+ }
+
+ @DeleteMapping("{id}")
+ @ApiOperation("编码表-删除")
+ public AlitaResult delete(@PathVariable("id") Long id) {
+ return AlitaResult.success(codeSettingService.delete(id));
+ }
+
+ @GetMapping("{id}")
+ @ApiOperation("编码表-查询单个")
+ public AlitaResult findById(@PathVariable("id") Long id) {
+ return AlitaResult.success(codeSettingService.findById(id));
+ }
+
+ @GetMapping("list")
+ @ApiOperation("编码表-列表查询")
+ public AlitaResult> list(CodeSettingQueryDTO queryDTO) {
+ return AlitaResult.success(codeSettingService.list(queryDTO));
+ }
+
+ @GetMapping("page")
+ @ApiOperation("编码表-分页查询")
+ public AlitaResult> page(CodeSettingPageQueryDTO queryDTO) {
+ codeSettingService.page(queryDTO);
+ return AlitaResult.success(queryDTO.getPageResult());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/codesetting/convert/CodeSettingConvert.java b/src/main/java/com/newyetai/codesetting/convert/CodeSettingConvert.java
new file mode 100644
index 0000000..8ebc5fb
--- /dev/null
+++ b/src/main/java/com/newyetai/codesetting/convert/CodeSettingConvert.java
@@ -0,0 +1,25 @@
+package com.newyetai.codesetting.convert;
+
+import com.newyetai.codesetting.dto.CodeSettingDTO;
+import com.newyetai.codesetting.dto.CodeSettingOperatorDTO;
+import com.newyetai.codesetting.entity.CodeSetting;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * 编码表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2023-01-04
+ */
+@Mapper
+public interface CodeSettingConvert {
+ CodeSettingConvert INSTANCE = Mappers.getMapper(CodeSettingConvert.class);
+
+ CodeSetting convert(CodeSettingDTO dto);
+
+ CodeSettingDTO convert(CodeSetting entity);
+
+ CodeSetting convert(CodeSettingOperatorDTO dto);
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/codesetting/dao/CodeSettingMapper.java b/src/main/java/com/newyetai/codesetting/dao/CodeSettingMapper.java
new file mode 100644
index 0000000..33df0b1
--- /dev/null
+++ b/src/main/java/com/newyetai/codesetting/dao/CodeSettingMapper.java
@@ -0,0 +1,35 @@
+package com.newyetai.codesetting.dao;
+
+import com.newyetai.codesetting.dto.CodeSettingDTO;
+import com.newyetai.codesetting.dto.CodeSettingPageQueryDTO;
+import com.newyetai.codesetting.dto.CodeSettingQueryDTO;
+import com.newyetai.codesetting.entity.CodeSetting;
+import com.newyetai.tkmybatis.mybatis.MyMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ * 编码表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2023-01-04
+ */
+@Mapper
+public interface CodeSettingMapper extends MyMapper {
+
+ List page(@Param("param") CodeSettingPageQueryDTO queryDTO);
+
+ List list(@Param("param") CodeSettingQueryDTO queryDTO);
+
+ /**
+ * 根据类型查询
+ *
+ * @param type
+ * @return
+ */
+ @Select("select * from xs_code_setting where type = #{type} and deleted = 0")
+ List queryByType(String type);
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/codesetting/dto/CodeSettingDTO.java b/src/main/java/com/newyetai/codesetting/dto/CodeSettingDTO.java
new file mode 100644
index 0000000..b53d11c
--- /dev/null
+++ b/src/main/java/com/newyetai/codesetting/dto/CodeSettingDTO.java
@@ -0,0 +1,46 @@
+package com.newyetai.codesetting.dto;
+
+import com.newyetai.common.dto.BaseDTO;
+import com.newyetai.component.action.dto.ActionDetailDTO;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * 编码表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2023-01-04
+ */
+@ApiModel("编码表")
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CodeSettingDTO extends BaseDTO {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("编码")
+ private String code;
+
+ @ApiModelProperty("名称")
+ private String name;
+
+ @ApiModelProperty("备注")
+ private String remark;
+
+ @ApiModelProperty("类型 模板编码、配置编码")
+ private String type;
+
+ @ApiModelProperty("数据类型")
+ private String dataType;
+
+ @ApiModelProperty("级别 平台、渠道、定制机构、普通机构")
+ private String level;
+
+ @ApiModelProperty("数据值")
+ private String dataFormat;
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/codesetting/dto/CodeSettingOperatorDTO.java b/src/main/java/com/newyetai/codesetting/dto/CodeSettingOperatorDTO.java
new file mode 100644
index 0000000..a316768
--- /dev/null
+++ b/src/main/java/com/newyetai/codesetting/dto/CodeSettingOperatorDTO.java
@@ -0,0 +1,60 @@
+package com.newyetai.codesetting.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotEmpty;
+import java.io.Serializable;
+
+/**
+ * 编码表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2023-01-04
+ */
+@ApiModel("编码表")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class CodeSettingOperatorDTO implements Serializable {
+
+ private static final long serialVersionUID = 8836210011277521607L;
+ private Long id;
+
+ @ApiModelProperty("编码")
+ @NotEmpty(message = "配置项编码不能为空")
+ @Length(min = 1, max = 64, message = "配置项编码长度超限")
+ private String code;
+
+ @ApiModelProperty("名称")
+ @NotEmpty(message = "配置项名称不能为空")
+ @Length(min = 1, max = 128, message = "配置项名称长度超限")
+ private String name;
+
+ @ApiModelProperty("备注")
+// @NotEmpty(message = "备注不能为空")
+ private String remark;
+
+ @ApiModelProperty("数据值")
+ private String dataFormat;
+
+ @ApiModelProperty("类型 模板编码、配置编码")
+ @NotEmpty(message = "配置类型不能为空")
+ private String type;
+
+ @ApiModelProperty("数据类型")
+ @NotEmpty(message = "配置参数类型不能为空")
+ private String dataType;
+
+ @ApiModelProperty("级别 平台、渠道、定制机构、普通机构")
+ @NotEmpty(message = "配置应用级别不能为空")
+ private String level;
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/codesetting/dto/CodeSettingPageQueryDTO.java b/src/main/java/com/newyetai/codesetting/dto/CodeSettingPageQueryDTO.java
new file mode 100644
index 0000000..0c4376d
--- /dev/null
+++ b/src/main/java/com/newyetai/codesetting/dto/CodeSettingPageQueryDTO.java
@@ -0,0 +1,77 @@
+package com.newyetai.codesetting.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.newyetai.common.annotation.trimAndUpper.TrimAndUpper;
+import com.newyetai.common.dto.PageQueryDTO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 编码表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2023-01-04
+ */
+
+@ApiModel("编码表")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CodeSettingPageQueryDTO extends PageQueryDTO {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("主键ID")
+ private Long id;
+
+ @ApiModelProperty("编码")
+ private String code;
+
+ @ApiModelProperty("编码 (模糊匹配)")
+ @TrimAndUpper(TrimAndUpper.ExecuteType.TRIM)
+ private String codeLike;
+
+ @ApiModelProperty("名称 (模糊匹配)")
+ @TrimAndUpper(TrimAndUpper.ExecuteType.TRIM)
+ private String nameLike;
+
+ @ApiModelProperty("备注")
+ private String remark;
+
+ @ApiModelProperty("类型 模板编码、配置编码")
+ @TrimAndUpper(TrimAndUpper.ExecuteType.TRIM)
+ private String type;
+
+ @ApiModelProperty("数据类型")
+ private String dataType;
+
+ @ApiModelProperty("级别 平台、渠道、定制机构、普通机构")
+ private String level;
+
+ @ApiModelProperty("创建时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeStart;
+
+ @ApiModelProperty("创建时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeEnd;
+
+ @ApiModelProperty("修改时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeStart;
+
+ @ApiModelProperty("修改时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeEnd;
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/codesetting/dto/CodeSettingQueryDTO.java b/src/main/java/com/newyetai/codesetting/dto/CodeSettingQueryDTO.java
new file mode 100644
index 0000000..caead13
--- /dev/null
+++ b/src/main/java/com/newyetai/codesetting/dto/CodeSettingQueryDTO.java
@@ -0,0 +1,74 @@
+package com.newyetai.codesetting.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 编码表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2023-01-04
+ */
+@ApiModel("编码表")
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class CodeSettingQueryDTO implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("主键ID")
+ private Long id;
+
+ @ApiModelProperty("编码")
+ private String code;
+
+ @ApiModelProperty("编码 (模糊匹配)")
+ private String codeLike;
+
+ @ApiModelProperty("名称 (模糊匹配)")
+ private String nameLike;
+
+ @ApiModelProperty("备注")
+ private String remark;
+
+ @ApiModelProperty("类型 模板编码、配置编码")
+ private String type;
+
+ @ApiModelProperty("数据类型")
+ private String dataType;
+
+ @ApiModelProperty("级别 平台、渠道、定制机构、普通机构")
+ private String level;
+
+ @ApiModelProperty("创建时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeStart;
+
+ @ApiModelProperty("创建时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTimeEnd;
+
+ @ApiModelProperty("修改时间起,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeStart;
+
+ @ApiModelProperty("修改时间止,格式 (yyyy-MM-dd HH:mm:ss)")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTimeEnd;
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/codesetting/entity/CodeSetting.java b/src/main/java/com/newyetai/codesetting/entity/CodeSetting.java
new file mode 100644
index 0000000..d3511b4
--- /dev/null
+++ b/src/main/java/com/newyetai/codesetting/entity/CodeSetting.java
@@ -0,0 +1,56 @@
+package com.newyetai.codesetting.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.newyetai.common.entity.BaseEntity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 编码表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2023-01-04
+ */
+@TableName("xs_code_setting")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CodeSetting extends BaseEntity {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 编码
+ */
+ private String code;
+ /**
+ * 名称
+ */
+ private String name;
+ /**
+ * 备注
+ */
+ private String remark;
+ /**
+ * 类型 模板编码、配置编码
+ */
+ private String type;
+ /**
+ * 数据类型
+ */
+ private String dataType;
+ /**
+ * 数据格式编号
+ */
+ private String dataFormat;
+ /**
+ * 级别 平台、渠道、定制机构、普通机构
+ */
+ private String level;
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/codesetting/mapper/CodeSettingMapper.xml b/src/main/java/com/newyetai/codesetting/mapper/CodeSettingMapper.xml
new file mode 100644
index 0000000..f0a6569
--- /dev/null
+++ b/src/main/java/com/newyetai/codesetting/mapper/CodeSettingMapper.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+ FROM
+ xs_code_setting t
+ WHERE t.deleted = 0
+
+ AND t.id = #{param.id}
+
+
+ AND t.code = #{param.code}
+
+
+
+ AND t.code like #{codeLike}
+
+
+
+ AND t.name like #{nameLike}
+
+
+ AND t.remark = #{param.remark}
+
+
+ AND t.type = #{param.type}
+
+
+ AND t.data_type = #{param.dataType}
+
+
+ AND FIND_IN_SET(CONCAT(#{param.level},""),t.level)
+
+
+ AND t.create_time >= #{param.createTimeStart}
+
+
+ AND t.create_time <= #{param.createTimeEnd}
+
+
+ AND t.update_time >= #{param.updateTimeStart}
+
+
+ AND t.update_time <= #{param.updateTimeEnd}
+
+ ORDER BY t.id DESC
+
+
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/codesetting/service/CodeSettingService.java b/src/main/java/com/newyetai/codesetting/service/CodeSettingService.java
new file mode 100644
index 0000000..b66f8b5
--- /dev/null
+++ b/src/main/java/com/newyetai/codesetting/service/CodeSettingService.java
@@ -0,0 +1,96 @@
+package com.newyetai.codesetting.service;
+
+import com.newyetai.codesetting.dto.CodeSettingDTO;
+import com.newyetai.codesetting.dto.CodeSettingOperatorDTO;
+import com.newyetai.codesetting.dto.CodeSettingPageQueryDTO;
+import com.newyetai.codesetting.dto.CodeSettingQueryDTO;
+import com.newyetai.codesetting.entity.CodeSetting;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.Valid;
+import javax.validation.groups.Default;
+import java.util.List;
+
+/**
+ * 编码表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2023-01-04
+ */
+@Validated(Default.class)
+public interface CodeSettingService {
+
+ /**
+ * 编码表 - 创建
+ *
+ * @param operatorDto 操作dto
+ * @return {@link CodeSettingDTO}
+ */
+ CodeSettingDTO create(@Valid CodeSettingOperatorDTO operatorDto);
+
+ /**
+ * 校验编码是否存在
+ *
+ * @param code 代码
+ * @param codeSettingId 编码ID
+ * @return boolean true: 存在重复编码
+ */
+ boolean checkCode(String code, Long codeSettingId);
+
+ /**
+ * 编码表 - 修改
+ *
+ * @param operatorDto 操作dto
+ * @return {@link CodeSettingDTO}
+ */
+ CodeSettingDTO modify(@Valid CodeSettingOperatorDTO operatorDto);
+
+ /**
+ * 编码表 - 删除
+ *
+ * @param id id
+ * @return {@link CodeSettingDTO}
+ */
+ CodeSettingDTO delete(Long id);
+
+ /**
+ * 编码表 - 根据ID查询单个
+ *
+ * @param id id
+ * @return {@link CodeSettingDTO}
+ */
+ CodeSettingDTO findById(Long id);
+
+ /**
+ * 编码表 - 列表查询
+ *
+ * @param queryDTO 列表查询dto
+ * @return {@link List}<{@link CodeSettingDTO}>
+ */
+ List list(CodeSettingQueryDTO queryDTO);
+
+ /**
+ * 编码表 - 分页查询
+ *
+ * @param queryDTO 分页查询dto
+ * @return {@link CodeSettingDTO}
+ */
+ List page(CodeSettingPageQueryDTO queryDTO);
+
+ /**
+ * 根据type和code查询
+ *
+ * @param codeSettingType
+ * @param orgType
+ * @return
+ */
+ List queryCode(String codeSettingType, String orgType);
+
+ /**
+ * 根据code查询
+ *
+ * @param code
+ * @return
+ */
+ CodeSettingDTO getByCode(String code);
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/codesetting/service/impl/CodeSettingServiceImpl.java b/src/main/java/com/newyetai/codesetting/service/impl/CodeSettingServiceImpl.java
new file mode 100644
index 0000000..eaf0aff
--- /dev/null
+++ b/src/main/java/com/newyetai/codesetting/service/impl/CodeSettingServiceImpl.java
@@ -0,0 +1,119 @@
+package com.newyetai.codesetting.service.impl;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.springframework.stereotype.Service;
+
+import com.newyetai.codesetting.convert.CodeSettingConvert;
+import com.newyetai.codesetting.dao.CodeSettingMapper;
+import com.newyetai.codesetting.dto.CodeSettingDTO;
+import com.newyetai.codesetting.dto.CodeSettingOperatorDTO;
+import com.newyetai.codesetting.dto.CodeSettingPageQueryDTO;
+import com.newyetai.codesetting.dto.CodeSettingQueryDTO;
+import com.newyetai.codesetting.entity.CodeSetting;
+import com.newyetai.codesetting.service.CodeSettingService;
+import com.newyetai.common.constant.CommonConstants;
+import com.newyetai.common.exception.util.Assert;
+import com.newyetai.common.util.UserContextHolder;
+import com.newyetai.config.dao.ConfigMapper;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 编码表
+ *
+ * @author chenyun chenyun.home@outlook.com
+ * @since 1.0.0 2023-01-04
+ */
+@Slf4j
+@Service
+public class CodeSettingServiceImpl implements CodeSettingService {
+
+ @Resource
+ private CodeSettingMapper codeSettingMapper;
+
+ @Resource
+ private ConfigMapper configMapper;
+
+ @Override
+ public CodeSettingDTO create(CodeSettingOperatorDTO operatorDto) {
+ Assert.isTrue(!checkCode(operatorDto.getCode(), null), "配置项编码已存在");
+ CodeSetting codeSetting = CodeSettingConvert.INSTANCE.convert(operatorDto);
+ codeSettingMapper.saveEntity(codeSetting);
+ return CodeSettingConvert.INSTANCE.convert(codeSetting);
+ }
+
+ @Override
+ public boolean checkCode(String code, Long codeSettingId) {
+ return codeSettingMapper.existsEntity(CodeSetting.builder().code(code).build());
+ }
+
+ @Override
+ public CodeSettingDTO modify(CodeSettingOperatorDTO operatorDto) {
+ CodeSettingDTO codeSettingDto = this.findById(operatorDto.getId());
+ if (Objects.isNull(codeSettingDto)) {
+ return null;
+ }
+ Assert.isTrue(!checkCode(operatorDto.getCode(), operatorDto.getId()), "配置项编码已存在");
+ CodeSetting codeSetting = CodeSettingConvert.INSTANCE.convert(operatorDto);
+ codeSettingMapper.updateEntity(codeSetting);
+ return this.findById(operatorDto.getId());
+ }
+
+ @Override
+ public CodeSettingDTO delete(Long id) {
+ CodeSettingDTO codeSettingDto = this.findById(id);
+ if (Objects.isNull(codeSettingDto)) {
+ return null;
+ }
+ CodeSetting codeSetting = CodeSetting.builder().build();
+ codeSetting.setId(id);
+ codeSettingMapper.deleteEntity(codeSetting, UserContextHolder.getLoginUserId());
+ // 删除配置项的时候,同步删除配置项下的配置
+ configMapper.batchDelete(codeSettingDto.getCode(), UserContextHolder.getExistLoginUserId());
+ return codeSettingDto;
+ }
+
+ @Override
+ public CodeSettingDTO findById(Long id) {
+ CodeSetting codeSetting = codeSettingMapper.getById(id);
+ if (Objects.isNull(codeSetting)) {
+ return null;
+ }
+ return CodeSettingConvert.INSTANCE.convert(codeSetting);
+ }
+
+ @Override
+ public List list(CodeSettingQueryDTO queryDTO) {
+ return codeSettingMapper.list(queryDTO);
+ }
+
+ @Override
+ public List page(CodeSettingPageQueryDTO queryDTO) {
+ return codeSettingMapper.page(queryDTO);
+ }
+
+ @Override
+ public List queryCode(String codeSettingType, String orgType) {
+ List codeSettings = codeSettingMapper.queryByType(codeSettingType);
+ return codeSettings.stream()
+ .filter(codeSetting -> ArrayUtils
+ .contains(codeSetting.getLevel().split(CommonConstants.COMMA), orgType))
+ .map(CodeSettingConvert.INSTANCE::convert).collect(Collectors.toList());
+ }
+
+ @Override
+ public CodeSettingDTO getByCode(String code) {
+ List list = this.list(CodeSettingQueryDTO.builder().code(code).build());
+ if (CollectionUtils.isEmpty(list)) {
+ return null;
+ }
+ return list.get(0);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/newyetai/common/AlitaResult.java b/src/main/java/com/newyetai/common/AlitaResult.java
new file mode 100644
index 0000000..74054a0
--- /dev/null
+++ b/src/main/java/com/newyetai/common/AlitaResult.java
@@ -0,0 +1,254 @@
+package com.newyetai.common;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.newyetai.sdk.common.constant.SdkConstants;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用于 ajax 请求的响应工具类
+ *
+ * @author guhong
+ * @date 2019/8/19
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AlitaResult implements Serializable {
+
+ /** */
+ private static final long serialVersionUID = 5933105804003541576L;
+
+ /** 未登录 * */
+ public static final String UN_LOGIN_CODE = "401";
+ /** 无权限 * */
+ public static final String NO_AUTHORITY_CODE = "402";
+ /** 无查询信息 * */
+ public static final String NO_RESULT_CODE = "405";
+ /** 登录用户多机构 * */
+ public static final String DUPLICATE_ORG_CODE = "600";
+ /** 登录用户多用户 * */
+ public static final String DUPLICATE_USER_CODE = "601";
+ /** 用户未实名 * */
+ public static final String UN_AUTH_CODE = "602";
+ /** 用户更换token **/
+ public static final String CHANGE_TOKEN_CODE = "603";
+ /** 用户未绑定手机号 **/
+ public static final String UN_BINDING_PHONE = "604";
+ /** 登录用户相关异常 **/
+ public static final String LOGIN_ERROR_CODE = "666";
+ /** 系统异常 * */
+ public static final String SYSTEM_ERROR_CODE = "999";
+ /** 业务异常 **/
+ public static final String BUSINESS_ERROR_CODE = "700";
+ /** 校验异常 * */
+ public static final String VALIDATION_ERROR_CODE = "555";
+ /** 操作成功 * */
+ public static final String SUCCESS_CODE = "200";
+
+ public static final String CHANG_TOKEN_MSG = "token变更";
+
+ /** 链路id **/
+ private String requestId;
+ /** 响应信息 */
+ private String msg;
+ /** 响应code */
+ private String code;
+ /** 是否成功 */
+ private Boolean success;
+ /** 操作成功,响应数据 */
+ private T data;
+ /** 操作失败结果 **/
+ private Object errorData;
+
+ /** 临时json **/
+ @JsonIgnore
+ private String tempJson;
+
+ public AlitaResult(String code, String msg, boolean success, T data) {
+ this.msg = msg;
+ this.code = code;
+ this.success = success;
+ this.data = data;
+ }
+
+ public AlitaResult(String code, String msg, Serializable errorData) {
+ this.msg = msg;
+ this.code = code;
+ this.success = false;
+ this.errorData = errorData;
+ }
+
+ /**
+ * 创建一个成功的响应对象
+ *
+ * @return
+ */
+ public static AlitaResult success() {
+ return success(null);
+ }
+
+ /**
+ * 创建一个成功的响应对象
+ *
+ * @param data
+ * @return
+ */
+ public static AlitaResult success(T data) {
+ return new AlitaResult(SUCCESS_CODE, "请求成功", true, data);
+ }
+
+ /**
+ * 创建一个成功的响应对象
+ *
+ * @param msg
+ * @return
+ */
+ public static AlitaResult success(String msg, T data) {
+ return new AlitaResult(SUCCESS_CODE, msg, true, data);
+ }
+
+ /**
+ * 创建一个失败的响应对象
+ *
+ * @param msg
+ * @return
+ */
+ public static AlitaResult error(String msg) {
+ return new AlitaResult(SYSTEM_ERROR_CODE, msg, false, null);
+ }
+
+ /**
+ * 创建一个失败的响应对象
+ *
+ * @param code
+ * @param msg
+ * @return
+ */
+ public static AlitaResult error(String code, String msg) {
+ return new AlitaResult(code, msg, false, null);
+ }
+
+ /**
+ * 创建一个失败的响应对象
+ *
+ * @param code
+ * @param msg
+ * @return
+ */
+ public static AlitaResult error(String code, String msg, T data) {
+ return new AlitaResult(code, msg, false, data);
+ }
+
+ /**
+ * 创建一个失败的响应对象
+ *
+ * @param msg
+ * @return
+ */
+ public static AlitaResult error(String msg, T data) {
+ return new AlitaResult(SYSTEM_ERROR_CODE, msg, false, data);
+ }
+
+ /**
+ * 创建业务异常对象
+ *
+ * @param
+ * @param msg
+ * @return
+ * @author sr on 2020-07-02
+ */
+ public static AlitaResult bizError(String msg) {
+ return new AlitaResult(BUSINESS_ERROR_CODE, msg, false, null);
+ }
+
+ /**
+ * 创建一个未登录响应对象
+ *
+ * @return
+ */
+ public static AlitaResult unLogin() {
+ return new AlitaResult(UN_LOGIN_CODE, "请先登录", false, null);
+ }
+
+ /**
+ * 创建未实名响应对象
+ * @param
+ * @return
+ * @author sr on 2021-06-30
+ */
+ public static AlitaResult unAuth() {
+ return new AlitaResult(UN_AUTH_CODE, "请先实名", false, null);
+ }
+
+ /**
+ * 创建未绑定手机号响应对象
+ * @param
+ * @return
+ * @author sr on 2021-06-30
+ */
+ public static AlitaResult unBinding() {
+ return new AlitaResult(UN_BINDING_PHONE, "请先绑定手机号", false, null);
+ }
+
+ /**
+ * 创建一个未登录响应对象
+ *
+ * @param loginUrl 登录地址
+ * @return
+ * @author sr on 2019-12-29
+ */
+ public static AlitaResult unLogin(String loginUrl) {
+ return new AlitaResult(UN_LOGIN_CODE, "请先登录", false, loginUrl);
+ }
+
+ /**
+ * 更换token
+ * @param
+ * @param token
+ * @return
+ * @author sr on 2021-08-02
+ */
+ public static AlitaResult changeToken(Serializable token) {
+ return new AlitaResult(AlitaResult.CHANGE_TOKEN_CODE, CHANG_TOKEN_MSG, token);
+ }
+
+ /**
+ * 创建一个未登录响应对象
+ *
+ * @return
+ * @author sr on 2019-12-29
+ */
+ public static AlitaResult noResult() {
+ return new AlitaResult(NO_RESULT_CODE, "无查询信息", false, null);
+ }
+
+ /**
+ * 接口调用失败,未能拿到返回对象
+ *
+ * @param
+ * @param msg
+ * @return
+ * @author sr on 2020-04-10
+ */
+ public static AlitaResult sdkInvokeNotReachError(String msg) {
+ return new AlitaResult(SdkConstants.SDK_INVOKE_NOT_REACH_CODE, msg, false, null);
+ }
+
+ @SuppressWarnings({"hiding", "unchecked"})
+ public AlitaResult setRequestId(String requestId){
+ this.requestId = requestId;
+ return (AlitaResult