变更项目缩写

This commit is contained in:
wkc
2026-01-30 14:15:21 +08:00
parent e99b05acc2
commit 29a2e60ee1
107 changed files with 1134 additions and 990 deletions

62
ruoyi-ccdi/pom.xml Normal file
View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.9.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-ccdi</artifactId>
<description>
纪检初核系统模块
</description>
<dependencies>
<!-- 通用工具-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
</dependency>
<!-- easyexcel工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- spring-doc -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,134 @@
package com.ruoyi.ccdi.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.domain.dto.CcdiEmployeeAddDTO;
import com.ruoyi.ccdi.domain.dto.CcdiEmployeeEditDTO;
import com.ruoyi.ccdi.domain.dto.CcdiEmployeeQueryDTO;
import com.ruoyi.ccdi.domain.excel.CcdiEmployeeExcel;
import com.ruoyi.ccdi.domain.vo.CcdiEmployeeVO;
import com.ruoyi.ccdi.service.ICcdiEmployeeService;
import com.ruoyi.ccdi.utils.EasyExcelUtil;
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 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.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* 员工信息Controller
*
* @author ruoyi
* @date 2026-01-28
*/
@Tag(name = "员工信息管理")
@RestController
@RequestMapping("/ccdi/employee")
public class CcdiEmployeeController extends BaseController {
@Resource
private ICcdiEmployeeService employeeService;
/**
* 查询员工列表
*/
@Operation(summary = "查询员工列表")
@PreAuthorize("@ss.hasPermi('ccdi:employee:list')")
@GetMapping("/list")
public TableDataInfo list(CcdiEmployeeQueryDTO queryDTO) {
// 使用MyBatis Plus分页
PageDomain pageDomain = TableSupport.buildPageRequest();
Page<CcdiEmployeeVO> page = new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize());
Page<CcdiEmployeeVO> result = employeeService.selectEmployeePage(page, queryDTO);
return getDataTable(result.getRecords(), result.getTotal());
}
/**
* 导出员工列表
*/
@Operation(summary = "导出员工列表")
@PreAuthorize("@ss.hasPermi('ccdi:employee:export')")
@Log(title = "员工信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, CcdiEmployeeQueryDTO queryDTO) {
List<CcdiEmployeeExcel> list = employeeService.selectEmployeeListForExport(queryDTO);
EasyExcelUtil.exportExcel(response, list, CcdiEmployeeExcel.class, "员工信息");
}
/**
* 获取员工详细信息
*/
@Operation(summary = "获取员工详细信息")
@PreAuthorize("@ss.hasPermi('ccdi:employee:query')")
@GetMapping(value = "/{employeeId}")
public AjaxResult getInfo(@PathVariable Long employeeId) {
return success(employeeService.selectEmployeeById(employeeId));
}
/**
* 新增员工
*/
@Operation(summary = "新增员工")
@PreAuthorize("@ss.hasPermi('ccdi:employee:add')")
@Log(title = "员工信息", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody CcdiEmployeeAddDTO addDTO) {
return toAjax(employeeService.insertEmployee(addDTO));
}
/**
* 修改员工
*/
@Operation(summary = "修改员工")
@PreAuthorize("@ss.hasPermi('ccdi:employee:edit')")
@Log(title = "员工信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody CcdiEmployeeEditDTO editDTO) {
return toAjax(employeeService.updateEmployee(editDTO));
}
/**
* 删除员工
*/
@Operation(summary = "删除员工")
@PreAuthorize("@ss.hasPermi('ccdi:employee:remove')")
@Log(title = "员工信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{employeeIds}")
public AjaxResult remove(@PathVariable Long[] employeeIds) {
return toAjax(employeeService.deleteEmployeeByIds(employeeIds));
}
/**
* 下载带字典下拉框的导入模板
* 使用@DictDropdown注解自动添加下拉框
*/
@Operation(summary = "下载导入模板")
@PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response) {
EasyExcelUtil.importTemplateWithDictDropdown(response, CcdiEmployeeExcel.class, "员工信息");
}
/**
* 导入员工信息
*/
@Operation(summary = "导入员工信息")
@PreAuthorize("@ss.hasPermi('ccdi:employee:import')")
@Log(title = "员工信息", businessType = BusinessType.IMPORT)
@PostMapping("/importData")
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
List<CcdiEmployeeExcel> list = EasyExcelUtil.importExcel(file.getInputStream(), CcdiEmployeeExcel.class);
String message = employeeService.importEmployee(list, updateSupport);
return success(message);
}
}

View File

@@ -0,0 +1,154 @@
package com.ruoyi.ccdi.controller;
import com.ruoyi.ccdi.domain.vo.EnumOptionVO;
import com.ruoyi.ccdi.enums.*;
import com.ruoyi.common.core.domain.AjaxResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* DPC枚举接口Controller
*
* @author ruoyi
*/
@Tag(name = "DPC枚举接口", description = "中介黑名单相关枚举选项接口")
@RestController
@RequestMapping("/ccdi/enum")
public class CcdiEnumController {
/**
* 获取人员类型选项
*/
@Operation(summary = "获取人员类型选项")
@GetMapping("/indivType")
public AjaxResult getIndivTypeOptions() {
List<EnumOptionVO> options = new ArrayList<>();
for (IndivType type : IndivType.values()) {
options.add(new EnumOptionVO(type.getCode(), type.getDesc()));
}
return AjaxResult.success(options);
}
/**
* 获取人员子类型选项
*/
@Operation(summary = "获取人员子类型选项")
@GetMapping("/indivSubType")
public AjaxResult getIndivSubTypeOptions() {
List<EnumOptionVO> options = new ArrayList<>();
for (IndivSubType type : IndivSubType.values()) {
options.add(new EnumOptionVO(type.getCode(), type.getDesc()));
}
return AjaxResult.success(options);
}
/**
* 获取性别选项
*/
@Operation(summary = "获取性别选项")
@GetMapping("/gender")
public AjaxResult getGenderOptions() {
List<EnumOptionVO> options = new ArrayList<>();
for (Gender gender : Gender.values()) {
options.add(new EnumOptionVO(gender.getCode(), gender.getDesc()));
}
return AjaxResult.success(options);
}
/**
* 获取证件类型选项
*/
@Operation(summary = "获取证件类型选项")
@GetMapping("/certType")
public AjaxResult getCertTypeOptions() {
List<EnumOptionVO> options = new ArrayList<>();
for (CertType type : CertType.values()) {
options.add(new EnumOptionVO(type.getCode(), type.getDesc()));
}
return AjaxResult.success(options);
}
/**
* 获取关联关系选项
*/
@Operation(summary = "获取关联关系选项")
@GetMapping("/relationType")
public AjaxResult getRelationTypeOptions() {
List<EnumOptionVO> options = new ArrayList<>();
for (RelationType type : RelationType.values()) {
options.add(new EnumOptionVO(type.getCode(), type.getDesc()));
}
return AjaxResult.success(options);
}
/**
* 获取主体类型选项
*/
@Operation(summary = "获取主体类型选项")
@GetMapping("/corpType")
public AjaxResult getCorpTypeOptions() {
List<EnumOptionVO> options = new ArrayList<>();
for (CorpType type : CorpType.values()) {
options.add(new EnumOptionVO(type.getCode(), type.getDesc()));
}
return AjaxResult.success(options);
}
/**
* 获取企业性质选项
*/
@Operation(summary = "获取企业性质选项")
@GetMapping("/corpNature")
public AjaxResult getCorpNatureOptions() {
List<EnumOptionVO> options = new ArrayList<>();
for (CorpNature nature : CorpNature.values()) {
options.add(new EnumOptionVO(nature.getCode(), nature.getDesc()));
}
return AjaxResult.success(options);
}
/**
* 获取中介类型选项
*/
@Operation(summary = "获取中介类型选项")
@GetMapping("/intermediaryType")
public AjaxResult getIntermediaryTypeOptions() {
List<EnumOptionVO> options = new ArrayList<>();
for (IntermediaryType type : IntermediaryType.values()) {
options.add(new EnumOptionVO(type.getCode(), type.getDesc()));
}
return AjaxResult.success(options);
}
/**
* 获取中介状态选项
*/
@Operation(summary = "获取中介状态选项")
@GetMapping("/intermediaryStatus")
public AjaxResult getIntermediaryStatusOptions() {
List<EnumOptionVO> options = new ArrayList<>();
for (IntermediaryStatus status : IntermediaryStatus.values()) {
options.add(new EnumOptionVO(status.getCode(), status.getDesc()));
}
return AjaxResult.success(options);
}
/**
* 获取数据来源选项
*/
@Operation(summary = "获取数据来源选项")
@GetMapping("/dataSource")
public AjaxResult getDataSourceOptions() {
List<EnumOptionVO> options = new ArrayList<>();
for (DataSource source : DataSource.values()) {
options.add(new EnumOptionVO(source.getCode(), source.getDesc()));
}
return AjaxResult.success(options);
}
}

View File

@@ -0,0 +1,202 @@
package com.ruoyi.ccdi.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.domain.CcdiIntermediaryBlacklist;
import com.ruoyi.ccdi.domain.dto.*;
import com.ruoyi.ccdi.domain.excel.CcdiIntermediaryBlacklistExcel;
import com.ruoyi.ccdi.domain.excel.CcdiIntermediaryEntityExcel;
import com.ruoyi.ccdi.domain.excel.CcdiIntermediaryPersonExcel;
import com.ruoyi.ccdi.domain.vo.CcdiIntermediaryBlacklistVO;
import com.ruoyi.ccdi.service.ICcdiIntermediaryBlacklistService;
import com.ruoyi.ccdi.utils.EasyExcelUtil;
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 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.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* 中介人员黑名单Controller
*
* @author ruoyi
* @date 2026-01-27
*/
@Tag(name = "中介黑名单管理")
@RestController
@RequestMapping("/ccdi/intermediary")
public class CcdiIntermediaryBlacklistController extends BaseController {
@Resource
private ICcdiIntermediaryBlacklistService intermediaryService;
/**
* 查询中介黑名单列表
*/
@Operation(summary = "查询中介黑名单列表")
@PreAuthorize("@ss.hasPermi('ccdi:intermediary:list')")
@GetMapping("/list")
public TableDataInfo list(CcdiIntermediaryBlacklistQueryDTO queryDTO) {
// 使用MyBatis Plus分页
PageDomain pageDomain = TableSupport.buildPageRequest();
Page<CcdiIntermediaryBlacklist> page = new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize());
Page<CcdiIntermediaryBlacklistVO> result = intermediaryService.selectIntermediaryPage(page, queryDTO);
return getDataTable(result.getRecords(), result.getTotal());
}
/**
* 导出中介黑名单列表
*/
@Operation(summary = "导出中介黑名单列表")
@PreAuthorize("@ss.hasPermi('ccdi:intermediary:export')")
@Log(title = "中介黑名单", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, CcdiIntermediaryBlacklistQueryDTO queryDTO) {
List<CcdiIntermediaryBlacklistExcel> list = intermediaryService.selectIntermediaryListForExport(queryDTO);
EasyExcelUtil.exportExcel(response, list, CcdiIntermediaryBlacklistExcel.class, "中介黑名单");
}
/**
* 获取中介黑名单详细信息(根据类型返回不同结构)
*/
@Operation(summary = "获取中介黑名单详细信息")
@PreAuthorize("@ss.hasPermi('ccdi:intermediary:query')")
@GetMapping(value = "/{intermediaryId}")
public AjaxResult getInfo(@PathVariable Long intermediaryId) {
return success(intermediaryService.selectIntermediaryDetailById(intermediaryId));
}
/**
* 新增中介黑名单(已废弃,请使用类型专用接口)
*/
@Operation(summary = "新增中介黑名单(已废弃,请使用类型专用接口)")
@PreAuthorize("@ss.hasPermi('ccdi:intermediary:add')")
@Log(title = "中介黑名单", businessType = BusinessType.INSERT)
@PostMapping
@Deprecated
public AjaxResult add(@Validated @RequestBody CcdiIntermediaryBlacklistAddDTO addDTO) {
return toAjax(intermediaryService.insertIntermediary(addDTO));
}
/**
* 新增个人中介黑名单
*/
@Operation(summary = "新增个人中介黑名单")
@PreAuthorize("@ss.hasPermi('ccdi:intermediary:add')")
@Log(title = "个人中介黑名单", businessType = BusinessType.INSERT)
@PostMapping("/person")
public AjaxResult addPerson(@Validated @RequestBody CcdiIntermediaryPersonAddDTO addDTO) {
return toAjax(intermediaryService.insertPersonIntermediary(addDTO));
}
/**
* 新增机构中介黑名单
*/
@Operation(summary = "新增机构中介黑名单")
@PreAuthorize("@ss.hasPermi('ccdi:intermediary:add')")
@Log(title = "机构中介黑名单", businessType = BusinessType.INSERT)
@PostMapping("/entity")
public AjaxResult addEntity(@Validated @RequestBody CcdiIntermediaryEntityAddDTO addDTO) {
return toAjax(intermediaryService.insertEntityIntermediary(addDTO));
}
/**
* 修改中介黑名单
*/
@Operation(summary = "修改中介黑名单(已废弃,请使用类型专用接口)")
@PreAuthorize("@ss.hasPermi('ccdi:intermediary:edit')")
@Log(title = "中介黑名单", businessType = BusinessType.UPDATE)
@PutMapping
@Deprecated
public AjaxResult edit(@Validated @RequestBody CcdiIntermediaryBlacklistEditDTO editDTO) {
return toAjax(intermediaryService.updateIntermediary(editDTO));
}
/**
* 修改个人中介黑名单
*/
@Operation(summary = "修改个人中介黑名单")
@PreAuthorize("@ss.hasPermi('ccdi:intermediary:edit')")
@Log(title = "个人中介黑名单", businessType = BusinessType.UPDATE)
@PutMapping("/person")
public AjaxResult editPerson(@Validated @RequestBody CcdiIntermediaryPersonEditDTO editDTO) {
return toAjax(intermediaryService.updatePersonIntermediary(editDTO));
}
/**
* 修改机构中介黑名单
*/
@Operation(summary = "修改机构中介黑名单")
@PreAuthorize("@ss.hasPermi('ccdi:intermediary:edit')")
@Log(title = "机构中介黑名单", businessType = BusinessType.UPDATE)
@PutMapping("/entity")
public AjaxResult editEntity(@Validated @RequestBody CcdiIntermediaryEntityEditDTO editDTO) {
return toAjax(intermediaryService.updateEntityIntermediary(editDTO));
}
/**
* 删除中介黑名单
*/
@Operation(summary = "删除中介黑名单")
@PreAuthorize("@ss.hasPermi('ccdi:intermediary:remove')")
@Log(title = "中介黑名单", businessType = BusinessType.DELETE)
@DeleteMapping("/{intermediaryIds}")
public AjaxResult remove(@PathVariable Long[] intermediaryIds) {
return toAjax(intermediaryService.deleteIntermediaryByIds(intermediaryIds));
}
/**
* 下载个人中介导入模板(带字典下拉框)
*/
@Operation(summary = "下载个人中介导入模板")
@PostMapping("/importPersonTemplate")
public void importPersonTemplate(HttpServletResponse response) {
EasyExcelUtil.importTemplateWithDictDropdown(response, CcdiIntermediaryPersonExcel.class, "个人中介黑名单");
}
/**
* 下载机构中介导入模板(带字典下拉框)
*/
@Operation(summary = "下载机构中介导入模板")
@PostMapping("/importEntityTemplate")
public void importEntityTemplate(HttpServletResponse response) {
EasyExcelUtil.importTemplateWithDictDropdown(response, CcdiIntermediaryEntityExcel.class, "机构中介黑名单");
}
/**
* 导入个人中介黑名单
*/
@Operation(summary = "导入个人中介黑名单")
@PreAuthorize("@ss.hasPermi('ccdi:intermediary:import')")
@Log(title = "中介黑名单", businessType = BusinessType.IMPORT)
@PostMapping("/importPersonData")
public AjaxResult importPersonData(@RequestParam("file") MultipartFile file, @RequestParam(value = "updateSupport", defaultValue = "false") boolean updateSupport) throws Exception {
List<CcdiIntermediaryPersonExcel> list = EasyExcelUtil.importExcel(file.getInputStream(), CcdiIntermediaryPersonExcel.class);
String message = intermediaryService.importPersonIntermediary(list, updateSupport);
return success(message);
}
/**
* 导入机构中介黑名单
*/
@Operation(summary = "导入机构中介黑名单")
@PreAuthorize("@ss.hasPermi('ccdi:intermediary:import')")
@Log(title = "中介黑名单", businessType = BusinessType.IMPORT)
@PostMapping("/importEntityData")
public AjaxResult importEntityData(@RequestParam("file") MultipartFile file, @RequestParam(value = "updateSupport", defaultValue = "false") boolean updateSupport) throws Exception {
List<CcdiIntermediaryEntityExcel> list = EasyExcelUtil.importExcel(file.getInputStream(), CcdiIntermediaryEntityExcel.class);
String message = intermediaryService.importEntityIntermediary(list, updateSupport);
return success(message);
}
}

View File

@@ -0,0 +1,65 @@
package com.ruoyi.ccdi.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 lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 员工信息对象 dpc_employee
*
* @author ruoyi
* @date 2026-01-28
*/
@Data
public class CcdiEmployee implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 员工ID */
@TableId(type = IdType.AUTO)
private Long employeeId;
/** 姓名 */
private String name;
/** 柜员号 */
private String tellerNo;
/** 所属部门ID */
private Long deptId;
/** 身份证号 */
private String idCard;
/** 电话 */
private String phone;
/** 入职时间 */
private Date hireDate;
/** 状态 */
private String status;
/** 创建者 */
@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;
}

