Merge branch 'feat/cust-fmy-relation-backend' into dev_1
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
package com.ruoyi.ccdi.controller;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.ccdi.domain.dto.CcdiCustFmyRelationAddDTO;
|
||||
import com.ruoyi.ccdi.domain.dto.CcdiCustFmyRelationEditDTO;
|
||||
import com.ruoyi.ccdi.domain.dto.CcdiCustFmyRelationQueryDTO;
|
||||
import com.ruoyi.ccdi.domain.excel.CcdiCustFmyRelationExcel;
|
||||
import com.ruoyi.ccdi.domain.vo.CcdiCustFmyRelationVO;
|
||||
import com.ruoyi.ccdi.domain.vo.CustFmyRelationImportFailureVO;
|
||||
import com.ruoyi.ccdi.service.ICcdiCustFmyRelationService;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
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 org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 信贷客户家庭关系Controller
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-11
|
||||
*/
|
||||
@Tag(name = "信贷客户家庭关系管理")
|
||||
@RestController
|
||||
@RequestMapping("/ccdi/custFmyRelation")
|
||||
public class CcdiCustFmyRelationController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private ICcdiCustFmyRelationService relationService;
|
||||
|
||||
@Resource
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
/**
|
||||
* 查询信贷客户家庭关系列表
|
||||
*/
|
||||
@Operation(summary = "查询信贷客户家庭关系列表")
|
||||
@PreAuthorize("@ss.hasPermi('ccdi:custFmyRelation:query')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(CcdiCustFmyRelationQueryDTO query) {
|
||||
startPage();
|
||||
Page<CcdiCustFmyRelationVO> page = relationService.selectRelationPage(query, getPageNum(), getPageSize());
|
||||
return getDataTable(page.getRecords(), page.getTotal());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID查询信贷客户家庭关系详情
|
||||
*/
|
||||
@Operation(summary = "查询信贷客户家庭关系详情")
|
||||
@PreAuthorize("@ss.hasPermi('ccdi:custFmyRelation:query')")
|
||||
@GetMapping("/{id}")
|
||||
public AjaxResult getInfo(@PathVariable("id") Long id) {
|
||||
CcdiCustFmyRelationVO relation = relationService.selectRelationById(id);
|
||||
return success(relation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增信贷客户家庭关系
|
||||
*/
|
||||
@Operation(summary = "新增信贷客户家庭关系")
|
||||
@PreAuthorize("@ss.hasPermi('ccdi:custFmyRelation:add')")
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody CcdiCustFmyRelationAddDTO addDTO) {
|
||||
return toAjax(relationService.insertRelation(addDTO));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改信贷客户家庭关系
|
||||
*/
|
||||
@Operation(summary = "修改信贷客户家庭关系")
|
||||
@PreAuthorize("@ss.hasPermi('ccdi:custFmyRelation:edit')")
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody CcdiCustFmyRelationEditDTO editDTO) {
|
||||
return toAjax(relationService.updateRelation(editDTO));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除信贷客户家庭关系
|
||||
*/
|
||||
@Operation(summary = "删除信贷客户家庭关系")
|
||||
@PreAuthorize("@ss.hasPermi('ccdi:custFmyRelation:remove')")
|
||||
@DeleteMapping("/{ids}")
|
||||
public AjaxResult remove(@PathVariable Long[] ids) {
|
||||
return toAjax(relationService.deleteRelationByIds(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出信贷客户家庭关系
|
||||
*/
|
||||
@Operation(summary = "导出信贷客户家庭关系")
|
||||
@PreAuthorize("@ss.hasPermi('ccdi:custFmyRelation:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, CcdiCustFmyRelationQueryDTO query) {
|
||||
relationService.exportRelations(query, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载导入模板
|
||||
*/
|
||||
@Operation(summary = "下载导入模板")
|
||||
@PreAuthorize("@ss.hasPermi('ccdi:custFmyRelation:import')")
|
||||
@PostMapping("/importTemplate")
|
||||
public void importTemplate(HttpServletResponse response) {
|
||||
relationService.importTemplate(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入信贷客户家庭关系
|
||||
*/
|
||||
@Operation(summary = "导入信贷客户家庭关系")
|
||||
@PreAuthorize("@ss.hasPermi('ccdi:custFmyRelation:import')")
|
||||
@PostMapping("/importData")
|
||||
public AjaxResult importData(@RequestParam("file") MultipartFile file) throws IOException {
|
||||
List<CcdiCustFmyRelationExcel> excels = EasyExcel.read(file.getInputStream())
|
||||
.head(CcdiCustFmyRelationExcel.class)
|
||||
.sheet()
|
||||
.doReadSync();
|
||||
|
||||
String taskId = relationService.importRelations(excels);
|
||||
return success("导入任务已提交,任务ID: " + taskId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询导入状态
|
||||
*/
|
||||
@Operation(summary = "查询导入状态")
|
||||
@PreAuthorize("@ss.hasPermi('ccdi:custFmyRelation:query')")
|
||||
@GetMapping("/importStatus/{taskId}")
|
||||
public AjaxResult getImportStatus(@PathVariable("taskId") String taskId) {
|
||||
// 从Redis获取任务状态
|
||||
Object status = redisTemplate.opsForValue().get("import:custFmyRelation:" + taskId);
|
||||
return success(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询导入失败记录
|
||||
*/
|
||||
@Operation(summary = "查询导入失败记录")
|
||||
@PreAuthorize("@ss.hasPermi('ccdi:custFmyRelation:query')")
|
||||
@GetMapping("/importFailures/{taskId}")
|
||||
public TableDataInfo getImportFailures(
|
||||
@PathVariable("taskId") String taskId) {
|
||||
startPage();
|
||||
List<CustFmyRelationImportFailureVO> failures = relationService.getImportFailures(taskId);
|
||||
return getDataTable(failures, (long) failures.size());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
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 com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 信贷客户家庭关系对象 ccdi_cust_fmy_relation
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-11
|
||||
*/
|
||||
@Data
|
||||
@TableName("ccdi_cust_fmy_relation")
|
||||
public class CcdiCustFmyRelation implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 主键ID */
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 信贷客户身份证号 */
|
||||
private String personId;
|
||||
|
||||
/** 关系类型 */
|
||||
private String relationType;
|
||||
|
||||
/** 关系人姓名 */
|
||||
private String relationName;
|
||||
|
||||
/** 性别:M-男,F-女,O-其他 */
|
||||
private String gender;
|
||||
|
||||
/** 出生日期 */
|
||||
private Date birthDate;
|
||||
|
||||
/** 关系人证件类型 */
|
||||
private String relationCertType;
|
||||
|
||||
/** 关系人证件号码 */
|
||||
private String relationCertNo;
|
||||
|
||||
/** 手机号码1 */
|
||||
private String mobilePhone1;
|
||||
|
||||
/** 手机号码2 */
|
||||
private String mobilePhone2;
|
||||
|
||||
/** 微信名称1 */
|
||||
private String wechatNo1;
|
||||
|
||||
/** 微信名称2 */
|
||||
private String wechatNo2;
|
||||
|
||||
/** 微信名称3 */
|
||||
private String wechatNo3;
|
||||
|
||||
/** 详细联系地址 */
|
||||
private String contactAddress;
|
||||
|
||||
/** 关系详细描述 */
|
||||
private String relationDesc;
|
||||
|
||||
/** 状态:0-无效,1-有效 */
|
||||
private Integer status;
|
||||
|
||||
/** 生效日期 */
|
||||
private Date effectiveDate;
|
||||
|
||||
/** 失效日期 */
|
||||
private Date invalidDate;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/** 数据来源:MANUAL-手工录入,IMPORT-批量导入 */
|
||||
private String dataSource;
|
||||
|
||||
/** 是否是员工亲属:0-否 */
|
||||
private Boolean isEmpFamily;
|
||||
|
||||
/** 是否是客户亲属:1-是 */
|
||||
private Boolean isCustFamily;
|
||||
|
||||
/** 创建时间 */
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/** 更新时间 */
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateTime;
|
||||
|
||||
/** 创建人 */
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createdBy;
|
||||
|
||||
/** 更新人 */
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updatedBy;
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.ruoyi.ccdi.domain.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 信贷客户家庭关系新增DTO
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-11
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "信贷客户家庭关系新增")
|
||||
public class CcdiCustFmyRelationAddDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 信贷客户身份证号 */
|
||||
@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}[\\dXx]$", message = "信贷客户身份证号格式不正确")
|
||||
@Schema(description = "信贷客户身份证号")
|
||||
private String personId;
|
||||
|
||||
/** 关系类型 */
|
||||
@NotBlank(message = "关系类型不能为空")
|
||||
@Size(max = 50, message = "关系类型长度不能超过50个字符")
|
||||
@Schema(description = "关系类型")
|
||||
private String relationType;
|
||||
|
||||
/** 关系人姓名 */
|
||||
@NotBlank(message = "关系人姓名不能为空")
|
||||
@Size(max = 100, message = "关系人姓名长度不能超过100个字符")
|
||||
@Schema(description = "关系人姓名")
|
||||
private String relationName;
|
||||
|
||||
/** 性别 */
|
||||
@Pattern(regexp = "^[MFO]$", message = "性别只能是M、F或O")
|
||||
@Schema(description = "性别:M-男,F-女,O-其他")
|
||||
private String gender;
|
||||
|
||||
/** 出生日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "出生日期")
|
||||
private Date birthDate;
|
||||
|
||||
/** 关系人证件类型 */
|
||||
@NotBlank(message = "关系人证件类型不能为空")
|
||||
@Size(max = 50, message = "关系人证件类型长度不能超过50个字符")
|
||||
@Schema(description = "关系人证件类型")
|
||||
private String relationCertType;
|
||||
|
||||
/** 关系人证件号码 */
|
||||
@NotBlank(message = "关系人证件号码不能为空")
|
||||
@Size(max = 100, message = "关系人证件号码长度不能超过100个字符")
|
||||
@Schema(description = "关系人证件号码")
|
||||
private String relationCertNo;
|
||||
|
||||
/** 手机号码1 */
|
||||
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码1格式不正确")
|
||||
@Schema(description = "手机号码1")
|
||||
private String mobilePhone1;
|
||||
|
||||
/** 手机号码2 */
|
||||
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码2格式不正确")
|
||||
@Schema(description = "手机号码2")
|
||||
private String mobilePhone2;
|
||||
|
||||
/** 微信名称1 */
|
||||
@Size(max = 50, message = "微信名称1长度不能超过50个字符")
|
||||
@Schema(description = "微信名称1")
|
||||
private String wechatNo1;
|
||||
|
||||
/** 微信名称2 */
|
||||
@Size(max = 50, message = "微信名称2长度不能超过50个字符")
|
||||
@Schema(description = "微信名称2")
|
||||
private String wechatNo2;
|
||||
|
||||
/** 微信名称3 */
|
||||
@Size(max = 50, message = "微信名称3长度不能超过50个字符")
|
||||
@Schema(description = "微信名称3")
|
||||
private String wechatNo3;
|
||||
|
||||
/** 详细联系地址 */
|
||||
@Size(max = 500, message = "详细联系地址长度不能超过500个字符")
|
||||
@Schema(description = "详细联系地址")
|
||||
private String contactAddress;
|
||||
|
||||
/** 关系详细描述 */
|
||||
@Size(max = 500, message = "关系详细描述长度不能超过500个字符")
|
||||
@Schema(description = "关系详细描述")
|
||||
private String relationDesc;
|
||||
|
||||
/** 生效日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "生效日期")
|
||||
private Date effectiveDate;
|
||||
|
||||
/** 失效日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "失效日期")
|
||||
private Date invalidDate;
|
||||
|
||||
/** 状态 */
|
||||
@Schema(description = "状态:0-无效,1-有效")
|
||||
private Integer status;
|
||||
|
||||
/** 备注 */
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.ruoyi.ccdi.domain.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 信贷客户家庭关系编辑DTO
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-11
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "信贷客户家庭关系编辑")
|
||||
public class CcdiCustFmyRelationEditDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 主键ID */
|
||||
@NotNull(message = "ID不能为空")
|
||||
@Schema(description = "主键ID")
|
||||
private Long id;
|
||||
|
||||
/** 信贷客户身份证号 */
|
||||
@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}[\\dXx]$", message = "信贷客户身份证号格式不正确")
|
||||
@Schema(description = "信贷客户身份证号")
|
||||
private String personId;
|
||||
|
||||
/** 关系类型 */
|
||||
@NotBlank(message = "关系类型不能为空")
|
||||
@Size(max = 50, message = "关系类型长度不能超过50个字符")
|
||||
@Schema(description = "关系类型")
|
||||
private String relationType;
|
||||
|
||||
/** 关系人姓名 */
|
||||
@NotBlank(message = "关系人姓名不能为空")
|
||||
@Size(max = 100, message = "关系人姓名长度不能超过100个字符")
|
||||
@Schema(description = "关系人姓名")
|
||||
private String relationName;
|
||||
|
||||
/** 性别 */
|
||||
@Pattern(regexp = "^[MFO]$", message = "性别只能是M、F或O")
|
||||
@Schema(description = "性别:M-男,F-女,O-其他")
|
||||
private String gender;
|
||||
|
||||
/** 出生日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "出生日期")
|
||||
private Date birthDate;
|
||||
|
||||
/** 关系人证件类型 */
|
||||
@NotBlank(message = "关系人证件类型不能为空")
|
||||
@Size(max = 50, message = "关系人证件类型长度不能超过50个字符")
|
||||
@Schema(description = "关系人证件类型")
|
||||
private String relationCertType;
|
||||
|
||||
/** 关系人证件号码 */
|
||||
@NotBlank(message = "关系人证件号码不能为空")
|
||||
@Size(max = 100, message = "关系人证件号码长度不能超过100个字符")
|
||||
@Schema(description = "关系人证件号码")
|
||||
private String relationCertNo;
|
||||
|
||||
/** 手机号码1 */
|
||||
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码1格式不正确")
|
||||
@Schema(description = "手机号码1")
|
||||
private String mobilePhone1;
|
||||
|
||||
/** 手机号码2 */
|
||||
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码2格式不正确")
|
||||
@Schema(description = "手机号码2")
|
||||
private String mobilePhone2;
|
||||
|
||||
/** 微信名称1 */
|
||||
@Size(max = 50, message = "微信名称1长度不能超过50个字符")
|
||||
@Schema(description = "微信名称1")
|
||||
private String wechatNo1;
|
||||
|
||||
/** 微信名称2 */
|
||||
@Size(max = 50, message = "微信名称2长度不能超过50个字符")
|
||||
@Schema(description = "微信名称2")
|
||||
private String wechatNo2;
|
||||
|
||||
/** 微信名称3 */
|
||||
@Size(max = 50, message = "微信名称3长度不能超过50个字符")
|
||||
@Schema(description = "微信名称3")
|
||||
private String wechatNo3;
|
||||
|
||||
/** 详细联系地址 */
|
||||
@Size(max = 500, message = "详细联系地址长度不能超过500个字符")
|
||||
@Schema(description = "详细联系地址")
|
||||
private String contactAddress;
|
||||
|
||||
/** 关系详细描述 */
|
||||
@Size(max = 500, message = "关系详细描述长度不能超过500个字符")
|
||||
@Schema(description = "关系详细描述")
|
||||
private String relationDesc;
|
||||
|
||||
/** 状态 */
|
||||
@Schema(description = "状态:0-无效,1-有效")
|
||||
private Integer status;
|
||||
|
||||
/** 生效日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "生效日期")
|
||||
private Date effectiveDate;
|
||||
|
||||
/** 失效日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "失效日期")
|
||||
private Date invalidDate;
|
||||
|
||||
/** 备注 */
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.ruoyi.ccdi.domain.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 信贷客户家庭关系查询DTO
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-11
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "信贷客户家庭关系查询")
|
||||
public class CcdiCustFmyRelationQueryDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 信贷客户身份证号 */
|
||||
@Schema(description = "信贷客户身份证号")
|
||||
private String personId;
|
||||
|
||||
/** 关系类型 */
|
||||
@Schema(description = "关系类型")
|
||||
private String relationType;
|
||||
|
||||
/** 关系人姓名 */
|
||||
@Schema(description = "关系人姓名")
|
||||
private String relationName;
|
||||
|
||||
/** 状态 */
|
||||
@Schema(description = "状态:0-无效,1-有效")
|
||||
private Integer status;
|
||||
|
||||
/** 数据来源 */
|
||||
@Schema(description = "数据来源")
|
||||
private String dataSource;
|
||||
|
||||
/** 生效日期开始 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "生效日期开始")
|
||||
private Date effectiveDateStart;
|
||||
|
||||
/** 生效日期结束 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "生效日期结束")
|
||||
private Date effectiveDateEnd;
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
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 com.ruoyi.common.annotation.Required;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 信贷客户家庭关系Excel导入导出对象
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-11
|
||||
*/
|
||||
@Data
|
||||
public class CcdiCustFmyRelationExcel implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 信贷客户身份证号 */
|
||||
@ExcelProperty(value = "信贷客户身份证号*", index = 0)
|
||||
@ColumnWidth(20)
|
||||
@Required
|
||||
private String personId;
|
||||
|
||||
/** 关系类型 */
|
||||
@ExcelProperty(value = "关系类型*", index = 1)
|
||||
@ColumnWidth(15)
|
||||
@DictDropdown(dictType = "ccdi_relation_type")
|
||||
@Required
|
||||
private String relationType;
|
||||
|
||||
/** 关系人姓名 */
|
||||
@ExcelProperty(value = "关系人姓名*", index = 2)
|
||||
@ColumnWidth(15)
|
||||
@Required
|
||||
private String relationName;
|
||||
|
||||
/** 性别 */
|
||||
@ExcelProperty(value = "性别", index = 3)
|
||||
@ColumnWidth(10)
|
||||
@DictDropdown(dictType = "ccdi_indiv_gender")
|
||||
private String gender;
|
||||
|
||||
/** 出生日期 */
|
||||
@ExcelProperty(value = "出生日期", index = 4)
|
||||
@ColumnWidth(15)
|
||||
private Date birthDate;
|
||||
|
||||
/** 关系人证件类型 */
|
||||
@ExcelProperty(value = "关系人证件类型*", index = 5)
|
||||
@ColumnWidth(15)
|
||||
@DictDropdown(dictType = "ccdi_certificate_type")
|
||||
@Required
|
||||
private String relationCertType;
|
||||
|
||||
/** 关系人证件号码 */
|
||||
@ExcelProperty(value = "关系人证件号码*", index = 6)
|
||||
@ColumnWidth(20)
|
||||
@Required
|
||||
private String relationCertNo;
|
||||
|
||||
/** 手机号码1 */
|
||||
@ExcelProperty(value = "手机号码1", index = 7)
|
||||
@ColumnWidth(15)
|
||||
private String mobilePhone1;
|
||||
|
||||
/** 手机号码2 */
|
||||
@ExcelProperty(value = "手机号码2", index = 8)
|
||||
@ColumnWidth(15)
|
||||
private String mobilePhone2;
|
||||
|
||||
/** 微信名称1 */
|
||||
@ExcelProperty(value = "微信名称1", index = 9)
|
||||
@ColumnWidth(15)
|
||||
private String wechatNo1;
|
||||
|
||||
/** 微信名称2 */
|
||||
@ExcelProperty(value = "微信名称2", index = 10)
|
||||
@ColumnWidth(15)
|
||||
private String wechatNo2;
|
||||
|
||||
/** 微信名称3 */
|
||||
@ExcelProperty(value = "微信名称3", index = 11)
|
||||
@ColumnWidth(15)
|
||||
private String wechatNo3;
|
||||
|
||||
/** 详细联系地址 */
|
||||
@ExcelProperty(value = "详细联系地址", index = 12)
|
||||
@ColumnWidth(30)
|
||||
private String contactAddress;
|
||||
|
||||
/** 关系详细描述 */
|
||||
@ExcelProperty(value = "关系详细描述", index = 13)
|
||||
@ColumnWidth(30)
|
||||
private String relationDesc;
|
||||
|
||||
/** 生效日期 */
|
||||
@ExcelProperty(value = "生效日期", index = 14)
|
||||
@ColumnWidth(15)
|
||||
private Date effectiveDate;
|
||||
|
||||
/** 失效日期 */
|
||||
@ExcelProperty(value = "失效日期", index = 15)
|
||||
@ColumnWidth(15)
|
||||
private Date invalidDate;
|
||||
|
||||
/** 备注 */
|
||||
@ExcelProperty(value = "备注", index = 16)
|
||||
@ColumnWidth(30)
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package com.ruoyi.ccdi.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 信贷客户家庭关系VO
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-11
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "信贷客户家庭关系")
|
||||
public class CcdiCustFmyRelationVO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 主键ID */
|
||||
@Schema(description = "主键ID")
|
||||
private Long id;
|
||||
|
||||
/** 信贷客户身份证号 */
|
||||
@Schema(description = "信贷客户身份证号")
|
||||
private String personId;
|
||||
|
||||
/** 关系类型 */
|
||||
@Schema(description = "关系类型")
|
||||
private String relationType;
|
||||
|
||||
/** 关系人姓名 */
|
||||
@Schema(description = "关系人姓名")
|
||||
private String relationName;
|
||||
|
||||
/** 性别 */
|
||||
@Schema(description = "性别:M-男,F-女,O-其他")
|
||||
private String gender;
|
||||
|
||||
/** 性别名称 */
|
||||
@Schema(description = "性别名称")
|
||||
private String genderName;
|
||||
|
||||
/** 出生日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "出生日期")
|
||||
private Date birthDate;
|
||||
|
||||
/** 关系人证件类型 */
|
||||
@Schema(description = "关系人证件类型")
|
||||
private String relationCertType;
|
||||
|
||||
/** 关系人证件号码 */
|
||||
@Schema(description = "关系人证件号码")
|
||||
private String relationCertNo;
|
||||
|
||||
/** 手机号码1 */
|
||||
@Schema(description = "手机号码1")
|
||||
private String mobilePhone1;
|
||||
|
||||
/** 手机号码2 */
|
||||
@Schema(description = "手机号码2")
|
||||
private String mobilePhone2;
|
||||
|
||||
/** 微信名称1 */
|
||||
@Schema(description = "微信名称1")
|
||||
private String wechatNo1;
|
||||
|
||||
/** 微信名称2 */
|
||||
@Schema(description = "微信名称2")
|
||||
private String wechatNo2;
|
||||
|
||||
/** 微信名称3 */
|
||||
@Schema(description = "微信名称3")
|
||||
private String wechatNo3;
|
||||
|
||||
/** 详细联系地址 */
|
||||
@Schema(description = "详细联系地址")
|
||||
private String contactAddress;
|
||||
|
||||
/** 关系详细描述 */
|
||||
@Schema(description = "关系详细描述")
|
||||
private String relationDesc;
|
||||
|
||||
/** 生效日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "生效日期")
|
||||
private Date effectiveDate;
|
||||
|
||||
/** 失效日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "失效日期")
|
||||
private Date invalidDate;
|
||||
|
||||
/** 状态 */
|
||||
@Schema(description = "状态:0-无效,1-有效")
|
||||
private Integer status;
|
||||
|
||||
/** 状态名称 */
|
||||
@Schema(description = "状态名称")
|
||||
private String statusName;
|
||||
|
||||
/** 备注 */
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
/** 数据来源 */
|
||||
@Schema(description = "数据来源:MANUAL-手工录入,IMPORT-批量导入")
|
||||
private String dataSource;
|
||||
|
||||
/** 是否是员工亲属 */
|
||||
@Schema(description = "是否是员工亲属:0-否")
|
||||
private Boolean isEmpFamily;
|
||||
|
||||
/** 是否是客户亲属 */
|
||||
@Schema(description = "是否是客户亲属:1-是")
|
||||
private Boolean isCustFamily;
|
||||
|
||||
/** 创建时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/** 更新时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
/** 创建人 */
|
||||
@Schema(description = "创建人")
|
||||
private String createdBy;
|
||||
|
||||
/** 更新人 */
|
||||
@Schema(description = "更新人")
|
||||
private String updatedBy;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.ruoyi.ccdi.domain.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 信贷客户家庭关系导入失败VO
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-11
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "信贷客户家庭关系导入失败记录")
|
||||
public class CustFmyRelationImportFailureVO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 行号 */
|
||||
@Schema(description = "行号")
|
||||
private Integer rowNum;
|
||||
|
||||
/** 信贷客户身份证号 */
|
||||
@Schema(description = "信贷客户身份证号")
|
||||
private String personId;
|
||||
|
||||
/** 关系类型 */
|
||||
@Schema(description = "关系类型")
|
||||
private String relationType;
|
||||
|
||||
/** 关系人姓名 */
|
||||
@Schema(description = "关系人姓名")
|
||||
private String relationName;
|
||||
|
||||
/** 错误消息 */
|
||||
@Schema(description = "错误消息")
|
||||
private String errorMessage;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
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.CcdiCustFmyRelation;
|
||||
import com.ruoyi.ccdi.domain.dto.CcdiCustFmyRelationQueryDTO;
|
||||
import com.ruoyi.ccdi.domain.vo.CcdiCustFmyRelationVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 信贷客户家庭关系Mapper接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-11
|
||||
*/
|
||||
public interface CcdiCustFmyRelationMapper extends BaseMapper<CcdiCustFmyRelation> {
|
||||
|
||||
/**
|
||||
* 分页查询信贷客户家庭关系
|
||||
*
|
||||
* @param page 分页对象
|
||||
* @param query 查询条件
|
||||
* @return 信贷客户家庭关系VO列表
|
||||
*/
|
||||
Page<CcdiCustFmyRelationVO> selectRelationPage(Page<CcdiCustFmyRelationVO> page,
|
||||
@Param("query") CcdiCustFmyRelationQueryDTO query);
|
||||
|
||||
/**
|
||||
* 根据ID查询信贷客户家庭关系详情
|
||||
*
|
||||
* @param id 主键ID
|
||||
* @return 信贷客户家庭关系VO
|
||||
*/
|
||||
CcdiCustFmyRelationVO selectRelationById(@Param("id") Long id);
|
||||
|
||||
/**
|
||||
* 查询已存在的关系记录(用于导入校验)
|
||||
*
|
||||
* @param personId 信贷客户身份证号
|
||||
* @param relationType 关系类型
|
||||
* @param relationCertNo 关系人证件号码
|
||||
* @return 已存在的关系记录
|
||||
*/
|
||||
CcdiCustFmyRelation selectExistingRelations(@Param("personId") String personId,
|
||||
@Param("relationType") String relationType,
|
||||
@Param("relationCertNo") String relationCertNo);
|
||||
|
||||
/**
|
||||
* 批量插入信贷客户家庭关系
|
||||
*
|
||||
* @param relations 信贷客户家庭关系列表
|
||||
* @return 插入条数
|
||||
*/
|
||||
int insertBatch(@Param("relations") List<CcdiCustFmyRelation> relations);
|
||||
|
||||
/**
|
||||
* 根据证件号码查询关系数量
|
||||
*
|
||||
* @param relationCertNo 关系人证件号码
|
||||
* @return 关系数量
|
||||
*/
|
||||
int countByCertNo(@Param("relationCertNo") String relationCertNo);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.ruoyi.ccdi.service;
|
||||
|
||||
import com.ruoyi.ccdi.domain.excel.CcdiCustFmyRelationExcel;
|
||||
import com.ruoyi.ccdi.domain.vo.CustFmyRelationImportFailureVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 信贷客户家庭关系导入Service接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-11
|
||||
*/
|
||||
public interface ICcdiCustFmyRelationImportService {
|
||||
|
||||
/**
|
||||
* 异步导入信贷客户家庭关系
|
||||
*
|
||||
* @param excels Excel数据列表
|
||||
* @param taskId 任务ID
|
||||
*/
|
||||
void importRelationsAsync(List<CcdiCustFmyRelationExcel> excels, String taskId);
|
||||
|
||||
/**
|
||||
* 校验单条数据
|
||||
*
|
||||
* @param excel Excel数据
|
||||
* @param rowNum 行号
|
||||
* @return 错误消息,为null表示校验通过
|
||||
*/
|
||||
String validateExcelRow(CcdiCustFmyRelationExcel excel, Integer rowNum);
|
||||
|
||||
/**
|
||||
* 获取导入失败记录
|
||||
*
|
||||
* @param taskId 任务ID
|
||||
* @return 失败记录列表
|
||||
*/
|
||||
List<CustFmyRelationImportFailureVO> getImportFailures(String taskId);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.ruoyi.ccdi.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.ccdi.domain.dto.CcdiCustFmyRelationAddDTO;
|
||||
import com.ruoyi.ccdi.domain.dto.CcdiCustFmyRelationEditDTO;
|
||||
import com.ruoyi.ccdi.domain.dto.CcdiCustFmyRelationQueryDTO;
|
||||
import com.ruoyi.ccdi.domain.excel.CcdiCustFmyRelationExcel;
|
||||
import com.ruoyi.ccdi.domain.vo.CcdiCustFmyRelationVO;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 信贷客户家庭关系Service接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-11
|
||||
*/
|
||||
public interface ICcdiCustFmyRelationService {
|
||||
|
||||
/**
|
||||
* 分页查询信贷客户家庭关系
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param pageNum 页码
|
||||
* @param pageSize 每页条数
|
||||
* @return 分页结果
|
||||
*/
|
||||
Page<CcdiCustFmyRelationVO> selectRelationPage(CcdiCustFmyRelationQueryDTO query,
|
||||
Integer pageNum, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 根据ID查询信贷客户家庭关系详情
|
||||
*
|
||||
* @param id 主键ID
|
||||
* @return 信贷客户家庭关系VO
|
||||
*/
|
||||
CcdiCustFmyRelationVO selectRelationById(Long id);
|
||||
|
||||
/**
|
||||
* 新增信贷客户家庭关系
|
||||
*
|
||||
* @param addDTO 新增DTO
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean insertRelation(CcdiCustFmyRelationAddDTO addDTO);
|
||||
|
||||
/**
|
||||
* 修改信贷客户家庭关系
|
||||
*
|
||||
* @param editDTO 编辑DTO
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateRelation(CcdiCustFmyRelationEditDTO editDTO);
|
||||
|
||||
/**
|
||||
* 删除信贷客户家庭关系
|
||||
*
|
||||
* @param ids 主键ID数组
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean deleteRelationByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 导出信贷客户家庭关系
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param response HTTP响应
|
||||
*/
|
||||
void exportRelations(CcdiCustFmyRelationQueryDTO query, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 生成导入模板
|
||||
*
|
||||
* @param response HTTP响应
|
||||
*/
|
||||
void importTemplate(HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 批量导入信贷客户家庭关系
|
||||
*
|
||||
* @param excels Excel数据列表
|
||||
* @return 导入任务ID
|
||||
*/
|
||||
String importRelations(List<CcdiCustFmyRelationExcel> excels);
|
||||
|
||||
/**
|
||||
* 获取导入失败记录
|
||||
*
|
||||
* @param taskId 任务ID
|
||||
* @return 失败记录列表
|
||||
*/
|
||||
List<com.ruoyi.ccdi.domain.vo.CustFmyRelationImportFailureVO> getImportFailures(String taskId);
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package com.ruoyi.ccdi.service.impl;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.ruoyi.ccdi.domain.CcdiCustFmyRelation;
|
||||
import com.ruoyi.ccdi.domain.excel.CcdiCustFmyRelationExcel;
|
||||
import com.ruoyi.ccdi.domain.vo.CustFmyRelationImportFailureVO;
|
||||
import com.ruoyi.ccdi.mapper.CcdiCustFmyRelationMapper;
|
||||
import com.ruoyi.ccdi.service.ICcdiCustFmyRelationImportService;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 信贷客户家庭关系导入Service实现
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-11
|
||||
*/
|
||||
@Service
|
||||
public class CcdiCustFmyRelationImportServiceImpl implements ICcdiCustFmyRelationImportService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CcdiCustFmyRelationImportServiceImpl.class);
|
||||
|
||||
@Resource
|
||||
private CcdiCustFmyRelationMapper mapper;
|
||||
|
||||
@Resource
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
private static final String IMPORT_TASK_KEY_PREFIX = "import:custFmyRelation:";
|
||||
private static final String IMPORT_FAILURE_KEY_PREFIX = "import:custFmyRelation:failures:";
|
||||
|
||||
@Async
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void importRelationsAsync(List<CcdiCustFmyRelationExcel> excels, String taskId) {
|
||||
List<CcdiCustFmyRelation> validRelations = new ArrayList<>();
|
||||
List<CustFmyRelationImportFailureVO> failures = new ArrayList<>();
|
||||
|
||||
try {
|
||||
for (int i = 0; i < excels.size(); i++) {
|
||||
CcdiCustFmyRelationExcel excel = excels.get(i);
|
||||
Integer rowNum = i + 2; // Excel行号从2开始(第1行是表头)
|
||||
|
||||
String errorMessage = validateExcelRow(excel, rowNum);
|
||||
if (errorMessage != null) {
|
||||
CustFmyRelationImportFailureVO failure = new CustFmyRelationImportFailureVO();
|
||||
failure.setRowNum(rowNum);
|
||||
failure.setPersonId(excel.getPersonId());
|
||||
failure.setRelationType(excel.getRelationType());
|
||||
failure.setRelationName(excel.getRelationName());
|
||||
failure.setErrorMessage(errorMessage);
|
||||
failures.add(failure);
|
||||
continue;
|
||||
}
|
||||
|
||||
CcdiCustFmyRelation relation = convertToRelation(excel);
|
||||
validRelations.add(relation);
|
||||
}
|
||||
|
||||
// 批量插入有效数据
|
||||
if (!validRelations.isEmpty()) {
|
||||
mapper.insertBatch(validRelations);
|
||||
}
|
||||
|
||||
// 保存失败记录到Redis(24小时过期)
|
||||
if (!failures.isEmpty()) {
|
||||
redisTemplate.opsForValue().set(
|
||||
IMPORT_FAILURE_KEY_PREFIX + taskId,
|
||||
failures,
|
||||
24,
|
||||
TimeUnit.HOURS
|
||||
);
|
||||
}
|
||||
|
||||
// 更新任务状态
|
||||
redisTemplate.opsForValue().set(
|
||||
IMPORT_TASK_KEY_PREFIX + taskId,
|
||||
"COMPLETED:" + validRelations.size() + ":" + failures.size(),
|
||||
1,
|
||||
TimeUnit.HOURS
|
||||
);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("导入失败", e);
|
||||
redisTemplate.opsForValue().set(
|
||||
IMPORT_TASK_KEY_PREFIX + taskId,
|
||||
"FAILED:" + e.getMessage(),
|
||||
1,
|
||||
TimeUnit.HOURS
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String validateExcelRow(CcdiCustFmyRelationExcel excel, Integer rowNum) {
|
||||
if (excel.getPersonId() == null || excel.getPersonId().trim().isEmpty()) {
|
||||
return "信贷客户身份证号不能为空";
|
||||
}
|
||||
|
||||
if (excel.getRelationType() == null || excel.getRelationType().trim().isEmpty()) {
|
||||
return "关系类型不能为空";
|
||||
}
|
||||
|
||||
if (excel.getRelationName() == null || excel.getRelationName().trim().isEmpty()) {
|
||||
return "关系人姓名不能为空";
|
||||
}
|
||||
|
||||
if (excel.getRelationCertType() == null || excel.getRelationCertType().trim().isEmpty()) {
|
||||
return "关系人证件类型不能为空";
|
||||
}
|
||||
|
||||
if (excel.getRelationCertNo() == null || excel.getRelationCertNo().trim().isEmpty()) {
|
||||
return "关系人证件号码不能为空";
|
||||
}
|
||||
|
||||
// 检查是否已存在相同的关系
|
||||
CcdiCustFmyRelation existing = mapper.selectExistingRelations(
|
||||
excel.getPersonId(),
|
||||
excel.getRelationType(),
|
||||
excel.getRelationCertNo()
|
||||
);
|
||||
|
||||
if (existing != null) {
|
||||
return "该关系已存在,请勿重复导入";
|
||||
}
|
||||
|
||||
return null; // 校验通过
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<CustFmyRelationImportFailureVO> getImportFailures(String taskId) {
|
||||
Object obj = redisTemplate.opsForValue().get(IMPORT_FAILURE_KEY_PREFIX + taskId);
|
||||
if (obj != null) {
|
||||
return (List<CustFmyRelationImportFailureVO>) obj;
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private CcdiCustFmyRelation convertToRelation(CcdiCustFmyRelationExcel excel) {
|
||||
CcdiCustFmyRelation relation = new CcdiCustFmyRelation();
|
||||
org.springframework.beans.BeanUtils.copyProperties(excel, relation);
|
||||
|
||||
relation.setIsEmpFamily(false);
|
||||
relation.setIsCustFamily(true);
|
||||
relation.setStatus(excel.getStatus() != null ? excel.getStatus() : 1);
|
||||
relation.setDataSource("IMPORT");
|
||||
relation.setCreatedBy(SecurityUtils.getUsername());
|
||||
relation.setCreateTime(new Date());
|
||||
|
||||
return relation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package com.ruoyi.ccdi.service.impl;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.ccdi.domain.CcdiCustFmyRelation;
|
||||
import com.ruoyi.ccdi.domain.dto.CcdiCustFmyRelationAddDTO;
|
||||
import com.ruoyi.ccdi.domain.dto.CcdiCustFmyRelationEditDTO;
|
||||
import com.ruoyi.ccdi.domain.dto.CcdiCustFmyRelationQueryDTO;
|
||||
import com.ruoyi.ccdi.domain.excel.CcdiCustFmyRelationExcel;
|
||||
import com.ruoyi.ccdi.domain.vo.CcdiCustFmyRelationVO;
|
||||
import com.ruoyi.ccdi.mapper.CcdiCustFmyRelationMapper;
|
||||
import com.ruoyi.ccdi.service.ICcdiCustFmyRelationImportService;
|
||||
import com.ruoyi.ccdi.service.ICcdiCustFmyRelationService;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 信贷客户家庭关系Service实现
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-11
|
||||
*/
|
||||
@Service
|
||||
public class CcdiCustFmyRelationServiceImpl implements ICcdiCustFmyRelationService {
|
||||
|
||||
@Resource
|
||||
private CcdiCustFmyRelationMapper mapper;
|
||||
|
||||
@Resource
|
||||
private ICcdiCustFmyRelationImportService importService;
|
||||
|
||||
@Resource
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
private static final String IMPORT_TASK_KEY_PREFIX = "import:custFmyRelation:";
|
||||
private static final String IMPORT_FAILURE_KEY_PREFIX = "import:custFmyRelation:failures:";
|
||||
|
||||
@Override
|
||||
public Page<CcdiCustFmyRelationVO> selectRelationPage(CcdiCustFmyRelationQueryDTO query,
|
||||
Integer pageNum, Integer pageSize) {
|
||||
Page<CcdiCustFmyRelationVO> page = new Page<>(pageNum, pageSize);
|
||||
return mapper.selectRelationPage(page, query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CcdiCustFmyRelationVO selectRelationById(Long id) {
|
||||
return mapper.selectRelationById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean insertRelation(CcdiCustFmyRelationAddDTO addDTO) {
|
||||
CcdiCustFmyRelation relation = new CcdiCustFmyRelation();
|
||||
BeanUtils.copyProperties(addDTO, relation);
|
||||
|
||||
// 关键设置:客户家庭关系
|
||||
relation.setIsEmpFamily(false);
|
||||
relation.setIsCustFamily(true);
|
||||
relation.setStatus(1);
|
||||
relation.setDataSource("MANUAL");
|
||||
|
||||
return mapper.insert(relation) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean updateRelation(CcdiCustFmyRelationEditDTO editDTO) {
|
||||
CcdiCustFmyRelation relation = new CcdiCustFmyRelation();
|
||||
BeanUtils.copyProperties(editDTO, relation);
|
||||
|
||||
return mapper.updateById(relation) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean deleteRelationByIds(Long[] ids) {
|
||||
return mapper.deleteBatchIds(List.of(ids)) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportRelations(CcdiCustFmyRelationQueryDTO query, HttpServletResponse response) {
|
||||
// 查询所有符合条件的数据(不分页)
|
||||
Page<CcdiCustFmyRelationVO> page = new Page<>(1, 10000);
|
||||
Page<CcdiCustFmyRelationVO> result = mapper.selectRelationPage(page, query);
|
||||
|
||||
List<CcdiCustFmyRelationExcel> excels = result.getRecords().stream()
|
||||
.map(this::convertToExcel)
|
||||
.toList();
|
||||
|
||||
// 使用EasyExcel导出
|
||||
try {
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
String fileName = URLEncoder.encode("信贷客户家庭关系", StandardCharsets.UTF_8)
|
||||
.replaceAll("\\+", "%20");
|
||||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||||
|
||||
EasyExcel.write(response.getOutputStream(), CcdiCustFmyRelationExcel.class)
|
||||
.sheet("信贷客户家庭关系")
|
||||
.doWrite(excels);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("导出失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importTemplate(HttpServletResponse response) {
|
||||
try {
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
String fileName = URLEncoder.encode("信贷客户家庭关系导入模板", StandardCharsets.UTF_8)
|
||||
.replaceAll("\\+", "%20");
|
||||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||||
|
||||
EasyExcel.write(response.getOutputStream(), CcdiCustFmyRelationExcel.class)
|
||||
.sheet("模板")
|
||||
.doWrite(Collections.emptyList());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("模板下载失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String importRelations(List<CcdiCustFmyRelationExcel> excels) {
|
||||
String taskId = UUID.randomUUID().toString();
|
||||
|
||||
// 保存任务状态到Redis
|
||||
redisTemplate.opsForValue().set(IMPORT_TASK_KEY_PREFIX + taskId, "PROCESSING", 1, TimeUnit.HOURS);
|
||||
|
||||
// 异步导入
|
||||
importService.importRelationsAsync(excels, taskId);
|
||||
|
||||
return taskId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<com.ruoyi.ccdi.domain.vo.CustFmyRelationImportFailureVO> getImportFailures(String taskId) {
|
||||
return importService.getImportFailures(taskId);
|
||||
}
|
||||
|
||||
private CcdiCustFmyRelationExcel convertToExcel(CcdiCustFmyRelationVO vo) {
|
||||
CcdiCustFmyRelationExcel excel = new CcdiCustFmyRelationExcel();
|
||||
BeanUtils.copyProperties(vo, excel);
|
||||
return excel;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user