Compare commits
46 Commits
dev-ui
...
c278d11390
| Author | SHA1 | Date | |
|---|---|---|---|
| c278d11390 | |||
| e0629f22e5 | |||
| 03ecbbd204 | |||
| eabd38fa58 | |||
| 03a4acb63a | |||
| 3286795f98 | |||
| 4c6ca52e7e | |||
| cc1a4538af | |||
| 5aaf6c83be | |||
| cb3265e796 | |||
| 8798aa9230 | |||
| 2fdf5f1546 | |||
| a32be65bf1 | |||
| 51810a325e | |||
| 6b24e02ba9 | |||
| d831edcaa4 | |||
| af63607069 | |||
| 0abc84c571 | |||
| 7dafabf7cb | |||
| 4dca2b2b63 | |||
| 001597d5e8 | |||
| 4b5ac7388c | |||
| 1e0813a84c | |||
| c8d45416cf | |||
| 09119a2365 | |||
| 5de46eabc5 | |||
| bcb2e39099 | |||
| 09b4cfe3c4 | |||
| c5a00f26ad | |||
| d4dc66a514 | |||
| 2877e26fa5 | |||
| 1a19dcbc13 | |||
| f981dc9906 | |||
| f0e2595a2b | |||
| 37e0c231a7 | |||
| 1397f12057 | |||
| 46e476e35b | |||
| bfac1f10d2 | |||
| d01362cc72 | |||
| 2aee9ff76e | |||
| 5b91cee935 | |||
| a3f49dc176 | |||
| 127a59bf78 | |||
| 988c2d3572 | |||
| f4a72a6110 | |||
| 3741ef5fe4 |
10
.gitignore
vendored
10
.gitignore
vendored
@@ -79,4 +79,12 @@ output/
|
|||||||
|
|
||||||
logs/
|
logs/
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
ruoyi-ui/vue.config.js
|
||||||
|
|
||||||
|
*/src/test/
|
||||||
|
|
||||||
|
.pytest_cache/
|
||||||
|
|
||||||
|
tests/
|
||||||
17
.mcp.json
17
.mcp.json
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"mcpServers": {
|
|
||||||
"mysql": {
|
|
||||||
"command": "node",
|
|
||||||
"args": [
|
|
||||||
"C:/Users/wkc/.codex/mcp-tools/mysql-server/node_modules/@fhuang/mcp-mysql-server/build/index.js"
|
|
||||||
],
|
|
||||||
"env": {
|
|
||||||
"MYSQL_DATABASE": "ccdi",
|
|
||||||
"MYSQL_HOST": "116.62.17.81",
|
|
||||||
"MYSQL_PASSWORD": "Kfcx@1234",
|
|
||||||
"MYSQL_PORT": "3306",
|
|
||||||
"MYSQL_USER": "root"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
24
.opencode
24
.opencode
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://opencode.ai/config.json",
|
|
||||||
"plugin": [
|
|
||||||
"oh-my-opencode@latest"
|
|
||||||
],
|
|
||||||
"agent": {
|
|
||||||
"Sisyphus-Junior": {
|
|
||||||
"mode": "subagent",
|
|
||||||
"model": "glm/glm-5"
|
|
||||||
},
|
|
||||||
"oracle": {
|
|
||||||
"mode": "subagent",
|
|
||||||
"model": "gmn/gpt-5.3-codex"
|
|
||||||
},
|
|
||||||
"Metis (Plan Consultant)": {
|
|
||||||
"mode": "subagent",
|
|
||||||
"model": "gmn/gpt-5.3-codex"
|
|
||||||
},
|
|
||||||
"Momus (Plan Critic)": {
|
|
||||||
"mode": "subagent",
|
|
||||||
"model": "gmn/gpt-5.3-codex"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BIN
assets/异常账户.xlsx
Normal file
BIN
assets/异常账户.xlsx
Normal file
Binary file not shown.
@@ -57,6 +57,12 @@
|
|||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.ruoyi</groupId>
|
||||||
|
<artifactId>ccdi-lsfx</artifactId>
|
||||||
|
<version>3.9.1</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
package com.ruoyi.info.collection.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.core.page.PageDomain;
|
||||||
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.common.core.page.TableSupport;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoAddDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoEditDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoQueryDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.excel.CcdiEnterpriseBaseInfoExcel;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.CcdiEnterpriseBaseInfoVO;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.EnterpriseBaseInfoImportFailureVO;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.ImportResultVO;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
||||||
|
import com.ruoyi.info.collection.service.ICcdiEnterpriseBaseInfoImportService;
|
||||||
|
import com.ruoyi.info.collection.service.ICcdiEnterpriseBaseInfoService;
|
||||||
|
import com.ruoyi.info.collection.utils.EasyExcelUtil;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
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 org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理 Controller
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Tag(name = "实体库管理")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/ccdi/enterpriseBaseInfo")
|
||||||
|
public class CcdiEnterpriseBaseInfoController extends BaseController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ICcdiEnterpriseBaseInfoService enterpriseBaseInfoService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ICcdiEnterpriseBaseInfoImportService enterpriseBaseInfoImportService;
|
||||||
|
|
||||||
|
@Operation(summary = "查询实体库列表")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:list')")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public TableDataInfo list(CcdiEnterpriseBaseInfoQueryDTO queryDTO) {
|
||||||
|
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||||
|
Page<CcdiEnterpriseBaseInfoVO> page = new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize());
|
||||||
|
Page<CcdiEnterpriseBaseInfoVO> result = enterpriseBaseInfoService.selectEnterpriseBaseInfoPage(page, queryDTO);
|
||||||
|
return getDataTable(result.getRecords(), result.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取实体库详细信息")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:query')")
|
||||||
|
@GetMapping("/{socialCreditCode}")
|
||||||
|
public AjaxResult getInfo(@PathVariable String socialCreditCode) {
|
||||||
|
return success(enterpriseBaseInfoService.selectEnterpriseBaseInfoById(socialCreditCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "新增实体库信息")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:add')")
|
||||||
|
@Log(title = "实体库管理", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping
|
||||||
|
public AjaxResult add(@Validated @RequestBody CcdiEnterpriseBaseInfoAddDTO addDTO) {
|
||||||
|
return toAjax(enterpriseBaseInfoService.insertEnterpriseBaseInfo(addDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "修改实体库信息")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:edit')")
|
||||||
|
@Log(title = "实体库管理", businessType = BusinessType.UPDATE)
|
||||||
|
@PutMapping
|
||||||
|
public AjaxResult edit(@Validated @RequestBody CcdiEnterpriseBaseInfoEditDTO editDTO) {
|
||||||
|
return toAjax(enterpriseBaseInfoService.updateEnterpriseBaseInfo(editDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "删除实体库信息")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:remove')")
|
||||||
|
@Log(title = "实体库管理", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/{socialCreditCodes}")
|
||||||
|
public AjaxResult remove(@PathVariable String[] socialCreditCodes) {
|
||||||
|
return toAjax(enterpriseBaseInfoService.deleteEnterpriseBaseInfoByIds(socialCreditCodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "下载导入模板")
|
||||||
|
@PostMapping("/importTemplate")
|
||||||
|
public void importTemplate(HttpServletResponse response) {
|
||||||
|
EasyExcelUtil.importTemplateWithDictDropdown(response, CcdiEnterpriseBaseInfoExcel.class, "实体库管理");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "导入实体库信息")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:import')")
|
||||||
|
@Log(title = "实体库管理", businessType = BusinessType.IMPORT)
|
||||||
|
@PostMapping("/importData")
|
||||||
|
public AjaxResult importData(MultipartFile file) throws Exception {
|
||||||
|
List<CcdiEnterpriseBaseInfoExcel> list = EasyExcelUtil.importExcel(file.getInputStream(), CcdiEnterpriseBaseInfoExcel.class);
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
return error("至少需要一条数据");
|
||||||
|
}
|
||||||
|
|
||||||
|
String taskId = enterpriseBaseInfoService.importEnterpriseBaseInfo(list);
|
||||||
|
ImportResultVO result = new ImportResultVO();
|
||||||
|
result.setTaskId(taskId);
|
||||||
|
result.setStatus("PROCESSING");
|
||||||
|
result.setMessage("导入任务已提交,正在后台处理");
|
||||||
|
return AjaxResult.success("导入任务已提交,正在后台处理", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询导入状态")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:import')")
|
||||||
|
@GetMapping("/importStatus/{taskId}")
|
||||||
|
public AjaxResult getImportStatus(@PathVariable String taskId) {
|
||||||
|
ImportStatusVO status = enterpriseBaseInfoImportService.getImportStatus(taskId);
|
||||||
|
return success(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询导入失败记录")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:import')")
|
||||||
|
@GetMapping("/importFailures/{taskId}")
|
||||||
|
public TableDataInfo getImportFailures(@PathVariable String taskId,
|
||||||
|
@RequestParam(defaultValue = "1") Integer pageNum,
|
||||||
|
@RequestParam(defaultValue = "10") Integer pageSize) {
|
||||||
|
List<EnterpriseBaseInfoImportFailureVO> failures = enterpriseBaseInfoImportService.getImportFailures(taskId);
|
||||||
|
int fromIndex = (pageNum - 1) * pageSize;
|
||||||
|
if (fromIndex >= failures.size()) {
|
||||||
|
return getDataTable(new ArrayList<>(), failures.size());
|
||||||
|
}
|
||||||
|
int toIndex = Math.min(fromIndex + pageSize, failures.size());
|
||||||
|
return getDataTable(failures.subList(fromIndex, toIndex), failures.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -138,4 +138,30 @@ public class CcdiEnumController {
|
|||||||
}
|
}
|
||||||
return AjaxResult.success(options);
|
return AjaxResult.success(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取实体风险等级选项
|
||||||
|
*/
|
||||||
|
@Operation(summary = "获取实体风险等级选项")
|
||||||
|
@GetMapping("/enterpriseRiskLevel")
|
||||||
|
public AjaxResult getEnterpriseRiskLevelOptions() {
|
||||||
|
List<EnumOptionVO> options = new ArrayList<>();
|
||||||
|
for (EnterpriseRiskLevel level : EnterpriseRiskLevel.values()) {
|
||||||
|
options.add(new EnumOptionVO(level.getCode(), level.getDesc()));
|
||||||
|
}
|
||||||
|
return AjaxResult.success(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取企业来源选项
|
||||||
|
*/
|
||||||
|
@Operation(summary = "获取企业来源选项")
|
||||||
|
@GetMapping("/enterpriseSource")
|
||||||
|
public AjaxResult getEnterpriseSourceOptions() {
|
||||||
|
List<EnumOptionVO> options = new ArrayList<>();
|
||||||
|
for (EnterpriseSource source : EnterpriseSource.values()) {
|
||||||
|
options.add(new EnumOptionVO(source.getCode(), source.getDesc()));
|
||||||
|
}
|
||||||
|
return AjaxResult.success(options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentAddDTO;
|
|||||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentEditDTO;
|
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentEditDTO;
|
||||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentQueryDTO;
|
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentQueryDTO;
|
||||||
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentExcel;
|
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentExcel;
|
||||||
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentWorkExcel;
|
|
||||||
import com.ruoyi.info.collection.domain.vo.CcdiStaffRecruitmentVO;
|
import com.ruoyi.info.collection.domain.vo.CcdiStaffRecruitmentVO;
|
||||||
import com.ruoyi.info.collection.domain.vo.ImportResultVO;
|
import com.ruoyi.info.collection.domain.vo.ImportResultVO;
|
||||||
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
||||||
@@ -129,15 +128,6 @@ public class CcdiStaffRecruitmentController extends BaseController {
|
|||||||
EasyExcelUtil.importTemplateWithDictDropdown(response, CcdiStaffRecruitmentExcel.class, "员工招聘信息");
|
EasyExcelUtil.importTemplateWithDictDropdown(response, CcdiStaffRecruitmentExcel.class, "员工招聘信息");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 下载历史工作经历导入模板
|
|
||||||
*/
|
|
||||||
@Operation(summary = "下载历史工作经历导入模板")
|
|
||||||
@PostMapping("/workImportTemplate")
|
|
||||||
public void workImportTemplate(HttpServletResponse response) {
|
|
||||||
EasyExcelUtil.importTemplateWithDictDropdown(response, CcdiStaffRecruitmentWorkExcel.class, "历史工作经历");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异步导入招聘信息
|
* 异步导入招聘信息
|
||||||
*/
|
*/
|
||||||
@@ -165,31 +155,6 @@ public class CcdiStaffRecruitmentController extends BaseController {
|
|||||||
return AjaxResult.success("导入任务已提交,正在后台处理", result);
|
return AjaxResult.success("导入任务已提交,正在后台处理", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 异步导入历史工作经历
|
|
||||||
*/
|
|
||||||
@Operation(summary = "异步导入历史工作经历")
|
|
||||||
@Parameter(name = "file", description = "导入文件", required = true)
|
|
||||||
@PreAuthorize("@ss.hasPermi('ccdi:staffRecruitment:import')")
|
|
||||||
@Log(title = "员工招聘历史工作经历", businessType = BusinessType.IMPORT)
|
|
||||||
@PostMapping("/importWorkData")
|
|
||||||
public AjaxResult importWorkData(@Parameter(description = "导入文件") MultipartFile file) throws Exception {
|
|
||||||
List<CcdiStaffRecruitmentWorkExcel> list = EasyExcelUtil.importExcel(file.getInputStream(), CcdiStaffRecruitmentWorkExcel.class);
|
|
||||||
|
|
||||||
if (list == null || list.isEmpty()) {
|
|
||||||
return error("至少需要一条数据");
|
|
||||||
}
|
|
||||||
|
|
||||||
String taskId = recruitmentService.importRecruitmentWork(list);
|
|
||||||
|
|
||||||
ImportResultVO result = new ImportResultVO();
|
|
||||||
result.setTaskId(taskId);
|
|
||||||
result.setStatus("PROCESSING");
|
|
||||||
result.setMessage("历史工作经历导入任务已提交,正在后台处理");
|
|
||||||
|
|
||||||
return AjaxResult.success("历史工作经历导入任务已提交,正在后台处理", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询导入状态
|
* 查询导入状态
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import lombok.Data;
|
|||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,6 +57,42 @@ public class CcdiAccountInfo implements Serializable {
|
|||||||
/** 币种 */
|
/** 币种 */
|
||||||
private String currency;
|
private String currency;
|
||||||
|
|
||||||
|
/** 是否实控账户:0-否 1-是 */
|
||||||
|
@TableField("is_self_account")
|
||||||
|
private Integer isActualControl;
|
||||||
|
|
||||||
|
/** 月均交易笔数 */
|
||||||
|
@TableField("monthly_avg_trans_count")
|
||||||
|
private Integer avgMonthTxnCount;
|
||||||
|
|
||||||
|
/** 月均交易金额 */
|
||||||
|
@TableField("monthly_avg_trans_amount")
|
||||||
|
private BigDecimal avgMonthTxnAmount;
|
||||||
|
|
||||||
|
/** 交易频率等级 */
|
||||||
|
@TableField("trans_freq_type")
|
||||||
|
private String txnFrequencyLevel;
|
||||||
|
|
||||||
|
/** 借方单笔最高额 */
|
||||||
|
@TableField("dr_max_single_amount")
|
||||||
|
private BigDecimal debitSingleMaxAmount;
|
||||||
|
|
||||||
|
/** 贷方单笔最高额 */
|
||||||
|
@TableField("cr_max_single_amount")
|
||||||
|
private BigDecimal creditSingleMaxAmount;
|
||||||
|
|
||||||
|
/** 借方日累计最高额 */
|
||||||
|
@TableField("dr_max_daily_amount")
|
||||||
|
private BigDecimal debitDailyMaxAmount;
|
||||||
|
|
||||||
|
/** 贷方日累计最高额 */
|
||||||
|
@TableField("cr_max_daily_amount")
|
||||||
|
private BigDecimal creditDailyMaxAmount;
|
||||||
|
|
||||||
|
/** 风险等级 */
|
||||||
|
@TableField("trans_risk_level")
|
||||||
|
private String txnRiskLevel;
|
||||||
|
|
||||||
/** 状态:1-正常 2-已销户 */
|
/** 状态:1-正常 2-已销户 */
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
package com.ruoyi.info.collection.domain;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 账户分析结果对象 ccdi_account_result
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2026-04-13
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@TableName("ccdi_account_result")
|
|
||||||
public class CcdiAccountResult implements Serializable {
|
|
||||||
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/** 主键ID */
|
|
||||||
@TableId(value = "result_id", type = IdType.AUTO)
|
|
||||||
private Long resultId;
|
|
||||||
|
|
||||||
/** 账户号码 */
|
|
||||||
private String accountNo;
|
|
||||||
|
|
||||||
/** 是否实控账户:0-否 1-是 */
|
|
||||||
@TableField("is_self_account")
|
|
||||||
private Integer isActualControl;
|
|
||||||
|
|
||||||
/** 月均交易笔数 */
|
|
||||||
@TableField("monthly_avg_trans_count")
|
|
||||||
private Integer avgMonthTxnCount;
|
|
||||||
|
|
||||||
/** 月均交易金额 */
|
|
||||||
@TableField("monthly_avg_trans_amount")
|
|
||||||
private BigDecimal avgMonthTxnAmount;
|
|
||||||
|
|
||||||
/** 交易频率等级 */
|
|
||||||
@TableField("trans_freq_type")
|
|
||||||
private String txnFrequencyLevel;
|
|
||||||
|
|
||||||
/** 借方单笔最高额 */
|
|
||||||
@TableField("dr_max_single_amount")
|
|
||||||
private BigDecimal debitSingleMaxAmount;
|
|
||||||
|
|
||||||
/** 贷方单笔最高额 */
|
|
||||||
@TableField("cr_max_single_amount")
|
|
||||||
private BigDecimal creditSingleMaxAmount;
|
|
||||||
|
|
||||||
/** 借方日累计最高额 */
|
|
||||||
@TableField("dr_max_daily_amount")
|
|
||||||
private BigDecimal debitDailyMaxAmount;
|
|
||||||
|
|
||||||
/** 贷方日累计最高额 */
|
|
||||||
@TableField("cr_max_daily_amount")
|
|
||||||
private BigDecimal creditDailyMaxAmount;
|
|
||||||
|
|
||||||
/** 风险等级 */
|
|
||||||
@TableField("trans_risk_level")
|
|
||||||
private String txnRiskLevel;
|
|
||||||
|
|
||||||
/** 创建者 */
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
private String createBy;
|
|
||||||
|
|
||||||
/** 创建时间 */
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
/** 更新者 */
|
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
|
||||||
private String updateBy;
|
|
||||||
|
|
||||||
/** 更新时间 */
|
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
|
||||||
private Date updateTime;
|
|
||||||
}
|
|
||||||
@@ -43,6 +43,10 @@ public class CcdiBaseStaff implements Serializable {
|
|||||||
/** 入职时间 */
|
/** 入职时间 */
|
||||||
private Date hireDate;
|
private Date hireDate;
|
||||||
|
|
||||||
|
/** 是否党员:0-否 1-是 */
|
||||||
|
@TableField("is_party_member")
|
||||||
|
private Integer partyMember;
|
||||||
|
|
||||||
/** 状态 */
|
/** 状态 */
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
|
|||||||
@@ -12,65 +12,35 @@ import java.io.Serializable;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 招聘记录历史工作经历对象 ccdi_staff_recruitment_work
|
* 中介关联机构关系对象 ccdi_intermediary_enterprise_relation
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2026-04-15
|
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("ccdi_staff_recruitment_work")
|
@TableName("ccdi_intermediary_enterprise_relation")
|
||||||
public class CcdiStaffRecruitmentWork implements Serializable {
|
public class CcdiIntermediaryEnterpriseRelation implements Serializable {
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** 主键 */
|
|
||||||
@TableId(type = IdType.AUTO)
|
@TableId(type = IdType.AUTO)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
/** 关联招聘记录编号 */
|
private String intermediaryBizId;
|
||||||
private String recruitId;
|
|
||||||
|
|
||||||
/** 排序号 */
|
private String socialCreditCode;
|
||||||
private Integer sortOrder;
|
|
||||||
|
|
||||||
/** 工作单位 */
|
private String relationPersonPost;
|
||||||
private String companyName;
|
|
||||||
|
|
||||||
/** 所属部门 */
|
|
||||||
private String departmentName;
|
|
||||||
|
|
||||||
/** 岗位名称 */
|
|
||||||
private String positionName;
|
|
||||||
|
|
||||||
/** 入职年月 */
|
|
||||||
private String jobStartMonth;
|
|
||||||
|
|
||||||
/** 离职年月 */
|
|
||||||
private String jobEndMonth;
|
|
||||||
|
|
||||||
/** 离职原因 */
|
|
||||||
private String departureReason;
|
|
||||||
|
|
||||||
/** 主要工作内容 */
|
|
||||||
private String workContent;
|
|
||||||
|
|
||||||
/** 备注 */
|
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
/** 创建人 */
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
@TableField(fill = FieldFill.INSERT)
|
||||||
private String createdBy;
|
private String createdBy;
|
||||||
|
|
||||||
/** 创建时间 */
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
@TableField(fill = FieldFill.INSERT)
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
|
|
||||||
/** 更新人 */
|
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
private String updatedBy;
|
private String updatedBy;
|
||||||
|
|
||||||
/** 更新时间 */
|
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
private Date updateTime;
|
private Date updateTime;
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ public class CcdiStaffRecruitment implements Serializable {
|
|||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** 招聘记录编号 */
|
/** 招聘项目编号 */
|
||||||
@TableId(type = IdType.INPUT)
|
@TableId(type = IdType.INPUT)
|
||||||
private String recruitId;
|
private String recruitId;
|
||||||
|
|
||||||
@@ -41,9 +41,6 @@ public class CcdiStaffRecruitment implements Serializable {
|
|||||||
/** 应聘人员姓名 */
|
/** 应聘人员姓名 */
|
||||||
private String candName;
|
private String candName;
|
||||||
|
|
||||||
/** 招聘类型:SOCIAL-社招,CAMPUS-校招 */
|
|
||||||
private String recruitType;
|
|
||||||
|
|
||||||
/** 应聘人员学历 */
|
/** 应聘人员学历 */
|
||||||
private String candEdu;
|
private String candEdu;
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ public class CcdiBaseStaffAddDTO implements Serializable {
|
|||||||
/** 入职时间 */
|
/** 入职时间 */
|
||||||
private Date hireDate;
|
private Date hireDate;
|
||||||
|
|
||||||
|
/** 是否党员:0-否 1-是 */
|
||||||
|
@NotNull(message = "是否党员不能为空")
|
||||||
|
private Integer partyMember;
|
||||||
|
|
||||||
/** 状态 */
|
/** 状态 */
|
||||||
@NotBlank(message = "状态不能为空")
|
@NotBlank(message = "状态不能为空")
|
||||||
private String status;
|
private String status;
|
||||||
|
|||||||
@@ -52,6 +52,10 @@ public class CcdiBaseStaffEditDTO implements Serializable {
|
|||||||
/** 入职时间 */
|
/** 入职时间 */
|
||||||
private Date hireDate;
|
private Date hireDate;
|
||||||
|
|
||||||
|
/** 是否党员:0-否 1-是 */
|
||||||
|
@NotNull(message = "是否党员不能为空")
|
||||||
|
private Integer partyMember;
|
||||||
|
|
||||||
/** 状态 */
|
/** 状态 */
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理新增 DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "实体库管理新增DTO")
|
||||||
|
public class CcdiEnterpriseBaseInfoAddDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
@NotBlank(message = "统一社会信用代码不能为空")
|
||||||
|
@Pattern(regexp = "^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$", message = "统一社会信用代码格式不正确")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "企业名称")
|
||||||
|
@NotBlank(message = "企业名称不能为空")
|
||||||
|
@Size(max = 200, message = "企业名称长度不能超过200个字符")
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@Schema(description = "企业类型")
|
||||||
|
@Size(max = 50, message = "企业类型长度不能超过50个字符")
|
||||||
|
private String enterpriseType;
|
||||||
|
|
||||||
|
@Schema(description = "企业性质")
|
||||||
|
@Size(max = 50, message = "企业性质长度不能超过50个字符")
|
||||||
|
private String enterpriseNature;
|
||||||
|
|
||||||
|
@Schema(description = "行业分类")
|
||||||
|
@Size(max = 100, message = "行业分类长度不能超过100个字符")
|
||||||
|
private String industryClass;
|
||||||
|
|
||||||
|
@Schema(description = "所属行业")
|
||||||
|
@Size(max = 100, message = "所属行业长度不能超过100个字符")
|
||||||
|
private String industryName;
|
||||||
|
|
||||||
|
@Schema(description = "成立日期")
|
||||||
|
private Date establishDate;
|
||||||
|
|
||||||
|
@Schema(description = "注册地址")
|
||||||
|
@Size(max = 500, message = "注册地址长度不能超过500个字符")
|
||||||
|
private String registerAddress;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人")
|
||||||
|
@Size(max = 100, message = "法定代表人长度不能超过100个字符")
|
||||||
|
private String legalRepresentative;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人证件类型")
|
||||||
|
@Size(max = 50, message = "法定代表人证件类型长度不能超过50个字符")
|
||||||
|
private String legalCertType;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人证件号码")
|
||||||
|
@Size(max = 50, message = "法定代表人证件号码长度不能超过50个字符")
|
||||||
|
private String legalCertNo;
|
||||||
|
|
||||||
|
@Schema(description = "股东1")
|
||||||
|
@Size(max = 100, message = "股东1长度不能超过100个字符")
|
||||||
|
private String shareholder1;
|
||||||
|
|
||||||
|
@Schema(description = "股东2")
|
||||||
|
@Size(max = 100, message = "股东2长度不能超过100个字符")
|
||||||
|
private String shareholder2;
|
||||||
|
|
||||||
|
@Schema(description = "股东3")
|
||||||
|
@Size(max = 100, message = "股东3长度不能超过100个字符")
|
||||||
|
private String shareholder3;
|
||||||
|
|
||||||
|
@Schema(description = "股东4")
|
||||||
|
@Size(max = 100, message = "股东4长度不能超过100个字符")
|
||||||
|
private String shareholder4;
|
||||||
|
|
||||||
|
@Schema(description = "股东5")
|
||||||
|
@Size(max = 100, message = "股东5长度不能超过100个字符")
|
||||||
|
private String shareholder5;
|
||||||
|
|
||||||
|
@Schema(description = "经营状态")
|
||||||
|
@NotBlank(message = "经营状态不能为空")
|
||||||
|
@Size(max = 50, message = "经营状态长度不能超过50个字符")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "风险等级")
|
||||||
|
@NotBlank(message = "风险等级不能为空")
|
||||||
|
private String riskLevel;
|
||||||
|
|
||||||
|
@Schema(description = "企业来源")
|
||||||
|
@NotBlank(message = "企业来源不能为空")
|
||||||
|
private String entSource;
|
||||||
|
|
||||||
|
@Schema(description = "数据来源")
|
||||||
|
@NotBlank(message = "数据来源不能为空")
|
||||||
|
private String dataSource;
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理编辑 DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "实体库管理编辑DTO")
|
||||||
|
public class CcdiEnterpriseBaseInfoEditDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
@NotBlank(message = "统一社会信用代码不能为空")
|
||||||
|
@Pattern(regexp = "^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$", message = "统一社会信用代码格式不正确")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "企业名称")
|
||||||
|
@NotBlank(message = "企业名称不能为空")
|
||||||
|
@Size(max = 200, message = "企业名称长度不能超过200个字符")
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@Schema(description = "企业类型")
|
||||||
|
@Size(max = 50, message = "企业类型长度不能超过50个字符")
|
||||||
|
private String enterpriseType;
|
||||||
|
|
||||||
|
@Schema(description = "企业性质")
|
||||||
|
@Size(max = 50, message = "企业性质长度不能超过50个字符")
|
||||||
|
private String enterpriseNature;
|
||||||
|
|
||||||
|
@Schema(description = "行业分类")
|
||||||
|
@Size(max = 100, message = "行业分类长度不能超过100个字符")
|
||||||
|
private String industryClass;
|
||||||
|
|
||||||
|
@Schema(description = "所属行业")
|
||||||
|
@Size(max = 100, message = "所属行业长度不能超过100个字符")
|
||||||
|
private String industryName;
|
||||||
|
|
||||||
|
@Schema(description = "成立日期")
|
||||||
|
private Date establishDate;
|
||||||
|
|
||||||
|
@Schema(description = "注册地址")
|
||||||
|
@Size(max = 500, message = "注册地址长度不能超过500个字符")
|
||||||
|
private String registerAddress;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人")
|
||||||
|
@Size(max = 100, message = "法定代表人长度不能超过100个字符")
|
||||||
|
private String legalRepresentative;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人证件类型")
|
||||||
|
@Size(max = 50, message = "法定代表人证件类型长度不能超过50个字符")
|
||||||
|
private String legalCertType;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人证件号码")
|
||||||
|
@Size(max = 50, message = "法定代表人证件号码长度不能超过50个字符")
|
||||||
|
private String legalCertNo;
|
||||||
|
|
||||||
|
@Schema(description = "股东1")
|
||||||
|
@Size(max = 100, message = "股东1长度不能超过100个字符")
|
||||||
|
private String shareholder1;
|
||||||
|
|
||||||
|
@Schema(description = "股东2")
|
||||||
|
@Size(max = 100, message = "股东2长度不能超过100个字符")
|
||||||
|
private String shareholder2;
|
||||||
|
|
||||||
|
@Schema(description = "股东3")
|
||||||
|
@Size(max = 100, message = "股东3长度不能超过100个字符")
|
||||||
|
private String shareholder3;
|
||||||
|
|
||||||
|
@Schema(description = "股东4")
|
||||||
|
@Size(max = 100, message = "股东4长度不能超过100个字符")
|
||||||
|
private String shareholder4;
|
||||||
|
|
||||||
|
@Schema(description = "股东5")
|
||||||
|
@Size(max = 100, message = "股东5长度不能超过100个字符")
|
||||||
|
private String shareholder5;
|
||||||
|
|
||||||
|
@Schema(description = "经营状态")
|
||||||
|
@NotBlank(message = "经营状态不能为空")
|
||||||
|
@Size(max = 50, message = "经营状态长度不能超过50个字符")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "风险等级")
|
||||||
|
@NotBlank(message = "风险等级不能为空")
|
||||||
|
private String riskLevel;
|
||||||
|
|
||||||
|
@Schema(description = "企业来源")
|
||||||
|
@NotBlank(message = "企业来源不能为空")
|
||||||
|
private String entSource;
|
||||||
|
|
||||||
|
@Schema(description = "数据来源")
|
||||||
|
@NotBlank(message = "数据来源不能为空")
|
||||||
|
private String dataSource;
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理查询 DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "实体库管理查询DTO")
|
||||||
|
public class CcdiEnterpriseBaseInfoQueryDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "企业名称")
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "企业类型")
|
||||||
|
private String enterpriseType;
|
||||||
|
|
||||||
|
@Schema(description = "企业性质")
|
||||||
|
private String enterpriseNature;
|
||||||
|
|
||||||
|
@Schema(description = "行业分类")
|
||||||
|
private String industryClass;
|
||||||
|
|
||||||
|
@Schema(description = "经营状态")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "风险等级")
|
||||||
|
private String riskLevel;
|
||||||
|
|
||||||
|
@Schema(description = "企业来源")
|
||||||
|
private String entSource;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介关联机构新增DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "中介关联机构新增DTO")
|
||||||
|
public class CcdiIntermediaryEnterpriseRelationAddDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
@NotBlank(message = "统一社会信用代码不能为空")
|
||||||
|
@Size(max = 18, message = "统一社会信用代码长度不能超过18个字符")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "关联角色/职务")
|
||||||
|
@Size(max = 100, message = "关联角色/职务长度不能超过100个字符")
|
||||||
|
private String relationPersonPost;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
@Size(max = 500, message = "备注长度不能超过500个字符")
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介关联机构编辑DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "中介关联机构编辑DTO")
|
||||||
|
public class CcdiIntermediaryEnterpriseRelationEditDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "主键ID")
|
||||||
|
@NotNull(message = "主键ID不能为空")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
@NotBlank(message = "统一社会信用代码不能为空")
|
||||||
|
@Size(max = 18, message = "统一社会信用代码长度不能超过18个字符")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "关联角色/职务")
|
||||||
|
@Size(max = 100, message = "关联角色/职务长度不能超过100个字符")
|
||||||
|
private String relationPersonPost;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
@Size(max = 500, message = "备注长度不能超过500个字符")
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介亲属新增DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "中介亲属新增DTO")
|
||||||
|
public class CcdiIntermediaryRelativeAddDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "姓名")
|
||||||
|
@NotBlank(message = "姓名不能为空")
|
||||||
|
@Size(max = 100, message = "姓名长度不能超过100个字符")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "人员类型")
|
||||||
|
private String personType;
|
||||||
|
|
||||||
|
@Schema(description = "亲属关系")
|
||||||
|
@NotBlank(message = "亲属关系不能为空")
|
||||||
|
@Size(max = 50, message = "亲属关系长度不能超过50个字符")
|
||||||
|
private String personSubType;
|
||||||
|
|
||||||
|
@Schema(description = "性别")
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
@Schema(description = "证件类型")
|
||||||
|
private String idType;
|
||||||
|
|
||||||
|
@Schema(description = "证件号码")
|
||||||
|
@NotBlank(message = "证件号码不能为空")
|
||||||
|
@Size(max = 50, message = "证件号码长度不能超过50个字符")
|
||||||
|
private String personId;
|
||||||
|
|
||||||
|
@Schema(description = "手机号码")
|
||||||
|
@Size(max = 20, message = "手机号码长度不能超过20个字符")
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
@Schema(description = "微信号")
|
||||||
|
@Size(max = 50, message = "微信号长度不能超过50个字符")
|
||||||
|
private String wechatNo;
|
||||||
|
|
||||||
|
@Schema(description = "联系地址")
|
||||||
|
@Size(max = 200, message = "联系地址长度不能超过200个字符")
|
||||||
|
private String contactAddress;
|
||||||
|
|
||||||
|
@Schema(description = "所在公司")
|
||||||
|
@Size(max = 200, message = "所在公司长度不能超过200个字符")
|
||||||
|
private String company;
|
||||||
|
|
||||||
|
@Schema(description = "企业统一信用码")
|
||||||
|
@Size(max = 50, message = "企业统一信用码长度不能超过50个字符")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "职位")
|
||||||
|
@Size(max = 100, message = "职位长度不能超过100个字符")
|
||||||
|
private String position;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
@Size(max = 500, message = "备注长度不能超过500个字符")
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介亲属编辑DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "中介亲属编辑DTO")
|
||||||
|
public class CcdiIntermediaryRelativeEditDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "人员ID")
|
||||||
|
@NotBlank(message = "人员ID不能为空")
|
||||||
|
private String bizId;
|
||||||
|
|
||||||
|
@Schema(description = "姓名")
|
||||||
|
@NotBlank(message = "姓名不能为空")
|
||||||
|
@Size(max = 100, message = "姓名长度不能超过100个字符")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "人员类型")
|
||||||
|
private String personType;
|
||||||
|
|
||||||
|
@Schema(description = "亲属关系")
|
||||||
|
@NotBlank(message = "亲属关系不能为空")
|
||||||
|
@Size(max = 50, message = "亲属关系长度不能超过50个字符")
|
||||||
|
private String personSubType;
|
||||||
|
|
||||||
|
@Schema(description = "性别")
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
@Schema(description = "证件类型")
|
||||||
|
private String idType;
|
||||||
|
|
||||||
|
@Schema(description = "证件号码")
|
||||||
|
@Size(max = 50, message = "证件号码长度不能超过50个字符")
|
||||||
|
private String personId;
|
||||||
|
|
||||||
|
@Schema(description = "手机号码")
|
||||||
|
@Size(max = 20, message = "手机号码长度不能超过20个字符")
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
@Schema(description = "微信号")
|
||||||
|
@Size(max = 50, message = "微信号长度不能超过50个字符")
|
||||||
|
private String wechatNo;
|
||||||
|
|
||||||
|
@Schema(description = "联系地址")
|
||||||
|
@Size(max = 200, message = "联系地址长度不能超过200个字符")
|
||||||
|
private String contactAddress;
|
||||||
|
|
||||||
|
@Schema(description = "所在公司")
|
||||||
|
@Size(max = 200, message = "所在公司长度不能超过200个字符")
|
||||||
|
private String company;
|
||||||
|
|
||||||
|
@Schema(description = "企业统一信用码")
|
||||||
|
@Size(max = 50, message = "企业统一信用码长度不能超过50个字符")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "职位")
|
||||||
|
@Size(max = 100, message = "职位长度不能超过100个字符")
|
||||||
|
private String position;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
@Size(max = 500, message = "备注长度不能超过500个字符")
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ package com.ruoyi.info.collection.domain.dto;
|
|||||||
|
|
||||||
import com.ruoyi.info.collection.annotation.EnumValid;
|
import com.ruoyi.info.collection.annotation.EnumValid;
|
||||||
import com.ruoyi.info.collection.enums.AdmitStatus;
|
import com.ruoyi.info.collection.enums.AdmitStatus;
|
||||||
import com.ruoyi.info.collection.enums.RecruitType;
|
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.Pattern;
|
import jakarta.validation.constraints.Pattern;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
@@ -23,9 +22,9 @@ public class CcdiStaffRecruitmentAddDTO implements Serializable {
|
|||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** 招聘记录编号 */
|
/** 招聘项目编号 */
|
||||||
@NotBlank(message = "招聘记录编号不能为空")
|
@NotBlank(message = "招聘项目编号不能为空")
|
||||||
@Size(max = 32, message = "招聘记录编号长度不能超过32个字符")
|
@Size(max = 32, message = "招聘项目编号长度不能超过32个字符")
|
||||||
private String recruitId;
|
private String recruitId;
|
||||||
|
|
||||||
/** 招聘项目名称 */
|
/** 招聘项目名称 */
|
||||||
@@ -52,11 +51,6 @@ public class CcdiStaffRecruitmentAddDTO implements Serializable {
|
|||||||
@Size(max = 20, message = "应聘人员姓名长度不能超过20个字符")
|
@Size(max = 20, message = "应聘人员姓名长度不能超过20个字符")
|
||||||
private String candName;
|
private String candName;
|
||||||
|
|
||||||
/** 招聘类型 */
|
|
||||||
@NotBlank(message = "招聘类型不能为空")
|
|
||||||
@EnumValid(enumClass = RecruitType.class, message = "招聘类型状态值不合法")
|
|
||||||
private String recruitType;
|
|
||||||
|
|
||||||
/** 应聘人员学历 */
|
/** 应聘人员学历 */
|
||||||
@NotBlank(message = "应聘人员学历不能为空")
|
@NotBlank(message = "应聘人员学历不能为空")
|
||||||
@Size(max = 20, message = "应聘人员学历长度不能超过20个字符")
|
@Size(max = 20, message = "应聘人员学历长度不能超过20个字符")
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.ruoyi.info.collection.domain.dto;
|
|||||||
|
|
||||||
import com.ruoyi.info.collection.annotation.EnumValid;
|
import com.ruoyi.info.collection.annotation.EnumValid;
|
||||||
import com.ruoyi.info.collection.enums.AdmitStatus;
|
import com.ruoyi.info.collection.enums.AdmitStatus;
|
||||||
import com.ruoyi.info.collection.enums.RecruitType;
|
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import jakarta.validation.constraints.Pattern;
|
import jakarta.validation.constraints.Pattern;
|
||||||
@@ -24,8 +23,8 @@ public class CcdiStaffRecruitmentEditDTO implements Serializable {
|
|||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** 招聘记录编号 */
|
/** 招聘项目编号 */
|
||||||
@NotNull(message = "招聘记录编号不能为空")
|
@NotNull(message = "招聘项目编号不能为空")
|
||||||
private String recruitId;
|
private String recruitId;
|
||||||
|
|
||||||
/** 招聘项目名称 */
|
/** 招聘项目名称 */
|
||||||
@@ -47,10 +46,6 @@ public class CcdiStaffRecruitmentEditDTO implements Serializable {
|
|||||||
@Size(max = 20, message = "应聘人员姓名长度不能超过20个字符")
|
@Size(max = 20, message = "应聘人员姓名长度不能超过20个字符")
|
||||||
private String candName;
|
private String candName;
|
||||||
|
|
||||||
/** 招聘类型 */
|
|
||||||
@EnumValid(enumClass = RecruitType.class, message = "招聘类型状态值不合法")
|
|
||||||
private String recruitType;
|
|
||||||
|
|
||||||
/** 应聘人员学历 */
|
/** 应聘人员学历 */
|
||||||
@Size(max = 20, message = "应聘人员学历长度不能超过20个字符")
|
@Size(max = 20, message = "应聘人员学历长度不能超过20个字符")
|
||||||
private String candEdu;
|
private String candEdu;
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ public class CcdiStaffRecruitmentQueryDTO implements Serializable {
|
|||||||
/** 候选人姓名(模糊查询) */
|
/** 候选人姓名(模糊查询) */
|
||||||
private String candName;
|
private String candName;
|
||||||
|
|
||||||
/** 招聘类型(精确查询) */
|
|
||||||
private String recruitType;
|
|
||||||
|
|
||||||
/** 证件号码(精确查询) */
|
/** 证件号码(精确查询) */
|
||||||
private String candId;
|
private String candId;
|
||||||
|
|
||||||
|
|||||||
@@ -63,8 +63,15 @@ public class CcdiBaseStaffExcel implements Serializable {
|
|||||||
@ColumnWidth(15)
|
@ColumnWidth(15)
|
||||||
private Date hireDate;
|
private Date hireDate;
|
||||||
|
|
||||||
|
/** 是否党员 */
|
||||||
|
@ExcelProperty(value = "是否党员", index = 7)
|
||||||
|
@ColumnWidth(12)
|
||||||
|
@DictDropdown(dictType = "ccdi_yes_no_flag")
|
||||||
|
@Required
|
||||||
|
private Integer partyMember;
|
||||||
|
|
||||||
/** 状态 */
|
/** 状态 */
|
||||||
@ExcelProperty(value = "状态", index = 7)
|
@ExcelProperty(value = "状态", index = 8)
|
||||||
@ColumnWidth(10)
|
@ColumnWidth(10)
|
||||||
@DictDropdown(dictType = "ccdi_employee_status")
|
@DictDropdown(dictType = "ccdi_employee_status")
|
||||||
@Required
|
@Required
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.excel;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||||
|
import com.ruoyi.common.annotation.DictDropdown;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理 Excel 导入模板对象
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CcdiEnterpriseBaseInfoExcel implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "统一社会信用代码*", index = 0)
|
||||||
|
@ColumnWidth(24)
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "企业名称*", index = 1)
|
||||||
|
@ColumnWidth(30)
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "企业类型", index = 2)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
@DictDropdown(dictType = "ccdi_entity_type")
|
||||||
|
private String enterpriseType;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "企业性质", index = 3)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
@DictDropdown(dictType = "ccdi_enterprise_nature")
|
||||||
|
private String enterpriseNature;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "行业分类", index = 4)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String industryClass;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "所属行业", index = 5)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String industryName;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "成立日期", index = 6)
|
||||||
|
@ColumnWidth(16)
|
||||||
|
private Date establishDate;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "注册地址", index = 7)
|
||||||
|
@ColumnWidth(36)
|
||||||
|
private String registerAddress;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "法定代表人", index = 8)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String legalRepresentative;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "法定代表人证件类型", index = 9)
|
||||||
|
@ColumnWidth(22)
|
||||||
|
@DictDropdown(dictType = "ccdi_certificate_type")
|
||||||
|
private String legalCertType;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "法定代表人证件号码", index = 10)
|
||||||
|
@ColumnWidth(24)
|
||||||
|
private String legalCertNo;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "股东1", index = 11)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String shareholder1;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "股东2", index = 12)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String shareholder2;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "股东3", index = 13)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String shareholder3;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "股东4", index = 14)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String shareholder4;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "股东5", index = 15)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String shareholder5;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "经营状态*", index = 16)
|
||||||
|
@ColumnWidth(16)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "风险等级*", index = 17)
|
||||||
|
@ColumnWidth(16)
|
||||||
|
private String riskLevel;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "企业来源*", index = 18)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String entSource;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "数据来源*", index = 19)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String dataSource;
|
||||||
|
}
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
package com.ruoyi.info.collection.domain.excel;
|
|
||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
|
||||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
|
||||||
import com.ruoyi.common.annotation.Required;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 招聘记录历史工作经历Excel导入对象
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2026-04-20
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class CcdiStaffRecruitmentWorkExcel implements Serializable {
|
|
||||||
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/** 招聘记录编号 */
|
|
||||||
@ExcelProperty(value = "招聘记录编号", index = 0)
|
|
||||||
@ColumnWidth(20)
|
|
||||||
@Required
|
|
||||||
private String recruitId;
|
|
||||||
|
|
||||||
/** 候选人姓名 */
|
|
||||||
@ExcelProperty(value = "候选人姓名", index = 1)
|
|
||||||
@ColumnWidth(15)
|
|
||||||
@Required
|
|
||||||
private String candName;
|
|
||||||
|
|
||||||
/** 招聘项目名称 */
|
|
||||||
@ExcelProperty(value = "招聘项目名称", index = 2)
|
|
||||||
@ColumnWidth(25)
|
|
||||||
@Required
|
|
||||||
private String recruitName;
|
|
||||||
|
|
||||||
/** 职位名称 */
|
|
||||||
@ExcelProperty(value = "职位名称", index = 3)
|
|
||||||
@ColumnWidth(20)
|
|
||||||
@Required
|
|
||||||
private String posName;
|
|
||||||
|
|
||||||
/** 排序号 */
|
|
||||||
@ExcelProperty(value = "排序号", index = 4)
|
|
||||||
@ColumnWidth(10)
|
|
||||||
@Required
|
|
||||||
private Integer sortOrder;
|
|
||||||
|
|
||||||
/** 工作单位 */
|
|
||||||
@ExcelProperty(value = "工作单位", index = 5)
|
|
||||||
@ColumnWidth(25)
|
|
||||||
@Required
|
|
||||||
private String companyName;
|
|
||||||
|
|
||||||
/** 所属部门 */
|
|
||||||
@ExcelProperty(value = "所属部门", index = 6)
|
|
||||||
@ColumnWidth(18)
|
|
||||||
private String departmentName;
|
|
||||||
|
|
||||||
/** 岗位 */
|
|
||||||
@ExcelProperty(value = "岗位", index = 7)
|
|
||||||
@ColumnWidth(20)
|
|
||||||
@Required
|
|
||||||
private String positionName;
|
|
||||||
|
|
||||||
/** 入职年月 */
|
|
||||||
@ExcelProperty(value = "入职年月", index = 8)
|
|
||||||
@ColumnWidth(12)
|
|
||||||
@Required
|
|
||||||
private String jobStartMonth;
|
|
||||||
|
|
||||||
/** 离职年月 */
|
|
||||||
@ExcelProperty(value = "离职年月", index = 9)
|
|
||||||
@ColumnWidth(12)
|
|
||||||
private String jobEndMonth;
|
|
||||||
|
|
||||||
/** 离职原因 */
|
|
||||||
@ExcelProperty(value = "离职原因", index = 10)
|
|
||||||
@ColumnWidth(30)
|
|
||||||
private String departureReason;
|
|
||||||
|
|
||||||
/** 工作内容 */
|
|
||||||
@ExcelProperty(value = "工作内容", index = 11)
|
|
||||||
@ColumnWidth(35)
|
|
||||||
private String workContent;
|
|
||||||
|
|
||||||
/** 备注 */
|
|
||||||
@ExcelProperty(value = "备注", index = 12)
|
|
||||||
@ColumnWidth(25)
|
|
||||||
private String remark;
|
|
||||||
}
|
|
||||||
@@ -44,6 +44,9 @@ public class CcdiBaseStaffVO implements Serializable {
|
|||||||
/** 入职时间 */
|
/** 入职时间 */
|
||||||
private Date hireDate;
|
private Date hireDate;
|
||||||
|
|
||||||
|
/** 是否党员:0-否 1-是 */
|
||||||
|
private Integer partyMember;
|
||||||
|
|
||||||
/** 状态 */
|
/** 状态 */
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理 VO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "实体库管理VO")
|
||||||
|
public class CcdiEnterpriseBaseInfoVO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "企业名称")
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@Schema(description = "企业类型")
|
||||||
|
private String enterpriseType;
|
||||||
|
|
||||||
|
@Schema(description = "企业性质")
|
||||||
|
private String enterpriseNature;
|
||||||
|
|
||||||
|
@Schema(description = "行业分类")
|
||||||
|
private String industryClass;
|
||||||
|
|
||||||
|
@Schema(description = "所属行业")
|
||||||
|
private String industryName;
|
||||||
|
|
||||||
|
@Schema(description = "成立日期")
|
||||||
|
private Date establishDate;
|
||||||
|
|
||||||
|
@Schema(description = "注册地址")
|
||||||
|
private String registerAddress;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人")
|
||||||
|
private String legalRepresentative;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人证件类型")
|
||||||
|
private String legalCertType;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人证件号码")
|
||||||
|
private String legalCertNo;
|
||||||
|
|
||||||
|
@Schema(description = "股东1")
|
||||||
|
private String shareholder1;
|
||||||
|
|
||||||
|
@Schema(description = "股东2")
|
||||||
|
private String shareholder2;
|
||||||
|
|
||||||
|
@Schema(description = "股东3")
|
||||||
|
private String shareholder3;
|
||||||
|
|
||||||
|
@Schema(description = "股东4")
|
||||||
|
private String shareholder4;
|
||||||
|
|
||||||
|
@Schema(description = "股东5")
|
||||||
|
private String shareholder5;
|
||||||
|
|
||||||
|
@Schema(description = "经营状态")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "风险等级")
|
||||||
|
private String riskLevel;
|
||||||
|
|
||||||
|
@Schema(description = "企业来源")
|
||||||
|
private String entSource;
|
||||||
|
|
||||||
|
@Schema(description = "数据来源")
|
||||||
|
private String dataSource;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介关联机构VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "中介关联机构VO")
|
||||||
|
public class CcdiIntermediaryEnterpriseRelationVO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "主键ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "所属中介ID")
|
||||||
|
private String intermediaryBizId;
|
||||||
|
|
||||||
|
@Schema(description = "所属中介姓名")
|
||||||
|
private String intermediaryName;
|
||||||
|
|
||||||
|
@Schema(description = "所属中介证件号")
|
||||||
|
private String intermediaryPersonId;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "机构名称")
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@Schema(description = "关联角色/职务")
|
||||||
|
private String relationPersonPost;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介亲属VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "中介亲属VO")
|
||||||
|
public class CcdiIntermediaryRelativeVO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "人员ID")
|
||||||
|
private String bizId;
|
||||||
|
|
||||||
|
@Schema(description = "所属中介ID")
|
||||||
|
private String relatedNumId;
|
||||||
|
|
||||||
|
@Schema(description = "姓名")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "人员类型")
|
||||||
|
private String personType;
|
||||||
|
|
||||||
|
@Schema(description = "亲属关系")
|
||||||
|
private String personSubType;
|
||||||
|
|
||||||
|
@Schema(description = "性别")
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
@Schema(description = "证件类型")
|
||||||
|
private String idType;
|
||||||
|
|
||||||
|
@Schema(description = "证件号码")
|
||||||
|
private String personId;
|
||||||
|
|
||||||
|
@Schema(description = "手机号码")
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
@Schema(description = "微信号")
|
||||||
|
private String wechatNo;
|
||||||
|
|
||||||
|
@Schema(description = "联系地址")
|
||||||
|
private String contactAddress;
|
||||||
|
|
||||||
|
@Schema(description = "所在公司")
|
||||||
|
private String company;
|
||||||
|
|
||||||
|
@Schema(description = "企业统一信用码")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "职位")
|
||||||
|
private String position;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@ import lombok.Data;
|
|||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 员工招聘信息VO
|
* 员工招聘信息VO
|
||||||
@@ -19,7 +18,7 @@ public class CcdiStaffRecruitmentVO implements Serializable {
|
|||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** 招聘记录编号 */
|
/** 招聘项目编号 */
|
||||||
private String recruitId;
|
private String recruitId;
|
||||||
|
|
||||||
/** 招聘项目名称 */
|
/** 招聘项目名称 */
|
||||||
@@ -37,9 +36,6 @@ public class CcdiStaffRecruitmentVO implements Serializable {
|
|||||||
/** 应聘人员姓名 */
|
/** 应聘人员姓名 */
|
||||||
private String candName;
|
private String candName;
|
||||||
|
|
||||||
/** 招聘类型 */
|
|
||||||
private String recruitType;
|
|
||||||
|
|
||||||
/** 应聘人员学历 */
|
/** 应聘人员学历 */
|
||||||
private String candEdu;
|
private String candEdu;
|
||||||
|
|
||||||
@@ -61,12 +57,6 @@ public class CcdiStaffRecruitmentVO implements Serializable {
|
|||||||
/** 录用情况描述 */
|
/** 录用情况描述 */
|
||||||
private String admitStatusDesc;
|
private String admitStatusDesc;
|
||||||
|
|
||||||
/** 历史工作经历条数 */
|
|
||||||
private Long workExperienceCount;
|
|
||||||
|
|
||||||
/** 历史工作经历列表 */
|
|
||||||
private List<CcdiStaffRecruitmentWorkVO> workExperienceList;
|
|
||||||
|
|
||||||
/** 面试官1姓名 */
|
/** 面试官1姓名 */
|
||||||
private String interviewerName1;
|
private String interviewerName1;
|
||||||
|
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
package com.ruoyi.info.collection.domain.vo;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 招聘记录历史工作经历VO
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2026-04-15
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class CcdiStaffRecruitmentWorkVO implements Serializable {
|
|
||||||
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/** 排序号 */
|
|
||||||
private Integer sortOrder;
|
|
||||||
|
|
||||||
/** 工作单位 */
|
|
||||||
private String companyName;
|
|
||||||
|
|
||||||
/** 所属部门 */
|
|
||||||
private String departmentName;
|
|
||||||
|
|
||||||
/** 岗位名称 */
|
|
||||||
private String positionName;
|
|
||||||
|
|
||||||
/** 入职年月 */
|
|
||||||
private String jobStartMonth;
|
|
||||||
|
|
||||||
/** 离职年月 */
|
|
||||||
private String jobEndMonth;
|
|
||||||
|
|
||||||
/** 离职原因 */
|
|
||||||
private String departureReason;
|
|
||||||
|
|
||||||
/** 主要工作内容 */
|
|
||||||
private String workContent;
|
|
||||||
|
|
||||||
/** 备注 */
|
|
||||||
private String remark;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库导入失败记录 VO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "实体库导入失败记录")
|
||||||
|
public class EnterpriseBaseInfoImportFailureVO {
|
||||||
|
|
||||||
|
@Schema(description = "企业名称")
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "企业类型")
|
||||||
|
private String enterpriseType;
|
||||||
|
|
||||||
|
@Schema(description = "企业性质")
|
||||||
|
private String enterpriseNature;
|
||||||
|
|
||||||
|
@Schema(description = "行业分类")
|
||||||
|
private String industryClass;
|
||||||
|
|
||||||
|
@Schema(description = "所属行业")
|
||||||
|
private String industryName;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人")
|
||||||
|
private String legalRepresentative;
|
||||||
|
|
||||||
|
@Schema(description = "经营状态")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "风险等级")
|
||||||
|
private String riskLevel;
|
||||||
|
|
||||||
|
@Schema(description = "企业来源")
|
||||||
|
private String entSource;
|
||||||
|
|
||||||
|
@Schema(description = "数据来源")
|
||||||
|
private String dataSource;
|
||||||
|
|
||||||
|
@Schema(description = "错误信息")
|
||||||
|
private String errorMessage;
|
||||||
|
}
|
||||||
@@ -32,6 +32,9 @@ public class ImportFailureVO {
|
|||||||
@Schema(description = "年收入")
|
@Schema(description = "年收入")
|
||||||
private BigDecimal annualIncome;
|
private BigDecimal annualIncome;
|
||||||
|
|
||||||
|
@Schema(description = "是否党员:0-否 1-是")
|
||||||
|
private Integer partyMember;
|
||||||
|
|
||||||
@Schema(description = "状态")
|
@Schema(description = "状态")
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
|
|||||||
@@ -19,9 +19,6 @@ public class RecruitmentImportFailureVO {
|
|||||||
@Schema(description = "招聘项目名称")
|
@Schema(description = "招聘项目名称")
|
||||||
private String recruitName;
|
private String recruitName;
|
||||||
|
|
||||||
@Schema(description = "职位名称")
|
|
||||||
private String posName;
|
|
||||||
|
|
||||||
@Schema(description = "应聘人员姓名")
|
@Schema(description = "应聘人员姓名")
|
||||||
private String candName;
|
private String candName;
|
||||||
|
|
||||||
@@ -31,12 +28,6 @@ public class RecruitmentImportFailureVO {
|
|||||||
@Schema(description = "录用情况")
|
@Schema(description = "录用情况")
|
||||||
private String admitStatus;
|
private String admitStatus;
|
||||||
|
|
||||||
@Schema(description = "工作单位")
|
|
||||||
private String companyName;
|
|
||||||
|
|
||||||
@Schema(description = "岗位")
|
|
||||||
private String positionName;
|
|
||||||
|
|
||||||
@Schema(description = "错误信息")
|
@Schema(description = "错误信息")
|
||||||
private String errorMessage;
|
private String errorMessage;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.ruoyi.info.collection.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体风险等级枚举
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public enum EnterpriseRiskLevel {
|
||||||
|
|
||||||
|
HIGH("1", "高风险"),
|
||||||
|
MEDIUM("2", "中风险"),
|
||||||
|
LOW("3", "低风险");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
EnterpriseRiskLevel(String code, String desc) {
|
||||||
|
this.code = code;
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDesc() {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDescByCode(String code) {
|
||||||
|
for (EnterpriseRiskLevel value : values()) {
|
||||||
|
if (value.code.equals(code)) {
|
||||||
|
return value.desc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean contains(String code) {
|
||||||
|
for (EnterpriseRiskLevel value : values()) {
|
||||||
|
if (value.code.equals(code)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String resolveCode(String value) {
|
||||||
|
for (EnterpriseRiskLevel item : values()) {
|
||||||
|
if (item.code.equals(value) || item.desc.equals(value)) {
|
||||||
|
return item.code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.ruoyi.info.collection.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 企业来源枚举
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public enum EnterpriseSource {
|
||||||
|
|
||||||
|
GENERAL("GENERAL", "一般企业"),
|
||||||
|
EMP_RELATION("EMP_RELATION", "员工关系人"),
|
||||||
|
CREDIT_CUSTOMER("CREDIT_CUSTOMER", "信贷客户"),
|
||||||
|
INTERMEDIARY("INTERMEDIARY", "中介"),
|
||||||
|
BOTH("BOTH", "兼有");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
EnterpriseSource(String code, String desc) {
|
||||||
|
this.code = code;
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDesc() {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDescByCode(String code) {
|
||||||
|
for (EnterpriseSource value : values()) {
|
||||||
|
if (value.code.equals(code)) {
|
||||||
|
return value.desc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean contains(String code) {
|
||||||
|
for (EnterpriseSource value : values()) {
|
||||||
|
if (value.code.equals(code)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String resolveCode(String value) {
|
||||||
|
for (EnterpriseSource item : values()) {
|
||||||
|
if (item.code.equals(value) || item.desc.equals(value)) {
|
||||||
|
return item.code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
package com.ruoyi.info.collection.enums;
|
|
||||||
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 招聘类型枚举
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public enum RecruitType {
|
|
||||||
|
|
||||||
/** 社招 */
|
|
||||||
SOCIAL("SOCIAL", "社招"),
|
|
||||||
|
|
||||||
/** 校招 */
|
|
||||||
CAMPUS("CAMPUS", "校招");
|
|
||||||
|
|
||||||
private final String code;
|
|
||||||
private final String desc;
|
|
||||||
|
|
||||||
RecruitType(String code, String desc) {
|
|
||||||
this.code = code;
|
|
||||||
this.desc = desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDesc() {
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getDescByCode(String code) {
|
|
||||||
for (RecruitType type : values()) {
|
|
||||||
if (type.code.equals(code)) {
|
|
||||||
return type.desc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String inferCode(String recruitName) {
|
|
||||||
if (StringUtils.isNotEmpty(recruitName) && recruitName.contains("校园")) {
|
|
||||||
return CAMPUS.code;
|
|
||||||
}
|
|
||||||
return SOCIAL.code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package com.ruoyi.info.collection.mapper;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import com.ruoyi.info.collection.domain.CcdiAccountResult;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 账户分析结果数据层
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2026-04-13
|
|
||||||
*/
|
|
||||||
public interface CcdiAccountResultMapper extends BaseMapper<CcdiAccountResult> {
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
package com.ruoyi.info.collection.mapper;
|
package com.ruoyi.info.collection.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.ruoyi.info.collection.domain.CcdiEnterpriseBaseInfo;
|
import com.ruoyi.info.collection.domain.CcdiEnterpriseBaseInfo;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoQueryDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.CcdiEnterpriseBaseInfoVO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
@@ -16,6 +19,16 @@ import java.util.List;
|
|||||||
@Mapper
|
@Mapper
|
||||||
public interface CcdiEnterpriseBaseInfoMapper extends BaseMapper<CcdiEnterpriseBaseInfo> {
|
public interface CcdiEnterpriseBaseInfoMapper extends BaseMapper<CcdiEnterpriseBaseInfo> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询实体库列表
|
||||||
|
*
|
||||||
|
* @param page 分页参数
|
||||||
|
* @param queryDTO 查询条件
|
||||||
|
* @return 分页结果
|
||||||
|
*/
|
||||||
|
Page<CcdiEnterpriseBaseInfoVO> selectEnterpriseBaseInfoPage(Page<CcdiEnterpriseBaseInfoVO> page,
|
||||||
|
@Param("queryDTO") CcdiEnterpriseBaseInfoQueryDTO queryDTO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量插入实体中介
|
* 批量插入实体中介
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.ruoyi.info.collection.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.ruoyi.info.collection.domain.CcdiIntermediaryEnterpriseRelation;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.CcdiIntermediaryEnterpriseRelationVO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介关联机构关系Mapper
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface CcdiIntermediaryEnterpriseRelationMapper extends BaseMapper<CcdiIntermediaryEnterpriseRelation> {
|
||||||
|
|
||||||
|
List<CcdiIntermediaryEnterpriseRelationVO> selectByIntermediaryBizId(@Param("bizId") String bizId);
|
||||||
|
|
||||||
|
CcdiIntermediaryEnterpriseRelationVO selectDetailById(@Param("id") Long id);
|
||||||
|
|
||||||
|
boolean existsByIntermediaryBizIdAndSocialCreditCode(@Param("bizId") String bizId,
|
||||||
|
@Param("socialCreditCode") String socialCreditCode);
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package com.ruoyi.info.collection.mapper;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import com.ruoyi.info.collection.domain.CcdiStaffRecruitmentWork;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 招聘记录历史工作经历 数据层
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2026-04-15
|
|
||||||
*/
|
|
||||||
public interface CcdiStaffRecruitmentWorkMapper extends BaseMapper<CcdiStaffRecruitmentWork> {
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.ruoyi.info.collection.service;
|
||||||
|
|
||||||
|
import com.ruoyi.info.collection.domain.CcdiEnterpriseBaseInfo;
|
||||||
|
import com.ruoyi.info.collection.domain.excel.CcdiEnterpriseBaseInfoExcel;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.EnterpriseBaseInfoImportFailureVO;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理导入 Service 接口
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
public interface ICcdiEnterpriseBaseInfoImportService {
|
||||||
|
|
||||||
|
void importEnterpriseBaseInfoAsync(List<CcdiEnterpriseBaseInfoExcel> excelList, String taskId, String userName);
|
||||||
|
|
||||||
|
ImportStatusVO getImportStatus(String taskId);
|
||||||
|
|
||||||
|
List<EnterpriseBaseInfoImportFailureVO> getImportFailures(String taskId);
|
||||||
|
|
||||||
|
CcdiEnterpriseBaseInfo validateAndBuildEntity(CcdiEnterpriseBaseInfoExcel excel,
|
||||||
|
Set<String> existingCreditCodes,
|
||||||
|
Set<String> processedCreditCodes,
|
||||||
|
String userName);
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.ruoyi.info.collection.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoAddDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoEditDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoQueryDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.excel.CcdiEnterpriseBaseInfoExcel;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.CcdiEnterpriseBaseInfoVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理 Service 接口
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
public interface ICcdiEnterpriseBaseInfoService {
|
||||||
|
|
||||||
|
Page<CcdiEnterpriseBaseInfoVO> selectEnterpriseBaseInfoPage(Page<CcdiEnterpriseBaseInfoVO> page,
|
||||||
|
CcdiEnterpriseBaseInfoQueryDTO queryDTO);
|
||||||
|
|
||||||
|
CcdiEnterpriseBaseInfoVO selectEnterpriseBaseInfoById(String socialCreditCode);
|
||||||
|
|
||||||
|
int insertEnterpriseBaseInfo(CcdiEnterpriseBaseInfoAddDTO addDTO);
|
||||||
|
|
||||||
|
int updateEnterpriseBaseInfo(CcdiEnterpriseBaseInfoEditDTO editDTO);
|
||||||
|
|
||||||
|
int deleteEnterpriseBaseInfoByIds(String[] socialCreditCodes);
|
||||||
|
|
||||||
|
List<CcdiEnterpriseBaseInfoExcel> selectEnterpriseBaseInfoListForExport(CcdiEnterpriseBaseInfoQueryDTO queryDTO);
|
||||||
|
|
||||||
|
String importEnterpriseBaseInfo(List<CcdiEnterpriseBaseInfoExcel> excelList);
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.ruoyi.info.collection.service;
|
package com.ruoyi.info.collection.service;
|
||||||
|
|
||||||
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentExcel;
|
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentExcel;
|
||||||
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentWorkExcel;
|
|
||||||
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
||||||
import com.ruoyi.info.collection.domain.vo.RecruitmentImportFailureVO;
|
import com.ruoyi.info.collection.domain.vo.RecruitmentImportFailureVO;
|
||||||
|
|
||||||
@@ -26,17 +25,6 @@ public interface ICcdiStaffRecruitmentImportService {
|
|||||||
String taskId,
|
String taskId,
|
||||||
String userName);
|
String userName);
|
||||||
|
|
||||||
/**
|
|
||||||
* 异步导入招聘记录历史工作经历数据
|
|
||||||
*
|
|
||||||
* @param excelList Excel数据列表
|
|
||||||
* @param taskId 任务ID
|
|
||||||
* @param userName 用户名
|
|
||||||
*/
|
|
||||||
void importRecruitmentWorkAsync(List<CcdiStaffRecruitmentWorkExcel> excelList,
|
|
||||||
String taskId,
|
|
||||||
String userName);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询导入状态
|
* 查询导入状态
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentAddDTO;
|
|||||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentEditDTO;
|
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentEditDTO;
|
||||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentQueryDTO;
|
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentQueryDTO;
|
||||||
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentExcel;
|
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentExcel;
|
||||||
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentWorkExcel;
|
|
||||||
import com.ruoyi.info.collection.domain.vo.CcdiStaffRecruitmentVO;
|
import com.ruoyi.info.collection.domain.vo.CcdiStaffRecruitmentVO;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -82,12 +81,4 @@ public interface ICcdiStaffRecruitmentService {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
String importRecruitment(List<CcdiStaffRecruitmentExcel> excelList);
|
String importRecruitment(List<CcdiStaffRecruitmentExcel> excelList);
|
||||||
|
|
||||||
/**
|
|
||||||
* 导入招聘记录历史工作经历数据(异步)
|
|
||||||
*
|
|
||||||
* @param excelList Excel实体列表
|
|
||||||
* @return 任务ID
|
|
||||||
*/
|
|
||||||
String importRecruitmentWork(List<CcdiStaffRecruitmentWorkExcel> excelList);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.info.collection.domain.CcdiAccountInfo;
|
import com.ruoyi.info.collection.domain.CcdiAccountInfo;
|
||||||
import com.ruoyi.info.collection.domain.CcdiAccountResult;
|
|
||||||
import com.ruoyi.info.collection.domain.CcdiBaseStaff;
|
import com.ruoyi.info.collection.domain.CcdiBaseStaff;
|
||||||
import com.ruoyi.info.collection.domain.CcdiStaffFmyRelation;
|
import com.ruoyi.info.collection.domain.CcdiStaffFmyRelation;
|
||||||
import com.ruoyi.info.collection.domain.dto.CcdiAccountInfoAddDTO;
|
import com.ruoyi.info.collection.domain.dto.CcdiAccountInfoAddDTO;
|
||||||
@@ -16,7 +15,6 @@ import com.ruoyi.info.collection.domain.vo.CcdiAccountInfoVO;
|
|||||||
import com.ruoyi.info.collection.domain.vo.CcdiAccountRelationOptionVO;
|
import com.ruoyi.info.collection.domain.vo.CcdiAccountRelationOptionVO;
|
||||||
import com.ruoyi.info.collection.domain.vo.ImportResult;
|
import com.ruoyi.info.collection.domain.vo.ImportResult;
|
||||||
import com.ruoyi.info.collection.mapper.CcdiAccountInfoMapper;
|
import com.ruoyi.info.collection.mapper.CcdiAccountInfoMapper;
|
||||||
import com.ruoyi.info.collection.mapper.CcdiAccountResultMapper;
|
|
||||||
import com.ruoyi.info.collection.mapper.CcdiBaseStaffMapper;
|
import com.ruoyi.info.collection.mapper.CcdiBaseStaffMapper;
|
||||||
import com.ruoyi.info.collection.mapper.CcdiStaffFmyRelationMapper;
|
import com.ruoyi.info.collection.mapper.CcdiStaffFmyRelationMapper;
|
||||||
import com.ruoyi.info.collection.service.ICcdiAccountInfoService;
|
import com.ruoyi.info.collection.service.ICcdiAccountInfoService;
|
||||||
@@ -56,9 +54,6 @@ public class CcdiAccountInfoServiceImpl implements ICcdiAccountInfoService {
|
|||||||
@Resource
|
@Resource
|
||||||
private CcdiAccountInfoMapper accountInfoMapper;
|
private CcdiAccountInfoMapper accountInfoMapper;
|
||||||
|
|
||||||
@Resource
|
|
||||||
private CcdiAccountResultMapper accountResultMapper;
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private CcdiBaseStaffMapper baseStaffMapper;
|
private CcdiBaseStaffMapper baseStaffMapper;
|
||||||
|
|
||||||
@@ -87,9 +82,8 @@ public class CcdiAccountInfoServiceImpl implements ICcdiAccountInfoService {
|
|||||||
|
|
||||||
CcdiAccountInfo accountInfo = new CcdiAccountInfo();
|
CcdiAccountInfo accountInfo = new CcdiAccountInfo();
|
||||||
BeanUtils.copyProperties(addDTO, accountInfo);
|
BeanUtils.copyProperties(addDTO, accountInfo);
|
||||||
int result = accountInfoMapper.insert(accountInfo);
|
prepareAnalysisFields(accountInfo);
|
||||||
syncAccountResult(accountInfo.getBankScope(), null, accountInfo.getAccountNo(), addDTO);
|
return accountInfoMapper.insert(accountInfo);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -110,26 +104,13 @@ public class CcdiAccountInfoServiceImpl implements ICcdiAccountInfoService {
|
|||||||
|
|
||||||
CcdiAccountInfo accountInfo = new CcdiAccountInfo();
|
CcdiAccountInfo accountInfo = new CcdiAccountInfo();
|
||||||
BeanUtils.copyProperties(editDTO, accountInfo);
|
BeanUtils.copyProperties(editDTO, accountInfo);
|
||||||
int result = accountInfoMapper.updateById(accountInfo);
|
prepareAnalysisFields(accountInfo);
|
||||||
syncAccountResult(accountInfo.getBankScope(), existing, accountInfo.getAccountNo(), editDTO);
|
return accountInfoMapper.updateById(accountInfo);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public int deleteAccountInfoByIds(Long[] ids) {
|
public int deleteAccountInfoByIds(Long[] ids) {
|
||||||
List<CcdiAccountInfo> accountList = accountInfoMapper.selectBatchIds(Arrays.asList(ids));
|
|
||||||
if (!accountList.isEmpty()) {
|
|
||||||
List<String> accountNos = accountList.stream()
|
|
||||||
.map(CcdiAccountInfo::getAccountNo)
|
|
||||||
.filter(StringUtils::isNotEmpty)
|
|
||||||
.toList();
|
|
||||||
if (!accountNos.isEmpty()) {
|
|
||||||
LambdaQueryWrapper<CcdiAccountResult> resultWrapper = new LambdaQueryWrapper<>();
|
|
||||||
resultWrapper.in(CcdiAccountResult::getAccountNo, accountNos);
|
|
||||||
accountResultMapper.delete(resultWrapper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return accountInfoMapper.deleteBatchIds(Arrays.asList(ids));
|
return accountInfoMapper.deleteBatchIds(Arrays.asList(ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,51 +231,38 @@ public class CcdiAccountInfoServiceImpl implements ICcdiAccountInfoService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncAccountResult(String newBankScope, CcdiAccountInfo existing, String accountNo, Object dto) {
|
private void prepareAnalysisFields(CcdiAccountInfo accountInfo) {
|
||||||
String oldBankScope = existing == null ? null : existing.getBankScope();
|
if (!"EXTERNAL".equals(accountInfo.getBankScope())) {
|
||||||
String oldAccountNo = existing == null ? null : existing.getAccountNo();
|
clearAnalysisFields(accountInfo);
|
||||||
|
|
||||||
if (existing != null && "EXTERNAL".equals(oldBankScope)
|
|
||||||
&& (!"EXTERNAL".equals(newBankScope) || !StringUtils.equals(oldAccountNo, accountNo))) {
|
|
||||||
LambdaQueryWrapper<CcdiAccountResult> deleteWrapper = new LambdaQueryWrapper<>();
|
|
||||||
deleteWrapper.eq(CcdiAccountResult::getAccountNo, oldAccountNo);
|
|
||||||
accountResultMapper.delete(deleteWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!"EXTERNAL".equals(newBankScope)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (accountInfo.getIsActualControl() == null) {
|
||||||
|
accountInfo.setIsActualControl(1);
|
||||||
|
}
|
||||||
|
if (accountInfo.getAvgMonthTxnCount() == null) {
|
||||||
|
accountInfo.setAvgMonthTxnCount(0);
|
||||||
|
}
|
||||||
|
if (accountInfo.getAvgMonthTxnAmount() == null) {
|
||||||
|
accountInfo.setAvgMonthTxnAmount(BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(accountInfo.getTxnFrequencyLevel())) {
|
||||||
|
accountInfo.setTxnFrequencyLevel("MEDIUM");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(accountInfo.getTxnRiskLevel())) {
|
||||||
|
accountInfo.setTxnRiskLevel("LOW");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LambdaQueryWrapper<CcdiAccountResult> wrapper = new LambdaQueryWrapper<>();
|
private void clearAnalysisFields(CcdiAccountInfo accountInfo) {
|
||||||
wrapper.eq(CcdiAccountResult::getAccountNo, accountNo);
|
accountInfo.setIsActualControl(null);
|
||||||
CcdiAccountResult existingResult = accountResultMapper.selectOne(wrapper);
|
accountInfo.setAvgMonthTxnCount(null);
|
||||||
|
accountInfo.setAvgMonthTxnAmount(null);
|
||||||
CcdiAccountResult accountResult = new CcdiAccountResult();
|
accountInfo.setTxnFrequencyLevel(null);
|
||||||
BeanUtils.copyProperties(dto, accountResult);
|
accountInfo.setDebitSingleMaxAmount(null);
|
||||||
accountResult.setAccountNo(accountNo);
|
accountInfo.setCreditSingleMaxAmount(null);
|
||||||
if (accountResult.getIsActualControl() == null) {
|
accountInfo.setDebitDailyMaxAmount(null);
|
||||||
accountResult.setIsActualControl(1);
|
accountInfo.setCreditDailyMaxAmount(null);
|
||||||
}
|
accountInfo.setTxnRiskLevel(null);
|
||||||
if (accountResult.getAvgMonthTxnCount() == null) {
|
|
||||||
accountResult.setAvgMonthTxnCount(0);
|
|
||||||
}
|
|
||||||
if (accountResult.getAvgMonthTxnAmount() == null) {
|
|
||||||
accountResult.setAvgMonthTxnAmount(BigDecimal.ZERO);
|
|
||||||
}
|
|
||||||
if (StringUtils.isEmpty(accountResult.getTxnFrequencyLevel())) {
|
|
||||||
accountResult.setTxnFrequencyLevel("MEDIUM");
|
|
||||||
}
|
|
||||||
if (StringUtils.isEmpty(accountResult.getTxnRiskLevel())) {
|
|
||||||
accountResult.setTxnRiskLevel("LOW");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existingResult == null) {
|
|
||||||
accountResultMapper.insert(accountResult);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
accountResult.setResultId(existingResult.getResultId());
|
|
||||||
accountResultMapper.updateById(accountResult);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateAmount(BigDecimal amount, String fieldLabel) {
|
private void validateAmount(BigDecimal amount, String fieldLabel) {
|
||||||
|
|||||||
@@ -320,6 +320,9 @@ public class CcdiBaseStaffImportServiceImpl implements ICcdiBaseStaffImportServi
|
|||||||
if (StringUtils.isEmpty(addDTO.getPhone())) {
|
if (StringUtils.isEmpty(addDTO.getPhone())) {
|
||||||
throw new RuntimeException("电话不能为空");
|
throw new RuntimeException("电话不能为空");
|
||||||
}
|
}
|
||||||
|
if (addDTO.getPartyMember() == null) {
|
||||||
|
throw new RuntimeException("是否党员不能为空");
|
||||||
|
}
|
||||||
if (StringUtils.isEmpty(addDTO.getStatus())) {
|
if (StringUtils.isEmpty(addDTO.getStatus())) {
|
||||||
throw new RuntimeException("状态不能为空");
|
throw new RuntimeException("状态不能为空");
|
||||||
}
|
}
|
||||||
@@ -357,6 +360,9 @@ public class CcdiBaseStaffImportServiceImpl implements ICcdiBaseStaffImportServi
|
|||||||
if (!"0".equals(addDTO.getStatus()) && !"1".equals(addDTO.getStatus())) {
|
if (!"0".equals(addDTO.getStatus()) && !"1".equals(addDTO.getStatus())) {
|
||||||
throw new RuntimeException("状态只能填写'在职'或'离职'");
|
throw new RuntimeException("状态只能填写'在职'或'离职'");
|
||||||
}
|
}
|
||||||
|
if (addDTO.getPartyMember() != 0 && addDTO.getPartyMember() != 1) {
|
||||||
|
throw new RuntimeException("是否党员只能填写'0'或'1'");
|
||||||
|
}
|
||||||
|
|
||||||
validateAnnualIncome(addDTO.getAnnualIncome(), "年收入");
|
validateAnnualIncome(addDTO.getAnnualIncome(), "年收入");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ public class CcdiBaseStaffServiceImpl implements ICcdiBaseStaffService {
|
|||||||
CcdiBaseStaff staff = baseStaffMapper.selectById(staffId);
|
CcdiBaseStaff staff = baseStaffMapper.selectById(staffId);
|
||||||
CcdiBaseStaffVO vo = convertToVO(staff);
|
CcdiBaseStaffVO vo = convertToVO(staff);
|
||||||
if (staff != null) {
|
if (staff != null) {
|
||||||
vo.setAssetInfoList(assetInfoService.selectByFamilyId(staff.getIdCard()).stream().map(asset -> {
|
vo.setAssetInfoList(assetInfoService.selectByFamilyIdAndPersonId(staff.getIdCard(), staff.getIdCard()).stream().map(asset -> {
|
||||||
CcdiAssetInfoVO assetInfoVO = new CcdiAssetInfoVO();
|
CcdiAssetInfoVO assetInfoVO = new CcdiAssetInfoVO();
|
||||||
BeanUtils.copyProperties(asset, assetInfoVO);
|
BeanUtils.copyProperties(asset, assetInfoVO);
|
||||||
return assetInfoVO;
|
return assetInfoVO;
|
||||||
@@ -131,6 +131,7 @@ public class CcdiBaseStaffServiceImpl implements ICcdiBaseStaffService {
|
|||||||
@Transactional
|
@Transactional
|
||||||
public int insertBaseStaff(CcdiBaseStaffAddDTO addDTO) {
|
public int insertBaseStaff(CcdiBaseStaffAddDTO addDTO) {
|
||||||
validateAnnualIncome(addDTO.getAnnualIncome(), "年收入");
|
validateAnnualIncome(addDTO.getAnnualIncome(), "年收入");
|
||||||
|
validatePartyMember(addDTO.getPartyMember(), "是否党员");
|
||||||
// 检查员工ID唯一性
|
// 检查员工ID唯一性
|
||||||
if (baseStaffMapper.selectById(addDTO.getStaffId()) != null) {
|
if (baseStaffMapper.selectById(addDTO.getStaffId()) != null) {
|
||||||
throw new RuntimeException("该员工ID已存在");
|
throw new RuntimeException("该员工ID已存在");
|
||||||
@@ -161,6 +162,7 @@ public class CcdiBaseStaffServiceImpl implements ICcdiBaseStaffService {
|
|||||||
@Transactional
|
@Transactional
|
||||||
public int updateBaseStaff(CcdiBaseStaffEditDTO editDTO) {
|
public int updateBaseStaff(CcdiBaseStaffEditDTO editDTO) {
|
||||||
validateAnnualIncome(editDTO.getAnnualIncome(), "年收入");
|
validateAnnualIncome(editDTO.getAnnualIncome(), "年收入");
|
||||||
|
validatePartyMember(editDTO.getPartyMember(), "是否党员");
|
||||||
CcdiBaseStaff existing = baseStaffMapper.selectById(editDTO.getStaffId());
|
CcdiBaseStaff existing = baseStaffMapper.selectById(editDTO.getStaffId());
|
||||||
if (existing == null) {
|
if (existing == null) {
|
||||||
throw new RuntimeException("员工不存在");
|
throw new RuntimeException("员工不存在");
|
||||||
@@ -291,4 +293,13 @@ public class CcdiBaseStaffServiceImpl implements ICcdiBaseStaffService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validatePartyMember(Integer partyMember, String fieldLabel) {
|
||||||
|
if (partyMember == null) {
|
||||||
|
throw new RuntimeException(fieldLabel + "不能为空");
|
||||||
|
}
|
||||||
|
if (partyMember != 0 && partyMember != 1) {
|
||||||
|
throw new RuntimeException(fieldLabel + "只能填写'0'或'1'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,225 @@
|
|||||||
|
package com.ruoyi.info.collection.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.info.collection.domain.CcdiEnterpriseBaseInfo;
|
||||||
|
import com.ruoyi.info.collection.domain.excel.CcdiEnterpriseBaseInfoExcel;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.EnterpriseBaseInfoImportFailureVO;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.ImportResult;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
||||||
|
import com.ruoyi.info.collection.enums.DataSource;
|
||||||
|
import com.ruoyi.info.collection.enums.EnterpriseRiskLevel;
|
||||||
|
import com.ruoyi.info.collection.enums.EnterpriseSource;
|
||||||
|
import com.ruoyi.info.collection.mapper.CcdiEnterpriseBaseInfoMapper;
|
||||||
|
import com.ruoyi.info.collection.service.ICcdiEnterpriseBaseInfoImportService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理导入 Service 实现
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@EnableAsync
|
||||||
|
public class CcdiEnterpriseBaseInfoImportServiceImpl implements ICcdiEnterpriseBaseInfoImportService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CcdiEnterpriseBaseInfoMapper enterpriseBaseInfoMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Async
|
||||||
|
public void importEnterpriseBaseInfoAsync(List<CcdiEnterpriseBaseInfoExcel> excelList, String taskId, String userName) {
|
||||||
|
List<CcdiEnterpriseBaseInfo> successRecords = new ArrayList<>();
|
||||||
|
List<EnterpriseBaseInfoImportFailureVO> failures = new ArrayList<>();
|
||||||
|
Set<String> existingCreditCodes = getExistingCreditCodes(excelList);
|
||||||
|
Set<String> processedCreditCodes = new HashSet<>();
|
||||||
|
|
||||||
|
for (CcdiEnterpriseBaseInfoExcel excel : excelList) {
|
||||||
|
try {
|
||||||
|
CcdiEnterpriseBaseInfo entity = validateAndBuildEntity(excel, existingCreditCodes, processedCreditCodes, userName);
|
||||||
|
successRecords.add(entity);
|
||||||
|
processedCreditCodes.add(entity.getSocialCreditCode());
|
||||||
|
} catch (Exception e) {
|
||||||
|
EnterpriseBaseInfoImportFailureVO failureVO = new EnterpriseBaseInfoImportFailureVO();
|
||||||
|
BeanUtils.copyProperties(excel, failureVO);
|
||||||
|
failureVO.setErrorMessage(e.getMessage());
|
||||||
|
failures.add(failureVO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!successRecords.isEmpty()) {
|
||||||
|
saveBatch(successRecords, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!failures.isEmpty()) {
|
||||||
|
redisTemplate.opsForValue().set(buildFailuresKey(taskId), failures, 7, TimeUnit.DAYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImportResult result = new ImportResult();
|
||||||
|
result.setTotalCount(excelList.size());
|
||||||
|
result.setSuccessCount(successRecords.size());
|
||||||
|
result.setFailureCount(failures.size());
|
||||||
|
updateImportStatus(taskId, failures.isEmpty() ? "SUCCESS" : "PARTIAL_SUCCESS", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImportStatusVO getImportStatus(String taskId) {
|
||||||
|
String key = buildStatusKey(taskId);
|
||||||
|
Boolean exists = redisTemplate.hasKey(key);
|
||||||
|
if (Boolean.FALSE.equals(exists)) {
|
||||||
|
throw new RuntimeException("任务不存在或已过期");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<Object, Object> statusMap = redisTemplate.opsForHash().entries(key);
|
||||||
|
ImportStatusVO statusVO = new ImportStatusVO();
|
||||||
|
statusVO.setTaskId((String) statusMap.get("taskId"));
|
||||||
|
statusVO.setStatus((String) statusMap.get("status"));
|
||||||
|
statusVO.setTotalCount((Integer) statusMap.get("totalCount"));
|
||||||
|
statusVO.setSuccessCount((Integer) statusMap.get("successCount"));
|
||||||
|
statusVO.setFailureCount((Integer) statusMap.get("failureCount"));
|
||||||
|
statusVO.setProgress((Integer) statusMap.get("progress"));
|
||||||
|
statusVO.setStartTime((Long) statusMap.get("startTime"));
|
||||||
|
statusVO.setEndTime((Long) statusMap.get("endTime"));
|
||||||
|
statusVO.setMessage((String) statusMap.get("message"));
|
||||||
|
return statusVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EnterpriseBaseInfoImportFailureVO> getImportFailures(String taskId) {
|
||||||
|
Object failuresObj = redisTemplate.opsForValue().get(buildFailuresKey(taskId));
|
||||||
|
if (failuresObj == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return JSON.parseArray(JSON.toJSONString(failuresObj), EnterpriseBaseInfoImportFailureVO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CcdiEnterpriseBaseInfo validateAndBuildEntity(CcdiEnterpriseBaseInfoExcel excel,
|
||||||
|
Set<String> existingCreditCodes,
|
||||||
|
Set<String> processedCreditCodes,
|
||||||
|
String userName) {
|
||||||
|
if (excel == null) {
|
||||||
|
throw new RuntimeException("导入数据不能为空");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(excel.getEnterpriseName())) {
|
||||||
|
throw new RuntimeException("企业名称不能为空");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(excel.getSocialCreditCode())) {
|
||||||
|
throw new RuntimeException("统一社会信用代码不能为空");
|
||||||
|
}
|
||||||
|
if (!excel.getSocialCreditCode().matches("^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$")) {
|
||||||
|
throw new RuntimeException("统一社会信用代码格式不正确");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(excel.getStatus())) {
|
||||||
|
throw new RuntimeException("经营状态不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
String riskLevel = EnterpriseRiskLevel.resolveCode(StringUtils.trim(excel.getRiskLevel()));
|
||||||
|
if (riskLevel == null) {
|
||||||
|
throw new RuntimeException("风险等级不在允许范围内");
|
||||||
|
}
|
||||||
|
String entSource = EnterpriseSource.resolveCode(StringUtils.trim(excel.getEntSource()));
|
||||||
|
if (entSource == null) {
|
||||||
|
throw new RuntimeException("企业来源不在允许范围内");
|
||||||
|
}
|
||||||
|
String dataSource = resolveDataSourceCode(StringUtils.trim(excel.getDataSource()));
|
||||||
|
if (dataSource == null) {
|
||||||
|
throw new RuntimeException("数据来源不在允许范围内");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingCreditCodes.contains(excel.getSocialCreditCode())) {
|
||||||
|
throw new RuntimeException(String.format("统一社会信用代码[%s]已存在,请勿重复导入", excel.getSocialCreditCode()));
|
||||||
|
}
|
||||||
|
if (processedCreditCodes.contains(excel.getSocialCreditCode())) {
|
||||||
|
throw new RuntimeException(String.format("统一社会信用代码[%s]在导入文件中重复,已跳过此条记录", excel.getSocialCreditCode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
CcdiEnterpriseBaseInfo entity = new CcdiEnterpriseBaseInfo();
|
||||||
|
BeanUtils.copyProperties(excel, entity);
|
||||||
|
entity.setRiskLevel(riskLevel);
|
||||||
|
entity.setEntSource(entSource);
|
||||||
|
entity.setDataSource(dataSource);
|
||||||
|
entity.setStatus(StringUtils.trim(excel.getStatus()));
|
||||||
|
entity.setCreatedBy(userName);
|
||||||
|
entity.setUpdatedBy(userName);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getExistingCreditCodes(List<CcdiEnterpriseBaseInfoExcel> excelList) {
|
||||||
|
List<String> creditCodes = excelList.stream()
|
||||||
|
.map(CcdiEnterpriseBaseInfoExcel::getSocialCreditCode)
|
||||||
|
.filter(StringUtils::isNotEmpty)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (creditCodes.isEmpty()) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<CcdiEnterpriseBaseInfo> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.in(CcdiEnterpriseBaseInfo::getSocialCreditCode, creditCodes);
|
||||||
|
return enterpriseBaseInfoMapper.selectList(wrapper).stream()
|
||||||
|
.map(CcdiEnterpriseBaseInfo::getSocialCreditCode)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int saveBatch(List<CcdiEnterpriseBaseInfo> list, int batchSize) {
|
||||||
|
int total = 0;
|
||||||
|
for (int i = 0; i < list.size(); i += batchSize) {
|
||||||
|
int end = Math.min(i + batchSize, list.size());
|
||||||
|
total += enterpriseBaseInfoMapper.insertBatch(list.subList(i, end));
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateImportStatus(String taskId, String status, ImportResult result) {
|
||||||
|
Map<String, Object> statusData = new HashMap<>();
|
||||||
|
statusData.put("status", status);
|
||||||
|
statusData.put("successCount", result.getSuccessCount());
|
||||||
|
statusData.put("failureCount", result.getFailureCount());
|
||||||
|
statusData.put("progress", 100);
|
||||||
|
statusData.put("endTime", System.currentTimeMillis());
|
||||||
|
if ("SUCCESS".equals(status)) {
|
||||||
|
statusData.put("message", "全部成功!共导入" + result.getTotalCount() + "条数据");
|
||||||
|
} else {
|
||||||
|
statusData.put("message", "成功" + result.getSuccessCount() + "条,失败" + result.getFailureCount() + "条");
|
||||||
|
}
|
||||||
|
redisTemplate.opsForHash().putAll(buildStatusKey(taskId), statusData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveDataSourceCode(String value) {
|
||||||
|
for (DataSource source : DataSource.values()) {
|
||||||
|
if (source.getCode().equals(value) || source.getDesc().equals(value)) {
|
||||||
|
return source.getCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildStatusKey(String taskId) {
|
||||||
|
return "import:enterpriseBaseInfo:" + taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildFailuresKey(String taskId) {
|
||||||
|
return "import:enterpriseBaseInfo:" + taskId + ":failures";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
package com.ruoyi.info.collection.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.info.collection.domain.CcdiEnterpriseBaseInfo;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoAddDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoEditDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoQueryDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.excel.CcdiEnterpriseBaseInfoExcel;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.CcdiEnterpriseBaseInfoVO;
|
||||||
|
import com.ruoyi.info.collection.enums.DataSource;
|
||||||
|
import com.ruoyi.info.collection.enums.EnterpriseRiskLevel;
|
||||||
|
import com.ruoyi.info.collection.enums.EnterpriseSource;
|
||||||
|
import com.ruoyi.info.collection.mapper.CcdiEnterpriseBaseInfoMapper;
|
||||||
|
import com.ruoyi.info.collection.service.ICcdiEnterpriseBaseInfoImportService;
|
||||||
|
import com.ruoyi.info.collection.service.ICcdiEnterpriseBaseInfoService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理 Service 实现
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class CcdiEnterpriseBaseInfoServiceImpl implements ICcdiEnterpriseBaseInfoService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CcdiEnterpriseBaseInfoMapper enterpriseBaseInfoMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ICcdiEnterpriseBaseInfoImportService enterpriseBaseInfoImportService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<CcdiEnterpriseBaseInfoVO> selectEnterpriseBaseInfoPage(Page<CcdiEnterpriseBaseInfoVO> page,
|
||||||
|
CcdiEnterpriseBaseInfoQueryDTO queryDTO) {
|
||||||
|
return enterpriseBaseInfoMapper.selectEnterpriseBaseInfoPage(page, queryDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CcdiEnterpriseBaseInfoVO selectEnterpriseBaseInfoById(String socialCreditCode) {
|
||||||
|
CcdiEnterpriseBaseInfo entity = enterpriseBaseInfoMapper.selectById(socialCreditCode);
|
||||||
|
if (entity == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
CcdiEnterpriseBaseInfoVO vo = new CcdiEnterpriseBaseInfoVO();
|
||||||
|
BeanUtils.copyProperties(entity, vo);
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public int insertEnterpriseBaseInfo(CcdiEnterpriseBaseInfoAddDTO addDTO) {
|
||||||
|
if (enterpriseBaseInfoMapper.selectById(addDTO.getSocialCreditCode()) != null) {
|
||||||
|
throw new RuntimeException("该统一社会信用代码已存在");
|
||||||
|
}
|
||||||
|
validateEnumFields(addDTO.getStatus(), addDTO.getRiskLevel(), addDTO.getEntSource(), addDTO.getDataSource());
|
||||||
|
|
||||||
|
CcdiEnterpriseBaseInfo entity = new CcdiEnterpriseBaseInfo();
|
||||||
|
BeanUtils.copyProperties(addDTO, entity);
|
||||||
|
return enterpriseBaseInfoMapper.insert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public int updateEnterpriseBaseInfo(CcdiEnterpriseBaseInfoEditDTO editDTO) {
|
||||||
|
CcdiEnterpriseBaseInfo existing = enterpriseBaseInfoMapper.selectById(editDTO.getSocialCreditCode());
|
||||||
|
if (existing == null) {
|
||||||
|
throw new RuntimeException("实体库记录不存在");
|
||||||
|
}
|
||||||
|
validateEnumFields(editDTO.getStatus(), editDTO.getRiskLevel(), editDTO.getEntSource(), editDTO.getDataSource());
|
||||||
|
|
||||||
|
CcdiEnterpriseBaseInfo entity = new CcdiEnterpriseBaseInfo();
|
||||||
|
BeanUtils.copyProperties(editDTO, entity);
|
||||||
|
return enterpriseBaseInfoMapper.updateById(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public int deleteEnterpriseBaseInfoByIds(String[] socialCreditCodes) {
|
||||||
|
if (socialCreditCodes == null || socialCreditCodes.length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return enterpriseBaseInfoMapper.deleteBatchIds(List.of(socialCreditCodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CcdiEnterpriseBaseInfoExcel> selectEnterpriseBaseInfoListForExport(CcdiEnterpriseBaseInfoQueryDTO queryDTO) {
|
||||||
|
LambdaQueryWrapper<CcdiEnterpriseBaseInfo> wrapper = buildQueryWrapper(queryDTO);
|
||||||
|
return enterpriseBaseInfoMapper.selectList(wrapper).stream().map(entity -> {
|
||||||
|
CcdiEnterpriseBaseInfoExcel excel = new CcdiEnterpriseBaseInfoExcel();
|
||||||
|
BeanUtils.copyProperties(entity, excel);
|
||||||
|
return excel;
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public String importEnterpriseBaseInfo(List<CcdiEnterpriseBaseInfoExcel> excelList) {
|
||||||
|
String taskId = UUID.randomUUID().toString();
|
||||||
|
String statusKey = "import:enterpriseBaseInfo:" + taskId;
|
||||||
|
|
||||||
|
Map<String, Object> statusData = new HashMap<>();
|
||||||
|
statusData.put("taskId", taskId);
|
||||||
|
statusData.put("status", "PROCESSING");
|
||||||
|
statusData.put("totalCount", excelList.size());
|
||||||
|
statusData.put("successCount", 0);
|
||||||
|
statusData.put("failureCount", 0);
|
||||||
|
statusData.put("progress", 0);
|
||||||
|
statusData.put("startTime", System.currentTimeMillis());
|
||||||
|
statusData.put("message", "正在处理...");
|
||||||
|
|
||||||
|
redisTemplate.opsForHash().putAll(statusKey, statusData);
|
||||||
|
redisTemplate.expire(statusKey, 7, TimeUnit.DAYS);
|
||||||
|
|
||||||
|
enterpriseBaseInfoImportService.importEnterpriseBaseInfoAsync(excelList, taskId, SecurityUtils.getUsername());
|
||||||
|
return taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LambdaQueryWrapper<CcdiEnterpriseBaseInfo> buildQueryWrapper(CcdiEnterpriseBaseInfoQueryDTO queryDTO) {
|
||||||
|
LambdaQueryWrapper<CcdiEnterpriseBaseInfo> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
if (queryDTO == null) {
|
||||||
|
return wrapper.orderByDesc(CcdiEnterpriseBaseInfo::getCreateTime);
|
||||||
|
}
|
||||||
|
wrapper.like(StringUtils.isNotEmpty(queryDTO.getEnterpriseName()),
|
||||||
|
CcdiEnterpriseBaseInfo::getEnterpriseName, queryDTO.getEnterpriseName());
|
||||||
|
wrapper.eq(StringUtils.isNotEmpty(queryDTO.getSocialCreditCode()),
|
||||||
|
CcdiEnterpriseBaseInfo::getSocialCreditCode, queryDTO.getSocialCreditCode());
|
||||||
|
wrapper.eq(StringUtils.isNotEmpty(queryDTO.getEnterpriseType()),
|
||||||
|
CcdiEnterpriseBaseInfo::getEnterpriseType, queryDTO.getEnterpriseType());
|
||||||
|
wrapper.eq(StringUtils.isNotEmpty(queryDTO.getEnterpriseNature()),
|
||||||
|
CcdiEnterpriseBaseInfo::getEnterpriseNature, queryDTO.getEnterpriseNature());
|
||||||
|
wrapper.like(StringUtils.isNotEmpty(queryDTO.getIndustryClass()),
|
||||||
|
CcdiEnterpriseBaseInfo::getIndustryClass, queryDTO.getIndustryClass());
|
||||||
|
wrapper.eq(StringUtils.isNotEmpty(queryDTO.getStatus()),
|
||||||
|
CcdiEnterpriseBaseInfo::getStatus, queryDTO.getStatus());
|
||||||
|
wrapper.eq(StringUtils.isNotEmpty(queryDTO.getRiskLevel()),
|
||||||
|
CcdiEnterpriseBaseInfo::getRiskLevel, queryDTO.getRiskLevel());
|
||||||
|
wrapper.eq(StringUtils.isNotEmpty(queryDTO.getEntSource()),
|
||||||
|
CcdiEnterpriseBaseInfo::getEntSource, queryDTO.getEntSource());
|
||||||
|
return wrapper.orderByDesc(CcdiEnterpriseBaseInfo::getCreateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateEnumFields(String status, String riskLevel, String entSource, String dataSource) {
|
||||||
|
if (StringUtils.isEmpty(status)) {
|
||||||
|
throw new RuntimeException("经营状态不能为空");
|
||||||
|
}
|
||||||
|
if (!EnterpriseRiskLevel.contains(riskLevel)) {
|
||||||
|
throw new RuntimeException("风险等级不在允许范围内");
|
||||||
|
}
|
||||||
|
if (!EnterpriseSource.contains(entSource)) {
|
||||||
|
throw new RuntimeException("企业来源不在允许范围内");
|
||||||
|
}
|
||||||
|
if (!containsDataSource(dataSource)) {
|
||||||
|
throw new RuntimeException("数据来源不在允许范围内");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean containsDataSource(String code) {
|
||||||
|
for (DataSource source : DataSource.values()) {
|
||||||
|
if (source.getCode().equals(code)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,17 +3,13 @@ package com.ruoyi.info.collection.service.impl;
|
|||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.ruoyi.info.collection.domain.CcdiStaffRecruitment;
|
import com.ruoyi.info.collection.domain.CcdiStaffRecruitment;
|
||||||
import com.ruoyi.info.collection.domain.CcdiStaffRecruitmentWork;
|
|
||||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentAddDTO;
|
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentAddDTO;
|
||||||
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentExcel;
|
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentExcel;
|
||||||
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentWorkExcel;
|
|
||||||
import com.ruoyi.info.collection.domain.vo.ImportResult;
|
import com.ruoyi.info.collection.domain.vo.ImportResult;
|
||||||
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
||||||
import com.ruoyi.info.collection.domain.vo.RecruitmentImportFailureVO;
|
import com.ruoyi.info.collection.domain.vo.RecruitmentImportFailureVO;
|
||||||
import com.ruoyi.info.collection.enums.AdmitStatus;
|
import com.ruoyi.info.collection.enums.AdmitStatus;
|
||||||
import com.ruoyi.info.collection.enums.RecruitType;
|
|
||||||
import com.ruoyi.info.collection.mapper.CcdiStaffRecruitmentMapper;
|
import com.ruoyi.info.collection.mapper.CcdiStaffRecruitmentMapper;
|
||||||
import com.ruoyi.info.collection.mapper.CcdiStaffRecruitmentWorkMapper;
|
|
||||||
import com.ruoyi.info.collection.service.ICcdiStaffRecruitmentImportService;
|
import com.ruoyi.info.collection.service.ICcdiStaffRecruitmentImportService;
|
||||||
import com.ruoyi.info.collection.utils.ImportLogUtils;
|
import com.ruoyi.info.collection.utils.ImportLogUtils;
|
||||||
import com.ruoyi.common.utils.IdCardUtil;
|
import com.ruoyi.common.utils.IdCardUtil;
|
||||||
@@ -47,9 +43,6 @@ public class CcdiStaffRecruitmentImportServiceImpl implements ICcdiStaffRecruitm
|
|||||||
@Resource
|
@Resource
|
||||||
private CcdiStaffRecruitmentMapper recruitmentMapper;
|
private CcdiStaffRecruitmentMapper recruitmentMapper;
|
||||||
|
|
||||||
@Resource
|
|
||||||
private CcdiStaffRecruitmentWorkMapper recruitmentWorkMapper;
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
@@ -67,10 +60,10 @@ public class CcdiStaffRecruitmentImportServiceImpl implements ICcdiStaffRecruitm
|
|||||||
List<CcdiStaffRecruitment> newRecords = new ArrayList<>();
|
List<CcdiStaffRecruitment> newRecords = new ArrayList<>();
|
||||||
List<RecruitmentImportFailureVO> failures = new ArrayList<>();
|
List<RecruitmentImportFailureVO> failures = new ArrayList<>();
|
||||||
|
|
||||||
// 批量查询已存在的招聘记录编号
|
// 批量查询已存在的招聘项目编号
|
||||||
ImportLogUtils.logBatchQueryStart(log, taskId, "已存在的招聘记录编号", excelList.size());
|
ImportLogUtils.logBatchQueryStart(log, taskId, "已存在的招聘项目编号", excelList.size());
|
||||||
Set<String> existingRecruitIds = getExistingRecruitIds(excelList);
|
Set<String> existingRecruitIds = getExistingRecruitIds(excelList);
|
||||||
ImportLogUtils.logBatchQueryComplete(log, taskId, "招聘记录编号", existingRecruitIds.size());
|
ImportLogUtils.logBatchQueryComplete(log, taskId, "招聘项目编号", existingRecruitIds.size());
|
||||||
|
|
||||||
// 用于检测Excel内部的重复ID
|
// 用于检测Excel内部的重复ID
|
||||||
Set<String> excelProcessedIds = new HashSet<>();
|
Set<String> excelProcessedIds = new HashSet<>();
|
||||||
@@ -83,21 +76,19 @@ public class CcdiStaffRecruitmentImportServiceImpl implements ICcdiStaffRecruitm
|
|||||||
// 转换为AddDTO进行验证
|
// 转换为AddDTO进行验证
|
||||||
CcdiStaffRecruitmentAddDTO addDTO = new CcdiStaffRecruitmentAddDTO();
|
CcdiStaffRecruitmentAddDTO addDTO = new CcdiStaffRecruitmentAddDTO();
|
||||||
BeanUtils.copyProperties(excel, addDTO);
|
BeanUtils.copyProperties(excel, addDTO);
|
||||||
addDTO.setRecruitType(RecruitType.inferCode(addDTO.getRecruitName()));
|
|
||||||
|
|
||||||
// 验证数据
|
// 验证数据
|
||||||
validateRecruitmentData(addDTO, existingRecruitIds);
|
validateRecruitmentData(addDTO, existingRecruitIds);
|
||||||
|
|
||||||
CcdiStaffRecruitment recruitment = new CcdiStaffRecruitment();
|
CcdiStaffRecruitment recruitment = new CcdiStaffRecruitment();
|
||||||
BeanUtils.copyProperties(excel, recruitment);
|
BeanUtils.copyProperties(excel, recruitment);
|
||||||
recruitment.setRecruitType(addDTO.getRecruitType());
|
|
||||||
|
|
||||||
if (existingRecruitIds.contains(excel.getRecruitId())) {
|
if (existingRecruitIds.contains(excel.getRecruitId())) {
|
||||||
// 招聘记录编号在数据库中已存在,直接报错
|
// 招聘项目编号在数据库中已存在,直接报错
|
||||||
throw new RuntimeException(String.format("招聘记录编号[%s]已存在,请勿重复导入", excel.getRecruitId()));
|
throw new RuntimeException(String.format("招聘项目编号[%s]已存在,请勿重复导入", excel.getRecruitId()));
|
||||||
} else if (excelProcessedIds.contains(excel.getRecruitId())) {
|
} else if (excelProcessedIds.contains(excel.getRecruitId())) {
|
||||||
// 招聘记录编号在Excel文件内部重复
|
// 招聘项目编号在Excel文件内部重复
|
||||||
throw new RuntimeException(String.format("招聘记录编号[%s]在导入文件中重复,已跳过此条记录", excel.getRecruitId()));
|
throw new RuntimeException(String.format("招聘项目编号[%s]在导入文件中重复,已跳过此条记录", excel.getRecruitId()));
|
||||||
} else {
|
} else {
|
||||||
recruitment.setCreatedBy(userName);
|
recruitment.setCreatedBy(userName);
|
||||||
recruitment.setUpdatedBy(userName);
|
recruitment.setUpdatedBy(userName);
|
||||||
@@ -116,7 +107,7 @@ public class CcdiStaffRecruitmentImportServiceImpl implements ICcdiStaffRecruitm
|
|||||||
failures.add(failure);
|
failures.add(failure);
|
||||||
|
|
||||||
// 记录验证失败日志
|
// 记录验证失败日志
|
||||||
String keyData = String.format("招聘记录编号=%s, 项目名称=%s, 应聘人员=%s",
|
String keyData = String.format("招聘项目编号=%s, 项目名称=%s, 应聘人员=%s",
|
||||||
excel.getRecruitId(), excel.getRecruitName(), excel.getCandName());
|
excel.getRecruitId(), excel.getRecruitName(), excel.getCandName());
|
||||||
ImportLogUtils.logValidationError(log, taskId, i + 1, e.getMessage(), keyData);
|
ImportLogUtils.logValidationError(log, taskId, i + 1, e.getMessage(), keyData);
|
||||||
}
|
}
|
||||||
@@ -151,85 +142,7 @@ public class CcdiStaffRecruitmentImportServiceImpl implements ICcdiStaffRecruitm
|
|||||||
|
|
||||||
// 记录导入完成
|
// 记录导入完成
|
||||||
long duration = System.currentTimeMillis() - startTime;
|
long duration = System.currentTimeMillis() - startTime;
|
||||||
ImportLogUtils.logImportComplete(log, taskId, "招聘信息",
|
ImportLogUtils.logImportComplete(log, taskId, "招聘信息",
|
||||||
excelList.size(), result.getSuccessCount(), result.getFailureCount(), duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Async
|
|
||||||
@Transactional
|
|
||||||
public void importRecruitmentWorkAsync(List<CcdiStaffRecruitmentWorkExcel> excelList,
|
|
||||||
String taskId,
|
|
||||||
String userName) {
|
|
||||||
long startTime = System.currentTimeMillis();
|
|
||||||
ImportLogUtils.logImportStart(log, taskId, "招聘历史工作经历", excelList.size(), userName);
|
|
||||||
|
|
||||||
List<RecruitmentImportFailureVO> failures = new ArrayList<>();
|
|
||||||
List<CcdiStaffRecruitmentWork> validRecords = new ArrayList<>();
|
|
||||||
Set<String> failedRecruitIds = new HashSet<>();
|
|
||||||
Set<String> processedRecruitSortKeys = new HashSet<>();
|
|
||||||
|
|
||||||
Map<String, CcdiStaffRecruitment> recruitmentMap = getRecruitmentMap(excelList);
|
|
||||||
|
|
||||||
for (int i = 0; i < excelList.size(); i++) {
|
|
||||||
CcdiStaffRecruitmentWorkExcel excel = excelList.get(i);
|
|
||||||
try {
|
|
||||||
CcdiStaffRecruitment recruitment = recruitmentMap.get(trim(excel.getRecruitId()));
|
|
||||||
validateRecruitmentWorkData(excel, recruitment, processedRecruitSortKeys);
|
|
||||||
|
|
||||||
CcdiStaffRecruitmentWork work = new CcdiStaffRecruitmentWork();
|
|
||||||
BeanUtils.copyProperties(excel, work);
|
|
||||||
work.setRecruitId(trim(excel.getRecruitId()));
|
|
||||||
work.setCreatedBy(userName);
|
|
||||||
work.setUpdatedBy(userName);
|
|
||||||
validRecords.add(work);
|
|
||||||
|
|
||||||
ImportLogUtils.logProgress(log, taskId, i + 1, excelList.size(),
|
|
||||||
validRecords.size(), failures.size());
|
|
||||||
} catch (Exception e) {
|
|
||||||
failedRecruitIds.add(trim(excel.getRecruitId()));
|
|
||||||
failures.add(buildWorkFailure(excel, e.getMessage()));
|
|
||||||
String keyData = String.format("招聘记录编号=%s, 候选人=%s, 工作单位=%s",
|
|
||||||
excel.getRecruitId(), excel.getCandName(), excel.getCompanyName());
|
|
||||||
ImportLogUtils.logValidationError(log, taskId, i + 1, e.getMessage(), keyData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<CcdiStaffRecruitmentWork> importRecords = validRecords.stream()
|
|
||||||
.filter(work -> !failedRecruitIds.contains(work.getRecruitId()))
|
|
||||||
.toList();
|
|
||||||
appendSkippedFailures(validRecords, failedRecruitIds, failures);
|
|
||||||
|
|
||||||
if (!importRecords.isEmpty()) {
|
|
||||||
Set<String> importRecruitIds = importRecords.stream()
|
|
||||||
.map(CcdiStaffRecruitmentWork::getRecruitId)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
LambdaQueryWrapper<CcdiStaffRecruitmentWork> deleteWrapper = new LambdaQueryWrapper<>();
|
|
||||||
deleteWrapper.in(CcdiStaffRecruitmentWork::getRecruitId, importRecruitIds);
|
|
||||||
recruitmentWorkMapper.delete(deleteWrapper);
|
|
||||||
|
|
||||||
importRecords.forEach(recruitmentWorkMapper::insert);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!failures.isEmpty()) {
|
|
||||||
try {
|
|
||||||
String failuresKey = "import:recruitment:" + taskId + ":failures";
|
|
||||||
redisTemplate.opsForValue().set(failuresKey, failures, 7, TimeUnit.DAYS);
|
|
||||||
ImportLogUtils.logRedisOperation(log, taskId, "保存失败记录", failures.size());
|
|
||||||
} catch (Exception e) {
|
|
||||||
ImportLogUtils.logRedisError(log, taskId, "保存失败记录", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImportResult result = new ImportResult();
|
|
||||||
result.setTotalCount(excelList.size());
|
|
||||||
result.setSuccessCount(importRecords.size());
|
|
||||||
result.setFailureCount(failures.size());
|
|
||||||
String finalStatus = result.getFailureCount() == 0 ? "SUCCESS" : "PARTIAL_SUCCESS";
|
|
||||||
updateImportStatus(taskId, finalStatus, result);
|
|
||||||
|
|
||||||
long duration = System.currentTimeMillis() - startTime;
|
|
||||||
ImportLogUtils.logImportComplete(log, taskId, "招聘历史工作经历",
|
|
||||||
excelList.size(), result.getSuccessCount(), result.getFailureCount(), duration);
|
excelList.size(), result.getSuccessCount(), result.getFailureCount(), duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +184,7 @@ public class CcdiStaffRecruitmentImportServiceImpl implements ICcdiStaffRecruitm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量查询已存在的招聘记录编号
|
* 批量查询已存在的招聘项目编号
|
||||||
*/
|
*/
|
||||||
private Set<String> getExistingRecruitIds(List<CcdiStaffRecruitmentExcel> excelList) {
|
private Set<String> getExistingRecruitIds(List<CcdiStaffRecruitmentExcel> excelList) {
|
||||||
List<String> recruitIds = excelList.stream()
|
List<String> recruitIds = excelList.stream()
|
||||||
@@ -299,7 +212,7 @@ public class CcdiStaffRecruitmentImportServiceImpl implements ICcdiStaffRecruitm
|
|||||||
Set<String> existingRecruitIds) {
|
Set<String> existingRecruitIds) {
|
||||||
// 验证必填字段
|
// 验证必填字段
|
||||||
if (StringUtils.isEmpty(addDTO.getRecruitId())) {
|
if (StringUtils.isEmpty(addDTO.getRecruitId())) {
|
||||||
throw new RuntimeException("招聘记录编号不能为空");
|
throw new RuntimeException("招聘项目编号不能为空");
|
||||||
}
|
}
|
||||||
if (StringUtils.isEmpty(addDTO.getRecruitName())) {
|
if (StringUtils.isEmpty(addDTO.getRecruitName())) {
|
||||||
throw new RuntimeException("招聘项目名称不能为空");
|
throw new RuntimeException("招聘项目名称不能为空");
|
||||||
@@ -334,9 +247,6 @@ public class CcdiStaffRecruitmentImportServiceImpl implements ICcdiStaffRecruitm
|
|||||||
if (StringUtils.isEmpty(addDTO.getAdmitStatus())) {
|
if (StringUtils.isEmpty(addDTO.getAdmitStatus())) {
|
||||||
throw new RuntimeException("录用情况不能为空");
|
throw new RuntimeException("录用情况不能为空");
|
||||||
}
|
}
|
||||||
if (StringUtils.isEmpty(addDTO.getRecruitType())) {
|
|
||||||
throw new RuntimeException("招聘类型不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证证件号码格式
|
// 验证证件号码格式
|
||||||
String idCardError = IdCardUtil.getErrorMessage(addDTO.getCandId());
|
String idCardError = IdCardUtil.getErrorMessage(addDTO.getCandId());
|
||||||
@@ -353,115 +263,6 @@ public class CcdiStaffRecruitmentImportServiceImpl implements ICcdiStaffRecruitm
|
|||||||
if (AdmitStatus.getDescByCode(addDTO.getAdmitStatus()) == null) {
|
if (AdmitStatus.getDescByCode(addDTO.getAdmitStatus()) == null) {
|
||||||
throw new RuntimeException("录用情况只能填写'录用'、'未录用'或'放弃'");
|
throw new RuntimeException("录用情况只能填写'录用'、'未录用'或'放弃'");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RecruitType.getDescByCode(addDTO.getRecruitType()) == null) {
|
|
||||||
throw new RuntimeException("招聘类型只能填写'SOCIAL'或'CAMPUS'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, CcdiStaffRecruitment> getRecruitmentMap(List<CcdiStaffRecruitmentWorkExcel> excelList) {
|
|
||||||
List<String> recruitIds = excelList.stream()
|
|
||||||
.map(CcdiStaffRecruitmentWorkExcel::getRecruitId)
|
|
||||||
.map(this::trim)
|
|
||||||
.filter(StringUtils::isNotEmpty)
|
|
||||||
.distinct()
|
|
||||||
.toList();
|
|
||||||
if (recruitIds.isEmpty()) {
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
List<CcdiStaffRecruitment> recruitments = recruitmentMapper.selectBatchIds(recruitIds);
|
|
||||||
return recruitments.stream()
|
|
||||||
.collect(Collectors.toMap(CcdiStaffRecruitment::getRecruitId, item -> item));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateRecruitmentWorkData(CcdiStaffRecruitmentWorkExcel excel,
|
|
||||||
CcdiStaffRecruitment recruitment,
|
|
||||||
Set<String> processedRecruitSortKeys) {
|
|
||||||
if (StringUtils.isEmpty(trim(excel.getRecruitId()))) {
|
|
||||||
throw new RuntimeException("招聘记录编号不能为空");
|
|
||||||
}
|
|
||||||
if (StringUtils.isEmpty(trim(excel.getCandName()))) {
|
|
||||||
throw new RuntimeException("候选人姓名不能为空");
|
|
||||||
}
|
|
||||||
if (StringUtils.isEmpty(trim(excel.getRecruitName()))) {
|
|
||||||
throw new RuntimeException("招聘项目名称不能为空");
|
|
||||||
}
|
|
||||||
if (StringUtils.isEmpty(trim(excel.getPosName()))) {
|
|
||||||
throw new RuntimeException("职位名称不能为空");
|
|
||||||
}
|
|
||||||
if (excel.getSortOrder() == null || excel.getSortOrder() <= 0) {
|
|
||||||
throw new RuntimeException("排序号不能为空且必须大于0");
|
|
||||||
}
|
|
||||||
if (StringUtils.isEmpty(trim(excel.getCompanyName()))) {
|
|
||||||
throw new RuntimeException("工作单位不能为空");
|
|
||||||
}
|
|
||||||
if (StringUtils.isEmpty(trim(excel.getPositionName()))) {
|
|
||||||
throw new RuntimeException("岗位不能为空");
|
|
||||||
}
|
|
||||||
if (StringUtils.isEmpty(trim(excel.getJobStartMonth()))) {
|
|
||||||
throw new RuntimeException("入职年月不能为空");
|
|
||||||
}
|
|
||||||
validateMonth(excel.getJobStartMonth(), "入职年月");
|
|
||||||
if (StringUtils.isNotEmpty(trim(excel.getJobEndMonth()))) {
|
|
||||||
validateMonth(excel.getJobEndMonth(), "离职年月");
|
|
||||||
}
|
|
||||||
if (recruitment == null) {
|
|
||||||
throw new RuntimeException("招聘记录编号不存在,请先维护招聘主信息");
|
|
||||||
}
|
|
||||||
if (!"SOCIAL".equals(recruitment.getRecruitType())) {
|
|
||||||
throw new RuntimeException("该招聘记录不是社招,不允许导入历史工作经历");
|
|
||||||
}
|
|
||||||
if (!sameText(excel.getCandName(), recruitment.getCandName())) {
|
|
||||||
throw new RuntimeException("招聘记录编号与候选人姓名不匹配");
|
|
||||||
}
|
|
||||||
if (!sameText(excel.getRecruitName(), recruitment.getRecruitName())) {
|
|
||||||
throw new RuntimeException("招聘记录编号与招聘项目名称不匹配");
|
|
||||||
}
|
|
||||||
if (!sameText(excel.getPosName(), recruitment.getPosName())) {
|
|
||||||
throw new RuntimeException("招聘记录编号与职位名称不匹配");
|
|
||||||
}
|
|
||||||
String duplicateKey = trim(excel.getRecruitId()) + "#" + excel.getSortOrder();
|
|
||||||
if (!processedRecruitSortKeys.add(duplicateKey)) {
|
|
||||||
throw new RuntimeException("同一招聘记录编号下排序号重复");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateMonth(String value, String fieldName) {
|
|
||||||
String month = trim(value);
|
|
||||||
if (!month.matches("^((19|20)\\d{2})-(0[1-9]|1[0-2])$")) {
|
|
||||||
throw new RuntimeException(fieldName + "格式不正确,应为YYYY-MM");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean sameText(String first, String second) {
|
|
||||||
return Objects.equals(trim(first), trim(second));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String trim(String value) {
|
|
||||||
return value == null ? null : value.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
private RecruitmentImportFailureVO buildWorkFailure(CcdiStaffRecruitmentWorkExcel excel, String errorMessage) {
|
|
||||||
RecruitmentImportFailureVO failure = new RecruitmentImportFailureVO();
|
|
||||||
BeanUtils.copyProperties(excel, failure);
|
|
||||||
failure.setErrorMessage(errorMessage);
|
|
||||||
return failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void appendSkippedFailures(List<CcdiStaffRecruitmentWork> validRecords,
|
|
||||||
Set<String> failedRecruitIds,
|
|
||||||
List<RecruitmentImportFailureVO> failures) {
|
|
||||||
Set<String> appendedRecruitIds = new HashSet<>();
|
|
||||||
for (CcdiStaffRecruitmentWork work : validRecords) {
|
|
||||||
if (failedRecruitIds.contains(work.getRecruitId()) && appendedRecruitIds.add(work.getRecruitId())) {
|
|
||||||
RecruitmentImportFailureVO failure = new RecruitmentImportFailureVO();
|
|
||||||
failure.setRecruitId(work.getRecruitId());
|
|
||||||
failure.setCompanyName(work.getCompanyName());
|
|
||||||
failure.setPositionName(work.getPositionName());
|
|
||||||
failure.setErrorMessage("同一招聘记录编号存在失败行,已跳过该编号下全部工作经历,避免覆盖旧数据");
|
|
||||||
failures.add(failure);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,18 +1,13 @@
|
|||||||
package com.ruoyi.info.collection.service.impl;
|
package com.ruoyi.info.collection.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.ruoyi.info.collection.domain.CcdiStaffRecruitment;
|
import com.ruoyi.info.collection.domain.CcdiStaffRecruitment;
|
||||||
import com.ruoyi.info.collection.domain.CcdiStaffRecruitmentWork;
|
|
||||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentAddDTO;
|
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentAddDTO;
|
||||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentEditDTO;
|
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentEditDTO;
|
||||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentQueryDTO;
|
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentQueryDTO;
|
||||||
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentExcel;
|
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentExcel;
|
||||||
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentWorkExcel;
|
|
||||||
import com.ruoyi.info.collection.domain.vo.CcdiStaffRecruitmentVO;
|
import com.ruoyi.info.collection.domain.vo.CcdiStaffRecruitmentVO;
|
||||||
import com.ruoyi.info.collection.domain.vo.CcdiStaffRecruitmentWorkVO;
|
|
||||||
import com.ruoyi.info.collection.enums.AdmitStatus;
|
import com.ruoyi.info.collection.enums.AdmitStatus;
|
||||||
import com.ruoyi.info.collection.mapper.CcdiStaffRecruitmentWorkMapper;
|
|
||||||
import com.ruoyi.info.collection.mapper.CcdiStaffRecruitmentMapper;
|
import com.ruoyi.info.collection.mapper.CcdiStaffRecruitmentMapper;
|
||||||
import com.ruoyi.info.collection.service.ICcdiStaffRecruitmentImportService;
|
import com.ruoyi.info.collection.service.ICcdiStaffRecruitmentImportService;
|
||||||
import com.ruoyi.info.collection.service.ICcdiStaffRecruitmentService;
|
import com.ruoyi.info.collection.service.ICcdiStaffRecruitmentService;
|
||||||
@@ -24,7 +19,6 @@ import org.springframework.data.redis.core.RedisTemplate;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -43,9 +37,6 @@ public class CcdiStaffRecruitmentServiceImpl implements ICcdiStaffRecruitmentSer
|
|||||||
@Resource
|
@Resource
|
||||||
private CcdiStaffRecruitmentMapper recruitmentMapper;
|
private CcdiStaffRecruitmentMapper recruitmentMapper;
|
||||||
|
|
||||||
@Resource
|
|
||||||
private CcdiStaffRecruitmentWorkMapper recruitmentWorkMapper;
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ICcdiStaffRecruitmentImportService recruitmentImportService;
|
private ICcdiStaffRecruitmentImportService recruitmentImportService;
|
||||||
|
|
||||||
@@ -105,7 +96,7 @@ public class CcdiStaffRecruitmentServiceImpl implements ICcdiStaffRecruitmentSer
|
|||||||
/**
|
/**
|
||||||
* 查询招聘信息详情
|
* 查询招聘信息详情
|
||||||
*
|
*
|
||||||
* @param recruitId 招聘记录编号
|
* @param recruitId 招聘项目编号
|
||||||
* @return 招聘信息VO
|
* @return 招聘信息VO
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -113,7 +104,6 @@ public class CcdiStaffRecruitmentServiceImpl implements ICcdiStaffRecruitmentSer
|
|||||||
CcdiStaffRecruitmentVO vo = recruitmentMapper.selectRecruitmentById(recruitId);
|
CcdiStaffRecruitmentVO vo = recruitmentMapper.selectRecruitmentById(recruitId);
|
||||||
if (vo != null) {
|
if (vo != null) {
|
||||||
vo.setAdmitStatusDesc(AdmitStatus.getDescByCode(vo.getAdmitStatus()));
|
vo.setAdmitStatusDesc(AdmitStatus.getDescByCode(vo.getAdmitStatus()));
|
||||||
vo.setWorkExperienceList(selectWorkExperienceList(recruitId));
|
|
||||||
}
|
}
|
||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
@@ -127,9 +117,9 @@ public class CcdiStaffRecruitmentServiceImpl implements ICcdiStaffRecruitmentSer
|
|||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public int insertRecruitment(CcdiStaffRecruitmentAddDTO addDTO) {
|
public int insertRecruitment(CcdiStaffRecruitmentAddDTO addDTO) {
|
||||||
// 检查招聘记录编号唯一性
|
// 检查招聘项目编号唯一性
|
||||||
if (recruitmentMapper.selectById(addDTO.getRecruitId()) != null) {
|
if (recruitmentMapper.selectById(addDTO.getRecruitId()) != null) {
|
||||||
throw new RuntimeException("该招聘记录编号已存在");
|
throw new RuntimeException("该招聘项目编号已存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
CcdiStaffRecruitment recruitment = new CcdiStaffRecruitment();
|
CcdiStaffRecruitment recruitment = new CcdiStaffRecruitment();
|
||||||
@@ -158,15 +148,12 @@ public class CcdiStaffRecruitmentServiceImpl implements ICcdiStaffRecruitmentSer
|
|||||||
/**
|
/**
|
||||||
* 批量删除招聘信息
|
* 批量删除招聘信息
|
||||||
*
|
*
|
||||||
* @param recruitIds 需要删除的招聘记录编号
|
* @param recruitIds 需要删除的招聘项目编号
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public int deleteRecruitmentByIds(String[] recruitIds) {
|
public int deleteRecruitmentByIds(String[] recruitIds) {
|
||||||
LambdaQueryWrapper<CcdiStaffRecruitmentWork> workWrapper = new LambdaQueryWrapper<>();
|
|
||||||
workWrapper.in(CcdiStaffRecruitmentWork::getRecruitId, List.of(recruitIds));
|
|
||||||
recruitmentWorkMapper.delete(workWrapper);
|
|
||||||
return recruitmentMapper.deleteBatchIds(List.of(recruitIds));
|
return recruitmentMapper.deleteBatchIds(List.of(recruitIds));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,56 +197,4 @@ public class CcdiStaffRecruitmentServiceImpl implements ICcdiStaffRecruitmentSer
|
|||||||
|
|
||||||
return taskId;
|
return taskId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 导入招聘记录历史工作经历数据(异步)
|
|
||||||
*
|
|
||||||
* @param excelList Excel实体列表
|
|
||||||
* @return 任务ID
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public String importRecruitmentWork(List<CcdiStaffRecruitmentWorkExcel> excelList) {
|
|
||||||
if (StringUtils.isNull(excelList) || excelList.isEmpty()) {
|
|
||||||
throw new RuntimeException("至少需要一条数据");
|
|
||||||
}
|
|
||||||
|
|
||||||
String taskId = UUID.randomUUID().toString();
|
|
||||||
long startTime = System.currentTimeMillis();
|
|
||||||
String userName = SecurityUtils.getUsername();
|
|
||||||
|
|
||||||
String statusKey = "import:recruitment:" + taskId;
|
|
||||||
Map<String, Object> statusData = new HashMap<>();
|
|
||||||
statusData.put("taskId", taskId);
|
|
||||||
statusData.put("status", "PROCESSING");
|
|
||||||
statusData.put("totalCount", excelList.size());
|
|
||||||
statusData.put("successCount", 0);
|
|
||||||
statusData.put("failureCount", 0);
|
|
||||||
statusData.put("progress", 0);
|
|
||||||
statusData.put("startTime", startTime);
|
|
||||||
statusData.put("message", "正在处理历史工作经历...");
|
|
||||||
|
|
||||||
redisTemplate.opsForHash().putAll(statusKey, statusData);
|
|
||||||
redisTemplate.expire(statusKey, 7, TimeUnit.DAYS);
|
|
||||||
|
|
||||||
recruitmentImportService.importRecruitmentWorkAsync(excelList, taskId, userName);
|
|
||||||
|
|
||||||
return taskId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<CcdiStaffRecruitmentWorkVO> selectWorkExperienceList(String recruitId) {
|
|
||||||
LambdaQueryWrapper<CcdiStaffRecruitmentWork> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.eq(CcdiStaffRecruitmentWork::getRecruitId, recruitId)
|
|
||||||
.orderByAsc(CcdiStaffRecruitmentWork::getSortOrder)
|
|
||||||
.orderByDesc(CcdiStaffRecruitmentWork::getId);
|
|
||||||
List<CcdiStaffRecruitmentWork> workList = recruitmentWorkMapper.selectList(wrapper);
|
|
||||||
if (workList == null || workList.isEmpty()) {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
return workList.stream().map(work -> {
|
|
||||||
CcdiStaffRecruitmentWorkVO vo = new CcdiStaffRecruitmentWorkVO();
|
|
||||||
BeanUtils.copyProperties(work, vo);
|
|
||||||
return vo;
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,15 +67,15 @@
|
|||||||
ai.status AS status,
|
ai.status AS status,
|
||||||
ai.effective_date AS effectiveDate,
|
ai.effective_date AS effectiveDate,
|
||||||
ai.invalid_date AS invalidDate,
|
ai.invalid_date AS invalidDate,
|
||||||
ar.is_self_account AS isActualControl,
|
ai.is_self_account AS isActualControl,
|
||||||
ar.monthly_avg_trans_count AS avgMonthTxnCount,
|
ai.monthly_avg_trans_count AS avgMonthTxnCount,
|
||||||
ar.monthly_avg_trans_amount AS avgMonthTxnAmount,
|
ai.monthly_avg_trans_amount AS avgMonthTxnAmount,
|
||||||
ar.trans_freq_type AS txnFrequencyLevel,
|
ai.trans_freq_type AS txnFrequencyLevel,
|
||||||
ar.dr_max_single_amount AS debitSingleMaxAmount,
|
ai.dr_max_single_amount AS debitSingleMaxAmount,
|
||||||
ar.cr_max_single_amount AS creditSingleMaxAmount,
|
ai.cr_max_single_amount AS creditSingleMaxAmount,
|
||||||
ar.dr_max_daily_amount AS debitDailyMaxAmount,
|
ai.dr_max_daily_amount AS debitDailyMaxAmount,
|
||||||
ar.cr_max_daily_amount AS creditDailyMaxAmount,
|
ai.cr_max_daily_amount AS creditDailyMaxAmount,
|
||||||
ar.trans_risk_level AS txnRiskLevel,
|
ai.trans_risk_level AS txnRiskLevel,
|
||||||
ai.create_by AS createBy,
|
ai.create_by AS createBy,
|
||||||
ai.create_time AS createTime,
|
ai.create_time AS createTime,
|
||||||
ai.update_by AS updateBy,
|
ai.update_by AS updateBy,
|
||||||
@@ -107,10 +107,10 @@
|
|||||||
AND ai.account_type = #{query.accountType}
|
AND ai.account_type = #{query.accountType}
|
||||||
</if>
|
</if>
|
||||||
<if test="query.isActualControl != null">
|
<if test="query.isActualControl != null">
|
||||||
AND ar.is_self_account = #{query.isActualControl}
|
AND ai.is_self_account = #{query.isActualControl}
|
||||||
</if>
|
</if>
|
||||||
<if test="query.riskLevel != null and query.riskLevel != ''">
|
<if test="query.riskLevel != null and query.riskLevel != ''">
|
||||||
AND ar.trans_risk_level = #{query.riskLevel}
|
AND ai.trans_risk_level = #{query.riskLevel}
|
||||||
</if>
|
</if>
|
||||||
<if test="query.status != null">
|
<if test="query.status != null">
|
||||||
AND ai.status = #{query.status}
|
AND ai.status = #{query.status}
|
||||||
@@ -121,7 +121,6 @@
|
|||||||
SELECT
|
SELECT
|
||||||
<include refid="AccountInfoSelectColumns"/>
|
<include refid="AccountInfoSelectColumns"/>
|
||||||
FROM ccdi_account_info ai
|
FROM ccdi_account_info ai
|
||||||
LEFT JOIN ccdi_account_result ar ON ai.account_no = ar.account_no
|
|
||||||
LEFT JOIN ccdi_base_staff bs ON ai.owner_type = 'EMPLOYEE' AND ai.owner_id = bs.id_card
|
LEFT JOIN ccdi_base_staff bs ON ai.owner_type = 'EMPLOYEE' AND ai.owner_id = bs.id_card
|
||||||
LEFT JOIN ccdi_staff_fmy_relation fr ON ai.owner_type = 'RELATION' AND ai.owner_id = fr.relation_cert_no
|
LEFT JOIN ccdi_staff_fmy_relation fr ON ai.owner_type = 'RELATION' AND ai.owner_id = fr.relation_cert_no
|
||||||
LEFT JOIN ccdi_base_staff bsRel ON fr.person_id = bsRel.id_card
|
LEFT JOIN ccdi_base_staff bsRel ON fr.person_id = bsRel.id_card
|
||||||
@@ -133,7 +132,6 @@
|
|||||||
SELECT
|
SELECT
|
||||||
<include refid="AccountInfoSelectColumns"/>
|
<include refid="AccountInfoSelectColumns"/>
|
||||||
FROM ccdi_account_info ai
|
FROM ccdi_account_info ai
|
||||||
LEFT JOIN ccdi_account_result ar ON ai.account_no = ar.account_no
|
|
||||||
LEFT JOIN ccdi_base_staff bs ON ai.owner_type = 'EMPLOYEE' AND ai.owner_id = bs.id_card
|
LEFT JOIN ccdi_base_staff bs ON ai.owner_type = 'EMPLOYEE' AND ai.owner_id = bs.id_card
|
||||||
LEFT JOIN ccdi_staff_fmy_relation fr ON ai.owner_type = 'RELATION' AND ai.owner_id = fr.relation_cert_no
|
LEFT JOIN ccdi_staff_fmy_relation fr ON ai.owner_type = 'RELATION' AND ai.owner_id = fr.relation_cert_no
|
||||||
LEFT JOIN ccdi_base_staff bsRel ON fr.person_id = bsRel.id_card
|
LEFT JOIN ccdi_base_staff bsRel ON fr.person_id = bsRel.id_card
|
||||||
@@ -145,7 +143,6 @@
|
|||||||
SELECT
|
SELECT
|
||||||
<include refid="AccountInfoSelectColumns"/>
|
<include refid="AccountInfoSelectColumns"/>
|
||||||
FROM ccdi_account_info ai
|
FROM ccdi_account_info ai
|
||||||
LEFT JOIN ccdi_account_result ar ON ai.account_no = ar.account_no
|
|
||||||
LEFT JOIN ccdi_base_staff bs ON ai.owner_type = 'EMPLOYEE' AND ai.owner_id = bs.id_card
|
LEFT JOIN ccdi_base_staff bs ON ai.owner_type = 'EMPLOYEE' AND ai.owner_id = bs.id_card
|
||||||
LEFT JOIN ccdi_staff_fmy_relation fr ON ai.owner_type = 'RELATION' AND ai.owner_id = fr.relation_cert_no
|
LEFT JOIN ccdi_staff_fmy_relation fr ON ai.owner_type = 'RELATION' AND ai.owner_id = fr.relation_cert_no
|
||||||
LEFT JOIN ccdi_base_staff bsRel ON fr.person_id = bsRel.id_card
|
LEFT JOIN ccdi_base_staff bsRel ON fr.person_id = bsRel.id_card
|
||||||
|
|||||||
@@ -14,13 +14,14 @@
|
|||||||
<result property="phone" column="phone"/>
|
<result property="phone" column="phone"/>
|
||||||
<result property="annualIncome" column="annual_income"/>
|
<result property="annualIncome" column="annual_income"/>
|
||||||
<result property="hireDate" column="hire_date"/>
|
<result property="hireDate" column="hire_date"/>
|
||||||
|
<result property="partyMember" column="is_party_member"/>
|
||||||
<result property="status" column="status"/>
|
<result property="status" column="status"/>
|
||||||
<result property="createTime" column="create_time"/>
|
<result property="createTime" column="create_time"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<select id="selectBaseStaffPageWithDept" resultMap="CcdiBaseStaffVOResult">
|
<select id="selectBaseStaffPageWithDept" resultMap="CcdiBaseStaffVOResult">
|
||||||
SELECT
|
SELECT
|
||||||
e.staff_id, e.name, e.dept_id, e.id_card, e.phone, e.annual_income, e.hire_date, e.status, e.create_time,
|
e.staff_id, e.name, e.dept_id, e.id_card, e.phone, e.annual_income, e.hire_date, e.is_party_member, e.status, e.create_time,
|
||||||
d.dept_name
|
d.dept_name
|
||||||
FROM ccdi_base_staff e
|
FROM ccdi_base_staff e
|
||||||
LEFT JOIN sys_dept d ON e.dept_id = d.dept_id
|
LEFT JOIN sys_dept d ON e.dept_id = d.dept_id
|
||||||
@@ -47,12 +48,12 @@
|
|||||||
<!-- 批量插入或更新员工信息(只更新非null字段) -->
|
<!-- 批量插入或更新员工信息(只更新非null字段) -->
|
||||||
<insert id="insertOrUpdateBatch" parameterType="java.util.List">
|
<insert id="insertOrUpdateBatch" parameterType="java.util.List">
|
||||||
INSERT INTO ccdi_base_staff
|
INSERT INTO ccdi_base_staff
|
||||||
(staff_id, name, dept_id, id_card, phone, annual_income, hire_date, status,
|
(staff_id, name, dept_id, id_card, phone, annual_income, hire_date, is_party_member, status,
|
||||||
create_time, create_by, update_by, update_time)
|
create_time, create_by, update_by, update_time)
|
||||||
VALUES
|
VALUES
|
||||||
<foreach collection="list" item="item" separator=",">
|
<foreach collection="list" item="item" separator=",">
|
||||||
(#{item.staffId}, #{item.name}, #{item.deptId}, #{item.idCard},
|
(#{item.staffId}, #{item.name}, #{item.deptId}, #{item.idCard},
|
||||||
#{item.phone}, #{item.annualIncome}, #{item.hireDate}, #{item.status}, NOW(),
|
#{item.phone}, #{item.annualIncome}, #{item.hireDate}, #{item.partyMember}, #{item.status}, NOW(),
|
||||||
#{item.createBy}, #{item.updateBy}, NOW())
|
#{item.createBy}, #{item.updateBy}, NOW())
|
||||||
</foreach>
|
</foreach>
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
@@ -61,6 +62,7 @@
|
|||||||
phone = COALESCE(VALUES(phone), phone),
|
phone = COALESCE(VALUES(phone), phone),
|
||||||
annual_income = COALESCE(VALUES(annual_income), annual_income),
|
annual_income = COALESCE(VALUES(annual_income), annual_income),
|
||||||
hire_date = COALESCE(VALUES(hire_date), hire_date),
|
hire_date = COALESCE(VALUES(hire_date), hire_date),
|
||||||
|
is_party_member = COALESCE(VALUES(is_party_member), is_party_member),
|
||||||
status = COALESCE(VALUES(status), status),
|
status = COALESCE(VALUES(status), status),
|
||||||
update_by = COALESCE(VALUES(update_by), update_by),
|
update_by = COALESCE(VALUES(update_by), update_by),
|
||||||
update_time = NOW()
|
update_time = NOW()
|
||||||
@@ -69,12 +71,12 @@
|
|||||||
<!-- 批量插入员工信息 -->
|
<!-- 批量插入员工信息 -->
|
||||||
<insert id="insertBatch" parameterType="java.util.List">
|
<insert id="insertBatch" parameterType="java.util.List">
|
||||||
INSERT INTO ccdi_base_staff
|
INSERT INTO ccdi_base_staff
|
||||||
(staff_id, name, dept_id, id_card, phone, annual_income, hire_date, status,
|
(staff_id, name, dept_id, id_card, phone, annual_income, hire_date, is_party_member, status,
|
||||||
create_time, create_by, update_by, update_time)
|
create_time, create_by, update_by, update_time)
|
||||||
VALUES
|
VALUES
|
||||||
<foreach collection="list" item="item" separator=",">
|
<foreach collection="list" item="item" separator=",">
|
||||||
(#{item.staffId}, #{item.name}, #{item.deptId}, #{item.idCard},
|
(#{item.staffId}, #{item.name}, #{item.deptId}, #{item.idCard},
|
||||||
#{item.phone}, #{item.annualIncome}, #{item.hireDate}, #{item.status}, NOW(),
|
#{item.phone}, #{item.annualIncome}, #{item.hireDate}, #{item.partyMember}, #{item.status}, NOW(),
|
||||||
#{item.createBy}, #{item.updateBy}, NOW())
|
#{item.createBy}, #{item.updateBy}, NOW())
|
||||||
</foreach>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
|
|||||||
@@ -4,6 +4,83 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="com.ruoyi.info.collection.mapper.CcdiEnterpriseBaseInfoMapper">
|
<mapper namespace="com.ruoyi.info.collection.mapper.CcdiEnterpriseBaseInfoMapper">
|
||||||
|
|
||||||
|
<resultMap id="CcdiEnterpriseBaseInfoVoResultMap" type="com.ruoyi.info.collection.domain.vo.CcdiEnterpriseBaseInfoVO">
|
||||||
|
<id property="socialCreditCode" column="social_credit_code"/>
|
||||||
|
<result property="enterpriseName" column="enterprise_name"/>
|
||||||
|
<result property="enterpriseType" column="enterprise_type"/>
|
||||||
|
<result property="enterpriseNature" column="enterprise_nature"/>
|
||||||
|
<result property="industryClass" column="industry_class"/>
|
||||||
|
<result property="industryName" column="industry_name"/>
|
||||||
|
<result property="establishDate" column="establish_date"/>
|
||||||
|
<result property="registerAddress" column="register_address"/>
|
||||||
|
<result property="legalRepresentative" column="legal_representative"/>
|
||||||
|
<result property="legalCertType" column="legal_cert_type"/>
|
||||||
|
<result property="legalCertNo" column="legal_cert_no"/>
|
||||||
|
<result property="shareholder1" column="shareholder1"/>
|
||||||
|
<result property="shareholder2" column="shareholder2"/>
|
||||||
|
<result property="shareholder3" column="shareholder3"/>
|
||||||
|
<result property="shareholder4" column="shareholder4"/>
|
||||||
|
<result property="shareholder5" column="shareholder5"/>
|
||||||
|
<result property="status" column="status"/>
|
||||||
|
<result property="riskLevel" column="risk_level"/>
|
||||||
|
<result property="entSource" column="ent_source"/>
|
||||||
|
<result property="dataSource" column="data_source"/>
|
||||||
|
<result property="createTime" column="create_time"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<select id="selectEnterpriseBaseInfoPage" resultMap="CcdiEnterpriseBaseInfoVoResultMap">
|
||||||
|
SELECT
|
||||||
|
social_credit_code,
|
||||||
|
enterprise_name,
|
||||||
|
enterprise_type,
|
||||||
|
enterprise_nature,
|
||||||
|
industry_class,
|
||||||
|
industry_name,
|
||||||
|
establish_date,
|
||||||
|
register_address,
|
||||||
|
legal_representative,
|
||||||
|
legal_cert_type,
|
||||||
|
legal_cert_no,
|
||||||
|
shareholder1,
|
||||||
|
shareholder2,
|
||||||
|
shareholder3,
|
||||||
|
shareholder4,
|
||||||
|
shareholder5,
|
||||||
|
status,
|
||||||
|
risk_level,
|
||||||
|
ent_source,
|
||||||
|
data_source,
|
||||||
|
create_time
|
||||||
|
FROM ccdi_enterprise_base_info
|
||||||
|
<where>
|
||||||
|
<if test="queryDTO != null and queryDTO.enterpriseName != null and queryDTO.enterpriseName != ''">
|
||||||
|
AND enterprise_name LIKE CONCAT('%', #{queryDTO.enterpriseName}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.socialCreditCode != null and queryDTO.socialCreditCode != ''">
|
||||||
|
AND social_credit_code = #{queryDTO.socialCreditCode}
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.enterpriseType != null and queryDTO.enterpriseType != ''">
|
||||||
|
AND enterprise_type = #{queryDTO.enterpriseType}
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.enterpriseNature != null and queryDTO.enterpriseNature != ''">
|
||||||
|
AND enterprise_nature = #{queryDTO.enterpriseNature}
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.industryClass != null and queryDTO.industryClass != ''">
|
||||||
|
AND industry_class LIKE CONCAT('%', #{queryDTO.industryClass}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.status != null and queryDTO.status != ''">
|
||||||
|
AND status = #{queryDTO.status}
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.riskLevel != null and queryDTO.riskLevel != ''">
|
||||||
|
AND risk_level = #{queryDTO.riskLevel}
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.entSource != null and queryDTO.entSource != ''">
|
||||||
|
AND ent_source = #{queryDTO.entSource}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
<!-- 批量插入实体中介 -->
|
<!-- 批量插入实体中介 -->
|
||||||
<insert id="insertBatch" parameterType="java.util.List">
|
<insert id="insertBatch" parameterType="java.util.List">
|
||||||
INSERT INTO ccdi_enterprise_base_info (
|
INSERT INTO ccdi_enterprise_base_info (
|
||||||
@@ -21,7 +98,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
#{item.legalRepresentative}, #{item.legalCertType}, #{item.legalCertNo},
|
#{item.legalRepresentative}, #{item.legalCertType}, #{item.legalCertNo},
|
||||||
#{item.shareholder1}, #{item.shareholder2}, #{item.shareholder3}, #{item.shareholder4}, #{item.shareholder5},
|
#{item.shareholder1}, #{item.shareholder2}, #{item.shareholder3}, #{item.shareholder4}, #{item.shareholder5},
|
||||||
#{item.status}, #{item.riskLevel}, #{item.entSource}, #{item.dataSource},
|
#{item.status}, #{item.riskLevel}, #{item.entSource}, #{item.dataSource},
|
||||||
#{item.createdBy}, #{item.updatedBy}, #{item.createTime}, #{item.updateTime}
|
#{item.createdBy}, #{item.updatedBy}, NOW(), NOW()
|
||||||
)
|
)
|
||||||
</foreach>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
@@ -43,7 +120,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
#{item.legalRepresentative}, #{item.legalCertType}, #{item.legalCertNo},
|
#{item.legalRepresentative}, #{item.legalCertType}, #{item.legalCertNo},
|
||||||
#{item.shareholder1}, #{item.shareholder2}, #{item.shareholder3}, #{item.shareholder4}, #{item.shareholder5},
|
#{item.shareholder1}, #{item.shareholder2}, #{item.shareholder3}, #{item.shareholder4}, #{item.shareholder5},
|
||||||
#{item.status}, #{item.riskLevel}, #{item.entSource}, #{item.dataSource},
|
#{item.status}, #{item.riskLevel}, #{item.entSource}, #{item.dataSource},
|
||||||
#{item.createdBy}, #{item.updatedBy}, #{item.createTime}, #{item.updateTime}
|
#{item.createdBy}, #{item.updatedBy}, NOW(), NOW()
|
||||||
)
|
)
|
||||||
</foreach>
|
</foreach>
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
@@ -67,7 +144,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
ent_source = VALUES(ent_source),
|
ent_source = VALUES(ent_source),
|
||||||
data_source = VALUES(data_source),
|
data_source = VALUES(data_source),
|
||||||
updated_by = VALUES(updated_by),
|
updated_by = VALUES(updated_by),
|
||||||
update_time = VALUES(update_time)
|
update_time = NOW()
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
<!-- 批量更新实体中介 -->
|
<!-- 批量更新实体中介 -->
|
||||||
@@ -95,7 +172,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="item.entSource != null">ent_source = #{item.entSource},</if>
|
<if test="item.entSource != null">ent_source = #{item.entSource},</if>
|
||||||
<if test="item.dataSource != null">data_source = #{item.dataSource},</if>
|
<if test="item.dataSource != null">data_source = #{item.dataSource},</if>
|
||||||
<if test="item.updatedBy != null">updated_by = #{item.updatedBy},</if>
|
<if test="item.updatedBy != null">updated_by = #{item.updatedBy},</if>
|
||||||
update_time = #{item.updateTime}
|
update_time = NOW()
|
||||||
</set>
|
</set>
|
||||||
WHERE social_credit_code = #{item.socialCreditCode}
|
WHERE social_credit_code = #{item.socialCreditCode}
|
||||||
</foreach>
|
</foreach>
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ruoyi.info.collection.mapper.CcdiIntermediaryEnterpriseRelationMapper">
|
||||||
|
|
||||||
|
<resultMap id="CcdiIntermediaryEnterpriseRelationVOResult"
|
||||||
|
type="com.ruoyi.info.collection.domain.vo.CcdiIntermediaryEnterpriseRelationVO">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="intermediaryBizId" column="intermediary_biz_id"/>
|
||||||
|
<result property="intermediaryName" column="intermediary_name"/>
|
||||||
|
<result property="intermediaryPersonId" column="intermediary_person_id"/>
|
||||||
|
<result property="socialCreditCode" column="social_credit_code"/>
|
||||||
|
<result property="enterpriseName" column="enterprise_name"/>
|
||||||
|
<result property="relationPersonPost" column="relation_person_post"/>
|
||||||
|
<result property="remark" column="remark"/>
|
||||||
|
<result property="createTime" column="create_time"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<select id="selectByIntermediaryBizId" resultMap="CcdiIntermediaryEnterpriseRelationVOResult">
|
||||||
|
SELECT
|
||||||
|
rel.id,
|
||||||
|
rel.intermediary_biz_id,
|
||||||
|
parent.name AS intermediary_name,
|
||||||
|
parent.person_id AS intermediary_person_id,
|
||||||
|
rel.social_credit_code,
|
||||||
|
ent.enterprise_name,
|
||||||
|
rel.relation_person_post,
|
||||||
|
rel.remark,
|
||||||
|
rel.create_time
|
||||||
|
FROM ccdi_intermediary_enterprise_relation rel
|
||||||
|
INNER JOIN ccdi_biz_intermediary parent
|
||||||
|
ON rel.intermediary_biz_id = parent.biz_id
|
||||||
|
LEFT JOIN ccdi_enterprise_base_info ent
|
||||||
|
ON rel.social_credit_code = ent.social_credit_code
|
||||||
|
WHERE rel.intermediary_biz_id = #{bizId}
|
||||||
|
ORDER BY rel.create_time DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectDetailById" resultMap="CcdiIntermediaryEnterpriseRelationVOResult">
|
||||||
|
SELECT
|
||||||
|
rel.id,
|
||||||
|
rel.intermediary_biz_id,
|
||||||
|
parent.name AS intermediary_name,
|
||||||
|
parent.person_id AS intermediary_person_id,
|
||||||
|
rel.social_credit_code,
|
||||||
|
ent.enterprise_name,
|
||||||
|
rel.relation_person_post,
|
||||||
|
rel.remark,
|
||||||
|
rel.create_time
|
||||||
|
FROM ccdi_intermediary_enterprise_relation rel
|
||||||
|
INNER JOIN ccdi_biz_intermediary parent
|
||||||
|
ON rel.intermediary_biz_id = parent.biz_id
|
||||||
|
LEFT JOIN ccdi_enterprise_base_info ent
|
||||||
|
ON rel.social_credit_code = ent.social_credit_code
|
||||||
|
WHERE rel.id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="existsByIntermediaryBizIdAndSocialCreditCode" resultType="boolean">
|
||||||
|
SELECT COUNT(1) > 0
|
||||||
|
FROM ccdi_intermediary_enterprise_relation
|
||||||
|
WHERE intermediary_biz_id = #{bizId}
|
||||||
|
AND social_credit_code = #{socialCreditCode}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -12,14 +12,12 @@
|
|||||||
<result property="posCategory" column="pos_category"/>
|
<result property="posCategory" column="pos_category"/>
|
||||||
<result property="posDesc" column="pos_desc"/>
|
<result property="posDesc" column="pos_desc"/>
|
||||||
<result property="candName" column="cand_name"/>
|
<result property="candName" column="cand_name"/>
|
||||||
<result property="recruitType" column="recruit_type"/>
|
|
||||||
<result property="candEdu" column="cand_edu"/>
|
<result property="candEdu" column="cand_edu"/>
|
||||||
<result property="candId" column="cand_id"/>
|
<result property="candId" column="cand_id"/>
|
||||||
<result property="candSchool" column="cand_school"/>
|
<result property="candSchool" column="cand_school"/>
|
||||||
<result property="candMajor" column="cand_major"/>
|
<result property="candMajor" column="cand_major"/>
|
||||||
<result property="candGrad" column="cand_grad"/>
|
<result property="candGrad" column="cand_grad"/>
|
||||||
<result property="admitStatus" column="admit_status"/>
|
<result property="admitStatus" column="admit_status"/>
|
||||||
<result property="workExperienceCount" column="work_experience_count"/>
|
|
||||||
<result property="interviewerName1" column="interviewer_name1"/>
|
<result property="interviewerName1" column="interviewer_name1"/>
|
||||||
<result property="interviewerId1" column="interviewer_id1"/>
|
<result property="interviewerId1" column="interviewer_id1"/>
|
||||||
<result property="interviewerName2" column="interviewer_name2"/>
|
<result property="interviewerName2" column="interviewer_name2"/>
|
||||||
@@ -33,53 +31,44 @@
|
|||||||
<!-- 分页查询招聘信息列表 -->
|
<!-- 分页查询招聘信息列表 -->
|
||||||
<select id="selectRecruitmentPage" resultMap="CcdiStaffRecruitmentVOResult">
|
<select id="selectRecruitmentPage" resultMap="CcdiStaffRecruitmentVOResult">
|
||||||
SELECT
|
SELECT
|
||||||
r.recruit_id, r.recruit_name, r.pos_name, r.pos_category, r.pos_desc,
|
recruit_id, recruit_name, pos_name, pos_category, pos_desc,
|
||||||
r.cand_name, r.recruit_type, r.cand_edu, r.cand_id, r.cand_school, r.cand_major, r.cand_grad,
|
cand_name, cand_edu, cand_id, cand_school, cand_major, cand_grad,
|
||||||
r.admit_status, COALESCE(w.work_experience_count, 0) AS work_experience_count,
|
admit_status, interviewer_name1, interviewer_id1, interviewer_name2, interviewer_id2,
|
||||||
r.interviewer_name1, r.interviewer_id1, r.interviewer_name2, r.interviewer_id2,
|
created_by, create_time, updated_by, update_time
|
||||||
r.created_by, r.create_time, r.updated_by, r.update_time
|
FROM ccdi_staff_recruitment
|
||||||
FROM ccdi_staff_recruitment r
|
|
||||||
LEFT JOIN (
|
|
||||||
SELECT recruit_id, COUNT(1) AS work_experience_count
|
|
||||||
FROM ccdi_staff_recruitment_work
|
|
||||||
GROUP BY recruit_id
|
|
||||||
) w ON w.recruit_id = r.recruit_id
|
|
||||||
<where>
|
<where>
|
||||||
<if test="query.recruitName != null and query.recruitName != ''">
|
<if test="query.recruitName != null and query.recruitName != ''">
|
||||||
AND r.recruit_name LIKE CONCAT('%', #{query.recruitName}, '%')
|
AND recruit_name LIKE CONCAT('%', #{query.recruitName}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="query.posName != null and query.posName != ''">
|
<if test="query.posName != null and query.posName != ''">
|
||||||
AND r.pos_name LIKE CONCAT('%', #{query.posName}, '%')
|
AND pos_name LIKE CONCAT('%', #{query.posName}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="query.candName != null and query.candName != ''">
|
<if test="query.candName != null and query.candName != ''">
|
||||||
AND r.cand_name LIKE CONCAT('%', #{query.candName}, '%')
|
AND cand_name LIKE CONCAT('%', #{query.candName}, '%')
|
||||||
</if>
|
|
||||||
<if test="query.recruitType != null and query.recruitType != ''">
|
|
||||||
AND r.recruit_type = #{query.recruitType}
|
|
||||||
</if>
|
</if>
|
||||||
<if test="query.candId != null and query.candId != ''">
|
<if test="query.candId != null and query.candId != ''">
|
||||||
AND r.cand_id = #{query.candId}
|
AND cand_id = #{query.candId}
|
||||||
</if>
|
</if>
|
||||||
<if test="query.admitStatus != null and query.admitStatus != ''">
|
<if test="query.admitStatus != null and query.admitStatus != ''">
|
||||||
AND r.admit_status = #{query.admitStatus}
|
AND admit_status = #{query.admitStatus}
|
||||||
</if>
|
</if>
|
||||||
<if test="query.interviewerName != null and query.interviewerName != ''">
|
<if test="query.interviewerName != null and query.interviewerName != ''">
|
||||||
AND (r.interviewer_name1 LIKE CONCAT('%', #{query.interviewerName}, '%')
|
AND (interviewer_name1 LIKE CONCAT('%', #{query.interviewerName}, '%')
|
||||||
OR r.interviewer_name2 LIKE CONCAT('%', #{query.interviewerName}, '%'))
|
OR interviewer_name2 LIKE CONCAT('%', #{query.interviewerName}, '%'))
|
||||||
</if>
|
</if>
|
||||||
<if test="query.interviewerId != null and query.interviewerId != ''">
|
<if test="query.interviewerId != null and query.interviewerId != ''">
|
||||||
AND (r.interviewer_id1 = #{query.interviewerId}
|
AND (interviewer_id1 = #{query.interviewerId}
|
||||||
OR r.interviewer_id2 = #{query.interviewerId})
|
OR interviewer_id2 = #{query.interviewerId})
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
ORDER BY r.create_time DESC
|
ORDER BY create_time DESC
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<!-- 查询招聘信息详情 -->
|
<!-- 查询招聘信息详情 -->
|
||||||
<select id="selectRecruitmentById" resultMap="CcdiStaffRecruitmentVOResult">
|
<select id="selectRecruitmentById" resultMap="CcdiStaffRecruitmentVOResult">
|
||||||
SELECT
|
SELECT
|
||||||
recruit_id, recruit_name, pos_name, pos_category, pos_desc,
|
recruit_id, recruit_name, pos_name, pos_category, pos_desc,
|
||||||
cand_name, recruit_type, cand_edu, cand_id, cand_school, cand_major, cand_grad,
|
cand_name, cand_edu, cand_id, cand_school, cand_major, cand_grad,
|
||||||
admit_status, interviewer_name1, interviewer_id1, interviewer_name2, interviewer_id2,
|
admit_status, interviewer_name1, interviewer_id1, interviewer_name2, interviewer_id2,
|
||||||
created_by, create_time, updated_by, update_time
|
created_by, create_time, updated_by, update_time
|
||||||
FROM ccdi_staff_recruitment
|
FROM ccdi_staff_recruitment
|
||||||
@@ -90,13 +79,13 @@
|
|||||||
<insert id="insertBatch">
|
<insert id="insertBatch">
|
||||||
INSERT INTO ccdi_staff_recruitment
|
INSERT INTO ccdi_staff_recruitment
|
||||||
(recruit_id, recruit_name, pos_name, pos_category, pos_desc,
|
(recruit_id, recruit_name, pos_name, pos_category, pos_desc,
|
||||||
cand_name, recruit_type, cand_edu, cand_id, cand_school, cand_major, cand_grad,
|
cand_name, cand_edu, cand_id, cand_school, cand_major, cand_grad,
|
||||||
admit_status, interviewer_name1, interviewer_id1, interviewer_name2, interviewer_id2,
|
admit_status, interviewer_name1, interviewer_id1, interviewer_name2, interviewer_id2,
|
||||||
created_by, create_time, updated_by, update_time)
|
created_by, create_time, updated_by, update_time)
|
||||||
VALUES
|
VALUES
|
||||||
<foreach collection="list" item="item" separator=",">
|
<foreach collection="list" item="item" separator=",">
|
||||||
(#{item.recruitId}, #{item.recruitName}, #{item.posName}, #{item.posCategory}, #{item.posDesc},
|
(#{item.recruitId}, #{item.recruitName}, #{item.posName}, #{item.posCategory}, #{item.posDesc},
|
||||||
#{item.candName}, #{item.recruitType}, #{item.candEdu}, #{item.candId}, #{item.candSchool}, #{item.candMajor}, #{item.candGrad},
|
#{item.candName}, #{item.candEdu}, #{item.candId}, #{item.candSchool}, #{item.candMajor}, #{item.candGrad},
|
||||||
#{item.admitStatus}, #{item.interviewerName1}, #{item.interviewerId1}, #{item.interviewerName2}, #{item.interviewerId2},
|
#{item.admitStatus}, #{item.interviewerName1}, #{item.interviewerId1}, #{item.interviewerName2}, #{item.interviewerId2},
|
||||||
#{item.createdBy}, NOW(), #{item.updatedBy}, NOW())
|
#{item.createdBy}, NOW(), #{item.updatedBy}, NOW())
|
||||||
</foreach>
|
</foreach>
|
||||||
@@ -111,7 +100,6 @@
|
|||||||
pos_category = #{item.posCategory},
|
pos_category = #{item.posCategory},
|
||||||
pos_desc = #{item.posDesc},
|
pos_desc = #{item.posDesc},
|
||||||
cand_name = #{item.candName},
|
cand_name = #{item.candName},
|
||||||
recruit_type = #{item.recruitType},
|
|
||||||
cand_edu = #{item.candEdu},
|
cand_edu = #{item.candEdu},
|
||||||
cand_id = #{item.candId},
|
cand_id = #{item.candId},
|
||||||
cand_school = #{item.candSchool},
|
cand_school = #{item.candSchool},
|
||||||
|
|||||||
@@ -0,0 +1,109 @@
|
|||||||
|
package com.ruoyi.info.collection.mapper;
|
||||||
|
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiAccountInfoQueryDTO;
|
||||||
|
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
|
||||||
|
import org.apache.ibatis.mapping.BoundSql;
|
||||||
|
import org.apache.ibatis.mapping.Environment;
|
||||||
|
import org.apache.ibatis.mapping.MappedStatement;
|
||||||
|
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
|
||||||
|
import org.apache.ibatis.session.Configuration;
|
||||||
|
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
|
||||||
|
import org.apache.ibatis.type.TypeAliasRegistry;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class CcdiAccountInfoMapperTest {
|
||||||
|
|
||||||
|
private static final String RESOURCE = "mapper/info/collection/CcdiAccountInfoMapper.xml";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void selectAccountInfoPage_shouldReadAnalysisColumnsFromAccountInfoTableOnly() throws Exception {
|
||||||
|
MappedStatement mappedStatement = loadMappedStatement(
|
||||||
|
"com.ruoyi.info.collection.mapper.CcdiAccountInfoMapper.selectAccountInfoPage");
|
||||||
|
|
||||||
|
String sql = renderSql(mappedStatement, Map.of("query", new CcdiAccountInfoQueryDTO())).toLowerCase();
|
||||||
|
|
||||||
|
assertTrue(sql.contains("from ccdi_account_info ai"), sql);
|
||||||
|
assertFalse(sql.contains("ccdi_account_result"), sql);
|
||||||
|
assertTrue(sql.contains("ai.is_self_account as isactualcontrol"), sql);
|
||||||
|
assertTrue(sql.contains("ai.monthly_avg_trans_count as avgmonthtxncount"), sql);
|
||||||
|
assertTrue(sql.contains("ai.trans_risk_level as txnrisklevel"), sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MappedStatement loadMappedStatement(String statementId) throws Exception {
|
||||||
|
Configuration configuration = new Configuration();
|
||||||
|
configuration.setEnvironment(new Environment("test", new JdbcTransactionFactory(), new NoOpDataSource()));
|
||||||
|
registerTypeAliases(configuration.getTypeAliasRegistry());
|
||||||
|
configuration.getLanguageRegistry().register(XMLLanguageDriver.class);
|
||||||
|
configuration.addMapper(CcdiAccountInfoMapper.class);
|
||||||
|
|
||||||
|
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(RESOURCE)) {
|
||||||
|
XMLMapperBuilder xmlMapperBuilder =
|
||||||
|
new XMLMapperBuilder(inputStream, configuration, RESOURCE, configuration.getSqlFragments());
|
||||||
|
xmlMapperBuilder.parse();
|
||||||
|
}
|
||||||
|
return configuration.getMappedStatement(statementId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String renderSql(MappedStatement mappedStatement, Map<String, Object> params) {
|
||||||
|
BoundSql boundSql = mappedStatement.getBoundSql(new HashMap<>(params));
|
||||||
|
return boundSql.getSql().replaceAll("\\s+", " ").trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerTypeAliases(TypeAliasRegistry typeAliasRegistry) {
|
||||||
|
typeAliasRegistry.registerAlias("map", Map.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NoOpDataSource implements DataSource {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.sql.Connection getConnection() {
|
||||||
|
throw new UnsupportedOperationException("Not required for SQL rendering tests");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.sql.Connection getConnection(String username, String password) {
|
||||||
|
throw new UnsupportedOperationException("Not required for SQL rendering tests");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.io.PrintWriter getLogWriter() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLogWriter(java.io.PrintWriter out) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLoginTimeout(int seconds) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLoginTimeout() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.util.logging.Logger getParentLogger() {
|
||||||
|
return java.util.logging.Logger.getGlobal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T unwrap(Class<T> iface) {
|
||||||
|
throw new UnsupportedOperationException("Not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWrapperFor(Class<?> iface) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,8 @@ class CcdiBaseStaffMapperTest {
|
|||||||
|
|
||||||
assertTrue(xml.contains("annual_income"), xml);
|
assertTrue(xml.contains("annual_income"), xml);
|
||||||
assertTrue(xml.contains("#{item.annualIncome}"), xml);
|
assertTrue(xml.contains("#{item.annualIncome}"), xml);
|
||||||
|
assertTrue(xml.contains("is_party_member"), xml);
|
||||||
|
assertTrue(xml.contains("#{item.partyMember}"), xml);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
package com.ruoyi.info.collection.service;
|
||||||
|
|
||||||
|
import com.ruoyi.info.collection.domain.CcdiAccountInfo;
|
||||||
|
import com.ruoyi.info.collection.domain.CcdiBaseStaff;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiAccountInfoAddDTO;
|
||||||
|
import com.ruoyi.info.collection.mapper.CcdiAccountInfoMapper;
|
||||||
|
import com.ruoyi.info.collection.mapper.CcdiBaseStaffMapper;
|
||||||
|
import com.ruoyi.info.collection.mapper.CcdiStaffFmyRelationMapper;
|
||||||
|
import com.ruoyi.info.collection.service.impl.CcdiAccountInfoServiceImpl;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.beans.BeanWrapperImpl;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class CcdiAccountInfoServiceImplTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private CcdiAccountInfoServiceImpl service;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiAccountInfoMapper accountInfoMapper;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiBaseStaffMapper baseStaffMapper;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiStaffFmyRelationMapper staffFmyRelationMapper;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void insertExternalAccount_shouldPersistAnalysisFieldsOnAccountInfo() {
|
||||||
|
CcdiAccountInfoAddDTO dto = buildBaseAddDto();
|
||||||
|
dto.setOwnerType("EXTERNAL");
|
||||||
|
dto.setOwnerId("330101199001010011");
|
||||||
|
dto.setBankScope("EXTERNAL");
|
||||||
|
dto.setIsActualControl(0);
|
||||||
|
dto.setAvgMonthTxnCount(6);
|
||||||
|
dto.setAvgMonthTxnAmount(new BigDecimal("1234.56"));
|
||||||
|
dto.setTxnFrequencyLevel("HIGH");
|
||||||
|
dto.setDebitSingleMaxAmount(new BigDecimal("100.00"));
|
||||||
|
dto.setCreditSingleMaxAmount(new BigDecimal("200.00"));
|
||||||
|
dto.setDebitDailyMaxAmount(new BigDecimal("300.00"));
|
||||||
|
dto.setCreditDailyMaxAmount(new BigDecimal("400.00"));
|
||||||
|
dto.setTxnRiskLevel("MEDIUM");
|
||||||
|
|
||||||
|
when(accountInfoMapper.selectCount(any())).thenReturn(0L);
|
||||||
|
when(accountInfoMapper.insert(any(CcdiAccountInfo.class))).thenReturn(1);
|
||||||
|
|
||||||
|
service.insertAccountInfo(dto);
|
||||||
|
|
||||||
|
ArgumentCaptor<CcdiAccountInfo> captor = ArgumentCaptor.forClass(CcdiAccountInfo.class);
|
||||||
|
verify(accountInfoMapper).insert(captor.capture());
|
||||||
|
BeanWrapperImpl wrapper = new BeanWrapperImpl(captor.getValue());
|
||||||
|
assertEquals(0, wrapper.getPropertyValue("isActualControl"));
|
||||||
|
assertEquals(6, wrapper.getPropertyValue("avgMonthTxnCount"));
|
||||||
|
assertEquals(new BigDecimal("1234.56"), wrapper.getPropertyValue("avgMonthTxnAmount"));
|
||||||
|
assertEquals("HIGH", wrapper.getPropertyValue("txnFrequencyLevel"));
|
||||||
|
assertEquals("MEDIUM", wrapper.getPropertyValue("txnRiskLevel"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void insertInternalAccount_shouldClearAnalysisFieldsOnAccountInfo() {
|
||||||
|
CcdiAccountInfoAddDTO dto = buildBaseAddDto();
|
||||||
|
dto.setOwnerType("EMPLOYEE");
|
||||||
|
dto.setOwnerId("330101199001010022");
|
||||||
|
dto.setBankScope("INTERNAL");
|
||||||
|
dto.setIsActualControl(1);
|
||||||
|
dto.setAvgMonthTxnCount(8);
|
||||||
|
dto.setAvgMonthTxnAmount(new BigDecimal("9988.66"));
|
||||||
|
dto.setTxnFrequencyLevel("HIGH");
|
||||||
|
dto.setDebitSingleMaxAmount(new BigDecimal("111.11"));
|
||||||
|
dto.setCreditSingleMaxAmount(new BigDecimal("222.22"));
|
||||||
|
dto.setDebitDailyMaxAmount(new BigDecimal("333.33"));
|
||||||
|
dto.setCreditDailyMaxAmount(new BigDecimal("444.44"));
|
||||||
|
dto.setTxnRiskLevel("HIGH");
|
||||||
|
|
||||||
|
CcdiBaseStaff staff = new CcdiBaseStaff();
|
||||||
|
staff.setIdCard(dto.getOwnerId());
|
||||||
|
|
||||||
|
when(baseStaffMapper.selectOne(any())).thenReturn(staff);
|
||||||
|
when(accountInfoMapper.selectCount(any())).thenReturn(0L);
|
||||||
|
when(accountInfoMapper.insert(any(CcdiAccountInfo.class))).thenReturn(1);
|
||||||
|
|
||||||
|
service.insertAccountInfo(dto);
|
||||||
|
|
||||||
|
ArgumentCaptor<CcdiAccountInfo> captor = ArgumentCaptor.forClass(CcdiAccountInfo.class);
|
||||||
|
verify(accountInfoMapper).insert(captor.capture());
|
||||||
|
BeanWrapperImpl wrapper = new BeanWrapperImpl(captor.getValue());
|
||||||
|
assertNull(wrapper.getPropertyValue("isActualControl"));
|
||||||
|
assertNull(wrapper.getPropertyValue("avgMonthTxnCount"));
|
||||||
|
assertNull(wrapper.getPropertyValue("avgMonthTxnAmount"));
|
||||||
|
assertNull(wrapper.getPropertyValue("txnFrequencyLevel"));
|
||||||
|
assertNull(wrapper.getPropertyValue("debitSingleMaxAmount"));
|
||||||
|
assertNull(wrapper.getPropertyValue("creditSingleMaxAmount"));
|
||||||
|
assertNull(wrapper.getPropertyValue("debitDailyMaxAmount"));
|
||||||
|
assertNull(wrapper.getPropertyValue("creditDailyMaxAmount"));
|
||||||
|
assertNull(wrapper.getPropertyValue("txnRiskLevel"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private CcdiAccountInfoAddDTO buildBaseAddDto() {
|
||||||
|
CcdiAccountInfoAddDTO dto = new CcdiAccountInfoAddDTO();
|
||||||
|
dto.setAccountNo("6222024000000001");
|
||||||
|
dto.setAccountType("BANK");
|
||||||
|
dto.setAccountName("测试账户");
|
||||||
|
dto.setOpenBank("中国银行");
|
||||||
|
dto.setBankCode("BOC");
|
||||||
|
dto.setCurrency("CNY");
|
||||||
|
dto.setStatus(1);
|
||||||
|
dto.setEffectiveDate(new Date());
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,6 +27,28 @@ class CcdiBaseStaffImportServiceImplTest {
|
|||||||
assertDoesNotThrow(() -> service.validateStaffData(buildDto(new BigDecimal("12345.67")), false, Collections.emptySet(), Collections.emptySet()));
|
assertDoesNotThrow(() -> service.validateStaffData(buildDto(new BigDecimal("12345.67")), false, Collections.emptySet(), Collections.emptySet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validateStaffData_shouldAllowPartyMemberValuesZeroAndOne() {
|
||||||
|
CcdiBaseStaffAddDTO nonPartyMember = buildDto(null);
|
||||||
|
nonPartyMember.setPartyMember(0);
|
||||||
|
CcdiBaseStaffAddDTO partyMember = buildDto(null);
|
||||||
|
partyMember.setPartyMember(1);
|
||||||
|
|
||||||
|
assertDoesNotThrow(() -> service.validateStaffData(nonPartyMember, false, Collections.emptySet(), Collections.emptySet()));
|
||||||
|
assertDoesNotThrow(() -> service.validateStaffData(partyMember, false, Collections.emptySet(), Collections.emptySet()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validateStaffData_shouldRejectInvalidPartyMemberValue() {
|
||||||
|
CcdiBaseStaffAddDTO dto = buildDto(null);
|
||||||
|
dto.setPartyMember(2);
|
||||||
|
|
||||||
|
RuntimeException exception = assertThrows(RuntimeException.class,
|
||||||
|
() -> service.validateStaffData(dto, false, Set.of(), Set.of()));
|
||||||
|
|
||||||
|
assertEquals("是否党员只能填写'0'或'1'", exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void validateStaffData_shouldRejectNegativeAnnualIncome() {
|
void validateStaffData_shouldRejectNegativeAnnualIncome() {
|
||||||
RuntimeException exception = assertThrows(RuntimeException.class,
|
RuntimeException exception = assertThrows(RuntimeException.class,
|
||||||
@@ -51,6 +73,7 @@ class CcdiBaseStaffImportServiceImplTest {
|
|||||||
dto.setIdCard("320101199001010014");
|
dto.setIdCard("320101199001010014");
|
||||||
dto.setPhone("13812345678");
|
dto.setPhone("13812345678");
|
||||||
dto.setStatus("0");
|
dto.setStatus("0");
|
||||||
|
dto.setPartyMember(1);
|
||||||
dto.setAnnualIncome(annualIncome);
|
dto.setAnnualIncome(annualIncome);
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ class CcdiBaseStaffServiceImplTest {
|
|||||||
addDTO.setIdCard("320101199001010011");
|
addDTO.setIdCard("320101199001010011");
|
||||||
addDTO.setPhone("13812345678");
|
addDTO.setPhone("13812345678");
|
||||||
addDTO.setStatus("0");
|
addDTO.setStatus("0");
|
||||||
|
addDTO.setPartyMember(1);
|
||||||
addDTO.setAnnualIncome(new BigDecimal("12345.67"));
|
addDTO.setAnnualIncome(new BigDecimal("12345.67"));
|
||||||
addDTO.setAssetInfoList(List.of(
|
addDTO.setAssetInfoList(List.of(
|
||||||
buildAssetDto("房产"),
|
buildAssetDto("房产"),
|
||||||
@@ -70,6 +71,7 @@ class CcdiBaseStaffServiceImplTest {
|
|||||||
assertEquals(1, result);
|
assertEquals(1, result);
|
||||||
ArgumentCaptor<CcdiBaseStaff> staffCaptor = ArgumentCaptor.forClass(CcdiBaseStaff.class);
|
ArgumentCaptor<CcdiBaseStaff> staffCaptor = ArgumentCaptor.forClass(CcdiBaseStaff.class);
|
||||||
verify(baseStaffMapper).insert(staffCaptor.capture());
|
verify(baseStaffMapper).insert(staffCaptor.capture());
|
||||||
|
assertEquals(1, staffCaptor.getValue().getPartyMember());
|
||||||
assertEquals(new BigDecimal("12345.67"), staffCaptor.getValue().getAnnualIncome());
|
assertEquals(new BigDecimal("12345.67"), staffCaptor.getValue().getAnnualIncome());
|
||||||
ArgumentCaptor<List<CcdiAssetInfoDTO>> captor = ArgumentCaptor.forClass(List.class);
|
ArgumentCaptor<List<CcdiAssetInfoDTO>> captor = ArgumentCaptor.forClass(List.class);
|
||||||
verify(assetInfoService).replaceByFamilyId(eq("320101199001010011"), captor.capture());
|
verify(assetInfoService).replaceByFamilyId(eq("320101199001010011"), captor.capture());
|
||||||
@@ -92,6 +94,7 @@ class CcdiBaseStaffServiceImplTest {
|
|||||||
editDTO.setIdCard("320101199001010011");
|
editDTO.setIdCard("320101199001010011");
|
||||||
editDTO.setPhone("13812345678");
|
editDTO.setPhone("13812345678");
|
||||||
editDTO.setStatus("0");
|
editDTO.setStatus("0");
|
||||||
|
editDTO.setPartyMember(0);
|
||||||
editDTO.setAnnualIncome(new BigDecimal("45678.90"));
|
editDTO.setAnnualIncome(new BigDecimal("45678.90"));
|
||||||
editDTO.setAssetInfoList(List.of(buildAssetDto("车辆")));
|
editDTO.setAssetInfoList(List.of(buildAssetDto("车辆")));
|
||||||
|
|
||||||
@@ -104,6 +107,7 @@ class CcdiBaseStaffServiceImplTest {
|
|||||||
assertEquals(1, result);
|
assertEquals(1, result);
|
||||||
ArgumentCaptor<CcdiBaseStaff> staffCaptor = ArgumentCaptor.forClass(CcdiBaseStaff.class);
|
ArgumentCaptor<CcdiBaseStaff> staffCaptor = ArgumentCaptor.forClass(CcdiBaseStaff.class);
|
||||||
verify(baseStaffMapper).updateById(staffCaptor.capture());
|
verify(baseStaffMapper).updateById(staffCaptor.capture());
|
||||||
|
assertEquals(0, staffCaptor.getValue().getPartyMember());
|
||||||
assertEquals(new BigDecimal("45678.90"), staffCaptor.getValue().getAnnualIncome());
|
assertEquals(new BigDecimal("45678.90"), staffCaptor.getValue().getAnnualIncome());
|
||||||
verify(assetInfoService, never()).deleteByFamilyId("320101199001010011");
|
verify(assetInfoService, never()).deleteByFamilyId("320101199001010011");
|
||||||
verify(assetInfoService).replaceByFamilyId("320101199001010011", editDTO.getAssetInfoList());
|
verify(assetInfoService).replaceByFamilyId("320101199001010011", editDTO.getAssetInfoList());
|
||||||
@@ -122,6 +126,7 @@ class CcdiBaseStaffServiceImplTest {
|
|||||||
editDTO.setIdCard("320101199001010011");
|
editDTO.setIdCard("320101199001010011");
|
||||||
editDTO.setPhone("13812345678");
|
editDTO.setPhone("13812345678");
|
||||||
editDTO.setStatus("0");
|
editDTO.setStatus("0");
|
||||||
|
editDTO.setPartyMember(1);
|
||||||
editDTO.setAssetInfoList(List.of(buildAssetDto("车辆")));
|
editDTO.setAssetInfoList(List.of(buildAssetDto("车辆")));
|
||||||
|
|
||||||
when(baseStaffMapper.selectById(1001L)).thenReturn(existing);
|
when(baseStaffMapper.selectById(1001L)).thenReturn(existing);
|
||||||
@@ -135,17 +140,18 @@ class CcdiBaseStaffServiceImplTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void selectBaseStaffById_shouldReturnAssetInfoList() {
|
void selectBaseStaffById_shouldReturnSelfOwnedAssetInfoList() {
|
||||||
CcdiBaseStaff staff = new CcdiBaseStaff();
|
CcdiBaseStaff staff = new CcdiBaseStaff();
|
||||||
staff.setStaffId(1001L);
|
staff.setStaffId(1001L);
|
||||||
staff.setName("张三");
|
staff.setName("张三");
|
||||||
staff.setIdCard("320101199001010011");
|
staff.setIdCard("320101199001010011");
|
||||||
staff.setStatus("0");
|
staff.setStatus("0");
|
||||||
|
staff.setPartyMember(1);
|
||||||
staff.setAnnualIncome(new BigDecimal("88888.88"));
|
staff.setAnnualIncome(new BigDecimal("88888.88"));
|
||||||
|
|
||||||
CcdiAssetInfo assetInfo = new CcdiAssetInfo();
|
CcdiAssetInfo assetInfo = new CcdiAssetInfo();
|
||||||
assetInfo.setFamilyId("320101199001010011");
|
assetInfo.setFamilyId("320101199001010011");
|
||||||
assetInfo.setPersonId("320101199201010022");
|
assetInfo.setPersonId("320101199001010011");
|
||||||
assetInfo.setAssetMainType("车辆");
|
assetInfo.setAssetMainType("车辆");
|
||||||
assetInfo.setAssetSubType("小汽车");
|
assetInfo.setAssetSubType("小汽车");
|
||||||
assetInfo.setAssetName("家庭车辆");
|
assetInfo.setAssetName("家庭车辆");
|
||||||
@@ -153,14 +159,16 @@ class CcdiBaseStaffServiceImplTest {
|
|||||||
assetInfo.setAssetStatus("正常");
|
assetInfo.setAssetStatus("正常");
|
||||||
|
|
||||||
when(baseStaffMapper.selectById(1001L)).thenReturn(staff);
|
when(baseStaffMapper.selectById(1001L)).thenReturn(staff);
|
||||||
when(assetInfoService.selectByFamilyId("320101199001010011")).thenReturn(List.of(assetInfo));
|
when(assetInfoService.selectByFamilyIdAndPersonId("320101199001010011", "320101199001010011"))
|
||||||
|
.thenReturn(List.of(assetInfo));
|
||||||
|
|
||||||
CcdiBaseStaffVO result = service.selectBaseStaffById(1001L);
|
CcdiBaseStaffVO result = service.selectBaseStaffById(1001L);
|
||||||
|
|
||||||
assertNotNull(result.getAssetInfoList());
|
assertNotNull(result.getAssetInfoList());
|
||||||
|
assertEquals(1, result.getPartyMember());
|
||||||
assertEquals(new BigDecimal("88888.88"), result.getAnnualIncome());
|
assertEquals(new BigDecimal("88888.88"), result.getAnnualIncome());
|
||||||
assertEquals(1, result.getAssetInfoList().size());
|
assertEquals(1, result.getAssetInfoList().size());
|
||||||
assertEquals("320101199201010022", result.getAssetInfoList().get(0).getPersonId());
|
assertEquals("320101199001010011", result.getAssetInfoList().get(0).getPersonId());
|
||||||
assertEquals("车辆", result.getAssetInfoList().get(0).getAssetMainType());
|
assertEquals("车辆", result.getAssetInfoList().get(0).getAssetMainType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.ruoyi.info.collection.utils;
|
|||||||
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysDictData;
|
import com.ruoyi.common.core.domain.entity.SysDictData;
|
||||||
import com.ruoyi.common.utils.DictUtils;
|
import com.ruoyi.common.utils.DictUtils;
|
||||||
|
import com.ruoyi.info.collection.domain.excel.CcdiBaseStaffExcel;
|
||||||
import com.ruoyi.info.collection.domain.excel.CcdiAssetInfoExcel;
|
import com.ruoyi.info.collection.domain.excel.CcdiAssetInfoExcel;
|
||||||
import com.ruoyi.info.collection.domain.excel.CcdiStaffFmyRelationExcel;
|
import com.ruoyi.info.collection.domain.excel.CcdiStaffFmyRelationExcel;
|
||||||
import org.apache.poi.ss.usermodel.CellStyle;
|
import org.apache.poi.ss.usermodel.CellStyle;
|
||||||
@@ -72,6 +73,31 @@ class EasyExcelUtilTemplateTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void importTemplateWithDictDropdown_shouldAddPartyMemberDropdownToBaseStaffTemplate() throws Exception {
|
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|
||||||
|
try (MockedStatic<DictUtils> mocked = mockStatic(DictUtils.class)) {
|
||||||
|
mocked.when(() -> DictUtils.getDictCache("ccdi_employee_status"))
|
||||||
|
.thenReturn(List.of(
|
||||||
|
buildDictData("在职", "0"),
|
||||||
|
buildDictData("离职", "1")
|
||||||
|
));
|
||||||
|
mocked.when(() -> DictUtils.getDictCache("ccdi_yes_no_flag"))
|
||||||
|
.thenReturn(List.of(
|
||||||
|
buildDictData("是", "1"),
|
||||||
|
buildDictData("否", "0")
|
||||||
|
));
|
||||||
|
|
||||||
|
EasyExcelUtil.importTemplateWithDictDropdown(response, CcdiBaseStaffExcel.class, "员工信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
try (Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(response.getContentAsByteArray()))) {
|
||||||
|
Sheet sheet = workbook.getSheetAt(0);
|
||||||
|
assertTrue(hasValidationOnColumn(sheet, 7), "是否党员列应包含下拉校验");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void assertTextColumn(Sheet sheet, int columnIndex) {
|
private void assertTextColumn(Sheet sheet, int columnIndex) {
|
||||||
CellStyle style = sheet.getColumnStyle(columnIndex);
|
CellStyle style = sheet.getColumnStyle(columnIndex);
|
||||||
assertNotNull(style, "文本列应设置默认样式");
|
assertNotNull(style, "文本列应设置默认样式");
|
||||||
@@ -90,9 +116,13 @@ class EasyExcelUtilTemplateTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SysDictData buildDictData(String label) {
|
private SysDictData buildDictData(String label) {
|
||||||
|
return buildDictData(label, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SysDictData buildDictData(String label, String value) {
|
||||||
SysDictData dictData = new SysDictData();
|
SysDictData dictData = new SysDictData();
|
||||||
dictData.setDictLabel(label);
|
dictData.setDictLabel(label);
|
||||||
dictData.setDictValue(label);
|
dictData.setDictValue(value);
|
||||||
return dictData;
|
return dictData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
package com.ruoyi.lsfx.client;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.ruoyi.lsfx.domain.response.CreditParseResponse;
|
|
||||||
import com.ruoyi.lsfx.exception.LsfxApiException;
|
|
||||||
import com.ruoyi.lsfx.util.HttpUtil;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyMap;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.ArgumentMatchers.isNull;
|
|
||||||
import static org.mockito.Mockito.argThat;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
class CreditParseClientTest {
|
|
||||||
|
|
||||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private HttpUtil httpUtil;
|
|
||||||
|
|
||||||
@InjectMocks
|
|
||||||
private CreditParseClient client;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setUp() {
|
|
||||||
ReflectionTestUtils.setField(client, "creditParseUrl", "http://credit-host/xfeature-mngs/conversation/htmlEval");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldDeserializeCreditParseResponse() throws Exception {
|
|
||||||
String json = """
|
|
||||||
{
|
|
||||||
"message": "成功",
|
|
||||||
"status_code": "0",
|
|
||||||
"payload": {
|
|
||||||
"lx_header": {"query_cert_no": "3301"},
|
|
||||||
"lx_debt": {"uncle_bank_house_bal": "12.00"},
|
|
||||||
"lx_publictype": {"civil_cnt": 1}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
""";
|
|
||||||
|
|
||||||
CreditParseResponse response = objectMapper.readValue(json, CreditParseResponse.class);
|
|
||||||
|
|
||||||
assertEquals("0", response.getStatusCode());
|
|
||||||
assertEquals("3301", response.getPayload().getLxHeader().get("query_cert_no"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldCallConfiguredUrlWithMultipartParams() {
|
|
||||||
File file = new File("sample.html");
|
|
||||||
CreditParseResponse response = new CreditParseResponse();
|
|
||||||
response.setStatusCode("0");
|
|
||||||
|
|
||||||
when(httpUtil.uploadFile(eq("http://credit-host/xfeature-mngs/conversation/htmlEval"), anyMap(), isNull(), eq(CreditParseResponse.class)))
|
|
||||||
.thenReturn(response);
|
|
||||||
|
|
||||||
CreditParseResponse actual = client.parse("LXCUSTALL", "PERSON", file);
|
|
||||||
|
|
||||||
assertEquals("0", actual.getStatusCode());
|
|
||||||
verify(httpUtil).uploadFile(eq("http://credit-host/xfeature-mngs/conversation/htmlEval"), argThat(params ->
|
|
||||||
"LXCUSTALL".equals(params.get("model"))
|
|
||||||
&& "PERSON".equals(params.get("hType"))
|
|
||||||
&& file.equals(params.get("file"))
|
|
||||||
), isNull(), eq(CreditParseResponse.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldWrapHttpErrorsAsLsfxApiException() {
|
|
||||||
when(httpUtil.uploadFile(anyString(), anyMap(), isNull(), eq(CreditParseResponse.class)))
|
|
||||||
.thenThrow(new LsfxApiException("网络失败"));
|
|
||||||
|
|
||||||
assertThrows(LsfxApiException.class,
|
|
||||||
() -> client.parse("LXCUSTALL", "PERSON", new File("sample.html")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -43,6 +43,12 @@
|
|||||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- easyexcel工具 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>easyexcel</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- 测试依赖 -->
|
<!-- 测试依赖 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
package com.ruoyi.ccdi.project.controller;
|
|
||||||
|
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiEvidenceQueryDTO;
|
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiEvidenceSaveDTO;
|
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiEvidenceVO;
|
|
||||||
import com.ruoyi.ccdi.project.service.ICcdiEvidenceService;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
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.RestController;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 项目证据Controller
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/ccdi/evidence")
|
|
||||||
@Tag(name = "项目证据")
|
|
||||||
public class CcdiEvidenceController extends BaseController {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ICcdiEvidenceService evidenceService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存证据
|
|
||||||
*/
|
|
||||||
@PostMapping
|
|
||||||
@Operation(summary = "保存证据")
|
|
||||||
@PreAuthorize("@ss.hasPermi('ccdi:project:query')")
|
|
||||||
public AjaxResult saveEvidence(@Validated @RequestBody CcdiEvidenceSaveDTO dto) {
|
|
||||||
CcdiEvidenceVO vo = evidenceService.saveEvidence(dto, SecurityUtils.getUsername());
|
|
||||||
return AjaxResult.success("证据入库成功", vo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询项目证据列表
|
|
||||||
*/
|
|
||||||
@GetMapping("/list")
|
|
||||||
@Operation(summary = "查询项目证据列表")
|
|
||||||
@PreAuthorize("@ss.hasPermi('ccdi:project:query')")
|
|
||||||
public AjaxResult listEvidence(CcdiEvidenceQueryDTO queryDTO) {
|
|
||||||
List<CcdiEvidenceVO> list = evidenceService.listEvidence(queryDTO);
|
|
||||||
return AjaxResult.success(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询证据详情
|
|
||||||
*/
|
|
||||||
@GetMapping("/{evidenceId}")
|
|
||||||
@Operation(summary = "查询证据详情")
|
|
||||||
@PreAuthorize("@ss.hasPermi('ccdi:project:query')")
|
|
||||||
public AjaxResult getEvidence(@PathVariable Long evidenceId) {
|
|
||||||
CcdiEvidenceVO vo = evidenceService.getEvidence(evidenceId);
|
|
||||||
return AjaxResult.success(vo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.ccdi.project.controller;
|
package com.ruoyi.ccdi.project.controller;
|
||||||
|
|
||||||
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectAbnormalAccountQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
||||||
@@ -7,6 +8,7 @@ import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskPeopleQueryDTO;
|
|||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectRiskPeopleOverviewExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectRiskPeopleOverviewExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountPageVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativePageVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativePageVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisDetailVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisDetailVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewDashboardVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewDashboardVO;
|
||||||
@@ -130,6 +132,17 @@ public class CcdiProjectOverviewController extends BaseController {
|
|||||||
return AjaxResult.success(pageVO);
|
return AjaxResult.success(pageVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询异常账户人员信息
|
||||||
|
*/
|
||||||
|
@GetMapping("/abnormal-account-people")
|
||||||
|
@Operation(summary = "查询异常账户人员信息")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:project:query')")
|
||||||
|
public AjaxResult getAbnormalAccountPeople(CcdiProjectAbnormalAccountQueryDTO queryDTO) {
|
||||||
|
CcdiProjectAbnormalAccountPageVO pageVO = overviewService.getAbnormalAccountPeople(queryDTO);
|
||||||
|
return AjaxResult.success(pageVO);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出涉疑交易明细
|
* 导出涉疑交易明细
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package com.ruoyi.ccdi.project.domain.dto;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 项目证据查询入参
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class CcdiEvidenceQueryDTO {
|
|
||||||
|
|
||||||
/** 项目ID */
|
|
||||||
private Long projectId;
|
|
||||||
|
|
||||||
/** 证据类型:FLOW/MODEL/ASSET */
|
|
||||||
private String evidenceType;
|
|
||||||
|
|
||||||
/** 关键词:姓名、标题、摘要、证据编号 */
|
|
||||||
private String keyword;
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package com.ruoyi.ccdi.project.domain.dto;
|
|
||||||
|
|
||||||
import jakarta.validation.constraints.NotBlank;
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存项目证据入参
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class CcdiEvidenceSaveDTO {
|
|
||||||
|
|
||||||
/** 项目ID */
|
|
||||||
@NotNull(message = "项目ID不能为空")
|
|
||||||
private Long projectId;
|
|
||||||
|
|
||||||
/** 证据类型:FLOW/MODEL/ASSET */
|
|
||||||
@NotBlank(message = "证据类型不能为空")
|
|
||||||
private String evidenceType;
|
|
||||||
|
|
||||||
/** 关联人员姓名 */
|
|
||||||
@NotBlank(message = "关联人员不能为空")
|
|
||||||
private String relatedPersonName;
|
|
||||||
|
|
||||||
/** 关联人员标识 */
|
|
||||||
private String relatedPersonId;
|
|
||||||
|
|
||||||
/** 证据标题 */
|
|
||||||
@NotBlank(message = "证据标题不能为空")
|
|
||||||
private String evidenceTitle;
|
|
||||||
|
|
||||||
/** 证据摘要 */
|
|
||||||
@NotBlank(message = "证据摘要不能为空")
|
|
||||||
private String evidenceSummary;
|
|
||||||
|
|
||||||
/** 来源类型 */
|
|
||||||
@NotBlank(message = "来源类型不能为空")
|
|
||||||
private String sourceType;
|
|
||||||
|
|
||||||
/** 来源记录ID */
|
|
||||||
private String sourceRecordId;
|
|
||||||
|
|
||||||
/** 来源页面名称 */
|
|
||||||
private String sourcePage;
|
|
||||||
|
|
||||||
/** 证据快照JSON */
|
|
||||||
private String snapshotJson;
|
|
||||||
|
|
||||||
/** 确认理由/备注 */
|
|
||||||
@NotBlank(message = "确认理由/备注不能为空")
|
|
||||||
private String confirmReason;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.ruoyi.ccdi.project.domain.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常账户人员信息查询 DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CcdiProjectAbnormalAccountQueryDTO {
|
||||||
|
|
||||||
|
/** 项目ID */
|
||||||
|
private Long projectId;
|
||||||
|
|
||||||
|
/** 页码 */
|
||||||
|
private Integer pageNum;
|
||||||
|
|
||||||
|
/** 每页数量 */
|
||||||
|
private Integer pageSize;
|
||||||
|
}
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
package com.ruoyi.ccdi.project.domain.entity;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 项目证据对象 ccdi_evidence
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@TableName("ccdi_evidence")
|
|
||||||
public class CcdiEvidence implements Serializable {
|
|
||||||
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/** 证据ID */
|
|
||||||
@TableId(type = IdType.AUTO)
|
|
||||||
private Long evidenceId;
|
|
||||||
|
|
||||||
/** 项目ID */
|
|
||||||
private Long projectId;
|
|
||||||
|
|
||||||
/** 证据类型:FLOW/MODEL/ASSET */
|
|
||||||
private String evidenceType;
|
|
||||||
|
|
||||||
/** 关联人员姓名 */
|
|
||||||
private String relatedPersonName;
|
|
||||||
|
|
||||||
/** 关联人员标识,优先存身份证号或员工号 */
|
|
||||||
private String relatedPersonId;
|
|
||||||
|
|
||||||
/** 证据标题 */
|
|
||||||
private String evidenceTitle;
|
|
||||||
|
|
||||||
/** 证据摘要 */
|
|
||||||
private String evidenceSummary;
|
|
||||||
|
|
||||||
/** 来源类型:BANK_STATEMENT/MODEL_DETAIL/ASSET_DETAIL */
|
|
||||||
private String sourceType;
|
|
||||||
|
|
||||||
/** 来源记录ID */
|
|
||||||
private String sourceRecordId;
|
|
||||||
|
|
||||||
/** 来源页面名称 */
|
|
||||||
private String sourcePage;
|
|
||||||
|
|
||||||
/** 证据快照JSON */
|
|
||||||
private String snapshotJson;
|
|
||||||
|
|
||||||
/** 确认理由/备注 */
|
|
||||||
private String confirmReason;
|
|
||||||
|
|
||||||
/** 确认人 */
|
|
||||||
private String confirmBy;
|
|
||||||
|
|
||||||
/** 确认时间 */
|
|
||||||
private Date confirmTime;
|
|
||||||
|
|
||||||
/** 创建者 */
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
private String createBy;
|
|
||||||
|
|
||||||
/** 创建时间 */
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
/** 更新者 */
|
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
|
||||||
private String updateBy;
|
|
||||||
|
|
||||||
/** 更新时间 */
|
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
|
||||||
private Date updateTime;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.ruoyi.ccdi.project.domain.excel;
|
||||||
|
|
||||||
|
import com.ruoyi.common.annotation.Excel;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常账户人员信息导出对象
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CcdiProjectAbnormalAccountExcel {
|
||||||
|
|
||||||
|
@Excel(name = "账号")
|
||||||
|
private String accountNo;
|
||||||
|
|
||||||
|
@Excel(name = "开户人")
|
||||||
|
private String accountName;
|
||||||
|
|
||||||
|
@Excel(name = "银行")
|
||||||
|
private String bankName;
|
||||||
|
|
||||||
|
@Excel(name = "异常类型")
|
||||||
|
private String abnormalType;
|
||||||
|
|
||||||
|
@Excel(name = "异常发生时间")
|
||||||
|
private String abnormalTime;
|
||||||
|
|
||||||
|
@Excel(name = "状态")
|
||||||
|
private String status;
|
||||||
|
}
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
package com.ruoyi.ccdi.project.domain.vo;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 项目证据返回对象
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class CcdiEvidenceVO {
|
|
||||||
|
|
||||||
/** 证据ID */
|
|
||||||
private Long evidenceId;
|
|
||||||
|
|
||||||
/** 项目ID */
|
|
||||||
private Long projectId;
|
|
||||||
|
|
||||||
/** 证据类型:FLOW/MODEL/ASSET */
|
|
||||||
private String evidenceType;
|
|
||||||
|
|
||||||
/** 关联人员姓名 */
|
|
||||||
private String relatedPersonName;
|
|
||||||
|
|
||||||
/** 关联人员标识 */
|
|
||||||
private String relatedPersonId;
|
|
||||||
|
|
||||||
/** 证据标题 */
|
|
||||||
private String evidenceTitle;
|
|
||||||
|
|
||||||
/** 证据摘要 */
|
|
||||||
private String evidenceSummary;
|
|
||||||
|
|
||||||
/** 来源类型 */
|
|
||||||
private String sourceType;
|
|
||||||
|
|
||||||
/** 来源记录ID */
|
|
||||||
private String sourceRecordId;
|
|
||||||
|
|
||||||
/** 来源页面名称 */
|
|
||||||
private String sourcePage;
|
|
||||||
|
|
||||||
/** 证据快照JSON */
|
|
||||||
private String snapshotJson;
|
|
||||||
|
|
||||||
/** 确认理由/备注 */
|
|
||||||
private String confirmReason;
|
|
||||||
|
|
||||||
/** 确认人 */
|
|
||||||
private String confirmBy;
|
|
||||||
|
|
||||||
/** 确认时间 */
|
|
||||||
private Date confirmTime;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.ruoyi.ccdi.project.domain.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常账户人员信息行对象
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CcdiProjectAbnormalAccountItemVO {
|
||||||
|
|
||||||
|
private String accountNo;
|
||||||
|
|
||||||
|
private String accountName;
|
||||||
|
|
||||||
|
private String bankName;
|
||||||
|
|
||||||
|
private String abnormalType;
|
||||||
|
|
||||||
|
private String abnormalTime;
|
||||||
|
|
||||||
|
private String status;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.ruoyi.ccdi.project.domain.vo;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常账户人员信息分页结果
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CcdiProjectAbnormalAccountPageVO {
|
||||||
|
|
||||||
|
private List<CcdiProjectAbnormalAccountItemVO> rows = new ArrayList<>();
|
||||||
|
|
||||||
|
private Long total = 0L;
|
||||||
|
}
|
||||||
@@ -10,8 +10,6 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class CcdiProjectPersonAnalysisObjectRecordVO {
|
public class CcdiProjectPersonAnalysisObjectRecordVO {
|
||||||
|
|
||||||
private String modelCode;
|
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
private String subtitle;
|
private String subtitle;
|
||||||
|
|||||||
@@ -292,6 +292,22 @@ public interface CcdiBankTagAnalysisMapper {
|
|||||||
*/
|
*/
|
||||||
List<BankTagObjectHitVO> selectSalaryUnusedObjects(@Param("projectId") Long projectId);
|
List<BankTagObjectHitVO> selectSalaryUnusedObjects(@Param("projectId") Long projectId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 突然销户
|
||||||
|
*
|
||||||
|
* @param projectId 项目ID
|
||||||
|
* @return 对象命中结果
|
||||||
|
*/
|
||||||
|
List<BankTagObjectHitVO> selectSuddenAccountClosureObjects(@Param("projectId") Long projectId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 休眠账户大额启用
|
||||||
|
*
|
||||||
|
* @param projectId 项目ID
|
||||||
|
* @return 对象命中结果
|
||||||
|
*/
|
||||||
|
List<BankTagObjectHitVO> selectDormantAccountLargeActivationObjects(@Param("projectId") Long projectId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 大额炒股
|
* 大额炒股
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
package com.ruoyi.ccdi.project.mapper;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import com.ruoyi.ccdi.project.domain.entity.CcdiEvidence;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 项目证据Mapper接口
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public interface CcdiEvidenceMapper extends BaseMapper<CcdiEvidence> {
|
|
||||||
}
|
|
||||||
@@ -2,10 +2,12 @@ package com.ruoyi.ccdi.project.mapper;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
||||||
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectAbnormalAccountQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskPeopleQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskPeopleQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountItemVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeRiskAggregateVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeRiskAggregateVO;
|
||||||
@@ -106,6 +108,26 @@ public interface CcdiProjectOverviewMapper {
|
|||||||
@Param("query") CcdiProjectEmployeeCreditNegativeQueryDTO query
|
@Param("query") CcdiProjectEmployeeCreditNegativeQueryDTO query
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询异常账户人员信息
|
||||||
|
*
|
||||||
|
* @param page 分页参数
|
||||||
|
* @param query 查询条件
|
||||||
|
* @return 分页结果
|
||||||
|
*/
|
||||||
|
Page<CcdiProjectAbnormalAccountItemVO> selectAbnormalAccountPage(
|
||||||
|
Page<CcdiProjectAbnormalAccountItemVO> page,
|
||||||
|
@Param("query") CcdiProjectAbnormalAccountQueryDTO query
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询异常账户人员信息导出列表
|
||||||
|
*
|
||||||
|
* @param projectId 项目ID
|
||||||
|
* @return 导出列表
|
||||||
|
*/
|
||||||
|
List<CcdiProjectAbnormalAccountItemVO> selectAbnormalAccountList(@Param("projectId") Long projectId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询项目员工负面征信导出列表
|
* 查询项目员工负面征信导出列表
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
package com.ruoyi.ccdi.project.service;
|
|
||||||
|
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiEvidenceQueryDTO;
|
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiEvidenceSaveDTO;
|
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiEvidenceVO;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 项目证据Service接口
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public interface ICcdiEvidenceService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存证据
|
|
||||||
*
|
|
||||||
* @param dto 保存入参
|
|
||||||
* @param operator 操作人
|
|
||||||
* @return 证据
|
|
||||||
*/
|
|
||||||
CcdiEvidenceVO saveEvidence(CcdiEvidenceSaveDTO dto, String operator);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询项目证据列表
|
|
||||||
*
|
|
||||||
* @param queryDTO 查询入参
|
|
||||||
* @return 证据列表
|
|
||||||
*/
|
|
||||||
List<CcdiEvidenceVO> listEvidence(CcdiEvidenceQueryDTO queryDTO);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询证据详情
|
|
||||||
*
|
|
||||||
* @param evidenceId 证据ID
|
|
||||||
* @return 证据
|
|
||||||
*/
|
|
||||||
CcdiEvidenceVO getEvidence(Long evidenceId);
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
package com.ruoyi.ccdi.project.service;
|
package com.ruoyi.ccdi.project.service;
|
||||||
|
|
||||||
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectAbnormalAccountQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskPeopleQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskPeopleQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectAbnormalAccountExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectEmployeeCreditNegativeExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectEmployeeCreditNegativeExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectRiskPeopleOverviewExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectRiskPeopleOverviewExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountPageVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativePageVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativePageVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisDetailVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisDetailVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewDashboardVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewDashboardVO;
|
||||||
@@ -144,6 +147,28 @@ public interface ICcdiProjectOverviewService {
|
|||||||
return new CcdiProjectEmployeeCreditNegativePageVO();
|
return new CcdiProjectEmployeeCreditNegativePageVO();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询异常账户人员信息
|
||||||
|
*
|
||||||
|
* @param queryDTO 查询条件
|
||||||
|
* @return 分页结果
|
||||||
|
*/
|
||||||
|
default CcdiProjectAbnormalAccountPageVO getAbnormalAccountPeople(
|
||||||
|
CcdiProjectAbnormalAccountQueryDTO queryDTO
|
||||||
|
) {
|
||||||
|
return new CcdiProjectAbnormalAccountPageVO();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出异常账户人员信息
|
||||||
|
*
|
||||||
|
* @param projectId 项目ID
|
||||||
|
* @return 导出列表
|
||||||
|
*/
|
||||||
|
default List<CcdiProjectAbnormalAccountExcel> exportAbnormalAccountPeople(Long projectId) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重算结果总览员工结果并同步项目风险人数
|
* 重算结果总览员工结果并同步项目风险人数
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -288,6 +288,8 @@ public class CcdiBankTagServiceImpl implements ICcdiBankTagService {
|
|||||||
case "WITHDRAW_AMT" -> analysisMapper.selectWithdrawAmtObjects(projectId);
|
case "WITHDRAW_AMT" -> analysisMapper.selectWithdrawAmtObjects(projectId);
|
||||||
case "SALARY_QUICK_TRANSFER" -> analysisMapper.selectSalaryQuickTransferObjects(projectId);
|
case "SALARY_QUICK_TRANSFER" -> analysisMapper.selectSalaryQuickTransferObjects(projectId);
|
||||||
case "SALARY_UNUSED" -> analysisMapper.selectSalaryUnusedObjects(projectId);
|
case "SALARY_UNUSED" -> analysisMapper.selectSalaryUnusedObjects(projectId);
|
||||||
|
case "SUDDEN_ACCOUNT_CLOSURE" -> analysisMapper.selectSuddenAccountClosureObjects(projectId);
|
||||||
|
case "DORMANT_ACCOUNT_LARGE_ACTIVATION" -> analysisMapper.selectDormantAccountLargeActivationObjects(projectId);
|
||||||
case "PROXY_ACCOUNT_OPERATION" -> analysisMapper.selectProxyAccountOperationObjects(projectId);
|
case "PROXY_ACCOUNT_OPERATION" -> analysisMapper.selectProxyAccountOperationObjects(projectId);
|
||||||
default -> List.of();
|
default -> List.of();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
package com.ruoyi.ccdi.project.service.impl;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiEvidenceQueryDTO;
|
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiEvidenceSaveDTO;
|
|
||||||
import com.ruoyi.ccdi.project.domain.entity.CcdiEvidence;
|
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiEvidenceVO;
|
|
||||||
import com.ruoyi.ccdi.project.mapper.CcdiEvidenceMapper;
|
|
||||||
import com.ruoyi.ccdi.project.service.ICcdiEvidenceService;
|
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 项目证据Service实现类
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class CcdiEvidenceServiceImpl implements ICcdiEvidenceService {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private CcdiEvidenceMapper evidenceMapper;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public CcdiEvidenceVO saveEvidence(CcdiEvidenceSaveDTO dto, String operator) {
|
|
||||||
CcdiEvidence evidence = new CcdiEvidence();
|
|
||||||
BeanUtils.copyProperties(dto, evidence);
|
|
||||||
evidence.setConfirmBy(operator);
|
|
||||||
evidence.setConfirmTime(new Date());
|
|
||||||
evidenceMapper.insert(evidence);
|
|
||||||
return toVO(evidence);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<CcdiEvidenceVO> listEvidence(CcdiEvidenceQueryDTO queryDTO) {
|
|
||||||
if (queryDTO.getProjectId() == null) {
|
|
||||||
throw new ServiceException("项目ID不能为空");
|
|
||||||
}
|
|
||||||
LambdaQueryWrapper<CcdiEvidence> wrapper = new LambdaQueryWrapper<CcdiEvidence>()
|
|
||||||
.eq(CcdiEvidence::getProjectId, queryDTO.getProjectId())
|
|
||||||
.orderByDesc(CcdiEvidence::getConfirmTime)
|
|
||||||
.orderByDesc(CcdiEvidence::getEvidenceId);
|
|
||||||
|
|
||||||
if (StringUtils.hasText(queryDTO.getEvidenceType())) {
|
|
||||||
wrapper.eq(CcdiEvidence::getEvidenceType, queryDTO.getEvidenceType());
|
|
||||||
}
|
|
||||||
if (StringUtils.hasText(queryDTO.getKeyword())) {
|
|
||||||
String keyword = queryDTO.getKeyword().trim();
|
|
||||||
wrapper.and(item -> item
|
|
||||||
.like(CcdiEvidence::getRelatedPersonName, keyword)
|
|
||||||
.or()
|
|
||||||
.like(CcdiEvidence::getRelatedPersonId, keyword)
|
|
||||||
.or()
|
|
||||||
.like(CcdiEvidence::getEvidenceTitle, keyword)
|
|
||||||
.or()
|
|
||||||
.like(CcdiEvidence::getEvidenceSummary, keyword)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return evidenceMapper.selectList(wrapper).stream().map(this::toVO).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CcdiEvidenceVO getEvidence(Long evidenceId) {
|
|
||||||
CcdiEvidence evidence = evidenceMapper.selectById(evidenceId);
|
|
||||||
if (evidence == null) {
|
|
||||||
throw new ServiceException("证据不存在");
|
|
||||||
}
|
|
||||||
return toVO(evidence);
|
|
||||||
}
|
|
||||||
|
|
||||||
private CcdiEvidenceVO toVO(CcdiEvidence evidence) {
|
|
||||||
CcdiEvidenceVO vo = new CcdiEvidenceVO();
|
|
||||||
BeanUtils.copyProperties(evidence, vo);
|
|
||||||
return vo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,15 +2,19 @@ package com.ruoyi.ccdi.project.service.impl;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
||||||
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectAbnormalAccountQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskPeopleQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskPeopleQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectAbnormalAccountExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectEmployeeCreditNegativeExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectEmployeeCreditNegativeExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectRiskPeopleOverviewExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectRiskPeopleOverviewExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.entity.CcdiProjectOverviewEmployeeResult;
|
import com.ruoyi.ccdi.project.domain.entity.CcdiProjectOverviewEmployeeResult;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountItemVO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountPageVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementHitTagVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementHitTagVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO;
|
||||||
@@ -258,6 +262,31 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CcdiProjectAbnormalAccountPageVO getAbnormalAccountPeople(CcdiProjectAbnormalAccountQueryDTO queryDTO) {
|
||||||
|
ensureProjectExists(queryDTO.getProjectId());
|
||||||
|
|
||||||
|
Page<CcdiProjectAbnormalAccountItemVO> page = new Page<>(
|
||||||
|
defaultAbnormalAccountPageNum(queryDTO.getPageNum()),
|
||||||
|
defaultAbnormalAccountPageSize(queryDTO.getPageSize())
|
||||||
|
);
|
||||||
|
Page<CcdiProjectAbnormalAccountItemVO> resultPage = overviewMapper.selectAbnormalAccountPage(page, queryDTO);
|
||||||
|
|
||||||
|
CcdiProjectAbnormalAccountPageVO result = new CcdiProjectAbnormalAccountPageVO();
|
||||||
|
result.setRows(defaultList(resultPage == null ? null : resultPage.getRecords()));
|
||||||
|
result.setTotal(resultPage == null ? 0L : resultPage.getTotal());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CcdiProjectAbnormalAccountExcel> exportAbnormalAccountPeople(Long projectId) {
|
||||||
|
ensureProjectExists(projectId);
|
||||||
|
|
||||||
|
return defaultList(overviewMapper.selectAbnormalAccountList(projectId)).stream()
|
||||||
|
.map(this::buildAbnormalAccountExcelRow)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exportRiskDetails(HttpServletResponse response, Long projectId) {
|
public void exportRiskDetails(HttpServletResponse response, Long projectId) {
|
||||||
CcdiProjectSuspiciousTransactionQueryDTO queryDTO = new CcdiProjectSuspiciousTransactionQueryDTO();
|
CcdiProjectSuspiciousTransactionQueryDTO queryDTO = new CcdiProjectSuspiciousTransactionQueryDTO();
|
||||||
@@ -266,8 +295,9 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi
|
|||||||
|
|
||||||
List<CcdiProjectSuspiciousTransactionExcel> suspiciousRows = exportSuspiciousTransactions(queryDTO);
|
List<CcdiProjectSuspiciousTransactionExcel> suspiciousRows = exportSuspiciousTransactions(queryDTO);
|
||||||
List<CcdiProjectEmployeeCreditNegativeExcel> creditRows = exportEmployeeCreditNegative(projectId);
|
List<CcdiProjectEmployeeCreditNegativeExcel> creditRows = exportEmployeeCreditNegative(projectId);
|
||||||
|
List<CcdiProjectAbnormalAccountExcel> abnormalRows = exportAbnormalAccountPeople(projectId);
|
||||||
try {
|
try {
|
||||||
workbookExporter.export(response, projectId, suspiciousRows, creditRows);
|
workbookExporter.export(response, projectId, suspiciousRows, creditRows, abnormalRows);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ServiceException("导出风险明细失败");
|
throw new ServiceException("导出风险明细失败");
|
||||||
}
|
}
|
||||||
@@ -420,6 +450,14 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi
|
|||||||
return pageSize == null || pageSize <= 0 ? 5L : pageSize.longValue();
|
return pageSize == null || pageSize <= 0 ? 5L : pageSize.longValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long defaultAbnormalAccountPageNum(Integer pageNum) {
|
||||||
|
return pageNum == null || pageNum <= 0 ? 1L : pageNum.longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private long defaultAbnormalAccountPageSize(Integer pageSize) {
|
||||||
|
return pageSize == null || pageSize <= 0 ? 5L : pageSize.longValue();
|
||||||
|
}
|
||||||
|
|
||||||
private long defaultPageNum(Integer pageNum) {
|
private long defaultPageNum(Integer pageNum) {
|
||||||
return pageNum == null || pageNum < 1 ? 1L : pageNum.longValue();
|
return pageNum == null || pageNum < 1 ? 1L : pageNum.longValue();
|
||||||
}
|
}
|
||||||
@@ -462,6 +500,17 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi
|
|||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CcdiProjectAbnormalAccountExcel buildAbnormalAccountExcelRow(CcdiProjectAbnormalAccountItemVO item) {
|
||||||
|
CcdiProjectAbnormalAccountExcel row = new CcdiProjectAbnormalAccountExcel();
|
||||||
|
row.setAccountNo(item.getAccountNo());
|
||||||
|
row.setAccountName(item.getAccountName());
|
||||||
|
row.setBankName(item.getBankName());
|
||||||
|
row.setAbnormalType(item.getAbnormalType());
|
||||||
|
row.setAbnormalTime(item.getAbnormalTime());
|
||||||
|
row.setStatus(item.getStatus());
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
private String formatRelatedStaff(String relatedStaffName, String relatedStaffCode) {
|
private String formatRelatedStaff(String relatedStaffName, String relatedStaffCode) {
|
||||||
if (relatedStaffName == null || relatedStaffName.isBlank()) {
|
if (relatedStaffName == null || relatedStaffName.isBlank()) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.ccdi.project.service.impl;
|
package com.ruoyi.ccdi.project.service.impl;
|
||||||
|
|
||||||
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectAbnormalAccountExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectEmployeeCreditNegativeExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectEmployeeCreditNegativeExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
||||||
import com.ruoyi.common.utils.file.FileUtils;
|
import com.ruoyi.common.utils.file.FileUtils;
|
||||||
@@ -27,7 +28,8 @@ public class CcdiProjectRiskDetailWorkbookExporter {
|
|||||||
HttpServletResponse response,
|
HttpServletResponse response,
|
||||||
Long projectId,
|
Long projectId,
|
||||||
List<CcdiProjectSuspiciousTransactionExcel> suspiciousRows,
|
List<CcdiProjectSuspiciousTransactionExcel> suspiciousRows,
|
||||||
List<CcdiProjectEmployeeCreditNegativeExcel> creditRows
|
List<CcdiProjectEmployeeCreditNegativeExcel> creditRows,
|
||||||
|
List<CcdiProjectAbnormalAccountExcel> abnormalRows
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
response.setContentType(CONTENT_TYPE);
|
response.setContentType(CONTENT_TYPE);
|
||||||
FileUtils.setAttachmentResponseHeader(response, "风险明细_" + projectId + ".xlsx");
|
FileUtils.setAttachmentResponseHeader(response, "风险明细_" + projectId + ".xlsx");
|
||||||
@@ -35,7 +37,7 @@ public class CcdiProjectRiskDetailWorkbookExporter {
|
|||||||
try (Workbook workbook = new XSSFWorkbook()) {
|
try (Workbook workbook = new XSSFWorkbook()) {
|
||||||
writeSuspiciousSheet(workbook.createSheet("涉疑交易明细"), suspiciousRows);
|
writeSuspiciousSheet(workbook.createSheet("涉疑交易明细"), suspiciousRows);
|
||||||
writeCreditSheet(workbook.createSheet("员工负面征信信息"), creditRows);
|
writeCreditSheet(workbook.createSheet("员工负面征信信息"), creditRows);
|
||||||
writeAbnormalAccountSheet(workbook.createSheet("异常账户人员信息"));
|
writeAbnormalAccountSheet(workbook.createSheet("异常账户人员信息"), abnormalRows);
|
||||||
workbook.write(response.getOutputStream());
|
workbook.write(response.getOutputStream());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,10 +90,21 @@ public class CcdiProjectRiskDetailWorkbookExporter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeAbnormalAccountSheet(Sheet sheet) {
|
private void writeAbnormalAccountSheet(Sheet sheet, List<CcdiProjectAbnormalAccountExcel> rows) {
|
||||||
Row header = sheet.createRow(0);
|
Row header = sheet.createRow(0);
|
||||||
String[] headers = { "账号", "开户人", "银行", "异常类型", "异常发生时间", "状态" };
|
String[] headers = { "账号", "开户人", "银行", "异常类型", "异常发生时间", "状态" };
|
||||||
writeHeader(header, headers);
|
writeHeader(header, headers);
|
||||||
|
|
||||||
|
for (int i = 0; i < rows.size(); i++) {
|
||||||
|
CcdiProjectAbnormalAccountExcel item = rows.get(i);
|
||||||
|
Row row = sheet.createRow(i + 1);
|
||||||
|
row.createCell(0).setCellValue(safeText(item.getAccountNo()));
|
||||||
|
row.createCell(1).setCellValue(safeText(item.getAccountName()));
|
||||||
|
row.createCell(2).setCellValue(safeText(item.getBankName()));
|
||||||
|
row.createCell(3).setCellValue(safeText(item.getAbnormalType()));
|
||||||
|
row.createCell(4).setCellValue(safeText(item.getAbnormalTime()));
|
||||||
|
row.createCell(5).setCellValue(safeText(item.getStatus()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeHeader(Row row, String[] headers) {
|
private void writeHeader(Row row, String[] headers) {
|
||||||
|
|||||||
@@ -1211,6 +1211,101 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
) t
|
) t
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectSuddenAccountClosureObjects" resultMap="BankTagObjectHitResultMap">
|
||||||
|
select
|
||||||
|
'STAFF_ID_CARD' AS objectType,
|
||||||
|
t.objectKey AS objectKey,
|
||||||
|
CONCAT(
|
||||||
|
'账户', t.accountNo,
|
||||||
|
'于', DATE_FORMAT(t.invalidDate, '%Y-%m-%d'),
|
||||||
|
'销户,销户前30天内最后交易日', DATE_FORMAT(t.lastTxDate, '%Y-%m-%d'),
|
||||||
|
',累计交易金额', CAST(t.windowTotalAmount AS CHAR),
|
||||||
|
'元,单笔最大金额', CAST(t.windowMaxSingleAmount AS CHAR),
|
||||||
|
'元'
|
||||||
|
) AS reasonDetail
|
||||||
|
from (
|
||||||
|
select
|
||||||
|
staff.id_card AS objectKey,
|
||||||
|
ai.account_no AS accountNo,
|
||||||
|
ai.invalid_date AS invalidDate,
|
||||||
|
max(tx.txDate) AS lastTxDate,
|
||||||
|
round(sum(tx.tradeTotalAmount), 2) AS windowTotalAmount,
|
||||||
|
round(max(tx.tradeMaxSingleAmount), 2) AS windowMaxSingleAmount
|
||||||
|
from ccdi_account_info ai
|
||||||
|
inner join ccdi_base_staff staff
|
||||||
|
on staff.id_card = ai.owner_id
|
||||||
|
inner join (
|
||||||
|
select
|
||||||
|
trim(bs.LE_ACCOUNT_NO) AS accountNo,
|
||||||
|
COALESCE(
|
||||||
|
STR_TO_DATE(LEFT(TRIM(bs.TRX_DATE), 19), '%Y-%m-%d %H:%i:%s'),
|
||||||
|
STR_TO_DATE(LEFT(TRIM(bs.TRX_DATE), 10), '%Y-%m-%d')
|
||||||
|
) AS txDate,
|
||||||
|
IFNULL(bs.AMOUNT_DR, 0) + IFNULL(bs.AMOUNT_CR, 0) AS tradeTotalAmount,
|
||||||
|
GREATEST(IFNULL(bs.AMOUNT_DR, 0), IFNULL(bs.AMOUNT_CR, 0)) AS tradeMaxSingleAmount
|
||||||
|
from ccdi_bank_statement bs
|
||||||
|
where bs.project_id = #{projectId}
|
||||||
|
and trim(IFNULL(bs.LE_ACCOUNT_NO, '')) != ''
|
||||||
|
) tx
|
||||||
|
on tx.accountNo = trim(ai.account_no)
|
||||||
|
where ai.owner_type = 'EMPLOYEE'
|
||||||
|
and ai.status = 2
|
||||||
|
and ai.invalid_date is not null
|
||||||
|
and tx.txDate >= DATE_SUB(ai.invalid_date, INTERVAL 30 DAY)
|
||||||
|
and tx.txDate < ai.invalid_date
|
||||||
|
group by staff.id_card, ai.account_no, ai.invalid_date
|
||||||
|
) t
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectDormantAccountLargeActivationObjects" resultMap="BankTagObjectHitResultMap">
|
||||||
|
select
|
||||||
|
'STAFF_ID_CARD' AS objectType,
|
||||||
|
t.objectKey AS objectKey,
|
||||||
|
CONCAT(
|
||||||
|
'账户', t.accountNo,
|
||||||
|
'开户于', DATE_FORMAT(t.effectiveDate, '%Y-%m-%d'),
|
||||||
|
',首次交易日期', DATE_FORMAT(t.firstTxDate, '%Y-%m-%d'),
|
||||||
|
',沉睡时长', CAST(t.dormantMonths AS CHAR),
|
||||||
|
'个月,启用后累计交易金额', CAST(t.windowTotalAmount AS CHAR),
|
||||||
|
'元,单笔最大金额', CAST(t.windowMaxSingleAmount AS CHAR),
|
||||||
|
'元'
|
||||||
|
) AS reasonDetail
|
||||||
|
from (
|
||||||
|
select
|
||||||
|
staff.id_card AS objectKey,
|
||||||
|
ai.account_no AS accountNo,
|
||||||
|
ai.effective_date AS effectiveDate,
|
||||||
|
min(tx.txDate) AS firstTxDate,
|
||||||
|
timestampdiff(MONTH, ai.effective_date, min(tx.txDate)) AS dormantMonths,
|
||||||
|
round(sum(tx.tradeTotalAmount), 2) AS windowTotalAmount,
|
||||||
|
round(max(tx.tradeMaxSingleAmount), 2) AS windowMaxSingleAmount
|
||||||
|
from ccdi_account_info ai
|
||||||
|
inner join ccdi_base_staff staff
|
||||||
|
on staff.id_card = ai.owner_id
|
||||||
|
inner join (
|
||||||
|
select
|
||||||
|
trim(bs.LE_ACCOUNT_NO) AS accountNo,
|
||||||
|
COALESCE(
|
||||||
|
STR_TO_DATE(LEFT(TRIM(bs.TRX_DATE), 19), '%Y-%m-%d %H:%i:%s'),
|
||||||
|
STR_TO_DATE(LEFT(TRIM(bs.TRX_DATE), 10), '%Y-%m-%d')
|
||||||
|
) AS txDate,
|
||||||
|
IFNULL(bs.AMOUNT_DR, 0) + IFNULL(bs.AMOUNT_CR, 0) AS tradeTotalAmount,
|
||||||
|
GREATEST(IFNULL(bs.AMOUNT_DR, 0), IFNULL(bs.AMOUNT_CR, 0)) AS tradeMaxSingleAmount
|
||||||
|
from ccdi_bank_statement bs
|
||||||
|
where bs.project_id = #{projectId}
|
||||||
|
and trim(IFNULL(bs.LE_ACCOUNT_NO, '')) != ''
|
||||||
|
) tx
|
||||||
|
on tx.accountNo = trim(ai.account_no)
|
||||||
|
where ai.owner_type = 'EMPLOYEE'
|
||||||
|
and ai.status = 1
|
||||||
|
and ai.effective_date is not null
|
||||||
|
group by staff.id_card, ai.account_no, ai.effective_date
|
||||||
|
having min(tx.txDate) >= DATE_ADD(ai.effective_date, INTERVAL 6 MONTH)
|
||||||
|
) t
|
||||||
|
where t.windowTotalAmount >= 500000
|
||||||
|
or t.windowMaxSingleAmount >= 100000
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="selectLargeStockTradingStatements" resultMap="BankTagStatementHitResultMap">
|
<select id="selectLargeStockTradingStatements" resultMap="BankTagStatementHitResultMap">
|
||||||
select
|
select
|
||||||
bs.bank_statement_id AS bankStatementId,
|
bs.bank_statement_id AS bankStatementId,
|
||||||
|
|||||||
@@ -48,6 +48,15 @@
|
|||||||
<result property="hasNameListHit" column="hasNameListHit"/>
|
<result property="hasNameListHit" column="hasNameListHit"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
|
<resultMap id="AbnormalAccountItemResultMap" type="com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountItemVO">
|
||||||
|
<result property="accountNo" column="accountNo"/>
|
||||||
|
<result property="accountName" column="accountName"/>
|
||||||
|
<result property="bankName" column="bankName"/>
|
||||||
|
<result property="abnormalType" column="abnormalType"/>
|
||||||
|
<result property="abnormalTime" column="abnormal_time"/>
|
||||||
|
<result property="status" column="status"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
<sql id="digitTableSql">
|
<sql id="digitTableSql">
|
||||||
select 0 as digit
|
select 0 as digit
|
||||||
union all select 1
|
union all select 1
|
||||||
@@ -644,6 +653,92 @@
|
|||||||
order by neg.query_date desc, neg.person_id asc
|
order by neg.query_date desc, neg.person_id asc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<sql id="abnormalAccountBaseSql">
|
||||||
|
select
|
||||||
|
account.account_no as accountNo,
|
||||||
|
account.account_no as account_no,
|
||||||
|
coalesce(nullif(account.account_name, ''), staff.name) as accountName,
|
||||||
|
account.bank as bankName,
|
||||||
|
tr.rule_name as abnormalType,
|
||||||
|
tr.rule_code as rule_code,
|
||||||
|
case
|
||||||
|
when tr.rule_code = 'SUDDEN_ACCOUNT_CLOSURE' then date_format(account.invalid_date, '%Y-%m-%d')
|
||||||
|
when tr.rule_code = 'DORMANT_ACCOUNT_LARGE_ACTIVATION' then substring(
|
||||||
|
substring_index(
|
||||||
|
substring_index(tr.reason_detail, ',', 2),
|
||||||
|
'首次交易日期',
|
||||||
|
-1
|
||||||
|
),
|
||||||
|
1,
|
||||||
|
10
|
||||||
|
)
|
||||||
|
else null
|
||||||
|
end as abnormal_time,
|
||||||
|
case
|
||||||
|
when account.status = 1 then '正常'
|
||||||
|
when account.status = 2 then '已销户'
|
||||||
|
else cast(account.status as char)
|
||||||
|
end as status
|
||||||
|
from ccdi_bank_statement_tag_result tr
|
||||||
|
inner join ccdi_account_info account
|
||||||
|
on account.owner_type = 'EMPLOYEE'
|
||||||
|
and account.owner_id = tr.object_key
|
||||||
|
and instr(tr.reason_detail, account.account_no) > 0
|
||||||
|
left join ccdi_base_staff staff
|
||||||
|
on staff.id_card = tr.object_key
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectAbnormalAccountPage" resultMap="AbnormalAccountItemResultMap">
|
||||||
|
<!-- tr.model_code = 'ABNORMAL_ACCOUNT' -->
|
||||||
|
<!-- tr.bank_statement_id is null -->
|
||||||
|
<!-- account.owner_type = 'EMPLOYEE' -->
|
||||||
|
<!-- tr.reason_detail -->
|
||||||
|
<!-- instr(tr.reason_detail, account.account_no) > 0 -->
|
||||||
|
<!-- when account.status = 1 then '正常' -->
|
||||||
|
<!-- when account.status = 2 then '已销户' -->
|
||||||
|
<!-- when tr.rule_code = 'SUDDEN_ACCOUNT_CLOSURE' -->
|
||||||
|
<!-- when tr.rule_code = 'DORMANT_ACCOUNT_LARGE_ACTIVATION' -->
|
||||||
|
<!-- order by abnormal_time desc, account.account_no asc, tr.rule_code asc -->
|
||||||
|
select
|
||||||
|
abnormal.accountNo,
|
||||||
|
abnormal.accountName,
|
||||||
|
abnormal.bankName,
|
||||||
|
abnormal.abnormalType,
|
||||||
|
abnormal.abnormal_time,
|
||||||
|
abnormal.status
|
||||||
|
from (
|
||||||
|
<include refid="abnormalAccountBaseSql"/>
|
||||||
|
where tr.project_id = #{query.projectId}
|
||||||
|
and tr.model_code = 'ABNORMAL_ACCOUNT'
|
||||||
|
and tr.bank_statement_id is null
|
||||||
|
) abnormal
|
||||||
|
<!-- order by abnormal_time desc, account.account_no asc, tr.rule_code asc -->
|
||||||
|
order by abnormal.abnormal_time desc, abnormal.account_no asc, abnormal.rule_code asc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAbnormalAccountList" resultMap="AbnormalAccountItemResultMap">
|
||||||
|
<!-- tr.model_code = 'ABNORMAL_ACCOUNT' -->
|
||||||
|
<!-- tr.bank_statement_id is null -->
|
||||||
|
<!-- account.owner_type = 'EMPLOYEE' -->
|
||||||
|
<!-- tr.reason_detail -->
|
||||||
|
<!-- order by abnormal_time desc, account.account_no asc, tr.rule_code asc -->
|
||||||
|
select
|
||||||
|
abnormal.accountNo,
|
||||||
|
abnormal.accountName,
|
||||||
|
abnormal.bankName,
|
||||||
|
abnormal.abnormalType,
|
||||||
|
abnormal.abnormal_time,
|
||||||
|
abnormal.status
|
||||||
|
from (
|
||||||
|
<include refid="abnormalAccountBaseSql"/>
|
||||||
|
where tr.project_id = #{projectId}
|
||||||
|
and tr.model_code = 'ABNORMAL_ACCOUNT'
|
||||||
|
and tr.bank_statement_id is null
|
||||||
|
) abnormal
|
||||||
|
<!-- order by abnormal_time desc, account.account_no asc, tr.rule_code asc -->
|
||||||
|
order by abnormal.abnormal_time desc, abnormal.account_no asc, abnormal.rule_code asc
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="selectRiskModelNamesByScope" resultType="java.lang.String">
|
<select id="selectRiskModelNamesByScope" resultType="java.lang.String">
|
||||||
select
|
select
|
||||||
json_unquote(json_extract(result.model_hit_summary_json, concat('$[', idx.idx, '].modelName'))) as model_name
|
json_unquote(json_extract(result.model_hit_summary_json, concat('$[', idx.idx, '].modelName'))) as model_name
|
||||||
@@ -741,7 +836,6 @@
|
|||||||
|
|
||||||
<select id="selectPersonAnalysisObjectRows" resultType="com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisObjectRecordVO">
|
<select id="selectPersonAnalysisObjectRows" resultType="com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisObjectRecordVO">
|
||||||
select
|
select
|
||||||
max(tr.model_code) as modelCode,
|
|
||||||
coalesce(max(staff.name), max(relation.relation_name), max(tr.object_key), max(tr.object_type)) as title,
|
coalesce(max(staff.name), max(relation.relation_name), max(tr.object_key), max(tr.object_type)) as title,
|
||||||
max(case
|
max(case
|
||||||
when tr.object_type = 'STAFF_ID_CARD' then '员工对象'
|
when tr.object_type = 'STAFF_ID_CARD' then '员工对象'
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -126,6 +127,26 @@ class CcdiProjectOverviewControllerContractTest {
|
|||||||
assertEquals(AjaxResult.class, method.getReturnType());
|
assertEquals(AjaxResult.class, method.getReturnType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldExposeAbnormalAccountPeopleEndpointContract() throws Exception {
|
||||||
|
Class<?> controllerClass = Class.forName("com.ruoyi.ccdi.project.controller.CcdiProjectOverviewController");
|
||||||
|
Class<?> queryDtoClass =
|
||||||
|
Class.forName("com.ruoyi.ccdi.project.domain.dto.CcdiProjectAbnormalAccountQueryDTO");
|
||||||
|
|
||||||
|
Method method = controllerClass.getMethod("getAbnormalAccountPeople", queryDtoClass);
|
||||||
|
GetMapping getMapping = method.getAnnotation(GetMapping.class);
|
||||||
|
Operation operation = method.getAnnotation(Operation.class);
|
||||||
|
PreAuthorize preAuthorize = method.getAnnotation(PreAuthorize.class);
|
||||||
|
|
||||||
|
assertNotNull(getMapping);
|
||||||
|
assertEquals("/abnormal-account-people", getMapping.value()[0]);
|
||||||
|
assertNotNull(operation);
|
||||||
|
assertEquals("查询异常账户人员信息", operation.summary());
|
||||||
|
assertNotNull(preAuthorize);
|
||||||
|
assertEquals("@ss.hasPermi('ccdi:project:query')", preAuthorize.value());
|
||||||
|
assertEquals(queryDtoClass, method.getParameterTypes()[0]);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldExposeSuspiciousTransactionsExportEndpointContract() throws Exception {
|
void shouldExposeSuspiciousTransactionsExportEndpointContract() throws Exception {
|
||||||
Class<?> controllerClass = Class.forName("com.ruoyi.ccdi.project.controller.CcdiProjectOverviewController");
|
Class<?> controllerClass = Class.forName("com.ruoyi.ccdi.project.controller.CcdiProjectOverviewController");
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.ruoyi.ccdi.project.controller;
|
package com.ruoyi.ccdi.project.controller;
|
||||||
|
|
||||||
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectAbnormalAccountQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountPageVO;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectRiskPeopleOverviewExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectRiskPeopleOverviewExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativePageVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativePageVO;
|
||||||
@@ -244,6 +246,36 @@ class CcdiProjectOverviewControllerTest {
|
|||||||
assertNotNull(operation);
|
assertNotNull(operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldExposeAbnormalAccountPeopleEndpoint() throws Exception {
|
||||||
|
CcdiProjectAbnormalAccountQueryDTO queryDTO = new CcdiProjectAbnormalAccountQueryDTO();
|
||||||
|
queryDTO.setProjectId(40L);
|
||||||
|
|
||||||
|
CcdiProjectAbnormalAccountPageVO pageVO = new CcdiProjectAbnormalAccountPageVO();
|
||||||
|
when(overviewService.getAbnormalAccountPeople(queryDTO)).thenReturn(pageVO);
|
||||||
|
|
||||||
|
AjaxResult result = controller.getAbnormalAccountPeople(queryDTO);
|
||||||
|
|
||||||
|
assertEquals(200, result.get("code"));
|
||||||
|
assertEquals(pageVO, result.get("data"));
|
||||||
|
verify(overviewService).getAbnormalAccountPeople(same(queryDTO));
|
||||||
|
|
||||||
|
Method method = CcdiProjectOverviewController.class.getMethod(
|
||||||
|
"getAbnormalAccountPeople",
|
||||||
|
CcdiProjectAbnormalAccountQueryDTO.class
|
||||||
|
);
|
||||||
|
GetMapping getMapping = method.getAnnotation(GetMapping.class);
|
||||||
|
PreAuthorize preAuthorize = method.getAnnotation(PreAuthorize.class);
|
||||||
|
Operation operation = method.getAnnotation(Operation.class);
|
||||||
|
|
||||||
|
assertNotNull(getMapping);
|
||||||
|
assertEquals("/abnormal-account-people", getMapping.value()[0]);
|
||||||
|
assertNotNull(preAuthorize);
|
||||||
|
assertEquals("@ss.hasPermi('ccdi:project:query')", preAuthorize.value());
|
||||||
|
assertNotNull(operation);
|
||||||
|
assertEquals("查询异常账户人员信息", operation.summary());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldExposeSuspiciousTransactionsExportEndpoint() throws Exception {
|
void shouldExposeSuspiciousTransactionsExportEndpoint() throws Exception {
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|||||||
@@ -121,6 +121,36 @@ class CcdiProjectOverviewMapperSqlTest {
|
|||||||
assertFalse(employeeCreditExportSql.contains("ccdi_debts_info"), employeeCreditExportSql);
|
assertFalse(employeeCreditExportSql.contains("ccdi_debts_info"), employeeCreditExportSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldExposeAbnormalAccountQueries() throws Exception {
|
||||||
|
String xml = Files.readString(Path.of("src/main/resources/mapper/ccdi/project/CcdiProjectOverviewMapper.xml"));
|
||||||
|
String abnormalPageSql = extractSelect(xml, "selectAbnormalAccountPage");
|
||||||
|
String abnormalExportSql = extractSelect(xml, "selectAbnormalAccountList");
|
||||||
|
|
||||||
|
assertTrue(abnormalPageSql.contains("tr.model_code = 'ABNORMAL_ACCOUNT'"), abnormalPageSql);
|
||||||
|
assertTrue(abnormalPageSql.contains("tr.bank_statement_id is null"), abnormalPageSql);
|
||||||
|
assertTrue(abnormalPageSql.contains("account.owner_type = 'EMPLOYEE'"), abnormalPageSql);
|
||||||
|
assertTrue(abnormalPageSql.contains("tr.reason_detail"), abnormalPageSql);
|
||||||
|
assertTrue(abnormalPageSql.contains("instr(tr.reason_detail, account.account_no) > 0"), abnormalPageSql);
|
||||||
|
assertTrue(abnormalPageSql.contains("when account.status = 1 then '正常'"), abnormalPageSql);
|
||||||
|
assertTrue(abnormalPageSql.contains("when account.status = 2 then '已销户'"), abnormalPageSql);
|
||||||
|
assertTrue(abnormalPageSql.contains("when tr.rule_code = 'SUDDEN_ACCOUNT_CLOSURE'"), abnormalPageSql);
|
||||||
|
assertTrue(abnormalPageSql.contains("when tr.rule_code = 'DORMANT_ACCOUNT_LARGE_ACTIVATION'"), abnormalPageSql);
|
||||||
|
assertTrue(
|
||||||
|
abnormalPageSql.contains("order by abnormal_time desc, account.account_no asc, tr.rule_code asc"),
|
||||||
|
abnormalPageSql
|
||||||
|
);
|
||||||
|
|
||||||
|
assertTrue(abnormalExportSql.contains("tr.model_code = 'ABNORMAL_ACCOUNT'"), abnormalExportSql);
|
||||||
|
assertTrue(abnormalExportSql.contains("tr.bank_statement_id is null"), abnormalExportSql);
|
||||||
|
assertTrue(abnormalExportSql.contains("account.owner_type = 'EMPLOYEE'"), abnormalExportSql);
|
||||||
|
assertTrue(abnormalExportSql.contains("tr.reason_detail"), abnormalExportSql);
|
||||||
|
assertTrue(
|
||||||
|
abnormalExportSql.contains("order by abnormal_time desc, account.account_no asc, tr.rule_code asc"),
|
||||||
|
abnormalExportSql
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private String extractSelect(String xml, String selectId) {
|
private String extractSelect(String xml, String selectId) {
|
||||||
String start = "<select id=\"" + selectId + "\"";
|
String start = "<select id=\"" + selectId + "\"";
|
||||||
int startIndex = xml.indexOf(start);
|
int startIndex = xml.indexOf(start);
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
@@ -406,6 +408,112 @@ class CcdiBankTagServiceImplTest {
|
|||||||
verify(analysisMapper).selectSalaryUnusedObjects(40L);
|
verify(analysisMapper).selectSalaryUnusedObjects(40L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rebuildProject_shouldDispatchSuddenAccountClosureObjectRule() {
|
||||||
|
ReflectionTestUtils.setField(service, "tagRuleExecutor", (Executor) Runnable::run);
|
||||||
|
|
||||||
|
CcdiBankTagRule rule = buildRule("ABNORMAL_ACCOUNT", "异常账户",
|
||||||
|
"SUDDEN_ACCOUNT_CLOSURE", "突然销户", "OBJECT");
|
||||||
|
|
||||||
|
when(ruleMapper.selectEnabledRules("ABNORMAL_ACCOUNT")).thenReturn(List.of(rule));
|
||||||
|
when(configResolver.resolve(40L, rule)).thenReturn(buildConfig(40L, rule));
|
||||||
|
when(analysisMapper.selectSuddenAccountClosureObjects(40L)).thenReturn(List.of());
|
||||||
|
|
||||||
|
service.rebuildProject(40L, "ABNORMAL_ACCOUNT", "admin", TriggerType.MANUAL);
|
||||||
|
|
||||||
|
verify(analysisMapper).selectSuddenAccountClosureObjects(40L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rebuildProject_shouldDispatchDormantAccountLargeActivationObjectRule() {
|
||||||
|
ReflectionTestUtils.setField(service, "tagRuleExecutor", (Executor) Runnable::run);
|
||||||
|
|
||||||
|
CcdiBankTagRule rule = buildRule("ABNORMAL_ACCOUNT", "异常账户",
|
||||||
|
"DORMANT_ACCOUNT_LARGE_ACTIVATION", "休眠账户大额启用", "OBJECT");
|
||||||
|
|
||||||
|
when(ruleMapper.selectEnabledRules("ABNORMAL_ACCOUNT")).thenReturn(List.of(rule));
|
||||||
|
when(configResolver.resolve(40L, rule)).thenReturn(buildConfig(40L, rule));
|
||||||
|
when(analysisMapper.selectDormantAccountLargeActivationObjects(40L)).thenReturn(List.of());
|
||||||
|
|
||||||
|
service.rebuildProject(40L, "ABNORMAL_ACCOUNT", "admin", TriggerType.MANUAL);
|
||||||
|
|
||||||
|
verify(analysisMapper).selectDormantAccountLargeActivationObjects(40L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rebuildProject_shouldInsertSuddenAccountClosureObjectResults() {
|
||||||
|
ReflectionTestUtils.setField(service, "tagRuleExecutor", (Executor) Runnable::run);
|
||||||
|
|
||||||
|
CcdiBankTagRule rule = buildRule("ABNORMAL_ACCOUNT", "异常账户",
|
||||||
|
"SUDDEN_ACCOUNT_CLOSURE", "突然销户", "OBJECT");
|
||||||
|
BankTagRuleExecutionConfig config = buildConfig(40L, rule);
|
||||||
|
|
||||||
|
BankTagObjectHitVO hit = new BankTagObjectHitVO();
|
||||||
|
hit.setObjectType("STAFF_ID_CARD");
|
||||||
|
hit.setObjectKey("330101199001011234");
|
||||||
|
hit.setReasonDetail("账户62220001于2026-03-15销户,销户前30天内最后交易日2026-03-10,累计交易金额120000元,单笔最大金额80000元");
|
||||||
|
|
||||||
|
when(ruleMapper.selectEnabledRules("ABNORMAL_ACCOUNT")).thenReturn(List.of(rule));
|
||||||
|
when(configResolver.resolve(40L, rule)).thenReturn(config);
|
||||||
|
when(analysisMapper.selectSuddenAccountClosureObjects(40L)).thenReturn(List.of(hit));
|
||||||
|
|
||||||
|
service.rebuildProject(40L, "ABNORMAL_ACCOUNT", "admin", TriggerType.MANUAL);
|
||||||
|
|
||||||
|
verify(resultMapper).insertBatch(argThat(results -> results.stream().anyMatch(item ->
|
||||||
|
"ABNORMAL_ACCOUNT".equals(item.getModelCode())
|
||||||
|
&& "SUDDEN_ACCOUNT_CLOSURE".equals(item.getRuleCode())
|
||||||
|
&& "OBJECT".equals(item.getResultType())
|
||||||
|
&& "STAFF_ID_CARD".equals(item.getObjectType())
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rebuildProject_shouldInsertDormantAccountLargeActivationObjectResults() {
|
||||||
|
ReflectionTestUtils.setField(service, "tagRuleExecutor", (Executor) Runnable::run);
|
||||||
|
|
||||||
|
CcdiBankTagRule rule = buildRule("ABNORMAL_ACCOUNT", "异常账户",
|
||||||
|
"DORMANT_ACCOUNT_LARGE_ACTIVATION", "休眠账户大额启用", "OBJECT");
|
||||||
|
BankTagRuleExecutionConfig config = buildConfig(40L, rule);
|
||||||
|
|
||||||
|
BankTagObjectHitVO hit = new BankTagObjectHitVO();
|
||||||
|
hit.setObjectType("STAFF_ID_CARD");
|
||||||
|
hit.setObjectKey("330101199001011235");
|
||||||
|
hit.setReasonDetail("账户62220002开户于2025-01-01,首次交易日期2025-08-01,沉睡时长7个月,启用后累计交易金额500000元,单笔最大金额120000元");
|
||||||
|
|
||||||
|
when(ruleMapper.selectEnabledRules("ABNORMAL_ACCOUNT")).thenReturn(List.of(rule));
|
||||||
|
when(configResolver.resolve(40L, rule)).thenReturn(config);
|
||||||
|
when(analysisMapper.selectDormantAccountLargeActivationObjects(40L)).thenReturn(List.of(hit));
|
||||||
|
|
||||||
|
service.rebuildProject(40L, "ABNORMAL_ACCOUNT", "admin", TriggerType.MANUAL);
|
||||||
|
|
||||||
|
verify(resultMapper).insertBatch(argThat(results -> results.stream().anyMatch(item ->
|
||||||
|
"ABNORMAL_ACCOUNT".equals(item.getModelCode())
|
||||||
|
&& "DORMANT_ACCOUNT_LARGE_ACTIVATION".equals(item.getRuleCode())
|
||||||
|
&& "OBJECT".equals(item.getResultType())
|
||||||
|
&& "STAFF_ID_CARD".equals(item.getObjectType())
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void abnormalAccountMapperXml_shouldDeclareObjectSelects() throws Exception {
|
||||||
|
String xml = Files.readString(Path.of("src/main/resources/mapper/ccdi/project/CcdiBankTagAnalysisMapper.xml"));
|
||||||
|
|
||||||
|
assertTrue(xml.contains("select id=\"selectSuddenAccountClosureObjects\""));
|
||||||
|
assertTrue(xml.contains("select id=\"selectDormantAccountLargeActivationObjects\""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void dormantAccountLargeActivationMapperXml_shouldContainDormantAccountConditions() throws Exception {
|
||||||
|
String xml = Files.readString(Path.of("src/main/resources/mapper/ccdi/project/CcdiBankTagAnalysisMapper.xml"));
|
||||||
|
|
||||||
|
assertTrue(xml.contains("select id=\"selectDormantAccountLargeActivationObjects\""));
|
||||||
|
assertTrue(xml.contains("ai.owner_type = 'EMPLOYEE'"));
|
||||||
|
assertTrue(xml.contains("ai.status = 1"));
|
||||||
|
assertTrue(xml.contains("ai.effective_date is not null"));
|
||||||
|
assertTrue(xml.contains("DATE_ADD(ai.effective_date, INTERVAL 6 MONTH)"));
|
||||||
|
assertTrue(xml.contains("windowTotalAmount >= 500000") || xml.contains("windowMaxSingleAmount >= 100000"));
|
||||||
|
}
|
||||||
|
|
||||||
private CcdiBankTagRule buildRule(String modelCode, String modelName, String ruleCode, String ruleName, String resultType) {
|
private CcdiBankTagRule buildRule(String modelCode, String modelName, String ruleCode, String ruleName, String resultType) {
|
||||||
CcdiBankTagRule rule = new CcdiBankTagRule();
|
CcdiBankTagRule rule = new CcdiBankTagRule();
|
||||||
rule.setModelCode(modelCode);
|
rule.setModelCode(modelCode);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
class CcdiProjectOverviewEmployeeResultBuilderTest {
|
class CcdiProjectOverviewEmployeeResultBuilderTest {
|
||||||
|
|
||||||
@@ -38,7 +39,11 @@ class CcdiProjectOverviewEmployeeResultBuilderTest {
|
|||||||
buildHitRow(rowClass, "330000000000000001", "李四", "E1001", 12L, "信息二部",
|
buildHitRow(rowClass, "330000000000000001", "李四", "E1001", 12L, "信息二部",
|
||||||
"SUSPICIOUS_PART_TIME", "可疑兼职", "MONTHLY_FIXED_INCOME", "疑似兼职", "MEDIUM"),
|
"SUSPICIOUS_PART_TIME", "可疑兼职", "MONTHLY_FIXED_INCOME", "疑似兼职", "MEDIUM"),
|
||||||
buildHitRow(rowClass, "330000000000000001", "李四", "E1001", 12L, "信息二部",
|
buildHitRow(rowClass, "330000000000000001", "李四", "E1001", 12L, "信息二部",
|
||||||
"SUSPICIOUS_PROPERTY", "可疑财产", "HOUSE_REGISTRATION_MISMATCH", "房产登记不匹配", "LOW")
|
"SUSPICIOUS_PROPERTY", "可疑财产", "HOUSE_REGISTRATION_MISMATCH", "房产登记不匹配", "LOW"),
|
||||||
|
buildHitRow(rowClass, "330000000000000001", "李四", "E1001", 12L, "信息二部",
|
||||||
|
"ABNORMAL_ACCOUNT", "异常账户", "SUDDEN_ACCOUNT_CLOSURE", "突然销户", "HIGH"),
|
||||||
|
buildHitRow(rowClass, "330000000000000001", "李四", "E1001", 12L, "信息二部",
|
||||||
|
"ABNORMAL_ACCOUNT", "异常账户", "DORMANT_ACCOUNT_LARGE_ACTIVATION", "休眠账户大额启用", "HIGH")
|
||||||
);
|
);
|
||||||
|
|
||||||
List<CcdiProjectOverviewEmployeeResult> results =
|
List<CcdiProjectOverviewEmployeeResult> results =
|
||||||
@@ -52,20 +57,22 @@ class CcdiProjectOverviewEmployeeResultBuilderTest {
|
|||||||
assertEquals("E1001", result.getStaffCode());
|
assertEquals("E1001", result.getStaffCode());
|
||||||
assertEquals(12L, result.getDeptId());
|
assertEquals(12L, result.getDeptId());
|
||||||
assertEquals("信息二部", result.getDeptName());
|
assertEquals("信息二部", result.getDeptName());
|
||||||
assertEquals(5, result.getRuleCount());
|
assertEquals(7, result.getRuleCount());
|
||||||
assertEquals(4, result.getModelCount());
|
assertEquals(5, result.getModelCount());
|
||||||
assertEquals(7, result.getHitCount());
|
assertEquals(9, result.getHitCount());
|
||||||
assertEquals("HIGH", result.getRiskLevelCode());
|
assertEquals("HIGH", result.getRiskLevelCode());
|
||||||
assertEquals("ABNORMAL_TRANSACTION,LARGE_TRANSACTION,SUSPICIOUS_PART_TIME,SUSPICIOUS_PROPERTY",
|
assertEquals("ABNORMAL_ACCOUNT,ABNORMAL_TRANSACTION,LARGE_TRANSACTION,SUSPICIOUS_PART_TIME,SUSPICIOUS_PROPERTY",
|
||||||
result.getModelCodesCsv());
|
result.getModelCodesCsv());
|
||||||
assertNotNull(result.getRiskPoint());
|
assertNotNull(result.getRiskPoint());
|
||||||
|
|
||||||
JSONArray modelNames = JSON.parseArray(result.getModelNamesJson());
|
JSONArray modelNames = JSON.parseArray(result.getModelNamesJson());
|
||||||
assertEquals(List.of("异常交易", "大额交易", "可疑兼职", "可疑财产"),
|
assertEquals(List.of("异常账户", "异常交易", "大额交易", "可疑兼职", "可疑财产"),
|
||||||
modelNames.toList(String.class));
|
modelNames.toList(String.class));
|
||||||
|
|
||||||
JSONArray hitRules = JSON.parseArray(result.getHitRulesJson());
|
JSONArray hitRules = JSON.parseArray(result.getHitRulesJson());
|
||||||
assertEquals(5, hitRules.size());
|
assertEquals(7, hitRules.size());
|
||||||
|
assertTrue(result.getHitRulesJson().contains("SUDDEN_ACCOUNT_CLOSURE"));
|
||||||
|
assertTrue(result.getHitRulesJson().contains("DORMANT_ACCOUNT_LARGE_ACTIVATION"));
|
||||||
JSONObject firstRule = hitRules.getJSONObject(0);
|
JSONObject firstRule = hitRules.getJSONObject(0);
|
||||||
assertEquals("ABNORMAL_CUSTOMER_TRANSACTION", firstRule.getString("ruleCode"));
|
assertEquals("ABNORMAL_CUSTOMER_TRANSACTION", firstRule.getString("ruleCode"));
|
||||||
assertEquals("异常客户交易", firstRule.getString("ruleName"));
|
assertEquals("异常客户交易", firstRule.getString("ruleName"));
|
||||||
@@ -78,6 +85,7 @@ class CcdiProjectOverviewEmployeeResultBuilderTest {
|
|||||||
item -> item.getString("modelCode"),
|
item -> item.getString("modelCode"),
|
||||||
item -> item.getIntValue("warningCount")
|
item -> item.getIntValue("warningCount")
|
||||||
));
|
));
|
||||||
|
assertEquals(2, warningCountByModel.get("ABNORMAL_ACCOUNT"));
|
||||||
assertEquals(2, warningCountByModel.get("ABNORMAL_TRANSACTION"));
|
assertEquals(2, warningCountByModel.get("ABNORMAL_TRANSACTION"));
|
||||||
assertEquals(3, warningCountByModel.get("LARGE_TRANSACTION"));
|
assertEquals(3, warningCountByModel.get("LARGE_TRANSACTION"));
|
||||||
assertEquals(1, warningCountByModel.get("SUSPICIOUS_PROPERTY"));
|
assertEquals(1, warningCountByModel.get("SUSPICIOUS_PROPERTY"));
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
package com.ruoyi.ccdi.project.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
||||||
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectAbnormalAccountQueryDTO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectAbnormalAccountExcel;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountItemVO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountPageVO;
|
||||||
|
import com.ruoyi.ccdi.project.mapper.CcdiBankTagResultMapper;
|
||||||
|
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
|
||||||
|
import com.ruoyi.ccdi.project.mapper.CcdiProjectOverviewEmployeeResultMapper;
|
||||||
|
import com.ruoyi.ccdi.project.mapper.CcdiProjectOverviewMapper;
|
||||||
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.argThat;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class CcdiProjectOverviewServiceAbnormalAccountTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private CcdiProjectOverviewServiceImpl service;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiProjectOverviewMapper overviewMapper;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiProjectMapper projectMapper;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiProjectOverviewEmployeeResultMapper overviewEmployeeResultMapper;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiBankTagResultMapper bankTagResultMapper;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiProjectOverviewEmployeeResultBuilder overviewEmployeeResultBuilder;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiProjectRiskDetailWorkbookExporter workbookExporter;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldMapAbnormalAccountPageRowsAndTotal() {
|
||||||
|
mockProjectExists(40L);
|
||||||
|
|
||||||
|
CcdiProjectAbnormalAccountQueryDTO queryDTO = new CcdiProjectAbnormalAccountQueryDTO();
|
||||||
|
queryDTO.setProjectId(40L);
|
||||||
|
queryDTO.setPageNum(1);
|
||||||
|
queryDTO.setPageSize(5);
|
||||||
|
|
||||||
|
CcdiProjectAbnormalAccountItemVO item = new CcdiProjectAbnormalAccountItemVO();
|
||||||
|
item.setAccountNo("6222000000000001");
|
||||||
|
item.setAccountName("李四");
|
||||||
|
item.setBankName("中国农业银行");
|
||||||
|
item.setAbnormalType("突然销户");
|
||||||
|
item.setAbnormalTime("2026-03-20");
|
||||||
|
item.setStatus("已销户");
|
||||||
|
|
||||||
|
Page<CcdiProjectAbnormalAccountItemVO> resultPage = new Page<>(1, 5);
|
||||||
|
resultPage.setRecords(List.of(item));
|
||||||
|
resultPage.setTotal(1L);
|
||||||
|
when(overviewMapper.selectAbnormalAccountPage(any(Page.class), any(CcdiProjectAbnormalAccountQueryDTO.class)))
|
||||||
|
.thenReturn(resultPage);
|
||||||
|
|
||||||
|
CcdiProjectAbnormalAccountPageVO result = service.getAbnormalAccountPeople(queryDTO);
|
||||||
|
|
||||||
|
assertEquals(1, result.getRows().size());
|
||||||
|
assertEquals(1L, result.getTotal());
|
||||||
|
assertEquals("6222000000000001", result.getRows().getFirst().getAccountNo());
|
||||||
|
assertEquals("突然销户", result.getRows().getFirst().getAbnormalType());
|
||||||
|
verify(overviewMapper).selectAbnormalAccountPage(
|
||||||
|
argThat(page -> page.getCurrent() == 1L && page.getSize() == 5L),
|
||||||
|
argThat(query -> query.getProjectId().equals(40L))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldDefaultAbnormalAccountPageNumAndPageSizeToOneAndFive() {
|
||||||
|
mockProjectExists(40L);
|
||||||
|
|
||||||
|
Page<CcdiProjectAbnormalAccountItemVO> emptyPage = new Page<>(1, 5);
|
||||||
|
emptyPage.setRecords(List.of());
|
||||||
|
emptyPage.setTotal(0L);
|
||||||
|
when(overviewMapper.selectAbnormalAccountPage(any(Page.class), any(CcdiProjectAbnormalAccountQueryDTO.class)))
|
||||||
|
.thenReturn(emptyPage);
|
||||||
|
|
||||||
|
CcdiProjectAbnormalAccountQueryDTO queryDTO = new CcdiProjectAbnormalAccountQueryDTO();
|
||||||
|
queryDTO.setProjectId(40L);
|
||||||
|
service.getAbnormalAccountPeople(queryDTO);
|
||||||
|
|
||||||
|
verify(overviewMapper).selectAbnormalAccountPage(
|
||||||
|
argThat(page -> page.getCurrent() == 1L && page.getSize() == 5L),
|
||||||
|
any(CcdiProjectAbnormalAccountQueryDTO.class)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldExportAbnormalAccountPeopleRows() {
|
||||||
|
mockProjectExists(40L);
|
||||||
|
|
||||||
|
CcdiProjectAbnormalAccountItemVO item = new CcdiProjectAbnormalAccountItemVO();
|
||||||
|
item.setAccountNo("6222000000000002");
|
||||||
|
item.setAccountName("王五");
|
||||||
|
item.setBankName("中国银行");
|
||||||
|
item.setAbnormalType("休眠账户大额启用");
|
||||||
|
item.setAbnormalTime("2025-08-01");
|
||||||
|
item.setStatus("正常");
|
||||||
|
when(overviewMapper.selectAbnormalAccountList(40L)).thenReturn(List.of(item));
|
||||||
|
|
||||||
|
List<CcdiProjectAbnormalAccountExcel> rows = service.exportAbnormalAccountPeople(40L);
|
||||||
|
|
||||||
|
assertEquals(1, rows.size());
|
||||||
|
assertEquals("6222000000000002", rows.getFirst().getAccountNo());
|
||||||
|
assertEquals("王五", rows.getFirst().getAccountName());
|
||||||
|
assertEquals("中国银行", rows.getFirst().getBankName());
|
||||||
|
assertEquals("休眠账户大额启用", rows.getFirst().getAbnormalType());
|
||||||
|
assertEquals("2025-08-01", rows.getFirst().getAbnormalTime());
|
||||||
|
assertEquals("正常", rows.getFirst().getStatus());
|
||||||
|
verify(overviewMapper).selectAbnormalAccountList(40L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldThrowWhenProjectDoesNotExistForAbnormalAccountQueries() {
|
||||||
|
when(projectMapper.selectById(99L)).thenReturn(null);
|
||||||
|
|
||||||
|
CcdiProjectAbnormalAccountQueryDTO queryDTO = new CcdiProjectAbnormalAccountQueryDTO();
|
||||||
|
queryDTO.setProjectId(99L);
|
||||||
|
|
||||||
|
assertThrows(ServiceException.class, () -> service.getAbnormalAccountPeople(queryDTO));
|
||||||
|
assertThrows(ServiceException.class, () -> service.exportAbnormalAccountPeople(99L));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mockProjectExists(Long projectId) {
|
||||||
|
CcdiProject project = new CcdiProject();
|
||||||
|
project.setProjectId(projectId);
|
||||||
|
when(projectMapper.selectById(projectId)).thenReturn(project);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,10 +5,12 @@ import com.ruoyi.ccdi.project.domain.CcdiProject;
|
|||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskPeopleQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskPeopleQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectAbnormalAccountExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectEmployeeCreditNegativeExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectEmployeeCreditNegativeExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectRiskPeopleOverviewExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectRiskPeopleOverviewExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.entity.CcdiProjectOverviewEmployeeResult;
|
import com.ruoyi.ccdi.project.domain.entity.CcdiProjectOverviewEmployeeResult;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountItemVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeRiskAggregateVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeRiskAggregateVO;
|
||||||
@@ -268,6 +270,15 @@ class CcdiProjectOverviewServiceImplTest {
|
|||||||
creditItem.setCivilLmt(new BigDecimal("20000.00"));
|
creditItem.setCivilLmt(new BigDecimal("20000.00"));
|
||||||
when(overviewMapper.selectEmployeeCreditNegativeList(40L)).thenReturn(List.of(creditItem));
|
when(overviewMapper.selectEmployeeCreditNegativeList(40L)).thenReturn(List.of(creditItem));
|
||||||
|
|
||||||
|
CcdiProjectAbnormalAccountItemVO abnormalItem = new CcdiProjectAbnormalAccountItemVO();
|
||||||
|
abnormalItem.setAccountNo("6222000000000001");
|
||||||
|
abnormalItem.setAccountName("李四");
|
||||||
|
abnormalItem.setBankName("中国农业银行");
|
||||||
|
abnormalItem.setAbnormalType("突然销户");
|
||||||
|
abnormalItem.setAbnormalTime("2026-03-20");
|
||||||
|
abnormalItem.setStatus("已销户");
|
||||||
|
when(overviewMapper.selectAbnormalAccountList(40L)).thenReturn(List.of(abnormalItem));
|
||||||
|
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
service.exportRiskDetails(response, 40L);
|
service.exportRiskDetails(response, 40L);
|
||||||
|
|
||||||
@@ -282,6 +293,9 @@ class CcdiProjectOverviewServiceImplTest {
|
|||||||
),
|
),
|
||||||
argThat((List<CcdiProjectEmployeeCreditNegativeExcel> rows) ->
|
argThat((List<CcdiProjectEmployeeCreditNegativeExcel> rows) ->
|
||||||
rows.size() == 1 && "李四".equals(rows.getFirst().getPersonName())
|
rows.size() == 1 && "李四".equals(rows.getFirst().getPersonName())
|
||||||
|
),
|
||||||
|
argThat((List<CcdiProjectAbnormalAccountExcel> rows) ->
|
||||||
|
rows.size() == 1 && "6222000000000001".equals(rows.getFirst().getAccountNo())
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.ccdi.project.service.impl;
|
package com.ruoyi.ccdi.project.service.impl;
|
||||||
|
|
||||||
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectAbnormalAccountExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectEmployeeCreditNegativeExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectEmployeeCreditNegativeExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
||||||
import org.apache.poi.ss.usermodel.WorkbookFactory;
|
import org.apache.poi.ss.usermodel.WorkbookFactory;
|
||||||
@@ -36,7 +37,15 @@ class CcdiProjectRiskDetailWorkbookExporterTest {
|
|||||||
creditRow.setCivilCnt(1);
|
creditRow.setCivilCnt(1);
|
||||||
creditRow.setCivilLmt(new BigDecimal("20000.00"));
|
creditRow.setCivilLmt(new BigDecimal("20000.00"));
|
||||||
|
|
||||||
exporter.export(response, 40L, List.of(suspiciousRow), List.of(creditRow));
|
CcdiProjectAbnormalAccountExcel abnormalRow = new CcdiProjectAbnormalAccountExcel();
|
||||||
|
abnormalRow.setAccountNo("6222000000000001");
|
||||||
|
abnormalRow.setAccountName("李四");
|
||||||
|
abnormalRow.setBankName("中国农业银行");
|
||||||
|
abnormalRow.setAbnormalType("突然销户");
|
||||||
|
abnormalRow.setAbnormalTime("2026-03-20");
|
||||||
|
abnormalRow.setStatus("已销户");
|
||||||
|
|
||||||
|
exporter.export(response, 40L, List.of(suspiciousRow), List.of(creditRow), List.of(abnormalRow));
|
||||||
|
|
||||||
assertTrue(response.getContentType().startsWith(
|
assertTrue(response.getContentType().startsWith(
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||||
@@ -48,8 +57,18 @@ class CcdiProjectRiskDetailWorkbookExporterTest {
|
|||||||
assertEquals("员工负面征信信息", workbook.getSheetAt(1).getSheetName());
|
assertEquals("员工负面征信信息", workbook.getSheetAt(1).getSheetName());
|
||||||
assertEquals("异常账户人员信息", workbook.getSheetAt(2).getSheetName());
|
assertEquals("异常账户人员信息", workbook.getSheetAt(2).getSheetName());
|
||||||
assertEquals("账号", workbook.getSheetAt(2).getRow(0).getCell(0).getStringCellValue());
|
assertEquals("账号", workbook.getSheetAt(2).getRow(0).getCell(0).getStringCellValue());
|
||||||
|
assertEquals("开户人", workbook.getSheetAt(2).getRow(0).getCell(1).getStringCellValue());
|
||||||
|
assertEquals("银行", workbook.getSheetAt(2).getRow(0).getCell(2).getStringCellValue());
|
||||||
|
assertEquals("异常类型", workbook.getSheetAt(2).getRow(0).getCell(3).getStringCellValue());
|
||||||
|
assertEquals("异常发生时间", workbook.getSheetAt(2).getRow(0).getCell(4).getStringCellValue());
|
||||||
assertEquals("状态", workbook.getSheetAt(2).getRow(0).getCell(5).getStringCellValue());
|
assertEquals("状态", workbook.getSheetAt(2).getRow(0).getCell(5).getStringCellValue());
|
||||||
assertEquals(1, workbook.getSheetAt(2).getPhysicalNumberOfRows());
|
assertEquals("6222000000000001", workbook.getSheetAt(2).getRow(1).getCell(0).getStringCellValue());
|
||||||
|
assertEquals("李四", workbook.getSheetAt(2).getRow(1).getCell(1).getStringCellValue());
|
||||||
|
assertEquals("中国农业银行", workbook.getSheetAt(2).getRow(1).getCell(2).getStringCellValue());
|
||||||
|
assertEquals("突然销户", workbook.getSheetAt(2).getRow(1).getCell(3).getStringCellValue());
|
||||||
|
assertEquals("2026-03-20", workbook.getSheetAt(2).getRow(1).getCell(4).getStringCellValue());
|
||||||
|
assertEquals("已销户", workbook.getSheetAt(2).getRow(1).getCell(5).getStringCellValue());
|
||||||
|
assertEquals(2, workbook.getSheetAt(2).getPhysicalNumberOfRows());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.ruoyi.ccdi.project.sql;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class CcdiAbnormalAccountRuleSqlMetadataTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void abnormalAccountMetadataSql_shouldContainModelAndRuleDefinitions() throws IOException {
|
||||||
|
Path path = Path.of("..", "sql", "migration",
|
||||||
|
"2026-03-31-create-ccdi-account-info-and-abnormal-account-rules.sql");
|
||||||
|
|
||||||
|
assertTrue(Files.exists(path), "异常账户模型迁移脚本应存在");
|
||||||
|
|
||||||
|
String sql = Files.readString(path, StandardCharsets.UTF_8);
|
||||||
|
assertAll(
|
||||||
|
() -> assertTrue(sql.contains("ABNORMAL_ACCOUNT")),
|
||||||
|
() -> assertTrue(sql.contains("SUDDEN_ACCOUNT_CLOSURE")),
|
||||||
|
() -> assertTrue(sql.contains("DORMANT_ACCOUNT_LARGE_ACTIVATION")),
|
||||||
|
() -> assertTrue(sql.contains("'OBJECT'"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void abnormalAccountMetadataSql_shouldContainAccountInfoTableDefinition() throws IOException {
|
||||||
|
Path path = Path.of("..", "sql", "migration",
|
||||||
|
"2026-03-31-create-ccdi-account-info-and-abnormal-account-rules.sql");
|
||||||
|
|
||||||
|
assertTrue(Files.exists(path), "异常账户模型迁移脚本应存在");
|
||||||
|
|
||||||
|
String sql = Files.readString(path, StandardCharsets.UTF_8).toLowerCase();
|
||||||
|
assertAll(
|
||||||
|
() -> assertTrue(sql.contains("create table if not exists `ccdi_account_info`")),
|
||||||
|
() -> assertTrue(sql.contains("`account_no`")),
|
||||||
|
() -> assertTrue(sql.contains("`owner_type`")),
|
||||||
|
() -> assertTrue(sql.contains("`effective_date`")),
|
||||||
|
() -> assertTrue(sql.contains("`invalid_date`"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user