View File

@@ -0,0 +1,59 @@
package com.ruoyi.ccdi.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 lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 员工亲属对象 dpc_employee_relative
*
* @author ruoyi
* @date 2026-01-28
*/
@Data
public class CcdiEmployeeRelative implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 亲属ID */
@TableId(type = IdType.AUTO)
private Long relativeId;
/** 员工ID */
private Long employeeId;
/** 亲属姓名 */
private String relativeName;
/** 亲属身份证号 */
private String relativeIdCard;
/** 亲属手机号 */
private String relativePhone;
/** 与员工关系 */
private String relationship;
/** 创建者 */
@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;
}

View File

@@ -0,0 +1,154 @@
package com.ruoyi.ccdi.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 lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 中介人员黑名单对象 dpc_intermediary_blacklist
*
* @author ruoyi
* @date 2026-01-27
*/
@Data
public class CcdiIntermediaryBlacklist implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 中介ID */
@TableId(type = IdType.AUTO)
private Long intermediaryId;
/** 姓名/机构名称 */
private String name;
/** 证件号 */
private String certificateNo;
/** 中介类型 */
private String intermediaryType;
/** 状态 */
private String status;
/** 备注 */
private String remark;
// ============================================================
// 个人类型字段 (以 indiv_ 前缀标识individual 缩写)
// ============================================================
/** 人员类型(中介、职业背债人、房产中介等) */
private String indivType;
/** 人员子类型(本人、配偶等) */
private String indivSubType;
/** 性别M男 F女 O其他 */
private String indivGender;
/** 证件类型 */
private String indivCertType;
/** 手机号码(加密存储) */
private String indivPhone;
/** 微信号 */
private String indivWechat;
/** 联系地址 */
private String indivAddress;
/** 所在公司 */
private String indivCompany;
/** 职位/职务 */
private String indivPosition;
/** 关联人员ID */
private String indivRelatedId;
/** 关联关系 */
private String indivRelation;
// ============================================================
// 机构类型字段 (以 corp_ 前缀标识corporation 缩写)
// ============================================================
/** 统一社会信用代码 */
private String corpCreditCode;
/** 主体类型(有限责任公司、股份有限公司等) */
private String corpType;
/** 企业性质(国企、民企、外企等) */
private String corpNature;
/** 行业分类 */
private String corpIndustryCategory;
/** 所属行业 */
private String corpIndustry;
/** 成立日期 */
private Date corpEstablishDate;
/** 注册地址 */
private String corpAddress;
/** 法定代表人 */
private String corpLegalRep;
/** 法定代表人证件类型 */
private String corpLegalCertType;
/** 法定代表人证件号码 */
private String corpLegalCertNo;
/** 股东1 */
@TableField("corp_shareholder_1")
private String corpShareholder1;
/** 股东2 */
@TableField("corp_shareholder_2")
private String corpShareholder2;
/** 股东3 */
@TableField("corp_shareholder_3")
private String corpShareholder3;
/** 股东4 */
@TableField("corp_shareholder_4")
private String corpShareholder4;
/** 股东5 */
@TableField("corp_shareholder_5")
private String corpShareholder5;
// ============================================================
// 通用字段
// ============================================================
/** 数据来源MANUAL手动录入 SYSTEM系统同步 IMPORT批量导入 API接口获取 */
private String dataSource;
/** 创建者 */
@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;
}

View File

@@ -0,0 +1,56 @@
package com.ruoyi.ccdi.domain.dto;
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;
import java.util.List;
/**
* 员工信息新增 DTO
*
* @author ruoyi
* @date 2026-01-28
*/
@Data
public class CcdiEmployeeAddDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 姓名 */
@NotBlank(message = "姓名不能为空")
@Size(max = 100, message = "姓名长度不能超过100个字符")
private String name;
/** 柜员号 */
@NotBlank(message = "柜员号不能为空")
@Size(max = 50, message = "柜员号长度不能超过50个字符")
private String tellerNo;
/** 所属部门ID */
private Long deptId;
/** 身份证号 */
@NotBlank(message = "身份证号不能为空")
@Pattern(regexp = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]$", message = "身份证号格式不正确")
private String idCard;
/** 电话 */
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "电话格式不正确")
private String phone;
/** 入职时间 */
private Date hireDate;
/** 状态 */
@NotBlank(message = "状态不能为空")
private String status;
/** 亲属列表 */
private List<CcdiEmployeeRelativeAddDTO> relatives;
}

View File

@@ -0,0 +1,56 @@
package com.ruoyi.ccdi.domain.dto;
import jakarta.validation.constraints.NotNull;
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;
import java.util.List;
/**
* 员工信息编辑 DTO
*
* @author ruoyi
* @date 2026-01-28
*/
@Data
public class CcdiEmployeeEditDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 员工ID */
@NotNull(message = "员工ID不能为空")
private Long employeeId;
/** 姓名 */
@Size(max = 100, message = "姓名长度不能超过100个字符")
private String name;
/** 柜员号 */
@Size(max = 50, message = "柜员号长度不能超过50个字符")
private String tellerNo;
/** 所属部门ID */
private Long deptId;
/** 身份证号 */
@Pattern(regexp = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]$", message = "身份证号格式不正确")
private String idCard;
/** 电话 */
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "电话格式不正确")
private String phone;
/** 入职时间 */
private Date hireDate;
/** 状态 */
private String status;
/** 亲属列表 */
private List<CcdiEmployeeRelativeAddDTO> relatives;
}

View File

@@ -0,0 +1,34 @@
package com.ruoyi.ccdi.domain.dto;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 员工信息查询 DTO
*
* @author ruoyi
* @date 2026-01-28
*/
@Data
public class CcdiEmployeeQueryDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 姓名(模糊查询) */
private String name;
/** 柜员号(精确查询) */
private String tellerNo;
/** 所属部门ID */
private Long deptId;
/** 身份证号(模糊查询) */
private String idCard;
/** 状态 */
private String status;
}

View File

@@ -0,0 +1,40 @@
package com.ruoyi.ccdi.domain.dto;
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;
/**
* 员工亲属新增 DTO
*
* @author ruoyi
* @date 2026-01-28
*/
@Data
public class CcdiEmployeeRelativeAddDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 亲属姓名 */
@NotBlank(message = "亲属姓名不能为空")
@Size(max = 100, message = "亲属姓名长度不能超过100个字符")
private String relativeName;
/** 亲属身份证号 */
@Pattern(regexp = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]$", message = "亲属身份证号格式不正确")
private String relativeIdCard;
/** 亲属手机号 */
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "亲属手机号格式不正确")
private String relativePhone;
/** 与员工关系 */
@NotBlank(message = "与员工关系不能为空")
@Size(max = 50, message = "与员工关系长度不能超过50个字符")
private String relationship;
}

View File

@@ -0,0 +1,68 @@
package com.ruoyi.ccdi.domain.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import java.io.Serial;
import java.io.Serializable;
/**
* 中介人员黑名单新增 DTO
*
* @author ruoyi
* @date 2026-01-27
*/
public class CcdiIntermediaryBlacklistAddDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 姓名/机构名称 */
@NotBlank(message = "姓名/机构名称不能为空")
@Size(min = 1, max = 100, message = "姓名/机构名称长度不能超过100个字符")
private String name;
/** 证件号 */
@Size(max = 50, message = "证件号长度不能超过50个字符")
private String certificateNo;
/** 中介类型 */
@NotBlank(message = "中介类型不能为空")
private String intermediaryType;
/** 备注 */
@Size(max = 500, message = "备注长度不能超过500个字符")
private String remark;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCertificateNo() {
return certificateNo;
}
public void setCertificateNo(String certificateNo) {
this.certificateNo = certificateNo;
}
public String getIntermediaryType() {
return intermediaryType;
}
public void setIntermediaryType(String intermediaryType) {
this.intermediaryType = intermediaryType;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}

View File

@@ -0,0 +1,386 @@
package com.ruoyi.ccdi.domain.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 中介人员黑名单编辑 DTO
*
* @author ruoyi
* @date 2026-01-27
*/
public class CcdiIntermediaryBlacklistEditDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 中介ID */
@NotNull(message = "中介ID不能为空")
private Long intermediaryId;
/** 姓名/机构名称 */
@NotBlank(message = "姓名/机构名称不能为空")
@Size(min = 1, max = 100, message = "姓名/机构名称长度不能超过100个字符")
private String name;
/** 证件号 */
@Size(max = 50, message = "证件号长度不能超过50个字符")
private String certificateNo;
/** 中介类型 */
@NotBlank(message = "中介类型不能为空")
private String intermediaryType;
/** 状态 */
@NotBlank(message = "状态不能为空")
private String status;
/** 备注 */
@Size(max = 500, message = "备注长度不能超过500个字符")
private String remark;
// ============================================================
// 个人类型字段 (以 indiv_ 前缀标识individual 缩写)
// ============================================================
/** 人员类型(中介、职业背债人、房产中介等) */
private String indivType;
/** 人员子类型(本人、配偶等) */
private String indivSubType;
/** 性别M男 F女 O其他 */
private String indivGender;
/** 证件类型 */
private String indivCertType;
/** 手机号码(加密存储) */
private String indivPhone;
/** 微信号 */
private String indivWechat;
/** 联系地址 */
private String indivAddress;
/** 所在公司 */
private String indivCompany;
/** 职位/职务 */
private String indivPosition;
/** 关联人员ID */
private String indivRelatedId;
/** 关联关系 */
private String indivRelation;
// ============================================================
// 机构类型字段 (以 corp_ 前缀标识corporation 缩写)
// ============================================================
/** 统一社会信用代码 */
private String corpCreditCode;
/** 主体类型(有限责任公司、股份有限公司等) */
private String corpType;
/** 企业性质(国企、民企、外企等) */
private String corpNature;
/** 行业分类 */
private String corpIndustryCategory;
/** 所属行业 */
private String corpIndustry;
/** 成立日期 */
private Date corpEstablishDate;
/** 注册地址 */
private String corpAddress;
/** 法定代表人 */
private String corpLegalRep;
/** 法定代表人证件类型 */
private String corpLegalCertType;
/** 法定代表人证件号码 */
private String corpLegalCertNo;
/** 股东1 */
private String corpShareholder1;
/** 股东2 */
private String corpShareholder2;
/** 股东3 */
private String corpShareholder3;
/** 股东4 */
private String corpShareholder4;
/** 股东5 */
private String corpShareholder5;
public Long getIntermediaryId() {
return intermediaryId;
}
public void setIntermediaryId(Long intermediaryId) {
this.intermediaryId = intermediaryId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCertificateNo() {
return certificateNo;
}
public void setCertificateNo(String certificateNo) {
this.certificateNo = certificateNo;
}
public String getIntermediaryType() {
return intermediaryType;
}
public void setIntermediaryType(String intermediaryType) {
this.intermediaryType = intermediaryType;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getIndivType() {
return indivType;
}
public void setIndivType(String indivType) {
this.indivType = indivType;
}
public String getIndivSubType() {
return indivSubType;
}
public void setIndivSubType(String indivSubType) {
this.indivSubType = indivSubType;
}
public String getIndivGender() {
return indivGender;
}
public void setIndivGender(String indivGender) {
this.indivGender = indivGender;
}
public String getIndivCertType() {
return indivCertType;
}
public void setIndivCertType(String indivCertType) {
this.indivCertType = indivCertType;
}
public String getIndivPhone() {
return indivPhone;
}
public void setIndivPhone(String indivPhone) {
this.indivPhone = indivPhone;
}
public String getIndivWechat() {
return indivWechat;
}
public void setIndivWechat(String indivWechat) {
this.indivWechat = indivWechat;
}
public String getIndivAddress() {
return indivAddress;
}
public void setIndivAddress(String indivAddress) {
this.indivAddress = indivAddress;
}
public String getIndivCompany() {
return indivCompany;
}
public void setIndivCompany(String indivCompany) {
this.indivCompany = indivCompany;
}
public String getIndivPosition() {
return indivPosition;
}
public void setIndivPosition(String indivPosition) {
this.indivPosition = indivPosition;
}
public String getIndivRelatedId() {
return indivRelatedId;
}
public void setIndivRelatedId(String indivRelatedId) {
this.indivRelatedId = indivRelatedId;
}
public String getIndivRelation() {
return indivRelation;
}
public void setIndivRelation(String indivRelation) {
this.indivRelation = indivRelation;
}
public String getCorpCreditCode() {
return corpCreditCode;
}
public void setCorpCreditCode(String corpCreditCode) {
this.corpCreditCode = corpCreditCode;
}
public String getCorpType() {
return corpType;
}
public void setCorpType(String corpType) {
this.corpType = corpType;
}
public String getCorpNature() {
return corpNature;
}
public void setCorpNature(String corpNature) {
this.corpNature = corpNature;
}
public String getCorpIndustryCategory() {
return corpIndustryCategory;
}
public void setCorpIndustryCategory(String corpIndustryCategory) {
this.corpIndustryCategory = corpIndustryCategory;
}
public String getCorpIndustry() {
return corpIndustry;
}
public void setCorpIndustry(String corpIndustry) {
this.corpIndustry = corpIndustry;
}
public Date getCorpEstablishDate() {
return corpEstablishDate;
}
public void setCorpEstablishDate(Date corpEstablishDate) {
this.corpEstablishDate = corpEstablishDate;
}
public String getCorpAddress() {
return corpAddress;
}
public void setCorpAddress(String corpAddress) {
this.corpAddress = corpAddress;
}
public String getCorpLegalRep() {
return corpLegalRep;
}
public void setCorpLegalRep(String corpLegalRep) {
this.corpLegalRep = corpLegalRep;
}
public String getCorpLegalCertType() {
return corpLegalCertType;
}
public void setCorpLegalCertType(String corpLegalCertType) {
this.corpLegalCertType = corpLegalCertType;
}
public String getCorpLegalCertNo() {
return corpLegalCertNo;
}
public void setCorpLegalCertNo(String corpLegalCertNo) {
this.corpLegalCertNo = corpLegalCertNo;
}
public String getCorpShareholder1() {
return corpShareholder1;
}
public void setCorpShareholder1(String corpShareholder1) {
this.corpShareholder1 = corpShareholder1;
}
public String getCorpShareholder2() {
return corpShareholder2;
}
public void setCorpShareholder2(String corpShareholder2) {
this.corpShareholder2 = corpShareholder2;
}
public String getCorpShareholder3() {
return corpShareholder3;
}
public void setCorpShareholder3(String corpShareholder3) {
this.corpShareholder3 = corpShareholder3;
}
public String getCorpShareholder4() {
return corpShareholder4;
}
public void setCorpShareholder4(String corpShareholder4) {
this.corpShareholder4 = corpShareholder4;
}
public String getCorpShareholder5() {
return corpShareholder5;
}
public void setCorpShareholder5(String corpShareholder5) {
this.corpShareholder5 = corpShareholder5;
}
}

View File

@@ -0,0 +1,60 @@
package com.ruoyi.ccdi.domain.dto;
import java.io.Serial;
import java.io.Serializable;
/**
* 中介人员黑名单查询 DTO
*
* @author ruoyi
* @date 2026-01-27
*/
public class CcdiIntermediaryBlacklistQueryDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 姓名/机构名称(模糊查询) */
private String name;
/** 证件号(精确查询) */
private String certificateNo;
/** 中介类型 */
private String intermediaryType;
/** 状态 */
private String status;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCertificateNo() {
return certificateNo;
}
public void setCertificateNo(String certificateNo) {
this.certificateNo = certificateNo;
}
public String getIntermediaryType() {
return intermediaryType;
}
public void setIntermediaryType(String intermediaryType) {
this.intermediaryType = intermediaryType;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}

View File

@@ -0,0 +1,95 @@
package com.ruoyi.ccdi.domain.dto;
import jakarta.validation.constraints.NotBlank;
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-01-29
*/
@Data
public class CcdiIntermediaryEntityAddDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 机构名称 */
@NotBlank(message = "机构名称不能为空")
@Size(min = 1, max = 100, message = "机构名称长度不能超过100个字符")
private String name;
/** 统一社会信用代码 */
@NotBlank(message = "统一社会信用代码不能为空")
@Size(max = 18, message = "统一社会信用代码长度不能超过18个字符")
private String corpCreditCode;
/** 主体类型 */
@Size(max = 50, message = "主体类型长度不能超过50个字符")
private String corpType;
/** 企业性质 */
@Size(max = 50, message = "企业性质长度不能超过50个字符")
private String corpNature;
/** 行业分类 */
@Size(max = 100, message = "行业分类长度不能超过100个字符")
private String corpIndustryCategory;
/** 所属行业 */
@Size(max = 100, message = "所属行业长度不能超过100个字符")
private String corpIndustry;
/** 成立日期 */
private Date corpEstablishDate;
/** 注册地址 */
@Size(max = 500, message = "注册地址长度不能超过500个字符")
private String corpAddress;
/** 法定代表人 */
@Size(max = 50, message = "法定代表人长度不能超过50个字符")
private String corpLegalRep;
/** 法定代表人证件类型 */
@Size(max = 30, message = "法定代表人证件类型长度不能超过30个字符")
private String corpLegalCertType;
/** 法定代表人证件号码 */
@Size(max = 30, message = "法定代表人证件号码长度不能超过30个字符")
private String corpLegalCertNo;
/** 股东1 */
@Size(max = 30, message = "股东1长度不能超过30个字符")
private String corpShareholder1;
/** 股东2 */
@Size(max = 30, message = "股东2长度不能超过30个字符")
private String corpShareholder2;
/** 股东3 */
@Size(max = 30, message = "股东3长度不能超过30个字符")
private String corpShareholder3;
/** 股东4 */
@Size(max = 30, message = "股东4长度不能超过30个字符")
private String corpShareholder4;
/** 股东5 */
@Size(max = 30, message = "股东5长度不能超过30个字符")
private String corpShareholder5;
/** 状态 */
@NotBlank(message = "状态不能为空")
private String status;
/** 备注 */
@Size(max = 500, message = "备注长度不能超过500个字符")
private String remark;
}

View File

@@ -0,0 +1,89 @@
package com.ruoyi.ccdi.domain.dto;
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;
import java.util.Date;
/**
* 机构中介编辑 DTO
*
* @author ruoyi
* @date 2026-01-29
*/
@Data
public class CcdiIntermediaryEntityEditDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 中介ID */
@NotNull(message = "中介ID不能为空")
private Long intermediaryId;
/** 机构名称 */
@NotBlank(message = "机构名称不能为空")
@Size(min = 1, max = 100, message = "机构名称长度不能超过100个字符")
private String name;
/** 证件号(统一社会信用代码) */
@Size(max = 50, message = "证件号长度不能超过50个字符")
private String certificateNo;
/** 统一社会信用代码 */
private String corpCreditCode;
/** 主体类型(有限责任公司、股份有限公司等) */
private String corpType;
/** 企业性质(国企、民企、外企等) */
private String corpNature;
/** 行业分类 */
private String corpIndustryCategory;
/** 所属行业 */
private String corpIndustry;
/** 成立日期 */
private Date corpEstablishDate;
/** 注册地址 */
private String corpAddress;
/** 法定代表人 */
private String corpLegalRep;
/** 法定代表人证件类型 */
private String corpLegalCertType;
/** 法定代表人证件号码 */
private String corpLegalCertNo;
/** 股东1 */
private String corpShareholder1;
/** 股东2 */
private String corpShareholder2;
/** 股东3 */
private String corpShareholder3;
/** 股东4 */
private String corpShareholder4;
/** 股东5 */
private String corpShareholder5;
/** 状态 */
@NotBlank(message = "状态不能为空")
private String status;
/** 备注 */
@Size(max = 500, message = "备注长度不能超过500个字符")
private String remark;
}

View File

@@ -0,0 +1,83 @@
package com.ruoyi.ccdi.domain.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 个人中介新增 DTO
*
* @author ruoyi
* @date 2026-01-29
*/
@Data
public class CcdiIntermediaryPersonAddDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 姓名 */
@NotBlank(message = "姓名不能为空")
@Size(min = 1, max = 100, message = "姓名长度不能超过100个字符")
private String name;
/** 证件号 */
@NotBlank(message = "证件号不能为空")
@Size(max = 50, message = "证件号长度不能超过50个字符")
private String certificateNo;
/** 人员类型(中介、职业背债人、房产中介等) */
@Size(max = 30, message = "人员类型长度不能超过30个字符")
private String indivType;
/** 人员子类型(本人、配偶等) */
@Size(max = 50, message = "人员子类型长度不能超过50个字符")
private String indivSubType;
/** 性别M男 F女 O其他 */
@Size(max = 1, message = "性别长度不能超过1个字符")
private String indivGender;
/** 证件类型 */
@Size(max = 30, message = "证件类型长度不能超过30个字符")
private String indivCertType;
/** 手机号码(加密存储) */
@Size(max = 20, message = "手机号码长度不能超过20个字符")
private String indivPhone;
/** 微信号 */
@Size(max = 50, message = "微信号长度不能超过50个字符")
private String indivWechat;
/** 联系地址 */
@Size(max = 200, message = "联系地址长度不能超过200个字符")
private String indivAddress;
/** 所在公司 */
@Size(max = 100, message = "所在公司长度不能超过100个字符")
private String indivCompany;
/** 职位/职务 */
@Size(max = 100, message = "职位长度不能超过100个字符")
private String indivPosition;
/** 关联人员ID */
@Size(max = 20, message = "关联人员ID长度不能超过20个字符")
private String indivRelatedId;
/** 关联关系 */
@Size(max = 50, message = "关联关系长度不能超过50个字符")
private String indivRelation;
/** 状态 */
@NotBlank(message = "状态不能为空")
private String status;
/** 备注 */
@Size(max = 500, message = "备注长度不能超过500个字符")
private String remark;
}

View File

@@ -0,0 +1,76 @@
package com.ruoyi.ccdi.domain.dto;
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
*
* @author ruoyi
* @date 2026-01-29
*/
@Data
public class CcdiIntermediaryPersonEditDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 中介ID */
@NotNull(message = "中介ID不能为空")
private Long intermediaryId;
/** 姓名 */
@NotBlank(message = "姓名不能为空")
@Size(min = 1, max = 100, message = "姓名长度不能超过100个字符")
private String name;
/** 证件号 */
@Size(max = 50, message = "证件号长度不能超过50个字符")
private String certificateNo;
/** 人员类型(中介、职业背债人、房产中介等) */
private String indivType;
/** 人员子类型(本人、配偶等) */
private String indivSubType;
/** 性别M男 F女 O其他 */
private String indivGender;
/** 证件类型 */
private String indivCertType;
/** 手机号码(加密存储) */
private String indivPhone;
/** 微信号 */
private String indivWechat;
/** 联系地址 */
private String indivAddress;
/** 所在公司 */
private String indivCompany;
/** 职位/职务 */
private String indivPosition;
/** 关联人员ID */
private String indivRelatedId;
/** 关联关系 */
private String indivRelation;
/** 状态 */
@NotBlank(message = "状态不能为空")
private String status;
/** 备注 */
@Size(max = 500, message = "备注长度不能超过500个字符")
private String remark;
}

View File

@@ -0,0 +1,59 @@
package com.ruoyi.ccdi.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-01-28
*/
@Data
public class CcdiEmployeeExcel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 姓名 */
@ExcelProperty(value = "姓名", index = 0)
@ColumnWidth(15)
private String name;
/** 柜员号 */
@ExcelProperty(value = "柜员号", index = 1)
@ColumnWidth(15)
private String tellerNo;
/** 所属部门ID */
@ExcelProperty(value = "所属部门ID", index = 2)
@ColumnWidth(15)
private Long deptId;
/** 身份证号 */
@ExcelProperty(value = "身份证号", index = 3)
@ColumnWidth(20)
private String idCard;
/** 电话 */
@ExcelProperty(value = "电话", index = 4)
@ColumnWidth(15)
private String phone;
/** 入职时间 */
@ExcelProperty(value = "入职时间", index = 5)
@ColumnWidth(15)
private Date hireDate;
/** 状态 */
@ExcelProperty(value = "状态", index = 6)
@ColumnWidth(10)
@DictDropdown(dictType = "dpc_employee_status")
private String status;
}

View File

@@ -0,0 +1,41 @@
package com.ruoyi.ccdi.domain.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 员工亲属Excel导入导出对象
*
* @author ruoyi
* @date 2026-01-28
*/
@Data
public class CcdiEmployeeRelativeExcel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 亲属姓名 */
@ExcelProperty(value = "亲属姓名", index = 0)
@ColumnWidth(15)
private String relativeName;
/** 亲属身份证号 */
@ExcelProperty(value = "亲属身份证号", index = 1)
@ColumnWidth(20)
private String relativeIdCard;
/** 亲属手机号 */
@ExcelProperty(value = "亲属手机号", index = 2)
@ColumnWidth(15)
private String relativePhone;
/** 与员工关系 */
@ExcelProperty(value = "与员工关系", index = 3)
@ColumnWidth(15)
private String relationship;
}

View File

@@ -0,0 +1,48 @@
package com.ruoyi.ccdi.domain.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.ruoyi.ccdi.utils.converter.IntermediaryStatusConverter;
import com.ruoyi.ccdi.utils.converter.IntermediaryTypeConverter;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 中介人员黑名单Excel导入导出对象
*
* @author ruoyi
* @date 2026-01-27
*/
@Data
public class CcdiIntermediaryBlacklistExcel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 姓名/机构名称 */
@ExcelProperty(value = "姓名/机构名称", index = 0)
@ColumnWidth(20)
private String name;
/** 证件号 */
@ExcelProperty(value = "证件号", index = 1)
@ColumnWidth(20)
private String certificateNo;
/** 中介类型 */
@ExcelProperty(value = "中介类型", converter = IntermediaryTypeConverter.class, index = 2)
@ColumnWidth(15)
private String intermediaryType;
/** 状态 */
@ExcelProperty(value = "状态", converter = IntermediaryStatusConverter.class, index = 3)
@ColumnWidth(10)
private String status;
/** 备注 */
@ExcelProperty(value = "备注", index = 4)
@ColumnWidth(30)
private String remark;
}

View File

@@ -0,0 +1,96 @@
package com.ruoyi.ccdi.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;
/**
* 机构中介黑名单Excel导入对象
*
* @author ruoyi
* @date 2026-01-29
*/
@Data
public class CcdiIntermediaryEntityExcel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@ExcelProperty(value = "机构名称", index = 0)
@ColumnWidth(25)
private String name;
@ExcelProperty(value = "统一社会信用代码", index = 1)
@ColumnWidth(20)
private String corpCreditCode;
@ExcelProperty(value = "主体类型", index = 2)
@ColumnWidth(20)
@DictDropdown(dictType = "dpc_entity_type")
private String corpType;
@ExcelProperty(value = "企业性质", index = 3)
@ColumnWidth(15)
@DictDropdown(dictType = "dpc_enterprise_nature")
private String corpNature;
@ExcelProperty(value = "行业分类", index = 4)
@ColumnWidth(15)
private String corpIndustryCategory;
@ExcelProperty(value = "所属行业", index = 5)
@ColumnWidth(15)
private String corpIndustry;
@ExcelProperty(value = "成立日期", index = 6)
@ColumnWidth(15)
private String corpEstablishDate;
@ExcelProperty(value = "注册地址", index = 7)
@ColumnWidth(40)
private String corpAddress;
@ExcelProperty(value = "法定代表人", index = 8)
@ColumnWidth(15)
private String corpLegalRep;
@ExcelProperty(value = "法定代表人证件类型", index = 9)
@ColumnWidth(20)
private String corpLegalCertType;
@ExcelProperty(value = "法定代表人证件号码", index = 10)
@ColumnWidth(20)
private String corpLegalCertNo;
@ExcelProperty(value = "股东1", index = 11)
@ColumnWidth(15)
private String corpShareholder1;
@ExcelProperty(value = "股东2", index = 12)
@ColumnWidth(15)
private String corpShareholder2;
@ExcelProperty(value = "股东3", index = 13)
@ColumnWidth(15)
private String corpShareholder3;
@ExcelProperty(value = "股东4", index = 14)
@ColumnWidth(15)
private String corpShareholder4;
@ExcelProperty(value = "股东5", index = 15)
@ColumnWidth(15)
private String corpShareholder5;
@ExcelProperty(value = "备注", index = 16)
@ColumnWidth(30)
private String remark;
// 以下字段不在 Excel 中显示,由系统自动设置
// private String status; // 默认正常0
// private String dataSource; // 默认批量导入IMPORT
}

View File

@@ -0,0 +1,84 @@
package com.ruoyi.ccdi.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;
/**
* 个人中介黑名单Excel导入对象
*
* @author ruoyi
* @date 2026-01-29
*/
@Data
public class CcdiIntermediaryPersonExcel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@ExcelProperty(value = "姓名", index = 0)
@ColumnWidth(15)
private String name;
@ExcelProperty(value = "人员类型", index = 1)
@ColumnWidth(15)
private String indivType;
@ExcelProperty(value = "人员子类型", index = 2)
@ColumnWidth(15)
private String indivSubType;
@ExcelProperty(value = "性别", index = 3)
@ColumnWidth(10)
@DictDropdown(dictType = "dpc_indiv_gender")
private String indivGender;
@ExcelProperty(value = "证件类型", index = 4)
@ColumnWidth(15)
@DictDropdown(dictType = "dpc_certificate_type")
private String indivCertType;
@ExcelProperty(value = "证件号码", index = 5)
@ColumnWidth(20)
private String certificateNo;
@ExcelProperty(value = "手机号码", index = 6)
@ColumnWidth(15)
private String indivPhone;
@ExcelProperty(value = "微信号", index = 7)
@ColumnWidth(15)
private String indivWechat;
@ExcelProperty(value = "联系地址", index = 8)
@ColumnWidth(30)
private String indivAddress;
@ExcelProperty(value = "所在公司", index = 9)
@ColumnWidth(20)
private String indivCompany;
@ExcelProperty(value = "职位", index = 10)
@ColumnWidth(15)
private String indivPosition;
@ExcelProperty(value = "关联人员ID", index = 11)
@ColumnWidth(15)
private String indivRelatedId;
@ExcelProperty(value = "关联关系", index = 12)
@ColumnWidth(15)
private String indivRelation;
@ExcelProperty(value = "备注", index = 13)
@ColumnWidth(30)
private String remark;
// 以下字段不在 Excel 中显示,由系统自动设置
// private String status; // 默认正常0
// private String dataSource; // 默认批量导入IMPORT
}

View File

@@ -0,0 +1,37 @@
package com.ruoyi.ccdi.domain.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 员工亲属 VO
*
* @author ruoyi
* @date 2026-01-28
*/
@Data
public class CcdiEmployeeRelativeVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 亲属ID */
private Long relativeId;
/** 员工ID */
private Long employeeId;
/** 亲属姓名 */
private String relativeName;
/** 亲属身份证号 */
private String relativeIdCard;
/** 亲属手机号 */
private String relativePhone;
/** 与员工关系 */
private String relationship;
}

View File

@@ -0,0 +1,66 @@
package com.ruoyi.ccdi.domain.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 员工信息 VO
*
* @author ruoyi
* @date 2026-01-28
*/
@Data
public class CcdiEmployeeVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 员工ID */
private Long employeeId;
/** 姓名 */
private String name;
/** 柜员号 */
private String tellerNo;
/** 所属部门ID */
private Long deptId;
/** 所属部门名称 */
private String deptName;
/** 身份证号 */
private String idCard;
/** 电话 */
private String phone;
/** 入职时间 */
private Date hireDate;
/** 状态 */
private String status;
/** 状态描述 */
private String statusDesc;
/** 创建时间 */
private Date createTime;
/** 创建者 */
private String createBy;
/** 更新时间 */
private Date updateTime;
/** 更新者 */
private String updateBy;
/** 亲属列表 */
private List<CcdiEmployeeRelativeVO> relatives;
}

View File

@@ -0,0 +1,59 @@
package com.ruoyi.ccdi.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 中介人员黑名单视图对象 VO
*
* @author ruoyi
* @date 2026-01-27
*/
@Data
public class CcdiIntermediaryBlacklistVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 中介ID */
private Long intermediaryId;
/** 姓名/机构名称 */
private String name;
/** 证件号 */
private String certificateNo;
/** 中介类型 */
private String intermediaryType;
/** 中介类型名称(用于前端显示) */
private String intermediaryTypeName;
/** 状态 */
private String status;
/** 状态名称(用于前端显示) */
private String statusName;
/** 备注 */
private String remark;
/** 创建者 */
private String createBy;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新者 */
private String updateBy;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}

View File

@@ -0,0 +1,126 @@
package com.ruoyi.ccdi.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 机构中介黑名单详情 VO
*
* @author ruoyi
* @date 2026-01-29
*/
@Data
public class CcdiIntermediaryEntityDetailVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
// ============================================================
// 核心字段
// ============================================================
/** 中介ID */
private Long intermediaryId;
/** 机构名称 */
private String name;
/** 证件号码 */
private String certificateNo;
/** 中介类型 */
private String intermediaryType;
/** 中介类型名称 */
private String intermediaryTypeName;
/** 状态 */
private String status;
/** 状态名称 */
private String statusName;
/** 备注 */
private String remark;
/** 数据来源 */
private String dataSource;
/** 数据来源名称 */
private String dataSourceName;
// ============================================================
// 机构专属字段
// ============================================================
/** 统一社会信用代码 */
private String corpCreditCode;
/** 主体类型 */
private String corpType;
/** 主体类型名称 */
private String corpTypeName;
/** 企业性质 */
private String corpNature;
/** 企业性质名称 */
private String corpNatureName;
/** 行业分类 */
private String corpIndustryCategory;
/** 所属行业 */
private String corpIndustry;
/** 成立日期 */
@JsonFormat(pattern = "yyyy-MM-dd")
private Date corpEstablishDate;
/** 注册地址 */
private String corpAddress;
/** 法定代表人 */
private String corpLegalRep;
/** 法定代表人证件类型 */
private String corpLegalCertType;
/** 法定代表人证件号码 */
private String corpLegalCertNo;
/** 股东1 */
private String corpShareholder1;
/** 股东2 */
private String corpShareholder2;
/** 股东3 */
private String corpShareholder3;
/** 股东4 */
private String corpShareholder4;
/** 股东5 */
private String corpShareholder5;
// ============================================================
// 审计字段
// ============================================================
/** 创建者 */
private String createBy;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新者 */
private String updateBy;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}

View File

@@ -0,0 +1,113 @@
package com.ruoyi.ccdi.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 个人中介黑名单详情 VO
*
* @author ruoyi
* @date 2026-01-29
*/
@Data
public class CcdiIntermediaryPersonDetailVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
// ============================================================
// 核心字段
// ============================================================
/** 中介ID */
private Long intermediaryId;
/** 姓名 */
private String name;
/** 证件号码 */
private String certificateNo;
/** 中介类型 */
private String intermediaryType;
/** 中介类型名称 */
private String intermediaryTypeName;
/** 状态 */
private String status;
/** 状态名称 */
private String statusName;
/** 备注 */
private String remark;
/** 数据来源 */
private String dataSource;
/** 数据来源名称 */
private String dataSourceName;
// ============================================================
// 个人专属字段
// ============================================================
/** 人员类型 */
private String indivType;
/** 人员子类型 */
private String indivSubType;
/** 性别 */
private String indivGender;
/** 性别名称 */
private String indivGenderName;
/** 证件类型 */
private String indivCertType;
/** 证件类型名称 */
private String indivCertTypeName;
/** 手机号码 */
private String indivPhone;
/** 微信号 */
private String indivWechat;
/** 联系地址 */
private String indivAddress;
/** 所在公司 */
private String indivCompany;
/** 职位/职务 */
private String indivPosition;
/** 关联人员ID */
private String indivRelatedId;
/** 关联关系 */
private String indivRelation;
// ============================================================
// 审计字段
// ============================================================
/** 创建者 */
private String createBy;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新者 */
private String updateBy;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}

View File

@@ -0,0 +1,28 @@
package com.ruoyi.ccdi.domain.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
/**
* 枚举选项VO
*
* @author ruoyi
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EnumOptionVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 选项值 */
private String value;
/** 选项标签 */
private String label;
}

View File

@@ -0,0 +1,50 @@
package com.ruoyi.ccdi.enums;
/**
* 证件类型枚举
*
* @author ruoyi
*/
public enum CertType {
/** 身份证 */
ID_CARD("身份证", "身份证"),
/** 护照 */
PASSPORT("护照", "护照"),
/** 港澳通行证 */
HK_MACAU_PASS("港澳通行证", "港澳通行证"),
/** 台湾通行证 */
TAIWAN_PASS("台湾通行证", "台湾通行证");
private final String code;
private final String desc;
CertType(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 (CertType type : values()) {
if (type.getCode().equals(code)) {
return type.getDesc();
}
}
return null;
}
}

View File

@@ -0,0 +1,62 @@
package com.ruoyi.ccdi.enums;
/**
* 企业性质枚举
*
* @author ruoyi
*/
public enum CorpNature {
/** 国有企业 */
STATE_OWNED("国有企业", "国有企业"),
/** 民营企业 */
PRIVATE("民营企业", "民营企业"),
/** 外资企业 */
FOREIGN("外资企业", "外资企业"),
/** 合资企业 */
JOINT_VENTURE("合资企业", "合资企业"),
/** 港澳台企业 */
HONG_KONG_MACAO_TAIWAN("港澳台企业", "港澳台企业"),
/** 集体企业 */
COLLECTIVE("集体企业", "集体企业"),
/** 个体工商户 */
INDIVIDUAL("个体工商户", "个体工商户"),
/** 其他 */
OTHER("其他", "其他");
private final String code;
private final String desc;
CorpNature(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 (CorpNature nature : values()) {
if (nature.getCode().equals(code)) {
return nature.getDesc();
}
}
return null;
}
}

View File

@@ -0,0 +1,65 @@
package com.ruoyi.ccdi.enums;
/**
* 主体类型枚举
*
* @author ruoyi
*/
public enum CorpType {
/** 有限责任公司 */
LIMITED_LIABILITY("有限责任公司", "有限责任公司"),
/** 股份有限公司 */
JOINT_STOCK("股份有限公司", "股份有限公司"),
/** 个体工商户 */
INDIVIDUAL("个体工商户", "个体工商户"),
/** 合伙企业 */
PARTNERSHIP("合伙企业", "合伙企业"),
/** 个人独资企业 */
SOLE_PROPRIETORSHIP("个人独资企业", "个人独资企业"),
/** 国有企业 */
STATE_OWNED("国有企业", "国有企业"),
/** 集体企业 */
COLLECTIVE("集体企业", "集体企业"),
/** 外商投资企业 */
FOREIGN_INVESTED("外商投资企业", "外商投资企业"),
/** 港澳台投资企业 */
HONG_KONG_MACAO_TAIWAN("港澳台投资企业", "港澳台投资企业");
private final String code;
private final String desc;
CorpType(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 (CorpType type : values()) {
if (type.getCode().equals(code)) {
return type.getDesc();
}
}
return null;
}
}

View File

@@ -0,0 +1,49 @@
package com.ruoyi.ccdi.enums;
/**
* 数据来源枚举
*
* @author ruoyi
*/
public enum DataSource {
/** 手动录入 */
MANUAL("MANUAL", "手动录入"),
/** 系统同步 */
SYSTEM("SYSTEM", "系统同步"),
/** 批量导入 */
IMPORT("IMPORT", "批量导入"),
/** 接口获取 */
API("API", "接口获取");
private final String code;
private final String desc;
DataSource(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 (DataSource source : values()) {
if (source.getCode().equals(code)) {
return source.getDesc();
}
}
return null;
}
}

View File

@@ -0,0 +1,44 @@
package com.ruoyi.ccdi.enums;
/**
* 员工状态枚举
*
* @author ruoyi
*/
public enum EmployeeStatus {
/** 在职 */
ACTIVE("0", "在职"),
/** 离职 */
INACTIVE("1", "离职");
private final String code;
private final String desc;
EmployeeStatus(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 (EmployeeStatus status : values()) {
if (status.getCode().equals(code)) {
return status.getDesc();
}
}
return null;
}
}

View File

@@ -0,0 +1,47 @@
package com.ruoyi.ccdi.enums;
/**
* 性别枚举
*
* @author ruoyi
*/
public enum Gender {
/** 男 */
MALE("M", ""),
/** 女 */
FEMALE("F", ""),
/** 其他 */
OTHER("O", "其他");
private final String code;
private final String desc;
Gender(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 (Gender gender : values()) {
if (gender.getCode().equals(code)) {
return gender.getDesc();
}
}
return null;
}
}

View File

@@ -0,0 +1,59 @@
package com.ruoyi.ccdi.enums;
/**
* 人员子类型枚举
*
* @author ruoyi
*/
public enum IndivSubType {
/** 本人 */
SELF("本人", "本人"),
/** 配偶 */
SPOUSE("配偶", "配偶"),
/** 父亲 */
FATHER("父亲", "父亲"),
/** 母亲 */
MOTHER("母亲", "母亲"),
/** 兄弟 */
BROTHER("兄弟", "兄弟"),
/** 姐妹 */
SISTER("姐妹", "姐妹"),
/** 子女 */
CHILD("子女", "子女");
private final String code;
private final String desc;
IndivSubType(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 (IndivSubType type : values()) {
if (type.getCode().equals(code)) {
return type.getDesc();
}
}
return null;
}
}

View File

@@ -0,0 +1,53 @@
package com.ruoyi.ccdi.enums;
/**
* 人员类型枚举
*
* @author ruoyi
*/
public enum IndivType {
/** 房产中介 */
REAL_ESTATE_AGENT("房产中介", "房产中介"),
/** 贷款中介 */
LOAN_AGENT("贷款中介", "贷款中介"),
/** 职业背债人 */
PROFESSIONAL_DEBTOR("职业背债人", "职业背债人"),
/** 担保中介 */
GUARANTEE_AGENT("担保中介", "担保中介"),
/** 评估中介 */
EVALUATION_AGENT("评估中介", "评估中介");
private final String code;
private final String desc;
IndivType(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 (IndivType type : values()) {
if (type.getCode().equals(code)) {
return type.getDesc();
}
}
return null;
}
}

View File

@@ -0,0 +1,44 @@
package com.ruoyi.ccdi.enums;
/**
* 中介状态枚举
*
* @author ruoyi
*/
public enum IntermediaryStatus {
/** 正常 */
NORMAL("0", "正常"),
/** 停用 */
DISABLED("1", "停用");
private final String code;
private final String desc;
IntermediaryStatus(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 (IntermediaryStatus status : values()) {
if (status.getCode().equals(code)) {
return status.getDesc();
}
}
return null;
}
}

View File

@@ -0,0 +1,44 @@
package com.ruoyi.ccdi.enums;
/**
* 中介类型枚举
*
* @author ruoyi
*/
public enum IntermediaryType {
/** 个人 */
PERSON("1", "个人"),
/** 机构 */
ENTITY("2", "机构");
private final String code;
private final String desc;
IntermediaryType(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 (IntermediaryType type : values()) {
if (type.getCode().equals(code)) {
return type.getDesc();
}
}
return null;
}
}

View File

@@ -0,0 +1,62 @@
package com.ruoyi.ccdi.enums;
/**
* 关联关系枚举
*
* @author ruoyi
*/
public enum RelationType {
/** 配偶 */
SPOUSE("配偶", "配偶"),
/** 父子 */
FATHER_SON("父子", "父子"),
/** 母女 */
MOTHER_DAUGHTER("母女", "母女"),
/** 兄弟 */
BROTHER("兄弟", "兄弟"),
/** 姐妹 */
SISTER("姐妹", "姐妹"),
/** 亲属 */
RELATIVE("亲属", "亲属"),
/** 朋友 */
FRIEND("朋友", "朋友"),
/** 同事 */
COLLEAGUE("同事", "同事");
private final String code;
private final String desc;
RelationType(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 (RelationType type : values()) {
if (type.getCode().equals(code)) {
return type.getDesc();
}
}
return null;
}
}

View File

@@ -0,0 +1,336 @@
package com.ruoyi.ccdi.handler;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.ruoyi.common.annotation.DictDropdown;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.utils.DictUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import java.lang.reflect.Field;
import java.util.*;
/**
* EasyExcel字典下拉框写入处理器
* 在Excel模板生成时为标注了@DictDropdown注解的字段添加下拉框
*
* @author ruoyi
*/
@Slf4j
public class DictDropdownWriteHandler implements SheetWriteHandler {
/**
* Excel下拉列表直接写入的最大字符数限制
*/
private static final int MAX_DIRECT_LENGTH = 255;
/**
* 实体类Class对象
*/
private final Class<?> modelClass;
/**
* 构造函数
*
* @param modelClass 实体类Class对象
*/
public DictDropdownWriteHandler(Class<?> modelClass) {
this.modelClass = modelClass;
}
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
// 获取工作簿和工作表
Workbook workbook = writeWorkbookHolder.getWorkbook();
Sheet sheet = writeSheetHolder.getSheet();
// 创建数据验证助手
DataValidationHelper validationHelper = sheet.getDataValidationHelper();
// 解析实体类中的字段及其注解
Map<Integer, DictDropdown> dropdownMap = parseDropdownFields();
// 为每个需要下拉框的字段添加数据验证
for (Map.Entry<Integer, DictDropdown> entry : dropdownMap.entrySet()) {
Integer columnIndex = entry.getKey();
DictDropdown dropdown = entry.getValue();
try {
// 获取字典数据
List<SysDictData> dictDataList = getDictData(dropdown.dictType());
if (dictDataList == null || dictDataList.isEmpty()) {
log.warn("字典类型[{}]没有可用数据,跳过下拉框创建", dropdown.dictType());
continue;
}
// 获取下拉选项列表
String[] dropdownOptions = extractOptions(dictDataList, dropdown.displayType());
if (dropdownOptions.length == 0) {
log.warn("字典类型[{}]提取选项为空,跳过下拉框创建", dropdown.dictType());
continue;
}
// 创建数据验证
DataValidation validation = createDataValidation(
workbook,
sheet,
validationHelper,
columnIndex,
dropdownOptions,
dropdown.hiddenSheetName(),
dropdown.strict()
);
if (validation != null) {
sheet.addValidationData(validation);
log.info("成功为列[{}]添加字典[{}]的下拉框,选项数量:{}", columnIndex, dropdown.dictType(), dropdownOptions.length);
}
} catch (Exception e) {
log.error("为列[{}]添加字典[{}]下拉框失败:{}", columnIndex, dropdown.dictType(), e.getMessage(), e);
}
}
}
/**
* 解析实体类中的字段,获取需要添加下拉框的字段及其注解
*
* @return 字段索引与注解的映射
*/
private Map<Integer, DictDropdown> parseDropdownFields() {
Map<Integer, DictDropdown> result = new HashMap<>();
// 获取所有字段(包括父类的)
List<Field> fields = getAllFields(modelClass);
for (Field field : fields) {
// 检查是否有@DictDropdown注解
DictDropdown dropdown = field.getAnnotation(DictDropdown.class);
if (dropdown == null) {
continue;
}
// 获取列索引
Integer columnIndex = getColumnIndex(field);
if (columnIndex == null) {
log.warn("字段[{}]没有指定@ExcelProperty的index跳过下拉框创建", field.getName());
continue;
}
result.put(columnIndex, dropdown);
}
return result;
}
/**
* 获取类的所有字段(包括父类的)
*
* @param clazz 类对象
* @return 字段列表
*/
private List<Field> getAllFields(Class<?> clazz) {
List<Field> fields = new ArrayList<>();
while (clazz != null && clazz != Object.class) {
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
clazz = clazz.getSuperclass();
}
return fields;
}
/**
* 获取字段对应的列索引
*
* @param field 字段对象
* @return 列索引
*/
private Integer getColumnIndex(Field field) {
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
if (excelProperty != null && excelProperty.index() >= 0) {
return excelProperty.index();
}
return null;
}
/**
* 获取字典数据
*
* @param dictType 字典类型
* @return 字典数据列表
*/
private List<SysDictData> getDictData(String dictType) {
try {
// 先从缓存获取
List<SysDictData> dictDataList = DictUtils.getDictCache(dictType);
if (dictDataList == null || dictDataList.isEmpty()) {
log.warn("从缓存获取字典[{}]数据为空", dictType);
}
return dictDataList;
} catch (Exception e) {
log.error("获取字典[{}]数据失败:{}", dictType, e.getMessage(), e);
return Collections.emptyList();
}
}
/**
* 从字典数据中提取下拉选项
*
* @param dictDataList 字典数据列表
* @param displayType 显示类型
* @return 下拉选项数组
*/
private String[] extractOptions(List<SysDictData> dictDataList, DictDropdown.DisplayType displayType) {
List<String> options = new ArrayList<>();
for (SysDictData dictData : dictDataList) {
String optionValue;
if (displayType == DictDropdown.DisplayType.VALUE) {
optionValue = dictData.getDictValue();
} else {
optionValue = dictData.getDictLabel();
}
if (optionValue != null && !optionValue.isEmpty()) {
options.add(optionValue);
}
}
return options.toArray(new String[0]);
}
/**
* 创建数据验证
*
* @param workbook 工作簿
* @param sheet 工作表
* @param validationHelper 数据验证助手
* @param columnIndex 列索引
* @param options 下拉选项
* @param hiddenSheetName 隐藏Sheet名称
* @param strict 是否严格模式
* @return 数据验证对象
*/
private DataValidation createDataValidation(
Workbook workbook,
Sheet sheet,
DataValidationHelper validationHelper,
int columnIndex,
String[] options,
String hiddenSheetName,
boolean strict
) {
// 计算选项字符串总长度
int totalLength = Arrays.stream(options)
.mapToInt(String::length)
.sum() + options.length - 1; // 加上分隔符
// 设置数据验证的范围从第2行开始第1行是表头
int firstRow = 1; // 从第2行开始0-based索引
int lastRow = sheet.getLastRowNum() + 1000; // 扩展到足够多的行
if (lastRow < 100) {
lastRow = 100; // 至少100行
}
CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, columnIndex, columnIndex);
// 判断是否需要使用隐藏Sheet
if (totalLength > MAX_DIRECT_LENGTH) {
// 使用隐藏Sheet存储选项
return createHiddenSheetValidation(workbook, sheet, validationHelper, addressList, options, hiddenSheetName, strict);
} else {
// 直接创建下拉列表
return createDirectValidation(validationHelper, addressList, options, strict);
}
}
/**
* 使用隐藏Sheet创建数据验证适用于选项较多的情况
*
* @param workbook 工作簿
* @param sheet 主工作表
* @param validationHelper 数据验证助手
* @param addressList 单元格范围
* @param options 下拉选项
* @param hiddenSheetName 隐藏Sheet名称
* @param strict 是否严格模式
* @return 数据验证对象
*/
private DataValidation createHiddenSheetValidation(
Workbook workbook,
Sheet sheet,
DataValidationHelper validationHelper,
CellRangeAddressList addressList,
String[] options,
String hiddenSheetName,
boolean strict
) {
try {
// 创建或获取隐藏Sheet
Sheet hiddenSheet = workbook.getSheet(hiddenSheetName);
if (hiddenSheet == null) {
hiddenSheet = workbook.createSheet(hiddenSheetName);
}
// 写入选项到隐藏Sheet
Row row = hiddenSheet.createRow(0);
for (int i = 0; i < options.length; i++) {
Cell cell = row.createCell(i);
cell.setCellValue(options[i]);
}
// 构建公式引用
String formula = String.format("%s!$A$1:$%s$1", hiddenSheetName,
(char) ('A' + options.length - 1));
// 创建列表验证
DataValidationConstraint constraint = validationHelper.createFormulaListConstraint(formula);
// 设置验证属性
DataValidation validation = validationHelper.createValidation(constraint, addressList);
validation.setSuppressDropDownArrow(true);
validation.setErrorStyle(strict ? DataValidation.ErrorStyle.STOP : DataValidation.ErrorStyle.WARNING);
validation.setShowErrorBox(true);
// 隐藏Sheet在Excel中无法通过界面隐藏需要通过代码设置
workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheetName), true);
return validation;
} catch (Exception e) {
log.error("创建隐藏Sheet数据验证失败{}", e.getMessage(), e);
return null;
}
}
/**
* 直接创建下拉列表验证(适用于选项较少的情况)
*
* @param validationHelper 数据验证助手
* @param addressList 单元格范围
* @param options 下拉选项
* @param strict 是否严格模式
* @return 数据验证对象
*/
private DataValidation createDirectValidation(
DataValidationHelper validationHelper,
CellRangeAddressList addressList,
String[] options,
boolean strict
) {
// 创建显式列表验证
DataValidationConstraint constraint = validationHelper.createExplicitListConstraint(options);
// 创建数据验证
DataValidation validation = validationHelper.createValidation(constraint, addressList);
// 设置验证属性
validation.setSuppressDropDownArrow(true);
validation.setErrorStyle(strict ? DataValidation.ErrorStyle.STOP : DataValidation.ErrorStyle.WARNING);
validation.setShowErrorBox(true);
return validation;
}
}

View File

@@ -0,0 +1,35 @@
package com.ruoyi.ccdi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.domain.CcdiEmployee;
import com.ruoyi.ccdi.domain.dto.CcdiEmployeeQueryDTO;
import com.ruoyi.ccdi.domain.vo.CcdiEmployeeVO;
import org.apache.ibatis.annotations.Param;
/**
* 员工信息 数据层
*
* @author ruoyi
* @date 2026-01-28
*/
public interface CcdiEmployeeMapper extends BaseMapper<CcdiEmployee> {
/**
* 分页查询员工列表(包含部门名称)
*
* @param page 分页对象
* @param queryDTO 查询条件
* @return 员工VO分页结果
*/
Page<CcdiEmployeeVO> selectEmployeePageWithDept(@Param("page") Page<CcdiEmployeeVO> page,
@Param("query") CcdiEmployeeQueryDTO queryDTO);
/**
* 查询员工详情(包含亲属列表)
*
* @param employeeId 员工ID
* @return 员工VO
*/
CcdiEmployeeVO selectEmployeeWithRelatives(@Param("employeeId") Long employeeId);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.ccdi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.ccdi.domain.CcdiEmployeeRelative;
/**
* 员工亲属 数据层
*
* @author ruoyi
* @date 2026-01-28
*/
public interface CcdiEmployeeRelativeMapper extends BaseMapper<CcdiEmployeeRelative> {
}

View File

@@ -0,0 +1,32 @@
package com.ruoyi.ccdi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.ccdi.domain.CcdiIntermediaryBlacklist;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 中介人员黑名单 数据层
*
* @author ruoyi
* @date 2026-01-27
*/
public interface CcdiIntermediaryBlacklistMapper extends BaseMapper<CcdiIntermediaryBlacklist> {
/**
* 批量插入中介黑名单数据
*
* @param list 中介黑名单列表
* @return 插入行数
*/
int batchInsert(@Param("list") List<CcdiIntermediaryBlacklist> list);
/**
* 批量更新中介黑名单数据
*
* @param list 中介黑名单列表
* @return 更新行数
*/
int batchUpdate(@Param("list") List<CcdiIntermediaryBlacklist> list);
}

View File

@@ -0,0 +1,85 @@
package com.ruoyi.ccdi.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.domain.dto.CcdiEmployeeAddDTO;
import com.ruoyi.ccdi.domain.dto.CcdiEmployeeEditDTO;
import com.ruoyi.ccdi.domain.dto.CcdiEmployeeQueryDTO;
import com.ruoyi.ccdi.domain.excel.CcdiEmployeeExcel;
import com.ruoyi.ccdi.domain.vo.CcdiEmployeeVO;
import java.util.List;
/**
* 员工信息 服务层
*
* @author ruoyi
* @date 2026-01-28
*/
public interface ICcdiEmployeeService {
/**
* 查询员工列表
*
* @param queryDTO 查询条件
* @return 员工VO集合
*/
List<CcdiEmployeeVO> selectEmployeeList(CcdiEmployeeQueryDTO queryDTO);
/**
* 分页查询员工列表
*
* @param page 分页对象
* @param queryDTO 查询条件
* @return 员工VO分页结果
*/
Page<CcdiEmployeeVO> selectEmployeePage(Page<CcdiEmployeeVO> page, CcdiEmployeeQueryDTO queryDTO);
/**
* 查询员工列表(用于导出)
*
* @param queryDTO 查询条件
* @return 员工Excel实体集合
*/
List<CcdiEmployeeExcel> selectEmployeeListForExport(CcdiEmployeeQueryDTO queryDTO);
/**
* 查询员工详情
*
* @param employeeId 员工ID
* @return 员工VO
*/
CcdiEmployeeVO selectEmployeeById(Long employeeId);
/**
* 新增员工
*
* @param addDTO 新增DTO
* @return 结果
*/
int insertEmployee(CcdiEmployeeAddDTO addDTO);
/**
* 修改员工
*
* @param editDTO 编辑DTO
* @return 结果
*/
int updateEmployee(CcdiEmployeeEditDTO editDTO);
/**
* 批量删除员工
*
* @param employeeIds 需要删除的员工ID
* @return 结果
*/
int deleteEmployeeByIds(Long[] employeeIds);
/**
* 导入员工数据
*
* @param excelList Excel实体列表
* @param isUpdateSupport 是否更新支持
* @return 结果
*/
String importEmployee(List<CcdiEmployeeExcel> excelList, Boolean isUpdateSupport);
}

View File

@@ -0,0 +1,148 @@
package com.ruoyi.ccdi.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.domain.CcdiIntermediaryBlacklist;
import com.ruoyi.ccdi.domain.dto.*;
import com.ruoyi.ccdi.domain.excel.CcdiIntermediaryBlacklistExcel;
import com.ruoyi.ccdi.domain.excel.CcdiIntermediaryEntityExcel;
import com.ruoyi.ccdi.domain.excel.CcdiIntermediaryPersonExcel;
import com.ruoyi.ccdi.domain.vo.CcdiIntermediaryBlacklistVO;
import java.util.List;
/**
* 中介人员黑名单 服务层
*
* @author ruoyi
* @date 2026-01-27
*/
public interface ICcdiIntermediaryBlacklistService {
/**
* 查询中介黑名单列表
*
* @param queryDTO 查询条件
* @return 中介黑名单集合
*/
List<CcdiIntermediaryBlacklistVO> selectIntermediaryList(CcdiIntermediaryBlacklistQueryDTO queryDTO);
/**
* 分页查询中介黑名单列表
*
* @param page 分页对象
* @param queryDTO 查询条件
* @return 中介黑名单VO分页结果
*/
Page<CcdiIntermediaryBlacklistVO> selectIntermediaryPage(Page<CcdiIntermediaryBlacklist> page, CcdiIntermediaryBlacklistQueryDTO queryDTO);
/**
* 查询中介黑名单列表(用于导出)
*
* @param queryDTO 查询条件
* @return 中介黑名单Excel实体集合
*/
List<CcdiIntermediaryBlacklistExcel> selectIntermediaryListForExport(CcdiIntermediaryBlacklistQueryDTO queryDTO);
/**
* 查询中介黑名单详细
*
* @param intermediaryId 中介ID
* @return 中介黑名单VO
*/
CcdiIntermediaryBlacklistVO selectIntermediaryById(Long intermediaryId);
/**
* 新增中介黑名单(通用接口,不推荐使用)
*
* @param addDTO 新增DTO
* @return 结果
* @deprecated 请使用 insertPersonIntermediary 或 insertEntityIntermediary 代替
*/
@Deprecated
int insertIntermediary(CcdiIntermediaryBlacklistAddDTO addDTO);
/**
* 新增个人中介黑名单
*
* @param addDTO 个人中介新增DTO
* @return 结果
*/
int insertPersonIntermediary(CcdiIntermediaryPersonAddDTO addDTO);
/**
* 新增机构中介黑名单
*
* @param addDTO 机构中介新增DTO
* @return 结果
*/
int insertEntityIntermediary(CcdiIntermediaryEntityAddDTO addDTO);
/**
* 修改中介黑名单(通用接口,不推荐使用)
*
* @param editDTO 编辑DTO
* @return 结果
* @deprecated 请使用 updatePersonIntermediary 或 updateEntityIntermediary 代替
*/
@Deprecated
int updateIntermediary(CcdiIntermediaryBlacklistEditDTO editDTO);
/**
* 修改个人中介黑名单
*
* @param editDTO 个人中介编辑DTO
* @return 结果
*/
int updatePersonIntermediary(CcdiIntermediaryPersonEditDTO editDTO);
/**
* 修改机构中介黑名单
*
* @param editDTO 机构中介编辑DTO
* @return 结果
*/
int updateEntityIntermediary(CcdiIntermediaryEntityEditDTO editDTO);
/**
* 批量删除中介黑名单
*
* @param intermediaryIds 需要删除的中介ID
* @return 结果
*/
int deleteIntermediaryByIds(Long[] intermediaryIds);
/**
* 导入中介黑名单数据
*
* @param excelList Excel实体列表
* @param isUpdateSupport 是否更新支持
* @return 结果
*/
String importIntermediary(List<CcdiIntermediaryBlacklistExcel> excelList, Boolean isUpdateSupport);
/**
* 根据中介类型获取详情(返回不同类型)
*
* @param intermediaryId 中介ID
* @return 个人返回 CcdiIntermediaryPersonDetailVO机构返回 CcdiIntermediaryEntityDetailVO
*/
Object selectIntermediaryDetailById(Long intermediaryId);
/**
* 导入个人中介数据
*
* @param excelList Excel实体列表
* @param isUpdateSupport 是否更新支持
* @return 结果
*/
String importPersonIntermediary(List<CcdiIntermediaryPersonExcel> excelList, Boolean isUpdateSupport);
/**
* 导入机构中介数据
*
* @param excelList Excel实体列表
* @param isUpdateSupport 是否更新支持
* @return 结果
*/
String importEntityIntermediary(List<CcdiIntermediaryEntityExcel> excelList, Boolean isUpdateSupport);
}

View File

@@ -0,0 +1,338 @@
package com.ruoyi.ccdi.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.domain.CcdiEmployee;
import com.ruoyi.ccdi.domain.CcdiEmployeeRelative;
import com.ruoyi.ccdi.domain.dto.CcdiEmployeeAddDTO;
import com.ruoyi.ccdi.domain.dto.CcdiEmployeeEditDTO;
import com.ruoyi.ccdi.domain.dto.CcdiEmployeeQueryDTO;
import com.ruoyi.ccdi.domain.dto.CcdiEmployeeRelativeAddDTO;
import com.ruoyi.ccdi.domain.excel.CcdiEmployeeExcel;
import com.ruoyi.ccdi.domain.vo.CcdiEmployeeVO;
import com.ruoyi.ccdi.enums.EmployeeStatus;
import com.ruoyi.ccdi.mapper.CcdiEmployeeMapper;
import com.ruoyi.ccdi.mapper.CcdiEmployeeRelativeMapper;
import com.ruoyi.ccdi.service.ICcdiEmployeeService;
import com.ruoyi.common.utils.IdCardUtil;
import com.ruoyi.common.utils.StringUtils;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* 员工信息 服务层处理
*
* @author ruoyi
* @date 2026-01-28
*/
@Service
public class CcdiEmployeeServiceImpl implements ICcdiEmployeeService {
@Resource
private CcdiEmployeeMapper employeeMapper;
@Resource
private CcdiEmployeeRelativeMapper relativeMapper;
/**
* 查询员工列表
*
* @param queryDTO 查询条件
* @return 员工VO集合
*/
@Override
public List<CcdiEmployeeVO> selectEmployeeList(CcdiEmployeeQueryDTO queryDTO) {
LambdaQueryWrapper<CcdiEmployee> wrapper = buildQueryWrapper(queryDTO);
List<CcdiEmployee> list = employeeMapper.selectList(wrapper);
List<CcdiEmployeeVO> voList = new ArrayList<>();
for (CcdiEmployee employee : list) {
voList.add(convertToVO(employee));
}
return voList;
}
/**
* 分页查询员工列表
*
* @param page 分页对象
* @param queryDTO 查询条件
* @return 员工VO分页结果
*/
@Override
public Page<CcdiEmployeeVO> selectEmployeePage(Page<CcdiEmployeeVO> page, CcdiEmployeeQueryDTO queryDTO) {
// 使用关联查询获取部门名称
Page<CcdiEmployeeVO> voPage = new Page<>(page.getCurrent(), page.getSize());
Page<CcdiEmployeeVO> resultPage = employeeMapper.selectEmployeePageWithDept(voPage, queryDTO);
// 设置状态描述
resultPage.getRecords().forEach(vo ->
vo.setStatusDesc(EmployeeStatus.getDescByCode(vo.getStatus()))
);
return resultPage;
}
/**
* 查询员工列表(用于导出)
*
* @param queryDTO 查询条件
* @return 员工Excel实体集合
*/
@Override
public List<CcdiEmployeeExcel> selectEmployeeListForExport(CcdiEmployeeQueryDTO queryDTO) {
LambdaQueryWrapper<CcdiEmployee> wrapper = buildQueryWrapper(queryDTO);
List<CcdiEmployee> list = employeeMapper.selectList(wrapper);
return list.stream().map(employee -> {
CcdiEmployeeExcel excel = new CcdiEmployeeExcel();
BeanUtils.copyProperties(employee, excel);
return excel;
}).toList();
}
/**
* 查询员工详情
*
* @param employeeId 员工ID
* @return 员工VO
*/
@Override
public CcdiEmployeeVO selectEmployeeById(Long employeeId) {
return employeeMapper.selectEmployeeWithRelatives(employeeId);
}
/**
* 新增员工
*
* @param addDTO 新增DTO
* @return 结果
*/
@Override
@Transactional
public int insertEmployee(CcdiEmployeeAddDTO addDTO) {
// 检查柜员号唯一性
LambdaQueryWrapper<CcdiEmployee> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CcdiEmployee::getTellerNo, addDTO.getTellerNo());
if (employeeMapper.selectCount(wrapper) > 0) {
throw new RuntimeException("该柜员号已存在");
}
// 检查身份证号唯一性
wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CcdiEmployee::getIdCard, addDTO.getIdCard());
if (employeeMapper.selectCount(wrapper) > 0) {
throw new RuntimeException("该身份证号已存在");
}
CcdiEmployee employee = new CcdiEmployee();
BeanUtils.copyProperties(addDTO, employee);
int result = employeeMapper.insert(employee);
// 插入亲属信息
if (addDTO.getRelatives() != null && !addDTO.getRelatives().isEmpty()) {
for (CcdiEmployeeRelativeAddDTO relativeAddDTO : addDTO.getRelatives()) {
CcdiEmployeeRelative relative = new CcdiEmployeeRelative();
BeanUtils.copyProperties(relativeAddDTO, relative);
relative.setEmployeeId(employee.getEmployeeId());
relativeMapper.insert(relative);
}
}
return result;
}
/**
* 修改员工
*
* @param editDTO 编辑DTO
* @return 结果
*/
@Override
@Transactional
public int updateEmployee(CcdiEmployeeEditDTO editDTO) {
// 检查柜员号唯一性(排除自己)
if (StringUtils.isNotEmpty(editDTO.getTellerNo())) {
LambdaQueryWrapper<CcdiEmployee> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CcdiEmployee::getTellerNo, editDTO.getTellerNo())
.ne(CcdiEmployee::getEmployeeId, editDTO.getEmployeeId());
if (employeeMapper.selectCount(wrapper) > 0) {
throw new RuntimeException("该柜员号已存在");
}
}
// 检查身份证号唯一性(排除自己)
if (StringUtils.isNotEmpty(editDTO.getIdCard())) {
LambdaQueryWrapper<CcdiEmployee> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CcdiEmployee::getIdCard, editDTO.getIdCard())
.ne(CcdiEmployee::getEmployeeId, editDTO.getEmployeeId());
if (employeeMapper.selectCount(wrapper) > 0) {
throw new RuntimeException("该身份证号已存在");
}
}
CcdiEmployee employee = new CcdiEmployee();
BeanUtils.copyProperties(editDTO, employee);
int result = employeeMapper.updateById(employee);
// 删除原有亲属信息
LambdaQueryWrapper<CcdiEmployeeRelative> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CcdiEmployeeRelative::getEmployeeId, editDTO.getEmployeeId());
relativeMapper.delete(wrapper);
// 插入新的亲属信息
if (editDTO.getRelatives() != null && !editDTO.getRelatives().isEmpty()) {
for (CcdiEmployeeRelativeAddDTO relativeAddDTO : editDTO.getRelatives()) {
CcdiEmployeeRelative relative = new CcdiEmployeeRelative();
BeanUtils.copyProperties(relativeAddDTO, relative);
relative.setEmployeeId(editDTO.getEmployeeId());
relativeMapper.insert(relative);
}
}
return result;
}
/**
* 批量删除员工
*
* @param employeeIds 需要删除的员工ID
* @return 结果
*/
@Override
@Transactional
public int deleteEmployeeByIds(Long[] employeeIds) {
// 级联删除亲属信息
for (Long employeeId : employeeIds) {
LambdaQueryWrapper<CcdiEmployeeRelative> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CcdiEmployeeRelative::getEmployeeId, employeeId);
relativeMapper.delete(wrapper);
}
return employeeMapper.deleteBatchIds(List.of(employeeIds));
}
/**
* 导入员工数据
*
* @param excelList Excel实体列表
* @param isUpdateSupport 是否更新支持
* @return 结果
*/
@Override
@Transactional
public String importEmployee(List<CcdiEmployeeExcel> excelList, Boolean isUpdateSupport) {
if (StringUtils.isNull(excelList) || excelList.isEmpty()) {
return "至少需要一条数据";
}
int successNum = 0;
int failureNum = 0;
StringBuilder successMsg = new StringBuilder();
StringBuilder failureMsg = new StringBuilder();
for (CcdiEmployeeExcel excel : excelList) {
try {
// 转换为AddDTO
CcdiEmployeeAddDTO addDTO = new CcdiEmployeeAddDTO();
BeanUtils.copyProperties(excel, addDTO);
// 验证数据
validateEmployeeData(addDTO, isUpdateSupport);
CcdiEmployee employee = new CcdiEmployee();
BeanUtils.copyProperties(addDTO, employee);
employeeMapper.insert(employee);
successNum++;
successMsg.append("<br/>").append(successNum).append("").append(addDTO.getName()).append(" 导入成功");
} catch (Exception e) {
failureNum++;
failureMsg.append("<br/>").append(failureNum).append("").append(excel.getName()).append(" 导入失败:");
failureMsg.append(e.getMessage());
}
}
if (failureNum > 0) {
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new RuntimeException(failureMsg.toString());
} else {
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + "");
return successMsg.toString();
}
}
/**
* 构建查询条件
*/
private LambdaQueryWrapper<CcdiEmployee> buildQueryWrapper(CcdiEmployeeQueryDTO queryDTO) {
LambdaQueryWrapper<CcdiEmployee> wrapper = new LambdaQueryWrapper<>();
wrapper.like(StringUtils.isNotEmpty(queryDTO.getName()), CcdiEmployee::getName, queryDTO.getName())
.eq(StringUtils.isNotEmpty(queryDTO.getTellerNo()), CcdiEmployee::getTellerNo, queryDTO.getTellerNo())
.eq(queryDTO.getDeptId() != null, CcdiEmployee::getDeptId, queryDTO.getDeptId())
.like(StringUtils.isNotEmpty(queryDTO.getIdCard()), CcdiEmployee::getIdCard, queryDTO.getIdCard())
.eq(StringUtils.isNotEmpty(queryDTO.getStatus()), CcdiEmployee::getStatus, queryDTO.getStatus())
.orderByDesc(CcdiEmployee::getCreateTime);
return wrapper;
}
/**
* 验证员工数据
*/
private void validateEmployeeData(CcdiEmployeeAddDTO addDTO, Boolean isUpdateSupport) {
// 验证必填字段
if (StringUtils.isEmpty(addDTO.getName())) {
throw new RuntimeException("姓名不能为空");
}
if (StringUtils.isEmpty(addDTO.getTellerNo())) {
throw new RuntimeException("柜员号不能为空");
}
if (StringUtils.isEmpty(addDTO.getIdCard())) {
throw new RuntimeException("身份证号不能为空");
}
if (StringUtils.isEmpty(addDTO.getStatus())) {
throw new RuntimeException("状态不能为空");
}
// 验证身份证号格式
String idCardError = IdCardUtil.getErrorMessage(addDTO.getIdCard());
if (idCardError != null) {
throw new RuntimeException(idCardError);
}
// 检查柜员号唯一性
LambdaQueryWrapper<CcdiEmployee> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CcdiEmployee::getTellerNo, addDTO.getTellerNo());
if (employeeMapper.selectCount(wrapper) > 0) {
throw new RuntimeException("该柜员号已存在");
}
// 检查身份证号唯一性
wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CcdiEmployee::getIdCard, addDTO.getIdCard());
if (employeeMapper.selectCount(wrapper) > 0) {
throw new RuntimeException("该身份证号已存在");
}
// 验证状态
if (!"0".equals(addDTO.getStatus()) && !"1".equals(addDTO.getStatus())) {
throw new RuntimeException("状态只能填写'在职'或'离职'");
}
}
/**
* 转换为VO对象
*/
private CcdiEmployeeVO convertToVO(CcdiEmployee employee) {
if (employee == null) {
return null;
}
CcdiEmployeeVO vo = new CcdiEmployeeVO();
BeanUtils.copyProperties(employee, vo);
vo.setStatusDesc(EmployeeStatus.getDescByCode(employee.getStatus()));
return vo;
}
}

View File

@@ -0,0 +1,741 @@
package com.ruoyi.ccdi.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.domain.CcdiIntermediaryBlacklist;
import com.ruoyi.ccdi.domain.dto.*;
import com.ruoyi.ccdi.domain.excel.CcdiIntermediaryBlacklistExcel;
import com.ruoyi.ccdi.domain.excel.CcdiIntermediaryEntityExcel;
import com.ruoyi.ccdi.domain.excel.CcdiIntermediaryPersonExcel;
import com.ruoyi.ccdi.domain.vo.CcdiIntermediaryBlacklistVO;
import com.ruoyi.ccdi.domain.vo.CcdiIntermediaryEntityDetailVO;
import com.ruoyi.ccdi.domain.vo.CcdiIntermediaryPersonDetailVO;
import com.ruoyi.ccdi.enums.DataSource;
import com.ruoyi.ccdi.enums.Gender;
import com.ruoyi.ccdi.enums.IntermediaryStatus;
import com.ruoyi.ccdi.enums.IntermediaryType;
import com.ruoyi.ccdi.mapper.CcdiIntermediaryBlacklistMapper;
import com.ruoyi.ccdi.service.ICcdiIntermediaryBlacklistService;
import com.ruoyi.common.utils.StringUtils;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
* 中介人员黑名单 服务层处理
*
* @author ruoyi
* @date 2026-01-27
*/
@Service
public class CcdiIntermediaryBlacklistServiceImpl implements ICcdiIntermediaryBlacklistService {
@Resource
private CcdiIntermediaryBlacklistMapper intermediaryMapper;
/**
* 查询中介黑名单列表
*
* @param queryDTO 查询条件
* @return 中介黑名单集合
*/
@Override
public List<CcdiIntermediaryBlacklistVO> selectIntermediaryList(CcdiIntermediaryBlacklistQueryDTO queryDTO) {
LambdaQueryWrapper<CcdiIntermediaryBlacklist> wrapper = buildQueryWrapper(queryDTO);
List<CcdiIntermediaryBlacklist> list = intermediaryMapper.selectList(wrapper);
return list.stream().map(this::convertToVO).collect(Collectors.toList());
}
/**
* 分页查询中介黑名单列表
*
* @param page 分页对象
* @param queryDTO 查询条件
* @return 中介黑名单VO分页结果
*/
@Override
public Page<CcdiIntermediaryBlacklistVO> selectIntermediaryPage(Page<CcdiIntermediaryBlacklist> page, CcdiIntermediaryBlacklistQueryDTO queryDTO) {
LambdaQueryWrapper<CcdiIntermediaryBlacklist> wrapper = buildQueryWrapper(queryDTO);
Page<CcdiIntermediaryBlacklist> resultPage = intermediaryMapper.selectPage(page, wrapper);
// 转换为VO
Page<CcdiIntermediaryBlacklistVO> voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal());
voPage.setRecords(resultPage.getRecords().stream().map(this::convertToVO).collect(Collectors.toList()));
voPage.setPages(resultPage.getPages());
return voPage;
}
/**
* 查询中介黑名单列表(用于导出)
*
* @param queryDTO 查询条件
* @return 中介黑名单Excel实体集合
*/
@Override
public List<CcdiIntermediaryBlacklistExcel> selectIntermediaryListForExport(CcdiIntermediaryBlacklistQueryDTO queryDTO) {
LambdaQueryWrapper<CcdiIntermediaryBlacklist> wrapper = buildQueryWrapper(queryDTO);
List<CcdiIntermediaryBlacklist> list = intermediaryMapper.selectList(wrapper);
return list.stream().map(entity -> {
CcdiIntermediaryBlacklistExcel excel = new CcdiIntermediaryBlacklistExcel();
BeanUtils.copyProperties(entity, excel);
return excel;
}).toList();
}
/**
* 查询中介黑名单详细
*
* @param intermediaryId 中介ID
* @return 中介黑名单VO
*/
@Override
public CcdiIntermediaryBlacklistVO selectIntermediaryById(Long intermediaryId) {
CcdiIntermediaryBlacklist intermediary = intermediaryMapper.selectById(intermediaryId);
return convertToVO(intermediary);
}
/**
* 新增中介黑名单
*
* @param addDTO 新增DTO
* @return 结果
*/
@Override
@Deprecated
public int insertIntermediary(CcdiIntermediaryBlacklistAddDTO addDTO) {
CcdiIntermediaryBlacklist intermediary = new CcdiIntermediaryBlacklist();
BeanUtils.copyProperties(addDTO, intermediary);
// 手动新增时,数据来源设置为 MANUAL
intermediary.setDataSource("MANUAL");
// 默认状态设置为正常
intermediary.setStatus("0");
return intermediaryMapper.insert(intermediary);
}
/**
* 新增个人中介黑名单
*
* @param addDTO 个人中介新增DTO
* @return 结果
*/
@Override
public int insertPersonIntermediary(CcdiIntermediaryPersonAddDTO addDTO) {
CcdiIntermediaryBlacklist intermediary = new CcdiIntermediaryBlacklist();
BeanUtils.copyProperties(addDTO, intermediary);
// 设置中介类型为个人
intermediary.setIntermediaryType("1");
// 手动新增时,数据来源设置为 MANUAL
intermediary.setDataSource("MANUAL");
return intermediaryMapper.insert(intermediary);
}
/**
* 新增机构中介黑名单
*
* @param addDTO 机构中介新增DTO
* @return 结果
*/
@Override
public int insertEntityIntermediary(CcdiIntermediaryEntityAddDTO addDTO) {
CcdiIntermediaryBlacklist intermediary = new CcdiIntermediaryBlacklist();
BeanUtils.copyProperties(addDTO, intermediary);
// 设置中介类型为机构
intermediary.setIntermediaryType("2");
// 证件号使用统一社会信用代码
intermediary.setCertificateNo(addDTO.getCorpCreditCode());
// 手动新增时,数据来源设置为 MANUAL
intermediary.setDataSource("MANUAL");
return intermediaryMapper.insert(intermediary);
}
/**
* 修改中介黑名单
*
* @param editDTO 编辑DTO
* @return 结果
*/
@Override
@Deprecated
public int updateIntermediary(CcdiIntermediaryBlacklistEditDTO editDTO) {
CcdiIntermediaryBlacklist intermediary = new CcdiIntermediaryBlacklist();
BeanUtils.copyProperties(editDTO, intermediary);
return intermediaryMapper.updateById(intermediary);
}
/**
* 修改个人中介黑名单
*
* @param editDTO 个人中介编辑DTO
* @return 结果
*/
@Override
public int updatePersonIntermediary(CcdiIntermediaryPersonEditDTO editDTO) {
CcdiIntermediaryBlacklist intermediary = new CcdiIntermediaryBlacklist();
BeanUtils.copyProperties(editDTO, intermediary);
// 设置中介类型为个人
intermediary.setIntermediaryType("1");
// 清空机构专属字段
clearEntityFields(intermediary);
return intermediaryMapper.updateById(intermediary);
}
/**
* 修改机构中介黑名单
*
* @param editDTO 机构中介编辑DTO
* @return 结果
*/
@Override
public int updateEntityIntermediary(CcdiIntermediaryEntityEditDTO editDTO) {
CcdiIntermediaryBlacklist intermediary = new CcdiIntermediaryBlacklist();
BeanUtils.copyProperties(editDTO, intermediary);
// 设置中介类型为机构
intermediary.setIntermediaryType("2");
// 清空个人专属字段
clearPersonFields(intermediary);
return intermediaryMapper.updateById(intermediary);
}
/**
* 清空个人专属字段
*/
private void clearPersonFields(CcdiIntermediaryBlacklist intermediary) {
intermediary.setIndivType(null);
intermediary.setIndivSubType(null);
intermediary.setIndivGender(null);
intermediary.setIndivCertType(null);
intermediary.setIndivPhone(null);
intermediary.setIndivWechat(null);
intermediary.setIndivAddress(null);
intermediary.setIndivCompany(null);
intermediary.setIndivPosition(null);
intermediary.setIndivRelatedId(null);
intermediary.setIndivRelation(null);
}
/**
* 清空机构专属字段
*/
private void clearEntityFields(CcdiIntermediaryBlacklist intermediary) {
intermediary.setCorpCreditCode(null);
intermediary.setCorpType(null);
intermediary.setCorpNature(null);
intermediary.setCorpIndustryCategory(null);
intermediary.setCorpIndustry(null);
intermediary.setCorpEstablishDate(null);
intermediary.setCorpAddress(null);
intermediary.setCorpLegalRep(null);
intermediary.setCorpLegalCertType(null);
intermediary.setCorpLegalCertNo(null);
intermediary.setCorpShareholder1(null);
intermediary.setCorpShareholder2(null);
intermediary.setCorpShareholder3(null);
intermediary.setCorpShareholder4(null);
intermediary.setCorpShareholder5(null);
}
/**
* 批量删除中介黑名单
*
* @param intermediaryIds 需要删除的中介ID
* @return 结果
*/
@Override
public int deleteIntermediaryByIds(Long[] intermediaryIds) {
return intermediaryMapper.deleteBatchIds(List.of(intermediaryIds));
}
/**
* 导入中介黑名单数据
*
* @param excelList Excel实体列表
* @param isUpdateSupport 是否更新支持
* @return 结果
*/
@Override
public String importIntermediary(List<CcdiIntermediaryBlacklistExcel> excelList, Boolean isUpdateSupport) {
if (excelList == null || excelList.isEmpty()) {
return "至少需要一条数据";
}
int successNum = 0;
int failureNum = 0;
StringBuilder successMsg = new StringBuilder();
StringBuilder failureMsg = new StringBuilder();
for (CcdiIntermediaryBlacklistExcel excel : excelList) {
try {
// 转换为AddDTO
CcdiIntermediaryBlacklistAddDTO addDTO = new CcdiIntermediaryBlacklistAddDTO();
BeanUtils.copyProperties(excel, addDTO);
// 验证数据
validateIntermediaryData(addDTO);
CcdiIntermediaryBlacklist intermediary = new CcdiIntermediaryBlacklist();
BeanUtils.copyProperties(addDTO, intermediary);
intermediaryMapper.insert(intermediary);
successNum++;
successMsg.append("<br/>").append(successNum).append("").append(addDTO.getName()).append(" 导入成功");
} catch (Exception e) {
failureNum++;
failureMsg.append("<br/>").append(failureNum).append("").append(excel.getName()).append(" 导入失败:");
failureMsg.append(e.getMessage());
}
}
if (failureNum > 0) {
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new RuntimeException(failureMsg.toString());
} else {
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + "");
return successMsg.toString();
}
}
/**
* 根据中介类型获取详情(返回不同类型)
*
* @param intermediaryId 中介ID
* @return 个人返回 CcdiIntermediaryPersonDetailVO机构返回 CcdiIntermediaryEntityDetailVO
*/
@Override
public Object selectIntermediaryDetailById(Long intermediaryId) {
CcdiIntermediaryBlacklist intermediary = intermediaryMapper.selectById(intermediaryId);
if (intermediary == null) {
return null;
}
// 根据中介类型返回不同的 VO
if ("1".equals(intermediary.getIntermediaryType())) {
// 个人类型
return convertToPersonDetailVO(intermediary);
} else {
// 机构类型
return convertToEntityDetailVO(intermediary);
}
}
/**
* 导入个人中介数据(批量插入优化版)
*
* @param excelList Excel实体列表
* @param isUpdateSupport 是否更新支持
* @return 结果
*/
@Override
public String importPersonIntermediary(List<CcdiIntermediaryPersonExcel> excelList, Boolean isUpdateSupport) {
if (excelList == null || excelList.isEmpty()) {
return "至少需要一条数据";
}
// 批量处理:先验证所有数据
List<CcdiIntermediaryBlacklist> toInsertList = new ArrayList<>();
List<CcdiIntermediaryBlacklist> toUpdateList = new ArrayList<>();
List<String> errorMessages = new ArrayList<>();
// 批量查询已存在的记录(用于唯一性校验或更新支持)
Set<String> existingCertNos = new HashSet<>();
Map<String, Long> certNoToIdMap = new HashMap<>();
for (CcdiIntermediaryPersonExcel excel : excelList) {
if (StringUtils.isNotEmpty(excel.getCertificateNo())) {
existingCertNos.add(excel.getCertificateNo());
}
}
if (!existingCertNos.isEmpty()) {
LambdaQueryWrapper<CcdiIntermediaryBlacklist> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CcdiIntermediaryBlacklist::getIntermediaryType, "1")
.in(CcdiIntermediaryBlacklist::getCertificateNo, existingCertNos)
.select(CcdiIntermediaryBlacklist::getIntermediaryId, CcdiIntermediaryBlacklist::getCertificateNo);
List<CcdiIntermediaryBlacklist> existingList = intermediaryMapper.selectList(wrapper);
for (CcdiIntermediaryBlacklist existing : existingList) {
certNoToIdMap.put(existing.getCertificateNo(), existing.getIntermediaryId());
}
}
// 如果不是更新模式,先进行唯一性校验
if (!isUpdateSupport) {
for (CcdiIntermediaryPersonExcel excel : excelList) {
if (StringUtils.isNotEmpty(excel.getCertificateNo()) && certNoToIdMap.containsKey(excel.getCertificateNo())) {
throw new RuntimeException("证件号 " + excel.getCertificateNo() + " 已存在,请勿重复导入");
}
}
}
// 处理每条数据
for (int i = 0; i < excelList.size(); i++) {
CcdiIntermediaryPersonExcel excel = excelList.get(i);
try {
// 验证数据
validatePersonIntermediaryData(excel);
// 转换为实体
CcdiIntermediaryBlacklist intermediary = new CcdiIntermediaryBlacklist();
intermediary.setName(excel.getName());
intermediary.setCertificateNo(excel.getCertificateNo());
intermediary.setIntermediaryType("1");
intermediary.setStatus("0");
intermediary.setDataSource("IMPORT");
intermediary.setRemark(excel.getRemark());
// 个人专属字段
intermediary.setIndivType(excel.getIndivType());
intermediary.setIndivSubType(excel.getIndivSubType());
intermediary.setIndivGender(excel.getIndivGender());
intermediary.setIndivCertType(StringUtils.isNotEmpty(excel.getIndivCertType()) ? excel.getIndivCertType() : "身份证");
intermediary.setIndivPhone(excel.getIndivPhone());
intermediary.setIndivWechat(excel.getIndivWechat());
intermediary.setIndivAddress(excel.getIndivAddress());
intermediary.setIndivCompany(excel.getIndivCompany());
intermediary.setIndivPosition(excel.getIndivPosition());
intermediary.setIndivRelatedId(excel.getIndivRelatedId());
intermediary.setIndivRelation(excel.getIndivRelation());
// 检查是否需要更新
if (isUpdateSupport && StringUtils.isNotEmpty(excel.getCertificateNo()) && certNoToIdMap.containsKey(excel.getCertificateNo())) {
intermediary.setIntermediaryId(certNoToIdMap.get(excel.getCertificateNo()));
toUpdateList.add(intermediary);
} else {
toInsertList.add(intermediary);
}
} catch (Exception e) {
errorMessages.add("" + (i + 1) + "行导入失败:" + e.getMessage());
}
}
// 批量执行数据库操作
int successNum = 0;
int failureNum = errorMessages.size();
// 批量插入
if (!toInsertList.isEmpty()) {
intermediaryMapper.batchInsert(toInsertList);
successNum += toInsertList.size();
}
// 批量更新
if (!toUpdateList.isEmpty()) {
intermediaryMapper.batchUpdate(toUpdateList);
successNum += toUpdateList.size();
}
// 构建失败消息
StringBuilder failureMsg = new StringBuilder();
for (String error : errorMessages) {
failureMsg.append("<br/>").append(error);
}
// 返回结果
if (failureNum > 0) {
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new RuntimeException(failureMsg.toString());
} else {
return "恭喜您,数据已全部导入成功!共 " + successNum + "";
}
}
/**
* 导入机构中介数据(批量插入优化版)
*
* @param excelList Excel实体列表
* @param isUpdateSupport 是否更新支持
* @return 结果
*/
@Override
public String importEntityIntermediary(List<CcdiIntermediaryEntityExcel> excelList, Boolean isUpdateSupport) {
if (excelList == null || excelList.isEmpty()) {
return "至少需要一条数据";
}
// 批量处理:先验证所有数据
List<CcdiIntermediaryBlacklist> toInsertList = new ArrayList<>();
List<CcdiIntermediaryBlacklist> toUpdateList = new ArrayList<>();
List<String> errorMessages = new ArrayList<>();
// 批量查询已存在的记录(用于唯一性校验或更新支持)
Set<String> existingCreditCodes = new HashSet<>();
Map<String, Long> creditCodeToIdMap = new HashMap<>();
for (CcdiIntermediaryEntityExcel excel : excelList) {
if (StringUtils.isNotEmpty(excel.getCorpCreditCode())) {
existingCreditCodes.add(excel.getCorpCreditCode());
}
}
if (!existingCreditCodes.isEmpty()) {
LambdaQueryWrapper<CcdiIntermediaryBlacklist> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CcdiIntermediaryBlacklist::getIntermediaryType, "2")
.in(CcdiIntermediaryBlacklist::getCorpCreditCode, existingCreditCodes)
.select(CcdiIntermediaryBlacklist::getIntermediaryId, CcdiIntermediaryBlacklist::getCorpCreditCode);
List<CcdiIntermediaryBlacklist> existingList = intermediaryMapper.selectList(wrapper);
for (CcdiIntermediaryBlacklist existing : existingList) {
creditCodeToIdMap.put(existing.getCorpCreditCode(), existing.getIntermediaryId());
}
}
// 如果不是更新模式,先进行唯一性校验
if (!isUpdateSupport) {
for (CcdiIntermediaryEntityExcel excel : excelList) {
if (StringUtils.isNotEmpty(excel.getCorpCreditCode()) && creditCodeToIdMap.containsKey(excel.getCorpCreditCode())) {
throw new RuntimeException("统一社会信用代码 " + excel.getCorpCreditCode() + " 已存在,请勿重复导入");
}
}
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 处理每条数据
for (int i = 0; i < excelList.size(); i++) {
CcdiIntermediaryEntityExcel excel = excelList.get(i);
try {
// 验证数据
validateEntityIntermediaryData(excel);
// 转换为实体
CcdiIntermediaryBlacklist intermediary = new CcdiIntermediaryBlacklist();
intermediary.setName(excel.getName());
// 对于机构中介,使用统一社会信用代码作为证件号
intermediary.setCertificateNo(excel.getCorpCreditCode());
intermediary.setIntermediaryType("2");
intermediary.setStatus("0");
intermediary.setDataSource("IMPORT");
intermediary.setRemark(excel.getRemark());
// 机构专属字段
intermediary.setCorpCreditCode(excel.getCorpCreditCode());
intermediary.setCorpType(excel.getCorpType());
intermediary.setCorpNature(excel.getCorpNature());
intermediary.setCorpIndustryCategory(excel.getCorpIndustryCategory());
intermediary.setCorpIndustry(excel.getCorpIndustry());
// 解析成立日期
if (StringUtils.isNotEmpty(excel.getCorpEstablishDate())) {
try {
intermediary.setCorpEstablishDate(sdf.parse(excel.getCorpEstablishDate()));
} catch (Exception e) {
// 忽略日期解析错误
}
}
intermediary.setCorpAddress(excel.getCorpAddress());
intermediary.setCorpLegalRep(excel.getCorpLegalRep());
intermediary.setCorpLegalCertType(excel.getCorpLegalCertType());
intermediary.setCorpLegalCertNo(excel.getCorpLegalCertNo());
intermediary.setCorpShareholder1(excel.getCorpShareholder1());
intermediary.setCorpShareholder2(excel.getCorpShareholder2());
intermediary.setCorpShareholder3(excel.getCorpShareholder3());
intermediary.setCorpShareholder4(excel.getCorpShareholder4());
intermediary.setCorpShareholder5(excel.getCorpShareholder5());
// 检查是否需要更新
if (isUpdateSupport && StringUtils.isNotEmpty(excel.getCorpCreditCode()) && creditCodeToIdMap.containsKey(excel.getCorpCreditCode())) {
intermediary.setIntermediaryId(creditCodeToIdMap.get(excel.getCorpCreditCode()));
toUpdateList.add(intermediary);
} else {
toInsertList.add(intermediary);
}
} catch (Exception e) {
errorMessages.add("" + (i + 1) + "行导入失败:" + e.getMessage());
}
}
// 批量执行数据库操作
int successNum = 0;
int failureNum = errorMessages.size();
// 批量插入
if (!toInsertList.isEmpty()) {
intermediaryMapper.batchInsert(toInsertList);
successNum += toInsertList.size();
}
// 批量更新
if (!toUpdateList.isEmpty()) {
intermediaryMapper.batchUpdate(toUpdateList);
successNum += toUpdateList.size();
}
// 构建失败消息
StringBuilder failureMsg = new StringBuilder();
for (String error : errorMessages) {
failureMsg.append("<br/>").append(error);
}
// 返回结果
if (failureNum > 0) {
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new RuntimeException(failureMsg.toString());
} else {
return "恭喜您,数据已全部导入成功!共 " + successNum + "";
}
}
/**
* 验证个人中介数据
*/
private void validatePersonIntermediaryData(CcdiIntermediaryPersonExcel excel) {
if (StringUtils.isEmpty(excel.getName())) {
throw new RuntimeException("姓名不能为空");
}
if (StringUtils.isEmpty(excel.getCertificateNo())) {
throw new RuntimeException("证件号码不能为空");
}
}
/**
* 验证机构中介数据
*/
private void validateEntityIntermediaryData(CcdiIntermediaryEntityExcel excel) {
if (StringUtils.isEmpty(excel.getName())) {
throw new RuntimeException("机构名称不能为空");
}
// 验证统一社会信用代码不能为空(因为会用作 certificate_no 字段)
if (StringUtils.isEmpty(excel.getCorpCreditCode())) {
throw new RuntimeException("统一社会信用代码不能为空");
}
}
/**
* 转换为个人详情 VO
*/
private CcdiIntermediaryPersonDetailVO convertToPersonDetailVO(CcdiIntermediaryBlacklist intermediary) {
if (intermediary == null) {
return null;
}
CcdiIntermediaryPersonDetailVO vo = new CcdiIntermediaryPersonDetailVO();
// 复制基础字段
vo.setIntermediaryId(intermediary.getIntermediaryId());
vo.setName(intermediary.getName());
vo.setCertificateNo(intermediary.getCertificateNo());
vo.setIntermediaryType(intermediary.getIntermediaryType());
vo.setStatus(intermediary.getStatus());
vo.setRemark(intermediary.getRemark());
vo.setDataSource(intermediary.getDataSource());
vo.setCreateBy(intermediary.getCreateBy());
vo.setCreateTime(intermediary.getCreateTime());
vo.setUpdateBy(intermediary.getUpdateBy());
vo.setUpdateTime(intermediary.getUpdateTime());
// 复制个人专属字段
vo.setIndivType(intermediary.getIndivType());
vo.setIndivSubType(intermediary.getIndivSubType());
vo.setIndivGender(intermediary.getIndivGender());
vo.setIndivCertType(intermediary.getIndivCertType());
vo.setIndivPhone(intermediary.getIndivPhone());
vo.setIndivWechat(intermediary.getIndivWechat());
vo.setIndivAddress(intermediary.getIndivAddress());
vo.setIndivCompany(intermediary.getIndivCompany());
vo.setIndivPosition(intermediary.getIndivPosition());
vo.setIndivRelatedId(intermediary.getIndivRelatedId());
vo.setIndivRelation(intermediary.getIndivRelation());
// 设置枚举类型的名称
vo.setIntermediaryTypeName(IntermediaryType.PERSON.getDesc());
vo.setStatusName(IntermediaryStatus.getDescByCode(intermediary.getStatus()));
vo.setDataSourceName(DataSource.getDescByCode(intermediary.getDataSource()));
vo.setIndivGenderName(Gender.getDescByCode(intermediary.getIndivGender()));
return vo;
}
/**
* 转换为机构详情 VO
*/
private CcdiIntermediaryEntityDetailVO convertToEntityDetailVO(CcdiIntermediaryBlacklist intermediary) {
if (intermediary == null) {
return null;
}
CcdiIntermediaryEntityDetailVO vo = new CcdiIntermediaryEntityDetailVO();
// 复制基础字段
vo.setIntermediaryId(intermediary.getIntermediaryId());
vo.setName(intermediary.getName());
vo.setCertificateNo(intermediary.getCertificateNo());
vo.setIntermediaryType(intermediary.getIntermediaryType());
vo.setStatus(intermediary.getStatus());
vo.setRemark(intermediary.getRemark());
vo.setDataSource(intermediary.getDataSource());
vo.setCreateBy(intermediary.getCreateBy());
vo.setCreateTime(intermediary.getCreateTime());
vo.setUpdateBy(intermediary.getUpdateBy());
vo.setUpdateTime(intermediary.getUpdateTime());
// 复制机构专属字段
vo.setCorpCreditCode(intermediary.getCorpCreditCode());
vo.setCorpType(intermediary.getCorpType());
vo.setCorpNature(intermediary.getCorpNature());
vo.setCorpIndustryCategory(intermediary.getCorpIndustryCategory());
vo.setCorpIndustry(intermediary.getCorpIndustry());
vo.setCorpEstablishDate(intermediary.getCorpEstablishDate());
vo.setCorpAddress(intermediary.getCorpAddress());
vo.setCorpLegalRep(intermediary.getCorpLegalRep());
vo.setCorpLegalCertType(intermediary.getCorpLegalCertType());
vo.setCorpLegalCertNo(intermediary.getCorpLegalCertNo());
vo.setCorpShareholder1(intermediary.getCorpShareholder1());
vo.setCorpShareholder2(intermediary.getCorpShareholder2());
vo.setCorpShareholder3(intermediary.getCorpShareholder3());
vo.setCorpShareholder4(intermediary.getCorpShareholder4());
vo.setCorpShareholder5(intermediary.getCorpShareholder5());
// 设置枚举类型的名称
vo.setIntermediaryTypeName(IntermediaryType.ENTITY.getDesc());
vo.setStatusName(IntermediaryStatus.getDescByCode(intermediary.getStatus()));
vo.setDataSourceName(DataSource.getDescByCode(intermediary.getDataSource()));
return vo;
}
/**
* 构建查询条件
*/
private LambdaQueryWrapper<CcdiIntermediaryBlacklist> buildQueryWrapper(CcdiIntermediaryBlacklistQueryDTO queryDTO) {
LambdaQueryWrapper<CcdiIntermediaryBlacklist> wrapper = new LambdaQueryWrapper<>();
wrapper.like(StringUtils.isNotEmpty(queryDTO.getName()), CcdiIntermediaryBlacklist::getName, queryDTO.getName())
.like(StringUtils.isNotEmpty(queryDTO.getCertificateNo()), CcdiIntermediaryBlacklist::getCertificateNo, queryDTO.getCertificateNo())
.eq(StringUtils.isNotEmpty(queryDTO.getIntermediaryType()), CcdiIntermediaryBlacklist::getIntermediaryType, queryDTO.getIntermediaryType())
.eq(StringUtils.isNotEmpty(queryDTO.getStatus()), CcdiIntermediaryBlacklist::getStatus, queryDTO.getStatus())
.orderByDesc(CcdiIntermediaryBlacklist::getCreateTime);
return wrapper;
}
/**
* 验证中介数据
*/
private void validateIntermediaryData(CcdiIntermediaryBlacklistAddDTO addDTO) {
// 验证必填字段
if (StringUtils.isEmpty(addDTO.getName())) {
throw new RuntimeException("姓名/机构名称不能为空");
}
if (StringUtils.isEmpty(addDTO.getIntermediaryType())) {
throw new RuntimeException("中介类型不能为空");
}
// 验证中介类型
if (!"1".equals(addDTO.getIntermediaryType()) && !"2".equals(addDTO.getIntermediaryType())) {
throw new RuntimeException("中介类型只能填写'个人'或'机构'");
}
}
/**
* 转换为VO对象
*/
private CcdiIntermediaryBlacklistVO convertToVO(CcdiIntermediaryBlacklist intermediary) {
if (intermediary == null) {
return null;
}
CcdiIntermediaryBlacklistVO vo = new CcdiIntermediaryBlacklistVO();
BeanUtils.copyProperties(intermediary, vo);
vo.setIntermediaryTypeName(IntermediaryType.getDescByCode(intermediary.getIntermediaryType()));
vo.setStatusName(IntermediaryStatus.getDescByCode(intermediary.getStatus()));
return vo;
}
}

View File

@@ -0,0 +1,253 @@
package com.ruoyi.ccdi.utils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.ruoyi.ccdi.handler.DictDropdownWriteHandler;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
* EasyExcel工具类
*
* @author ruoyi
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class EasyExcelUtil {
/**
* 导出Excel
*
* @param response 响应对象
* @param list 数据列表
* @param clazz 实体类
* @param sheetName 工作表名称
* @param <T> 泛型
*/
public static <T> void exportExcel(HttpServletResponse response, List<T> list, Class<T> clazz, String sheetName) {
try {
setResponseHeader(response, sheetName);
EasyExcel.write(response.getOutputStream(), clazz)
.sheet(sheetName)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.doWrite(list);
} catch (IOException e) {
throw new RuntimeException("导出Excel失败", e);
}
}
/**
* 导出Excel指定数据
*
* @param response 响应对象
* @param list 数据列表
* @param clazz 实体类
* @param sheetName 工作表名称
* @param fileName 文件名称
* @param <T> 泛型
*/
public static <T> void exportExcel(HttpServletResponse response, List<T> list, Class<T> clazz, String sheetName, String fileName) {
try {
setResponseHeader(response, fileName);
EasyExcel.write(response.getOutputStream(), clazz)
.sheet(sheetName)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.doWrite(list);
} catch (IOException e) {
throw new RuntimeException("导出Excel失败", e);
}
}
/**
* 导入Excel
*
* @param fileName 文件名
* @param clazz 实体类
* @param <T> 泛型
* @return 数据列表
*/
public static <T> List<T> importExcel(String fileName, Class<T> clazz) {
try {
return EasyExcel.read(fileName).head(clazz).sheet().doReadSync();
} catch (Exception e) {
throw new RuntimeException("导入Excel失败", e);
}
}
/**
* 导入Excel通过输入流
*
* @param inputStream 输入流
* @param clazz 实体类
* @param <T> 泛型
* @return 数据列表
*/
public static <T> List<T> importExcel(java.io.InputStream inputStream, Class<T> clazz) {
try {
return EasyExcel.read(inputStream).head(clazz).sheet().doReadSync();
} catch (Exception e) {
throw new RuntimeException("导入Excel失败", e);
}
}
/**
* 下载导入模板
*
* @param response 响应对象
* @param clazz 实体类
* @param sheetName 工作表名称
* @param <T> 泛型
*/
public static <T> void importTemplateExcel(HttpServletResponse response, Class<T> clazz, String sheetName) {
try {
setResponseHeader(response, sheetName + "模板");
EasyExcel.write(response.getOutputStream(), clazz)
.sheet(sheetName)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.doWrite(List.of());
} catch (IOException e) {
throw new RuntimeException("下载导入模板失败", e);
}
}
/**
* 下载导入模板(带自定义处理器)
*
* @param response 响应对象
* @param clazz 实体类
* @param sheetName 工作表名称
* @param handlers 自定义写入处理器
* @param <T> 泛型
*/
@SafeVarargs
public static <T> void importTemplateExcel(HttpServletResponse response, Class<T> clazz, String sheetName,
WriteHandler... handlers) {
try {
setResponseHeader(response, sheetName + "模板");
var writerBuilder = EasyExcel.write(response.getOutputStream(), clazz)
.sheet(sheetName)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy());
// 注册所有自定义处理器
for (WriteHandler handler : handlers) {
writerBuilder.registerWriteHandler(handler);
}
writerBuilder.doWrite(List.of());
} catch (IOException e) {
throw new RuntimeException("下载导入模板失败", e);
}
}
/**
* 设置响应头
*
* @param response 响应对象
* @param fileName 文件名
*/
private static void setResponseHeader(HttpServletResponse response, String fileName) {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");
}
/**
* 下载带字典下拉框的导入模板
* 自动解析实体类中的@DictDropdown注解为对应字段添加下拉框
*
* @param response 响应对象
* @param clazz 实体类
* @param sheetName 工作表名称
* @param <T> 泛型
*/
public static <T> void importTemplateWithDictDropdown(HttpServletResponse response, Class<T> clazz, String sheetName) {
try {
setResponseHeader(response, sheetName + "模板");
EasyExcel.write(response.getOutputStream(), clazz)
.sheet(sheetName)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.registerWriteHandler(new DictDropdownWriteHandler(clazz))
.doWrite(List.of());
} catch (IOException e) {
throw new RuntimeException("下载带字典下拉框的导入模板失败", e);
}
}
/**
* 下载带字典下拉框的导入模板(指定文件名)
* 自动解析实体类中的@DictDropdown注解为对应字段添加下拉框
*
* @param response 响应对象
* @param clazz 实体类
* @param sheetName 工作表名称
* @param fileName 文件名称
* @param <T> 泛型
*/
public static <T> void importTemplateWithDictDropdown(HttpServletResponse response, Class<T> clazz,
String sheetName, String fileName) {
try {
setResponseHeader(response, fileName);
EasyExcel.write(response.getOutputStream(), clazz)
.sheet(sheetName)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.registerWriteHandler(new DictDropdownWriteHandler(clazz))
.doWrite(List.of());
} catch (IOException e) {
throw new RuntimeException("下载带字典下拉框的导入模板失败", e);
}
}
/**
* 导出Excel带字典下拉框
* 导出的数据包含实际值,但模板中有下拉框供后续编辑使用
*
* @param response 响应对象
* @param list 数据列表
* @param clazz 实体类
* @param sheetName 工作表名称
* @param <T> 泛型
*/
public static <T> void exportExcelWithDictDropdown(HttpServletResponse response, List<T> list,
Class<T> clazz, String sheetName) {
try {
setResponseHeader(response, sheetName);
EasyExcel.write(response.getOutputStream(), clazz)
.sheet(sheetName)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.registerWriteHandler(new DictDropdownWriteHandler(clazz))
.doWrite(list);
} catch (IOException e) {
throw new RuntimeException("导出带字典下拉框的Excel失败", e);
}
}
/**
* 导出Excel带字典下拉框指定文件名
* 导出的数据包含实际值,但模板中有下拉框供后续编辑使用
*
* @param response 响应对象
* @param list 数据列表
* @param clazz 实体类
* @param sheetName 工作表名称
* @param fileName 文件名称
* @param <T> 泛型
*/
public static <T> void exportExcelWithDictDropdown(HttpServletResponse response, List<T> list,
Class<T> clazz, String sheetName, String fileName) {
try {
setResponseHeader(response, fileName);
EasyExcel.write(response.getOutputStream(), clazz)
.sheet(sheetName)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.registerWriteHandler(new DictDropdownWriteHandler(clazz))
.doWrite(list);
} catch (IOException e) {
throw new RuntimeException("导出带字典下拉框的Excel失败", e);
}
}
}

View File

@@ -0,0 +1,65 @@
package com.ruoyi.ccdi.utils.converter;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.util.HashMap;
import java.util.Map;
/**
* 员工状态转换器
* 0=在职, 1=离职
*
* @author ruoyi
*/
public class EmployeeStatusConverter implements Converter<String> {
private static final Map<String, String> CODE_TO_DESC = new HashMap<>();
private static final Map<String, String> DESC_TO_CODE = new HashMap<>();
static {
CODE_TO_DESC.put("0", "在职");
CODE_TO_DESC.put("1", "离职");
DESC_TO_CODE.put("在职", "0");
DESC_TO_CODE.put("离职", "1");
}
@Override
public Class<?> supportJavaTypeKey() {
return String.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public String convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
String value = cellData.getStringValue();
if (value == null) {
return null;
}
// 支持中文和代码两种格式
if (DESC_TO_CODE.containsKey(value)) {
return DESC_TO_CODE.get(value);
}
// 如果是纯数字,直接返回
if (value.matches("\\d")) {
return value;
}
throw new IllegalArgumentException("无效的员工状态: " + value + ", 请使用: 在职/离职 或 0/1");
}
@Override
public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
String desc = CODE_TO_DESC.getOrDefault(value, value);
return new WriteCellData<>(desc);
}
}

View File

@@ -0,0 +1,65 @@
package com.ruoyi.ccdi.utils.converter;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.util.HashMap;
import java.util.Map;
/**
* 中介黑名单状态转换器
* 0=正常, 1=停用
*
* @author ruoyi
*/
public class IntermediaryStatusConverter implements Converter<String> {
private static final Map<String, String> CODE_TO_DESC = new HashMap<>();
private static final Map<String, String> DESC_TO_CODE = new HashMap<>();
static {
CODE_TO_DESC.put("0", "正常");
CODE_TO_DESC.put("1", "停用");
DESC_TO_CODE.put("正常", "0");
DESC_TO_CODE.put("停用", "1");
}
@Override
public Class<?> supportJavaTypeKey() {
return String.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public String convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
String value = cellData.getStringValue();
if (value == null) {
return null;
}
// 支持中文和代码两种格式
if (DESC_TO_CODE.containsKey(value)) {
return DESC_TO_CODE.get(value);
}
// 如果是纯数字,直接返回
if (value.matches("\\d")) {
return value;
}
throw new IllegalArgumentException("无效的状态: " + value + ", 请使用: 正常/停用 或 0/1");
}
@Override
public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
String desc = CODE_TO_DESC.getOrDefault(value, value);
return new WriteCellData<>(desc);
}
}

View File

@@ -0,0 +1,65 @@
package com.ruoyi.ccdi.utils.converter;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.util.HashMap;
import java.util.Map;
/**
* 中介类型转换器
* 1=个人, 2=机构
*
* @author ruoyi
*/
public class IntermediaryTypeConverter implements Converter<String> {
private static final Map<String, String> CODE_TO_DESC = new HashMap<>();
private static final Map<String, String> DESC_TO_CODE = new HashMap<>();
static {
CODE_TO_DESC.put("1", "个人");
CODE_TO_DESC.put("2", "机构");
DESC_TO_CODE.put("个人", "1");
DESC_TO_CODE.put("机构", "2");
}
@Override
public Class<?> supportJavaTypeKey() {
return String.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public String convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
String value = cellData.getStringValue();
if (value == null) {
return null;
}
// 支持中文和代码两种格式
if (DESC_TO_CODE.containsKey(value)) {
return DESC_TO_CODE.get(value);
}
// 如果是纯数字,直接返回
if (value.matches("\\d")) {
return value;
}
throw new IllegalArgumentException("无效的中介类型: " + value + ", 请使用: 个人/机构 或 1/2");
}
@Override
public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
String desc = CODE_TO_DESC.getOrDefault(value, value);
return new WriteCellData<>(desc);
}
}

View File

@@ -0,0 +1,47 @@
package com.ruoyi.ccdi.utils.handler;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddressList;
/**
* 员工状态下拉框处理器
*
* @author ruoyi
*/
public class EmployeeStatusSheetWriteHandler implements SheetWriteHandler {
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
Sheet sheet = writeSheetHolder.getSheet();
Workbook workbook = writeWorkbookHolder.getWorkbook();
DataValidationHelper helper = sheet.getDataValidationHelper();
// 创建下拉框数据列表
String[] statusList = {"在职", "离职"};
// 设置状态下拉框从第2行开始第1行是表头第7列状态列索引为6
CellRangeAddressList addressList = new CellRangeAddressList(1, 10000, 6, 6);
// 创建显式列表约束
DataValidation validation = helper.createValidation(
helper.createExplicitListConstraint(statusList),
addressList
);
// 设置提示信息
validation.createPromptBox("状态选择", "请选择员工状态:在职或离职");
validation.setShowPromptBox(true);
// 设置错误提示
validation.createErrorBox("状态错误", "请从下拉框中选择有效的状态值!");
validation.setShowErrorBox(true);
sheet.addValidationData(validation);
}
}

View File

@@ -0,0 +1,70 @@
<?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.ccdi.mapper.CcdiEmployeeMapper">
<!-- 员工基本信息ResultMap用于列表查询不包含亲属 -->
<resultMap type="com.ruoyi.ccdi.domain.vo.CcdiEmployeeVO" id="CcdiEmployeeVOResult">
<id property="employeeId" column="employee_id"/>
<result property="name" column="name"/>
<result property="tellerNo" column="teller_no"/>
<result property="deptId" column="dept_id"/>
<result property="deptName" column="dept_name"/>
<result property="idCard" column="id_card"/>
<result property="phone" column="phone"/>
<result property="hireDate" column="hire_date"/>
<result property="status" column="status"/>
<result property="createTime" column="create_time"/>
</resultMap>
<!-- 员工详情ResultMap包含亲属信息 -->
<resultMap type="com.ruoyi.ccdi.domain.vo.CcdiEmployeeVO" id="CcdiEmployeeWithRelativesResult" extends="CcdiEmployeeVOResult">
<collection property="relatives" ofType="CcdiEmployeeRelativeVO" notNullColumn="relative_id">
<id property="relativeId" column="relative_id"/>
<result property="employeeId" column="employee_id"/>
<result property="relativeName" column="relative_name"/>
<result property="relativeIdCard" column="relative_id_card"/>
<result property="relativePhone" column="relative_phone"/>
<result property="relationship" column="relationship"/>
</collection>
</resultMap>
<select id="selectEmployeePageWithDept" resultMap="CcdiEmployeeVOResult">
SELECT
e.employee_id, e.name, e.teller_no, e.dept_id, e.id_card, e.phone, e.hire_date, e.status, e.create_time,
d.dept_name
FROM ccdi_employee e
LEFT JOIN sys_dept d ON e.dept_id = d.dept_id
<where>
<if test="query.name != null and query.name != ''">
AND e.name LIKE CONCAT('%', #{query.name}, '%')
</if>
<if test="query.tellerNo != null and query.tellerNo != ''">
AND e.teller_no = #{query.tellerNo}
</if>
<if test="query.deptId != null">
AND e.dept_id = #{query.deptId}
</if>
<if test="query.idCard != null and query.idCard != ''">
AND e.id_card LIKE CONCAT('%', #{query.idCard}, '%')
</if>
<if test="query.status != null and query.status != ''">
AND e.status = #{query.status}
</if>
</where>
ORDER BY e.create_time DESC
</select>
<select id="selectEmployeeWithRelatives" parameterType="Long" resultMap="CcdiEmployeeWithRelativesResult">
SELECT
e.employee_id, e.name, e.teller_no, e.dept_id, e.id_card, e.phone, e.hire_date, e.status, e.create_time,
d.dept_name,
r.relative_id, r.employee_id, r.relative_name, r.relative_id_card, r.relative_phone, r.relationship
FROM ccdi_employee e
LEFT JOIN sys_dept d ON e.dept_id = d.dept_id
LEFT JOIN ccdi_employee_relative r ON e.employee_id = r.employee_id
WHERE e.employee_id = #{employeeId}
</select>
</mapper>

View File

@@ -0,0 +1,134 @@
<?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.ccdi.mapper.CcdiIntermediaryBlacklistMapper">
<!-- 批量插入中介黑名单数据 -->
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO ccdi_intermediary_blacklist (
name,
certificate_no,
intermediary_type,
status,
remark,
indiv_type,
indiv_sub_type,
indiv_gender,
indiv_cert_type,
indiv_phone,
indiv_wechat,
indiv_address,
indiv_company,
indiv_position,
indiv_related_id,
indiv_relation,
corp_credit_code,
corp_type,
corp_nature,
corp_industry_category,
corp_industry,
corp_establish_date,
corp_address,
corp_legal_rep,
corp_legal_cert_type,
corp_legal_cert_no,
corp_shareholder_1,
corp_shareholder_2,
corp_shareholder_3,
corp_shareholder_4,
corp_shareholder_5,
data_source,
create_by,
create_time,
update_by,
update_time
) VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.name},
#{item.certificateNo},
#{item.intermediaryType},
#{item.status},
#{item.remark},
#{item.indivType},
#{item.indivSubType},
#{item.indivGender},
#{item.indivCertType},
#{item.indivPhone},
#{item.indivWechat},
#{item.indivAddress},
#{item.indivCompany},
#{item.indivPosition},
#{item.indivRelatedId},
#{item.indivRelation},
#{item.corpCreditCode},
#{item.corpType},
#{item.corpNature},
#{item.corpIndustryCategory},
#{item.corpIndustry},
#{item.corpEstablishDate},
#{item.corpAddress},
#{item.corpLegalRep},
#{item.corpLegalCertType},
#{item.corpLegalCertNo},
#{item.corpShareholder1},
#{item.corpShareholder2},
#{item.corpShareholder3},
#{item.corpShareholder4},
#{item.corpShareholder5},
#{item.dataSource},
#{item.createBy},
#{item.createTime},
#{item.updateBy},
#{item.updateTime}
)
</foreach>
</insert>
<!-- 批量更新中介黑名单数据 -->
<update id="batchUpdate" parameterType="java.util.List">
<foreach collection="list" item="item" separator=";">
UPDATE ccdi_intermediary_blacklist
<set>
<if test="item.name != null">name = #{item.name},</if>
<if test="item.certificateNo != null">certificate_no = #{item.certificateNo},</if>
<if test="item.intermediaryType != null">intermediary_type = #{item.intermediaryType},</if>
<if test="item.status != null">status = #{item.status},</if>
<if test="item.remark != null">remark = #{item.remark},</if>
<if test="item.indivType != null">indiv_type = #{item.indivType},</if>
<if test="item.indivSubType != null">indiv_sub_type = #{item.indivSubType},</if>
<if test="item.indivGender != null">indiv_gender = #{item.indivGender},</if>
<if test="item.indivCertType != null">indiv_cert_type = #{item.indivCertType},</if>
<if test="item.indivPhone != null">indiv_phone = #{item.indivPhone},</if>
<if test="item.indivWechat != null">indiv_wechat = #{item.indivWechat},</if>
<if test="item.indivAddress != null">indiv_address = #{item.indivAddress},</if>
<if test="item.indivCompany != null">indiv_company = #{item.indivCompany},</if>
<if test="item.indivPosition != null">indiv_position = #{item.indivPosition},</if>
<if test="item.indivRelatedId != null">indiv_related_id = #{item.indivRelatedId},</if>
<if test="item.indivRelation != null">indiv_relation = #{item.indivRelation},</if>
<if test="item.corpCreditCode != null">corp_credit_code = #{item.corpCreditCode},</if>
<if test="item.corpType != null">corp_type = #{item.corpType},</if>
<if test="item.corpNature != null">corp_nature = #{item.corpNature},</if>
<if test="item.corpIndustryCategory != null">corp_industry_category = #{item.corpIndustryCategory},</if>
<if test="item.corpIndustry != null">corp_industry = #{item.corpIndustry},</if>
<if test="item.corpEstablishDate != null">corp_establish_date = #{item.corpEstablishDate},</if>
<if test="item.corpAddress != null">corp_address = #{item.corpAddress},</if>
<if test="item.corpLegalRep != null">corp_legal_rep = #{item.corpLegalRep},</if>
<if test="item.corpLegalCertType != null">corp_legal_cert_type = #{item.corpLegalCertType},</if>
<if test="item.corpLegalCertNo != null">corp_legal_cert_no = #{item.corpLegalCertNo},</if>
<if test="item.corpShareholder1 != null">corp_shareholder_1 = #{item.corpShareholder1},</if>
<if test="item.corpShareholder2 != null">corp_shareholder_2 = #{item.corpShareholder2},</if>
<if test="item.corpShareholder3 != null">corp_shareholder_3 = #{item.corpShareholder3},</if>
<if test="item.corpShareholder4 != null">corp_shareholder_4 = #{item.corpShareholder4},</if>
<if test="item.corpShareholder5 != null">corp_shareholder_5 = #{item.corpShareholder5},</if>
<if test="item.dataSource != null">data_source = #{item.dataSource},</if>
<if test="item.certificateNo != null">certificate_no = #{item.certificateNo},</if>
update_by = #{item.updateBy},
update_time = #{item.updateTime}
</set>
WHERE intermediary_id = #{item.intermediaryId}
</foreach>
</update>
</mapper>