修复
This commit is contained in:
@@ -0,0 +1,146 @@
|
|||||||
|
package com.ruoyi.info.collection.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.core.page.PageDomain;
|
||||||
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.common.core.page.TableSupport;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoAddDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoEditDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoQueryDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.excel.CcdiEnterpriseBaseInfoExcel;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.CcdiEnterpriseBaseInfoVO;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.EnterpriseBaseInfoImportFailureVO;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.ImportResultVO;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
||||||
|
import com.ruoyi.info.collection.service.ICcdiEnterpriseBaseInfoImportService;
|
||||||
|
import com.ruoyi.info.collection.service.ICcdiEnterpriseBaseInfoService;
|
||||||
|
import com.ruoyi.info.collection.utils.EasyExcelUtil;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理 Controller
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Tag(name = "实体库管理")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/ccdi/enterpriseBaseInfo")
|
||||||
|
public class CcdiEnterpriseBaseInfoController extends BaseController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ICcdiEnterpriseBaseInfoService enterpriseBaseInfoService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ICcdiEnterpriseBaseInfoImportService enterpriseBaseInfoImportService;
|
||||||
|
|
||||||
|
@Operation(summary = "查询实体库列表")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:list')")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public TableDataInfo list(CcdiEnterpriseBaseInfoQueryDTO queryDTO) {
|
||||||
|
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||||
|
Page<CcdiEnterpriseBaseInfoVO> page = new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize());
|
||||||
|
Page<CcdiEnterpriseBaseInfoVO> result = enterpriseBaseInfoService.selectEnterpriseBaseInfoPage(page, queryDTO);
|
||||||
|
return getDataTable(result.getRecords(), result.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取实体库详细信息")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:query')")
|
||||||
|
@GetMapping("/{socialCreditCode}")
|
||||||
|
public AjaxResult getInfo(@PathVariable String socialCreditCode) {
|
||||||
|
return success(enterpriseBaseInfoService.selectEnterpriseBaseInfoById(socialCreditCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "新增实体库信息")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:add')")
|
||||||
|
@Log(title = "实体库管理", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping
|
||||||
|
public AjaxResult add(@Validated @RequestBody CcdiEnterpriseBaseInfoAddDTO addDTO) {
|
||||||
|
return toAjax(enterpriseBaseInfoService.insertEnterpriseBaseInfo(addDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "修改实体库信息")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:edit')")
|
||||||
|
@Log(title = "实体库管理", businessType = BusinessType.UPDATE)
|
||||||
|
@PutMapping
|
||||||
|
public AjaxResult edit(@Validated @RequestBody CcdiEnterpriseBaseInfoEditDTO editDTO) {
|
||||||
|
return toAjax(enterpriseBaseInfoService.updateEnterpriseBaseInfo(editDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "删除实体库信息")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:remove')")
|
||||||
|
@Log(title = "实体库管理", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/{socialCreditCodes}")
|
||||||
|
public AjaxResult remove(@PathVariable String[] socialCreditCodes) {
|
||||||
|
return toAjax(enterpriseBaseInfoService.deleteEnterpriseBaseInfoByIds(socialCreditCodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "下载导入模板")
|
||||||
|
@PostMapping("/importTemplate")
|
||||||
|
public void importTemplate(HttpServletResponse response) {
|
||||||
|
EasyExcelUtil.importTemplateWithDictDropdown(response, CcdiEnterpriseBaseInfoExcel.class, "实体库管理");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "导入实体库信息")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:import')")
|
||||||
|
@Log(title = "实体库管理", businessType = BusinessType.IMPORT)
|
||||||
|
@PostMapping("/importData")
|
||||||
|
public AjaxResult importData(MultipartFile file) throws Exception {
|
||||||
|
List<CcdiEnterpriseBaseInfoExcel> list = EasyExcelUtil.importExcel(file.getInputStream(), CcdiEnterpriseBaseInfoExcel.class);
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
return error("至少需要一条数据");
|
||||||
|
}
|
||||||
|
|
||||||
|
String taskId = enterpriseBaseInfoService.importEnterpriseBaseInfo(list);
|
||||||
|
ImportResultVO result = new ImportResultVO();
|
||||||
|
result.setTaskId(taskId);
|
||||||
|
result.setStatus("PROCESSING");
|
||||||
|
result.setMessage("导入任务已提交,正在后台处理");
|
||||||
|
return AjaxResult.success("导入任务已提交,正在后台处理", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询导入状态")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:import')")
|
||||||
|
@GetMapping("/importStatus/{taskId}")
|
||||||
|
public AjaxResult getImportStatus(@PathVariable String taskId) {
|
||||||
|
ImportStatusVO status = enterpriseBaseInfoImportService.getImportStatus(taskId);
|
||||||
|
return success(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询导入失败记录")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:enterpriseBaseInfo:import')")
|
||||||
|
@GetMapping("/importFailures/{taskId}")
|
||||||
|
public TableDataInfo getImportFailures(@PathVariable String taskId,
|
||||||
|
@RequestParam(defaultValue = "1") Integer pageNum,
|
||||||
|
@RequestParam(defaultValue = "10") Integer pageSize) {
|
||||||
|
List<EnterpriseBaseInfoImportFailureVO> failures = enterpriseBaseInfoImportService.getImportFailures(taskId);
|
||||||
|
int fromIndex = (pageNum - 1) * pageSize;
|
||||||
|
if (fromIndex >= failures.size()) {
|
||||||
|
return getDataTable(new ArrayList<>(), failures.size());
|
||||||
|
}
|
||||||
|
int toIndex = Math.min(fromIndex + pageSize, failures.size());
|
||||||
|
return getDataTable(failures.subList(fromIndex, toIndex), failures.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -138,4 +138,30 @@ public class CcdiEnumController {
|
|||||||
}
|
}
|
||||||
return AjaxResult.success(options);
|
return AjaxResult.success(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取实体风险等级选项
|
||||||
|
*/
|
||||||
|
@Operation(summary = "获取实体风险等级选项")
|
||||||
|
@GetMapping("/enterpriseRiskLevel")
|
||||||
|
public AjaxResult getEnterpriseRiskLevelOptions() {
|
||||||
|
List<EnumOptionVO> options = new ArrayList<>();
|
||||||
|
for (EnterpriseRiskLevel level : EnterpriseRiskLevel.values()) {
|
||||||
|
options.add(new EnumOptionVO(level.getCode(), level.getDesc()));
|
||||||
|
}
|
||||||
|
return AjaxResult.success(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取企业来源选项
|
||||||
|
*/
|
||||||
|
@Operation(summary = "获取企业来源选项")
|
||||||
|
@GetMapping("/enterpriseSource")
|
||||||
|
public AjaxResult getEnterpriseSourceOptions() {
|
||||||
|
List<EnumOptionVO> options = new ArrayList<>();
|
||||||
|
for (EnterpriseSource source : EnterpriseSource.values()) {
|
||||||
|
options.add(new EnumOptionVO(source.getCode(), source.getDesc()));
|
||||||
|
}
|
||||||
|
return AjaxResult.success(options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.ruoyi.info.collection.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介关联机构关系对象 ccdi_intermediary_enterprise_relation
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("ccdi_intermediary_enterprise_relation")
|
||||||
|
public class CcdiIntermediaryEnterpriseRelation implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String intermediaryBizId;
|
||||||
|
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
private String relationPersonPost;
|
||||||
|
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private String createdBy;
|
||||||
|
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private String updatedBy;
|
||||||
|
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Date updateTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理新增 DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "实体库管理新增DTO")
|
||||||
|
public class CcdiEnterpriseBaseInfoAddDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
@NotBlank(message = "统一社会信用代码不能为空")
|
||||||
|
@Pattern(regexp = "^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$", message = "统一社会信用代码格式不正确")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "企业名称")
|
||||||
|
@NotBlank(message = "企业名称不能为空")
|
||||||
|
@Size(max = 200, message = "企业名称长度不能超过200个字符")
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@Schema(description = "企业类型")
|
||||||
|
@Size(max = 50, message = "企业类型长度不能超过50个字符")
|
||||||
|
private String enterpriseType;
|
||||||
|
|
||||||
|
@Schema(description = "企业性质")
|
||||||
|
@Size(max = 50, message = "企业性质长度不能超过50个字符")
|
||||||
|
private String enterpriseNature;
|
||||||
|
|
||||||
|
@Schema(description = "行业分类")
|
||||||
|
@Size(max = 100, message = "行业分类长度不能超过100个字符")
|
||||||
|
private String industryClass;
|
||||||
|
|
||||||
|
@Schema(description = "所属行业")
|
||||||
|
@Size(max = 100, message = "所属行业长度不能超过100个字符")
|
||||||
|
private String industryName;
|
||||||
|
|
||||||
|
@Schema(description = "成立日期")
|
||||||
|
private Date establishDate;
|
||||||
|
|
||||||
|
@Schema(description = "注册地址")
|
||||||
|
@Size(max = 500, message = "注册地址长度不能超过500个字符")
|
||||||
|
private String registerAddress;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人")
|
||||||
|
@Size(max = 100, message = "法定代表人长度不能超过100个字符")
|
||||||
|
private String legalRepresentative;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人证件类型")
|
||||||
|
@Size(max = 50, message = "法定代表人证件类型长度不能超过50个字符")
|
||||||
|
private String legalCertType;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人证件号码")
|
||||||
|
@Size(max = 50, message = "法定代表人证件号码长度不能超过50个字符")
|
||||||
|
private String legalCertNo;
|
||||||
|
|
||||||
|
@Schema(description = "股东1")
|
||||||
|
@Size(max = 100, message = "股东1长度不能超过100个字符")
|
||||||
|
private String shareholder1;
|
||||||
|
|
||||||
|
@Schema(description = "股东2")
|
||||||
|
@Size(max = 100, message = "股东2长度不能超过100个字符")
|
||||||
|
private String shareholder2;
|
||||||
|
|
||||||
|
@Schema(description = "股东3")
|
||||||
|
@Size(max = 100, message = "股东3长度不能超过100个字符")
|
||||||
|
private String shareholder3;
|
||||||
|
|
||||||
|
@Schema(description = "股东4")
|
||||||
|
@Size(max = 100, message = "股东4长度不能超过100个字符")
|
||||||
|
private String shareholder4;
|
||||||
|
|
||||||
|
@Schema(description = "股东5")
|
||||||
|
@Size(max = 100, message = "股东5长度不能超过100个字符")
|
||||||
|
private String shareholder5;
|
||||||
|
|
||||||
|
@Schema(description = "经营状态")
|
||||||
|
@NotBlank(message = "经营状态不能为空")
|
||||||
|
@Size(max = 50, message = "经营状态长度不能超过50个字符")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "风险等级")
|
||||||
|
@NotBlank(message = "风险等级不能为空")
|
||||||
|
private String riskLevel;
|
||||||
|
|
||||||
|
@Schema(description = "企业来源")
|
||||||
|
@NotBlank(message = "企业来源不能为空")
|
||||||
|
private String entSource;
|
||||||
|
|
||||||
|
@Schema(description = "数据来源")
|
||||||
|
@NotBlank(message = "数据来源不能为空")
|
||||||
|
private String dataSource;
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理编辑 DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "实体库管理编辑DTO")
|
||||||
|
public class CcdiEnterpriseBaseInfoEditDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
@NotBlank(message = "统一社会信用代码不能为空")
|
||||||
|
@Pattern(regexp = "^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$", message = "统一社会信用代码格式不正确")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "企业名称")
|
||||||
|
@NotBlank(message = "企业名称不能为空")
|
||||||
|
@Size(max = 200, message = "企业名称长度不能超过200个字符")
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@Schema(description = "企业类型")
|
||||||
|
@Size(max = 50, message = "企业类型长度不能超过50个字符")
|
||||||
|
private String enterpriseType;
|
||||||
|
|
||||||
|
@Schema(description = "企业性质")
|
||||||
|
@Size(max = 50, message = "企业性质长度不能超过50个字符")
|
||||||
|
private String enterpriseNature;
|
||||||
|
|
||||||
|
@Schema(description = "行业分类")
|
||||||
|
@Size(max = 100, message = "行业分类长度不能超过100个字符")
|
||||||
|
private String industryClass;
|
||||||
|
|
||||||
|
@Schema(description = "所属行业")
|
||||||
|
@Size(max = 100, message = "所属行业长度不能超过100个字符")
|
||||||
|
private String industryName;
|
||||||
|
|
||||||
|
@Schema(description = "成立日期")
|
||||||
|
private Date establishDate;
|
||||||
|
|
||||||
|
@Schema(description = "注册地址")
|
||||||
|
@Size(max = 500, message = "注册地址长度不能超过500个字符")
|
||||||
|
private String registerAddress;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人")
|
||||||
|
@Size(max = 100, message = "法定代表人长度不能超过100个字符")
|
||||||
|
private String legalRepresentative;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人证件类型")
|
||||||
|
@Size(max = 50, message = "法定代表人证件类型长度不能超过50个字符")
|
||||||
|
private String legalCertType;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人证件号码")
|
||||||
|
@Size(max = 50, message = "法定代表人证件号码长度不能超过50个字符")
|
||||||
|
private String legalCertNo;
|
||||||
|
|
||||||
|
@Schema(description = "股东1")
|
||||||
|
@Size(max = 100, message = "股东1长度不能超过100个字符")
|
||||||
|
private String shareholder1;
|
||||||
|
|
||||||
|
@Schema(description = "股东2")
|
||||||
|
@Size(max = 100, message = "股东2长度不能超过100个字符")
|
||||||
|
private String shareholder2;
|
||||||
|
|
||||||
|
@Schema(description = "股东3")
|
||||||
|
@Size(max = 100, message = "股东3长度不能超过100个字符")
|
||||||
|
private String shareholder3;
|
||||||
|
|
||||||
|
@Schema(description = "股东4")
|
||||||
|
@Size(max = 100, message = "股东4长度不能超过100个字符")
|
||||||
|
private String shareholder4;
|
||||||
|
|
||||||
|
@Schema(description = "股东5")
|
||||||
|
@Size(max = 100, message = "股东5长度不能超过100个字符")
|
||||||
|
private String shareholder5;
|
||||||
|
|
||||||
|
@Schema(description = "经营状态")
|
||||||
|
@NotBlank(message = "经营状态不能为空")
|
||||||
|
@Size(max = 50, message = "经营状态长度不能超过50个字符")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "风险等级")
|
||||||
|
@NotBlank(message = "风险等级不能为空")
|
||||||
|
private String riskLevel;
|
||||||
|
|
||||||
|
@Schema(description = "企业来源")
|
||||||
|
@NotBlank(message = "企业来源不能为空")
|
||||||
|
private String entSource;
|
||||||
|
|
||||||
|
@Schema(description = "数据来源")
|
||||||
|
@NotBlank(message = "数据来源不能为空")
|
||||||
|
private String dataSource;
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理查询 DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "实体库管理查询DTO")
|
||||||
|
public class CcdiEnterpriseBaseInfoQueryDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "企业名称")
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "企业类型")
|
||||||
|
private String enterpriseType;
|
||||||
|
|
||||||
|
@Schema(description = "企业性质")
|
||||||
|
private String enterpriseNature;
|
||||||
|
|
||||||
|
@Schema(description = "行业分类")
|
||||||
|
private String industryClass;
|
||||||
|
|
||||||
|
@Schema(description = "经营状态")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "风险等级")
|
||||||
|
private String riskLevel;
|
||||||
|
|
||||||
|
@Schema(description = "企业来源")
|
||||||
|
private String entSource;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介关联机构新增DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "中介关联机构新增DTO")
|
||||||
|
public class CcdiIntermediaryEnterpriseRelationAddDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
@NotBlank(message = "统一社会信用代码不能为空")
|
||||||
|
@Size(max = 18, message = "统一社会信用代码长度不能超过18个字符")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "关联角色/职务")
|
||||||
|
@Size(max = 100, message = "关联角色/职务长度不能超过100个字符")
|
||||||
|
private String relationPersonPost;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
@Size(max = 500, message = "备注长度不能超过500个字符")
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介关联机构编辑DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "中介关联机构编辑DTO")
|
||||||
|
public class CcdiIntermediaryEnterpriseRelationEditDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "主键ID")
|
||||||
|
@NotNull(message = "主键ID不能为空")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
@NotBlank(message = "统一社会信用代码不能为空")
|
||||||
|
@Size(max = 18, message = "统一社会信用代码长度不能超过18个字符")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "关联角色/职务")
|
||||||
|
@Size(max = 100, message = "关联角色/职务长度不能超过100个字符")
|
||||||
|
private String relationPersonPost;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
@Size(max = 500, message = "备注长度不能超过500个字符")
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介亲属新增DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "中介亲属新增DTO")
|
||||||
|
public class CcdiIntermediaryRelativeAddDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "姓名")
|
||||||
|
@NotBlank(message = "姓名不能为空")
|
||||||
|
@Size(max = 100, message = "姓名长度不能超过100个字符")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "人员类型")
|
||||||
|
private String personType;
|
||||||
|
|
||||||
|
@Schema(description = "亲属关系")
|
||||||
|
@NotBlank(message = "亲属关系不能为空")
|
||||||
|
@Size(max = 50, message = "亲属关系长度不能超过50个字符")
|
||||||
|
private String personSubType;
|
||||||
|
|
||||||
|
@Schema(description = "性别")
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
@Schema(description = "证件类型")
|
||||||
|
private String idType;
|
||||||
|
|
||||||
|
@Schema(description = "证件号码")
|
||||||
|
@NotBlank(message = "证件号码不能为空")
|
||||||
|
@Size(max = 50, message = "证件号码长度不能超过50个字符")
|
||||||
|
private String personId;
|
||||||
|
|
||||||
|
@Schema(description = "手机号码")
|
||||||
|
@Size(max = 20, message = "手机号码长度不能超过20个字符")
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
@Schema(description = "微信号")
|
||||||
|
@Size(max = 50, message = "微信号长度不能超过50个字符")
|
||||||
|
private String wechatNo;
|
||||||
|
|
||||||
|
@Schema(description = "联系地址")
|
||||||
|
@Size(max = 200, message = "联系地址长度不能超过200个字符")
|
||||||
|
private String contactAddress;
|
||||||
|
|
||||||
|
@Schema(description = "所在公司")
|
||||||
|
@Size(max = 200, message = "所在公司长度不能超过200个字符")
|
||||||
|
private String company;
|
||||||
|
|
||||||
|
@Schema(description = "企业统一信用码")
|
||||||
|
@Size(max = 50, message = "企业统一信用码长度不能超过50个字符")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "职位")
|
||||||
|
@Size(max = 100, message = "职位长度不能超过100个字符")
|
||||||
|
private String position;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
@Size(max = 500, message = "备注长度不能超过500个字符")
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介亲属编辑DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "中介亲属编辑DTO")
|
||||||
|
public class CcdiIntermediaryRelativeEditDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "人员ID")
|
||||||
|
@NotBlank(message = "人员ID不能为空")
|
||||||
|
private String bizId;
|
||||||
|
|
||||||
|
@Schema(description = "姓名")
|
||||||
|
@NotBlank(message = "姓名不能为空")
|
||||||
|
@Size(max = 100, message = "姓名长度不能超过100个字符")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "人员类型")
|
||||||
|
private String personType;
|
||||||
|
|
||||||
|
@Schema(description = "亲属关系")
|
||||||
|
@NotBlank(message = "亲属关系不能为空")
|
||||||
|
@Size(max = 50, message = "亲属关系长度不能超过50个字符")
|
||||||
|
private String personSubType;
|
||||||
|
|
||||||
|
@Schema(description = "性别")
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
@Schema(description = "证件类型")
|
||||||
|
private String idType;
|
||||||
|
|
||||||
|
@Schema(description = "证件号码")
|
||||||
|
@Size(max = 50, message = "证件号码长度不能超过50个字符")
|
||||||
|
private String personId;
|
||||||
|
|
||||||
|
@Schema(description = "手机号码")
|
||||||
|
@Size(max = 20, message = "手机号码长度不能超过20个字符")
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
@Schema(description = "微信号")
|
||||||
|
@Size(max = 50, message = "微信号长度不能超过50个字符")
|
||||||
|
private String wechatNo;
|
||||||
|
|
||||||
|
@Schema(description = "联系地址")
|
||||||
|
@Size(max = 200, message = "联系地址长度不能超过200个字符")
|
||||||
|
private String contactAddress;
|
||||||
|
|
||||||
|
@Schema(description = "所在公司")
|
||||||
|
@Size(max = 200, message = "所在公司长度不能超过200个字符")
|
||||||
|
private String company;
|
||||||
|
|
||||||
|
@Schema(description = "企业统一信用码")
|
||||||
|
@Size(max = 50, message = "企业统一信用码长度不能超过50个字符")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "职位")
|
||||||
|
@Size(max = 100, message = "职位长度不能超过100个字符")
|
||||||
|
private String position;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
@Size(max = 500, message = "备注长度不能超过500个字符")
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.excel;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||||
|
import com.ruoyi.common.annotation.DictDropdown;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理 Excel 导入模板对象
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CcdiEnterpriseBaseInfoExcel implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "统一社会信用代码*", index = 0)
|
||||||
|
@ColumnWidth(24)
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "企业名称*", index = 1)
|
||||||
|
@ColumnWidth(30)
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "企业类型", index = 2)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
@DictDropdown(dictType = "ccdi_entity_type")
|
||||||
|
private String enterpriseType;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "企业性质", index = 3)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
@DictDropdown(dictType = "ccdi_enterprise_nature")
|
||||||
|
private String enterpriseNature;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "行业分类", index = 4)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String industryClass;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "所属行业", index = 5)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String industryName;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "成立日期", index = 6)
|
||||||
|
@ColumnWidth(16)
|
||||||
|
private Date establishDate;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "注册地址", index = 7)
|
||||||
|
@ColumnWidth(36)
|
||||||
|
private String registerAddress;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "法定代表人", index = 8)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String legalRepresentative;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "法定代表人证件类型", index = 9)
|
||||||
|
@ColumnWidth(22)
|
||||||
|
@DictDropdown(dictType = "ccdi_certificate_type")
|
||||||
|
private String legalCertType;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "法定代表人证件号码", index = 10)
|
||||||
|
@ColumnWidth(24)
|
||||||
|
private String legalCertNo;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "股东1", index = 11)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String shareholder1;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "股东2", index = 12)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String shareholder2;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "股东3", index = 13)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String shareholder3;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "股东4", index = 14)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String shareholder4;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "股东5", index = 15)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String shareholder5;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "经营状态*", index = 16)
|
||||||
|
@ColumnWidth(16)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "风险等级*", index = 17)
|
||||||
|
@ColumnWidth(16)
|
||||||
|
private String riskLevel;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "企业来源*", index = 18)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String entSource;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "数据来源*", index = 19)
|
||||||
|
@ColumnWidth(18)
|
||||||
|
private String dataSource;
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理 VO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "实体库管理VO")
|
||||||
|
public class CcdiEnterpriseBaseInfoVO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "企业名称")
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@Schema(description = "企业类型")
|
||||||
|
private String enterpriseType;
|
||||||
|
|
||||||
|
@Schema(description = "企业性质")
|
||||||
|
private String enterpriseNature;
|
||||||
|
|
||||||
|
@Schema(description = "行业分类")
|
||||||
|
private String industryClass;
|
||||||
|
|
||||||
|
@Schema(description = "所属行业")
|
||||||
|
private String industryName;
|
||||||
|
|
||||||
|
@Schema(description = "成立日期")
|
||||||
|
private Date establishDate;
|
||||||
|
|
||||||
|
@Schema(description = "注册地址")
|
||||||
|
private String registerAddress;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人")
|
||||||
|
private String legalRepresentative;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人证件类型")
|
||||||
|
private String legalCertType;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人证件号码")
|
||||||
|
private String legalCertNo;
|
||||||
|
|
||||||
|
@Schema(description = "股东1")
|
||||||
|
private String shareholder1;
|
||||||
|
|
||||||
|
@Schema(description = "股东2")
|
||||||
|
private String shareholder2;
|
||||||
|
|
||||||
|
@Schema(description = "股东3")
|
||||||
|
private String shareholder3;
|
||||||
|
|
||||||
|
@Schema(description = "股东4")
|
||||||
|
private String shareholder4;
|
||||||
|
|
||||||
|
@Schema(description = "股东5")
|
||||||
|
private String shareholder5;
|
||||||
|
|
||||||
|
@Schema(description = "经营状态")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "风险等级")
|
||||||
|
private String riskLevel;
|
||||||
|
|
||||||
|
@Schema(description = "企业来源")
|
||||||
|
private String entSource;
|
||||||
|
|
||||||
|
@Schema(description = "数据来源")
|
||||||
|
private String dataSource;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介关联机构VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "中介关联机构VO")
|
||||||
|
public class CcdiIntermediaryEnterpriseRelationVO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "主键ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "所属中介ID")
|
||||||
|
private String intermediaryBizId;
|
||||||
|
|
||||||
|
@Schema(description = "所属中介姓名")
|
||||||
|
private String intermediaryName;
|
||||||
|
|
||||||
|
@Schema(description = "所属中介证件号")
|
||||||
|
private String intermediaryPersonId;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "机构名称")
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@Schema(description = "关联角色/职务")
|
||||||
|
private String relationPersonPost;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介亲属VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "中介亲属VO")
|
||||||
|
public class CcdiIntermediaryRelativeVO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "人员ID")
|
||||||
|
private String bizId;
|
||||||
|
|
||||||
|
@Schema(description = "所属中介ID")
|
||||||
|
private String relatedNumId;
|
||||||
|
|
||||||
|
@Schema(description = "姓名")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "人员类型")
|
||||||
|
private String personType;
|
||||||
|
|
||||||
|
@Schema(description = "亲属关系")
|
||||||
|
private String personSubType;
|
||||||
|
|
||||||
|
@Schema(description = "性别")
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
@Schema(description = "证件类型")
|
||||||
|
private String idType;
|
||||||
|
|
||||||
|
@Schema(description = "证件号码")
|
||||||
|
private String personId;
|
||||||
|
|
||||||
|
@Schema(description = "手机号码")
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
@Schema(description = "微信号")
|
||||||
|
private String wechatNo;
|
||||||
|
|
||||||
|
@Schema(description = "联系地址")
|
||||||
|
private String contactAddress;
|
||||||
|
|
||||||
|
@Schema(description = "所在公司")
|
||||||
|
private String company;
|
||||||
|
|
||||||
|
@Schema(description = "企业统一信用码")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "职位")
|
||||||
|
private String position;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.ruoyi.info.collection.domain.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库导入失败记录 VO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "实体库导入失败记录")
|
||||||
|
public class EnterpriseBaseInfoImportFailureVO {
|
||||||
|
|
||||||
|
@Schema(description = "企业名称")
|
||||||
|
private String enterpriseName;
|
||||||
|
|
||||||
|
@Schema(description = "统一社会信用代码")
|
||||||
|
private String socialCreditCode;
|
||||||
|
|
||||||
|
@Schema(description = "企业类型")
|
||||||
|
private String enterpriseType;
|
||||||
|
|
||||||
|
@Schema(description = "企业性质")
|
||||||
|
private String enterpriseNature;
|
||||||
|
|
||||||
|
@Schema(description = "行业分类")
|
||||||
|
private String industryClass;
|
||||||
|
|
||||||
|
@Schema(description = "所属行业")
|
||||||
|
private String industryName;
|
||||||
|
|
||||||
|
@Schema(description = "法定代表人")
|
||||||
|
private String legalRepresentative;
|
||||||
|
|
||||||
|
@Schema(description = "经营状态")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "风险等级")
|
||||||
|
private String riskLevel;
|
||||||
|
|
||||||
|
@Schema(description = "企业来源")
|
||||||
|
private String entSource;
|
||||||
|
|
||||||
|
@Schema(description = "数据来源")
|
||||||
|
private String dataSource;
|
||||||
|
|
||||||
|
@Schema(description = "错误信息")
|
||||||
|
private String errorMessage;
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.ruoyi.info.collection.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体风险等级枚举
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public enum EnterpriseRiskLevel {
|
||||||
|
|
||||||
|
HIGH("1", "高风险"),
|
||||||
|
MEDIUM("2", "中风险"),
|
||||||
|
LOW("3", "低风险");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
EnterpriseRiskLevel(String code, String desc) {
|
||||||
|
this.code = code;
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDesc() {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDescByCode(String code) {
|
||||||
|
for (EnterpriseRiskLevel value : values()) {
|
||||||
|
if (value.code.equals(code)) {
|
||||||
|
return value.desc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean contains(String code) {
|
||||||
|
for (EnterpriseRiskLevel value : values()) {
|
||||||
|
if (value.code.equals(code)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String resolveCode(String value) {
|
||||||
|
for (EnterpriseRiskLevel item : values()) {
|
||||||
|
if (item.code.equals(value) || item.desc.equals(value)) {
|
||||||
|
return item.code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.ruoyi.info.collection.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 企业来源枚举
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public enum EnterpriseSource {
|
||||||
|
|
||||||
|
GENERAL("GENERAL", "一般企业"),
|
||||||
|
EMP_RELATION("EMP_RELATION", "员工关系人"),
|
||||||
|
CREDIT_CUSTOMER("CREDIT_CUSTOMER", "信贷客户"),
|
||||||
|
INTERMEDIARY("INTERMEDIARY", "中介"),
|
||||||
|
BOTH("BOTH", "兼有");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
EnterpriseSource(String code, String desc) {
|
||||||
|
this.code = code;
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDesc() {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDescByCode(String code) {
|
||||||
|
for (EnterpriseSource value : values()) {
|
||||||
|
if (value.code.equals(code)) {
|
||||||
|
return value.desc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean contains(String code) {
|
||||||
|
for (EnterpriseSource value : values()) {
|
||||||
|
if (value.code.equals(code)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String resolveCode(String value) {
|
||||||
|
for (EnterpriseSource item : values()) {
|
||||||
|
if (item.code.equals(value) || item.desc.equals(value)) {
|
||||||
|
return item.code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
package com.ruoyi.info.collection.mapper;
|
package com.ruoyi.info.collection.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.ruoyi.info.collection.domain.CcdiEnterpriseBaseInfo;
|
import com.ruoyi.info.collection.domain.CcdiEnterpriseBaseInfo;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoQueryDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.CcdiEnterpriseBaseInfoVO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
@@ -16,6 +19,16 @@ import java.util.List;
|
|||||||
@Mapper
|
@Mapper
|
||||||
public interface CcdiEnterpriseBaseInfoMapper extends BaseMapper<CcdiEnterpriseBaseInfo> {
|
public interface CcdiEnterpriseBaseInfoMapper extends BaseMapper<CcdiEnterpriseBaseInfo> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询实体库列表
|
||||||
|
*
|
||||||
|
* @param page 分页参数
|
||||||
|
* @param queryDTO 查询条件
|
||||||
|
* @return 分页结果
|
||||||
|
*/
|
||||||
|
Page<CcdiEnterpriseBaseInfoVO> selectEnterpriseBaseInfoPage(Page<CcdiEnterpriseBaseInfoVO> page,
|
||||||
|
@Param("queryDTO") CcdiEnterpriseBaseInfoQueryDTO queryDTO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量插入实体中介
|
* 批量插入实体中介
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.ruoyi.info.collection.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.ruoyi.info.collection.domain.CcdiIntermediaryEnterpriseRelation;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.CcdiIntermediaryEnterpriseRelationVO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中介关联机构关系Mapper
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface CcdiIntermediaryEnterpriseRelationMapper extends BaseMapper<CcdiIntermediaryEnterpriseRelation> {
|
||||||
|
|
||||||
|
List<CcdiIntermediaryEnterpriseRelationVO> selectByIntermediaryBizId(@Param("bizId") String bizId);
|
||||||
|
|
||||||
|
CcdiIntermediaryEnterpriseRelationVO selectDetailById(@Param("id") Long id);
|
||||||
|
|
||||||
|
boolean existsByIntermediaryBizIdAndSocialCreditCode(@Param("bizId") String bizId,
|
||||||
|
@Param("socialCreditCode") String socialCreditCode);
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.ruoyi.info.collection.service;
|
||||||
|
|
||||||
|
import com.ruoyi.info.collection.domain.CcdiEnterpriseBaseInfo;
|
||||||
|
import com.ruoyi.info.collection.domain.excel.CcdiEnterpriseBaseInfoExcel;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.EnterpriseBaseInfoImportFailureVO;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理导入 Service 接口
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
public interface ICcdiEnterpriseBaseInfoImportService {
|
||||||
|
|
||||||
|
void importEnterpriseBaseInfoAsync(List<CcdiEnterpriseBaseInfoExcel> excelList, String taskId, String userName);
|
||||||
|
|
||||||
|
ImportStatusVO getImportStatus(String taskId);
|
||||||
|
|
||||||
|
List<EnterpriseBaseInfoImportFailureVO> getImportFailures(String taskId);
|
||||||
|
|
||||||
|
CcdiEnterpriseBaseInfo validateAndBuildEntity(CcdiEnterpriseBaseInfoExcel excel,
|
||||||
|
Set<String> existingCreditCodes,
|
||||||
|
Set<String> processedCreditCodes,
|
||||||
|
String userName);
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.ruoyi.info.collection.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoAddDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoEditDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoQueryDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.excel.CcdiEnterpriseBaseInfoExcel;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.CcdiEnterpriseBaseInfoVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理 Service 接口
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
public interface ICcdiEnterpriseBaseInfoService {
|
||||||
|
|
||||||
|
Page<CcdiEnterpriseBaseInfoVO> selectEnterpriseBaseInfoPage(Page<CcdiEnterpriseBaseInfoVO> page,
|
||||||
|
CcdiEnterpriseBaseInfoQueryDTO queryDTO);
|
||||||
|
|
||||||
|
CcdiEnterpriseBaseInfoVO selectEnterpriseBaseInfoById(String socialCreditCode);
|
||||||
|
|
||||||
|
int insertEnterpriseBaseInfo(CcdiEnterpriseBaseInfoAddDTO addDTO);
|
||||||
|
|
||||||
|
int updateEnterpriseBaseInfo(CcdiEnterpriseBaseInfoEditDTO editDTO);
|
||||||
|
|
||||||
|
int deleteEnterpriseBaseInfoByIds(String[] socialCreditCodes);
|
||||||
|
|
||||||
|
List<CcdiEnterpriseBaseInfoExcel> selectEnterpriseBaseInfoListForExport(CcdiEnterpriseBaseInfoQueryDTO queryDTO);
|
||||||
|
|
||||||
|
String importEnterpriseBaseInfo(List<CcdiEnterpriseBaseInfoExcel> excelList);
|
||||||
|
}
|
||||||
@@ -0,0 +1,225 @@
|
|||||||
|
package com.ruoyi.info.collection.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.info.collection.domain.CcdiEnterpriseBaseInfo;
|
||||||
|
import com.ruoyi.info.collection.domain.excel.CcdiEnterpriseBaseInfoExcel;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.EnterpriseBaseInfoImportFailureVO;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.ImportResult;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
||||||
|
import com.ruoyi.info.collection.enums.DataSource;
|
||||||
|
import com.ruoyi.info.collection.enums.EnterpriseRiskLevel;
|
||||||
|
import com.ruoyi.info.collection.enums.EnterpriseSource;
|
||||||
|
import com.ruoyi.info.collection.mapper.CcdiEnterpriseBaseInfoMapper;
|
||||||
|
import com.ruoyi.info.collection.service.ICcdiEnterpriseBaseInfoImportService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理导入 Service 实现
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@EnableAsync
|
||||||
|
public class CcdiEnterpriseBaseInfoImportServiceImpl implements ICcdiEnterpriseBaseInfoImportService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CcdiEnterpriseBaseInfoMapper enterpriseBaseInfoMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Async
|
||||||
|
public void importEnterpriseBaseInfoAsync(List<CcdiEnterpriseBaseInfoExcel> excelList, String taskId, String userName) {
|
||||||
|
List<CcdiEnterpriseBaseInfo> successRecords = new ArrayList<>();
|
||||||
|
List<EnterpriseBaseInfoImportFailureVO> failures = new ArrayList<>();
|
||||||
|
Set<String> existingCreditCodes = getExistingCreditCodes(excelList);
|
||||||
|
Set<String> processedCreditCodes = new HashSet<>();
|
||||||
|
|
||||||
|
for (CcdiEnterpriseBaseInfoExcel excel : excelList) {
|
||||||
|
try {
|
||||||
|
CcdiEnterpriseBaseInfo entity = validateAndBuildEntity(excel, existingCreditCodes, processedCreditCodes, userName);
|
||||||
|
successRecords.add(entity);
|
||||||
|
processedCreditCodes.add(entity.getSocialCreditCode());
|
||||||
|
} catch (Exception e) {
|
||||||
|
EnterpriseBaseInfoImportFailureVO failureVO = new EnterpriseBaseInfoImportFailureVO();
|
||||||
|
BeanUtils.copyProperties(excel, failureVO);
|
||||||
|
failureVO.setErrorMessage(e.getMessage());
|
||||||
|
failures.add(failureVO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!successRecords.isEmpty()) {
|
||||||
|
saveBatch(successRecords, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!failures.isEmpty()) {
|
||||||
|
redisTemplate.opsForValue().set(buildFailuresKey(taskId), failures, 7, TimeUnit.DAYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImportResult result = new ImportResult();
|
||||||
|
result.setTotalCount(excelList.size());
|
||||||
|
result.setSuccessCount(successRecords.size());
|
||||||
|
result.setFailureCount(failures.size());
|
||||||
|
updateImportStatus(taskId, failures.isEmpty() ? "SUCCESS" : "PARTIAL_SUCCESS", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImportStatusVO getImportStatus(String taskId) {
|
||||||
|
String key = buildStatusKey(taskId);
|
||||||
|
Boolean exists = redisTemplate.hasKey(key);
|
||||||
|
if (Boolean.FALSE.equals(exists)) {
|
||||||
|
throw new RuntimeException("任务不存在或已过期");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<Object, Object> statusMap = redisTemplate.opsForHash().entries(key);
|
||||||
|
ImportStatusVO statusVO = new ImportStatusVO();
|
||||||
|
statusVO.setTaskId((String) statusMap.get("taskId"));
|
||||||
|
statusVO.setStatus((String) statusMap.get("status"));
|
||||||
|
statusVO.setTotalCount((Integer) statusMap.get("totalCount"));
|
||||||
|
statusVO.setSuccessCount((Integer) statusMap.get("successCount"));
|
||||||
|
statusVO.setFailureCount((Integer) statusMap.get("failureCount"));
|
||||||
|
statusVO.setProgress((Integer) statusMap.get("progress"));
|
||||||
|
statusVO.setStartTime((Long) statusMap.get("startTime"));
|
||||||
|
statusVO.setEndTime((Long) statusMap.get("endTime"));
|
||||||
|
statusVO.setMessage((String) statusMap.get("message"));
|
||||||
|
return statusVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EnterpriseBaseInfoImportFailureVO> getImportFailures(String taskId) {
|
||||||
|
Object failuresObj = redisTemplate.opsForValue().get(buildFailuresKey(taskId));
|
||||||
|
if (failuresObj == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return JSON.parseArray(JSON.toJSONString(failuresObj), EnterpriseBaseInfoImportFailureVO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CcdiEnterpriseBaseInfo validateAndBuildEntity(CcdiEnterpriseBaseInfoExcel excel,
|
||||||
|
Set<String> existingCreditCodes,
|
||||||
|
Set<String> processedCreditCodes,
|
||||||
|
String userName) {
|
||||||
|
if (excel == null) {
|
||||||
|
throw new RuntimeException("导入数据不能为空");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(excel.getEnterpriseName())) {
|
||||||
|
throw new RuntimeException("企业名称不能为空");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(excel.getSocialCreditCode())) {
|
||||||
|
throw new RuntimeException("统一社会信用代码不能为空");
|
||||||
|
}
|
||||||
|
if (!excel.getSocialCreditCode().matches("^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$")) {
|
||||||
|
throw new RuntimeException("统一社会信用代码格式不正确");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(excel.getStatus())) {
|
||||||
|
throw new RuntimeException("经营状态不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
String riskLevel = EnterpriseRiskLevel.resolveCode(StringUtils.trim(excel.getRiskLevel()));
|
||||||
|
if (riskLevel == null) {
|
||||||
|
throw new RuntimeException("风险等级不在允许范围内");
|
||||||
|
}
|
||||||
|
String entSource = EnterpriseSource.resolveCode(StringUtils.trim(excel.getEntSource()));
|
||||||
|
if (entSource == null) {
|
||||||
|
throw new RuntimeException("企业来源不在允许范围内");
|
||||||
|
}
|
||||||
|
String dataSource = resolveDataSourceCode(StringUtils.trim(excel.getDataSource()));
|
||||||
|
if (dataSource == null) {
|
||||||
|
throw new RuntimeException("数据来源不在允许范围内");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingCreditCodes.contains(excel.getSocialCreditCode())) {
|
||||||
|
throw new RuntimeException(String.format("统一社会信用代码[%s]已存在,请勿重复导入", excel.getSocialCreditCode()));
|
||||||
|
}
|
||||||
|
if (processedCreditCodes.contains(excel.getSocialCreditCode())) {
|
||||||
|
throw new RuntimeException(String.format("统一社会信用代码[%s]在导入文件中重复,已跳过此条记录", excel.getSocialCreditCode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
CcdiEnterpriseBaseInfo entity = new CcdiEnterpriseBaseInfo();
|
||||||
|
BeanUtils.copyProperties(excel, entity);
|
||||||
|
entity.setRiskLevel(riskLevel);
|
||||||
|
entity.setEntSource(entSource);
|
||||||
|
entity.setDataSource(dataSource);
|
||||||
|
entity.setStatus(StringUtils.trim(excel.getStatus()));
|
||||||
|
entity.setCreatedBy(userName);
|
||||||
|
entity.setUpdatedBy(userName);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getExistingCreditCodes(List<CcdiEnterpriseBaseInfoExcel> excelList) {
|
||||||
|
List<String> creditCodes = excelList.stream()
|
||||||
|
.map(CcdiEnterpriseBaseInfoExcel::getSocialCreditCode)
|
||||||
|
.filter(StringUtils::isNotEmpty)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (creditCodes.isEmpty()) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<CcdiEnterpriseBaseInfo> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.in(CcdiEnterpriseBaseInfo::getSocialCreditCode, creditCodes);
|
||||||
|
return enterpriseBaseInfoMapper.selectList(wrapper).stream()
|
||||||
|
.map(CcdiEnterpriseBaseInfo::getSocialCreditCode)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int saveBatch(List<CcdiEnterpriseBaseInfo> list, int batchSize) {
|
||||||
|
int total = 0;
|
||||||
|
for (int i = 0; i < list.size(); i += batchSize) {
|
||||||
|
int end = Math.min(i + batchSize, list.size());
|
||||||
|
total += enterpriseBaseInfoMapper.insertBatch(list.subList(i, end));
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateImportStatus(String taskId, String status, ImportResult result) {
|
||||||
|
Map<String, Object> statusData = new HashMap<>();
|
||||||
|
statusData.put("status", status);
|
||||||
|
statusData.put("successCount", result.getSuccessCount());
|
||||||
|
statusData.put("failureCount", result.getFailureCount());
|
||||||
|
statusData.put("progress", 100);
|
||||||
|
statusData.put("endTime", System.currentTimeMillis());
|
||||||
|
if ("SUCCESS".equals(status)) {
|
||||||
|
statusData.put("message", "全部成功!共导入" + result.getTotalCount() + "条数据");
|
||||||
|
} else {
|
||||||
|
statusData.put("message", "成功" + result.getSuccessCount() + "条,失败" + result.getFailureCount() + "条");
|
||||||
|
}
|
||||||
|
redisTemplate.opsForHash().putAll(buildStatusKey(taskId), statusData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveDataSourceCode(String value) {
|
||||||
|
for (DataSource source : DataSource.values()) {
|
||||||
|
if (source.getCode().equals(value) || source.getDesc().equals(value)) {
|
||||||
|
return source.getCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildStatusKey(String taskId) {
|
||||||
|
return "import:enterpriseBaseInfo:" + taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildFailuresKey(String taskId) {
|
||||||
|
return "import:enterpriseBaseInfo:" + taskId + ":failures";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
package com.ruoyi.info.collection.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.info.collection.domain.CcdiEnterpriseBaseInfo;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoAddDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoEditDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.dto.CcdiEnterpriseBaseInfoQueryDTO;
|
||||||
|
import com.ruoyi.info.collection.domain.excel.CcdiEnterpriseBaseInfoExcel;
|
||||||
|
import com.ruoyi.info.collection.domain.vo.CcdiEnterpriseBaseInfoVO;
|
||||||
|
import com.ruoyi.info.collection.enums.DataSource;
|
||||||
|
import com.ruoyi.info.collection.enums.EnterpriseRiskLevel;
|
||||||
|
import com.ruoyi.info.collection.enums.EnterpriseSource;
|
||||||
|
import com.ruoyi.info.collection.mapper.CcdiEnterpriseBaseInfoMapper;
|
||||||
|
import com.ruoyi.info.collection.service.ICcdiEnterpriseBaseInfoImportService;
|
||||||
|
import com.ruoyi.info.collection.service.ICcdiEnterpriseBaseInfoService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体库管理 Service 实现
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-04-17
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class CcdiEnterpriseBaseInfoServiceImpl implements ICcdiEnterpriseBaseInfoService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CcdiEnterpriseBaseInfoMapper enterpriseBaseInfoMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ICcdiEnterpriseBaseInfoImportService enterpriseBaseInfoImportService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<CcdiEnterpriseBaseInfoVO> selectEnterpriseBaseInfoPage(Page<CcdiEnterpriseBaseInfoVO> page,
|
||||||
|
CcdiEnterpriseBaseInfoQueryDTO queryDTO) {
|
||||||
|
return enterpriseBaseInfoMapper.selectEnterpriseBaseInfoPage(page, queryDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CcdiEnterpriseBaseInfoVO selectEnterpriseBaseInfoById(String socialCreditCode) {
|
||||||
|
CcdiEnterpriseBaseInfo entity = enterpriseBaseInfoMapper.selectById(socialCreditCode);
|
||||||
|
if (entity == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
CcdiEnterpriseBaseInfoVO vo = new CcdiEnterpriseBaseInfoVO();
|
||||||
|
BeanUtils.copyProperties(entity, vo);
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public int insertEnterpriseBaseInfo(CcdiEnterpriseBaseInfoAddDTO addDTO) {
|
||||||
|
if (enterpriseBaseInfoMapper.selectById(addDTO.getSocialCreditCode()) != null) {
|
||||||
|
throw new RuntimeException("该统一社会信用代码已存在");
|
||||||
|
}
|
||||||
|
validateEnumFields(addDTO.getStatus(), addDTO.getRiskLevel(), addDTO.getEntSource(), addDTO.getDataSource());
|
||||||
|
|
||||||
|
CcdiEnterpriseBaseInfo entity = new CcdiEnterpriseBaseInfo();
|
||||||
|
BeanUtils.copyProperties(addDTO, entity);
|
||||||
|
return enterpriseBaseInfoMapper.insert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public int updateEnterpriseBaseInfo(CcdiEnterpriseBaseInfoEditDTO editDTO) {
|
||||||
|
CcdiEnterpriseBaseInfo existing = enterpriseBaseInfoMapper.selectById(editDTO.getSocialCreditCode());
|
||||||
|
if (existing == null) {
|
||||||
|
throw new RuntimeException("实体库记录不存在");
|
||||||
|
}
|
||||||
|
validateEnumFields(editDTO.getStatus(), editDTO.getRiskLevel(), editDTO.getEntSource(), editDTO.getDataSource());
|
||||||
|
|
||||||
|
CcdiEnterpriseBaseInfo entity = new CcdiEnterpriseBaseInfo();
|
||||||
|
BeanUtils.copyProperties(editDTO, entity);
|
||||||
|
return enterpriseBaseInfoMapper.updateById(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public int deleteEnterpriseBaseInfoByIds(String[] socialCreditCodes) {
|
||||||
|
if (socialCreditCodes == null || socialCreditCodes.length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return enterpriseBaseInfoMapper.deleteBatchIds(List.of(socialCreditCodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CcdiEnterpriseBaseInfoExcel> selectEnterpriseBaseInfoListForExport(CcdiEnterpriseBaseInfoQueryDTO queryDTO) {
|
||||||
|
LambdaQueryWrapper<CcdiEnterpriseBaseInfo> wrapper = buildQueryWrapper(queryDTO);
|
||||||
|
return enterpriseBaseInfoMapper.selectList(wrapper).stream().map(entity -> {
|
||||||
|
CcdiEnterpriseBaseInfoExcel excel = new CcdiEnterpriseBaseInfoExcel();
|
||||||
|
BeanUtils.copyProperties(entity, excel);
|
||||||
|
return excel;
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public String importEnterpriseBaseInfo(List<CcdiEnterpriseBaseInfoExcel> excelList) {
|
||||||
|
String taskId = UUID.randomUUID().toString();
|
||||||
|
String statusKey = "import:enterpriseBaseInfo:" + taskId;
|
||||||
|
|
||||||
|
Map<String, Object> statusData = new HashMap<>();
|
||||||
|
statusData.put("taskId", taskId);
|
||||||
|
statusData.put("status", "PROCESSING");
|
||||||
|
statusData.put("totalCount", excelList.size());
|
||||||
|
statusData.put("successCount", 0);
|
||||||
|
statusData.put("failureCount", 0);
|
||||||
|
statusData.put("progress", 0);
|
||||||
|
statusData.put("startTime", System.currentTimeMillis());
|
||||||
|
statusData.put("message", "正在处理...");
|
||||||
|
|
||||||
|
redisTemplate.opsForHash().putAll(statusKey, statusData);
|
||||||
|
redisTemplate.expire(statusKey, 7, TimeUnit.DAYS);
|
||||||
|
|
||||||
|
enterpriseBaseInfoImportService.importEnterpriseBaseInfoAsync(excelList, taskId, SecurityUtils.getUsername());
|
||||||
|
return taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LambdaQueryWrapper<CcdiEnterpriseBaseInfo> buildQueryWrapper(CcdiEnterpriseBaseInfoQueryDTO queryDTO) {
|
||||||
|
LambdaQueryWrapper<CcdiEnterpriseBaseInfo> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
if (queryDTO == null) {
|
||||||
|
return wrapper.orderByDesc(CcdiEnterpriseBaseInfo::getCreateTime);
|
||||||
|
}
|
||||||
|
wrapper.like(StringUtils.isNotEmpty(queryDTO.getEnterpriseName()),
|
||||||
|
CcdiEnterpriseBaseInfo::getEnterpriseName, queryDTO.getEnterpriseName());
|
||||||
|
wrapper.eq(StringUtils.isNotEmpty(queryDTO.getSocialCreditCode()),
|
||||||
|
CcdiEnterpriseBaseInfo::getSocialCreditCode, queryDTO.getSocialCreditCode());
|
||||||
|
wrapper.eq(StringUtils.isNotEmpty(queryDTO.getEnterpriseType()),
|
||||||
|
CcdiEnterpriseBaseInfo::getEnterpriseType, queryDTO.getEnterpriseType());
|
||||||
|
wrapper.eq(StringUtils.isNotEmpty(queryDTO.getEnterpriseNature()),
|
||||||
|
CcdiEnterpriseBaseInfo::getEnterpriseNature, queryDTO.getEnterpriseNature());
|
||||||
|
wrapper.like(StringUtils.isNotEmpty(queryDTO.getIndustryClass()),
|
||||||
|
CcdiEnterpriseBaseInfo::getIndustryClass, queryDTO.getIndustryClass());
|
||||||
|
wrapper.eq(StringUtils.isNotEmpty(queryDTO.getStatus()),
|
||||||
|
CcdiEnterpriseBaseInfo::getStatus, queryDTO.getStatus());
|
||||||
|
wrapper.eq(StringUtils.isNotEmpty(queryDTO.getRiskLevel()),
|
||||||
|
CcdiEnterpriseBaseInfo::getRiskLevel, queryDTO.getRiskLevel());
|
||||||
|
wrapper.eq(StringUtils.isNotEmpty(queryDTO.getEntSource()),
|
||||||
|
CcdiEnterpriseBaseInfo::getEntSource, queryDTO.getEntSource());
|
||||||
|
return wrapper.orderByDesc(CcdiEnterpriseBaseInfo::getCreateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateEnumFields(String status, String riskLevel, String entSource, String dataSource) {
|
||||||
|
if (StringUtils.isEmpty(status)) {
|
||||||
|
throw new RuntimeException("经营状态不能为空");
|
||||||
|
}
|
||||||
|
if (!EnterpriseRiskLevel.contains(riskLevel)) {
|
||||||
|
throw new RuntimeException("风险等级不在允许范围内");
|
||||||
|
}
|
||||||
|
if (!EnterpriseSource.contains(entSource)) {
|
||||||
|
throw new RuntimeException("企业来源不在允许范围内");
|
||||||
|
}
|
||||||
|
if (!containsDataSource(dataSource)) {
|
||||||
|
throw new RuntimeException("数据来源不在允许范围内");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean containsDataSource(String code) {
|
||||||
|
for (DataSource source : DataSource.values()) {
|
||||||
|
if (source.getCode().equals(code)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,83 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="com.ruoyi.info.collection.mapper.CcdiEnterpriseBaseInfoMapper">
|
<mapper namespace="com.ruoyi.info.collection.mapper.CcdiEnterpriseBaseInfoMapper">
|
||||||
|
|
||||||
|
<resultMap id="CcdiEnterpriseBaseInfoVoResultMap" type="com.ruoyi.info.collection.domain.vo.CcdiEnterpriseBaseInfoVO">
|
||||||
|
<id property="socialCreditCode" column="social_credit_code"/>
|
||||||
|
<result property="enterpriseName" column="enterprise_name"/>
|
||||||
|
<result property="enterpriseType" column="enterprise_type"/>
|
||||||
|
<result property="enterpriseNature" column="enterprise_nature"/>
|
||||||
|
<result property="industryClass" column="industry_class"/>
|
||||||
|
<result property="industryName" column="industry_name"/>
|
||||||
|
<result property="establishDate" column="establish_date"/>
|
||||||
|
<result property="registerAddress" column="register_address"/>
|
||||||
|
<result property="legalRepresentative" column="legal_representative"/>
|
||||||
|
<result property="legalCertType" column="legal_cert_type"/>
|
||||||
|
<result property="legalCertNo" column="legal_cert_no"/>
|
||||||
|
<result property="shareholder1" column="shareholder1"/>
|
||||||
|
<result property="shareholder2" column="shareholder2"/>
|
||||||
|
<result property="shareholder3" column="shareholder3"/>
|
||||||
|
<result property="shareholder4" column="shareholder4"/>
|
||||||
|
<result property="shareholder5" column="shareholder5"/>
|
||||||
|
<result property="status" column="status"/>
|
||||||
|
<result property="riskLevel" column="risk_level"/>
|
||||||
|
<result property="entSource" column="ent_source"/>
|
||||||
|
<result property="dataSource" column="data_source"/>
|
||||||
|
<result property="createTime" column="create_time"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<select id="selectEnterpriseBaseInfoPage" resultMap="CcdiEnterpriseBaseInfoVoResultMap">
|
||||||
|
SELECT
|
||||||
|
social_credit_code,
|
||||||
|
enterprise_name,
|
||||||
|
enterprise_type,
|
||||||
|
enterprise_nature,
|
||||||
|
industry_class,
|
||||||
|
industry_name,
|
||||||
|
establish_date,
|
||||||
|
register_address,
|
||||||
|
legal_representative,
|
||||||
|
legal_cert_type,
|
||||||
|
legal_cert_no,
|
||||||
|
shareholder1,
|
||||||
|
shareholder2,
|
||||||
|
shareholder3,
|
||||||
|
shareholder4,
|
||||||
|
shareholder5,
|
||||||
|
status,
|
||||||
|
risk_level,
|
||||||
|
ent_source,
|
||||||
|
data_source,
|
||||||
|
create_time
|
||||||
|
FROM ccdi_enterprise_base_info
|
||||||
|
<where>
|
||||||
|
<if test="queryDTO != null and queryDTO.enterpriseName != null and queryDTO.enterpriseName != ''">
|
||||||
|
AND enterprise_name LIKE CONCAT('%', #{queryDTO.enterpriseName}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.socialCreditCode != null and queryDTO.socialCreditCode != ''">
|
||||||
|
AND social_credit_code = #{queryDTO.socialCreditCode}
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.enterpriseType != null and queryDTO.enterpriseType != ''">
|
||||||
|
AND enterprise_type = #{queryDTO.enterpriseType}
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.enterpriseNature != null and queryDTO.enterpriseNature != ''">
|
||||||
|
AND enterprise_nature = #{queryDTO.enterpriseNature}
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.industryClass != null and queryDTO.industryClass != ''">
|
||||||
|
AND industry_class LIKE CONCAT('%', #{queryDTO.industryClass}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.status != null and queryDTO.status != ''">
|
||||||
|
AND status = #{queryDTO.status}
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.riskLevel != null and queryDTO.riskLevel != ''">
|
||||||
|
AND risk_level = #{queryDTO.riskLevel}
|
||||||
|
</if>
|
||||||
|
<if test="queryDTO != null and queryDTO.entSource != null and queryDTO.entSource != ''">
|
||||||
|
AND ent_source = #{queryDTO.entSource}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
<!-- 批量插入实体中介 -->
|
<!-- 批量插入实体中介 -->
|
||||||
<insert id="insertBatch" parameterType="java.util.List">
|
<insert id="insertBatch" parameterType="java.util.List">
|
||||||
INSERT INTO ccdi_enterprise_base_info (
|
INSERT INTO ccdi_enterprise_base_info (
|
||||||
@@ -21,7 +98,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
#{item.legalRepresentative}, #{item.legalCertType}, #{item.legalCertNo},
|
#{item.legalRepresentative}, #{item.legalCertType}, #{item.legalCertNo},
|
||||||
#{item.shareholder1}, #{item.shareholder2}, #{item.shareholder3}, #{item.shareholder4}, #{item.shareholder5},
|
#{item.shareholder1}, #{item.shareholder2}, #{item.shareholder3}, #{item.shareholder4}, #{item.shareholder5},
|
||||||
#{item.status}, #{item.riskLevel}, #{item.entSource}, #{item.dataSource},
|
#{item.status}, #{item.riskLevel}, #{item.entSource}, #{item.dataSource},
|
||||||
#{item.createdBy}, #{item.updatedBy}, #{item.createTime}, #{item.updateTime}
|
#{item.createdBy}, #{item.updatedBy}, NOW(), NOW()
|
||||||
)
|
)
|
||||||
</foreach>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
@@ -43,7 +120,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
#{item.legalRepresentative}, #{item.legalCertType}, #{item.legalCertNo},
|
#{item.legalRepresentative}, #{item.legalCertType}, #{item.legalCertNo},
|
||||||
#{item.shareholder1}, #{item.shareholder2}, #{item.shareholder3}, #{item.shareholder4}, #{item.shareholder5},
|
#{item.shareholder1}, #{item.shareholder2}, #{item.shareholder3}, #{item.shareholder4}, #{item.shareholder5},
|
||||||
#{item.status}, #{item.riskLevel}, #{item.entSource}, #{item.dataSource},
|
#{item.status}, #{item.riskLevel}, #{item.entSource}, #{item.dataSource},
|
||||||
#{item.createdBy}, #{item.updatedBy}, #{item.createTime}, #{item.updateTime}
|
#{item.createdBy}, #{item.updatedBy}, NOW(), NOW()
|
||||||
)
|
)
|
||||||
</foreach>
|
</foreach>
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
@@ -67,7 +144,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
ent_source = VALUES(ent_source),
|
ent_source = VALUES(ent_source),
|
||||||
data_source = VALUES(data_source),
|
data_source = VALUES(data_source),
|
||||||
updated_by = VALUES(updated_by),
|
updated_by = VALUES(updated_by),
|
||||||
update_time = VALUES(update_time)
|
update_time = NOW()
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
<!-- 批量更新实体中介 -->
|
<!-- 批量更新实体中介 -->
|
||||||
@@ -95,7 +172,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="item.entSource != null">ent_source = #{item.entSource},</if>
|
<if test="item.entSource != null">ent_source = #{item.entSource},</if>
|
||||||
<if test="item.dataSource != null">data_source = #{item.dataSource},</if>
|
<if test="item.dataSource != null">data_source = #{item.dataSource},</if>
|
||||||
<if test="item.updatedBy != null">updated_by = #{item.updatedBy},</if>
|
<if test="item.updatedBy != null">updated_by = #{item.updatedBy},</if>
|
||||||
update_time = #{item.updateTime}
|
update_time = NOW()
|
||||||
</set>
|
</set>
|
||||||
WHERE social_credit_code = #{item.socialCreditCode}
|
WHERE social_credit_code = #{item.socialCreditCode}
|
||||||
</foreach>
|
</foreach>
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ruoyi.info.collection.mapper.CcdiIntermediaryEnterpriseRelationMapper">
|
||||||
|
|
||||||
|
<resultMap id="CcdiIntermediaryEnterpriseRelationVOResult"
|
||||||
|
type="com.ruoyi.info.collection.domain.vo.CcdiIntermediaryEnterpriseRelationVO">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="intermediaryBizId" column="intermediary_biz_id"/>
|
||||||
|
<result property="intermediaryName" column="intermediary_name"/>
|
||||||
|
<result property="intermediaryPersonId" column="intermediary_person_id"/>
|
||||||
|
<result property="socialCreditCode" column="social_credit_code"/>
|
||||||
|
<result property="enterpriseName" column="enterprise_name"/>
|
||||||
|
<result property="relationPersonPost" column="relation_person_post"/>
|
||||||
|
<result property="remark" column="remark"/>
|
||||||
|
<result property="createTime" column="create_time"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<select id="selectByIntermediaryBizId" resultMap="CcdiIntermediaryEnterpriseRelationVOResult">
|
||||||
|
SELECT
|
||||||
|
rel.id,
|
||||||
|
rel.intermediary_biz_id,
|
||||||
|
parent.name AS intermediary_name,
|
||||||
|
parent.person_id AS intermediary_person_id,
|
||||||
|
rel.social_credit_code,
|
||||||
|
ent.enterprise_name,
|
||||||
|
rel.relation_person_post,
|
||||||
|
rel.remark,
|
||||||
|
rel.create_time
|
||||||
|
FROM ccdi_intermediary_enterprise_relation rel
|
||||||
|
INNER JOIN ccdi_biz_intermediary parent
|
||||||
|
ON rel.intermediary_biz_id = parent.biz_id
|
||||||
|
LEFT JOIN ccdi_enterprise_base_info ent
|
||||||
|
ON rel.social_credit_code = ent.social_credit_code
|
||||||
|
WHERE rel.intermediary_biz_id = #{bizId}
|
||||||
|
ORDER BY rel.create_time DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectDetailById" resultMap="CcdiIntermediaryEnterpriseRelationVOResult">
|
||||||
|
SELECT
|
||||||
|
rel.id,
|
||||||
|
rel.intermediary_biz_id,
|
||||||
|
parent.name AS intermediary_name,
|
||||||
|
parent.person_id AS intermediary_person_id,
|
||||||
|
rel.social_credit_code,
|
||||||
|
ent.enterprise_name,
|
||||||
|
rel.relation_person_post,
|
||||||
|
rel.remark,
|
||||||
|
rel.create_time
|
||||||
|
FROM ccdi_intermediary_enterprise_relation rel
|
||||||
|
INNER JOIN ccdi_biz_intermediary parent
|
||||||
|
ON rel.intermediary_biz_id = parent.biz_id
|
||||||
|
LEFT JOIN ccdi_enterprise_base_info ent
|
||||||
|
ON rel.social_credit_code = ent.social_credit_code
|
||||||
|
WHERE rel.id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="existsByIntermediaryBizIdAndSocialCreditCode" resultType="boolean">
|
||||||
|
SELECT COUNT(1) > 0
|
||||||
|
FROM ccdi_intermediary_enterprise_relation
|
||||||
|
WHERE intermediary_biz_id = #{bizId}
|
||||||
|
AND social_credit_code = #{socialCreditCode}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
# 实体库管理后端实施计划
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** 新增独立的实体库管理后端链路,基于 `ccdi_enterprise_base_info` 支持分页查询、详情、新增、编辑、删除、异步导入、导入状态查询和失败记录查询。
|
||||||
|
|
||||||
|
**Architecture:** 复用现有 `CcdiEnterpriseBaseInfo` 实体与 Mapper,新增独立的 Controller、Service、DTO、VO、Excel 与导入服务,接口风格与员工信息维护保持一致。`riskLevel`、`entSource`、`dataSource` 统一通过枚举接口对外提供选项,导入采用严格新增策略,数据库重复和 Excel 内重复统一记为失败。
|
||||||
|
|
||||||
|
**Tech Stack:** Java 21, Spring Boot 3, MyBatis Plus, Redis, EasyExcel, JUnit 5, MySQL, Markdown
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 文件结构与职责
|
||||||
|
|
||||||
|
**后端源码**
|
||||||
|
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiEnterpriseBaseInfoController.java`
|
||||||
|
实体库管理对外接口入口,提供 CRUD、导入模板、导入任务状态和失败记录查询。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiEnterpriseBaseInfoService.java`
|
||||||
|
定义实体库管理服务接口。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiEnterpriseBaseInfoImportService.java`
|
||||||
|
定义异步导入状态与失败记录查询接口。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiEnterpriseBaseInfoServiceImpl.java`
|
||||||
|
承接分页查询、详情、增删改和导入任务提交。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiEnterpriseBaseInfoImportServiceImpl.java`
|
||||||
|
处理异步导入、校验、失败记录落 Redis 与状态回写。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiEnterpriseBaseInfoQueryDTO.java`
|
||||||
|
定义查询条件。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiEnterpriseBaseInfoAddDTO.java`
|
||||||
|
定义新增入参和校验规则。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiEnterpriseBaseInfoEditDTO.java`
|
||||||
|
定义编辑入参与主键不可变约束。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiEnterpriseBaseInfoVO.java`
|
||||||
|
承接列表和详情返回。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/EnterpriseBaseInfoImportFailureVO.java`
|
||||||
|
承接导入失败记录回显。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiEnterpriseBaseInfoExcel.java`
|
||||||
|
定义导入模板列、导入字段和字典下拉。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/enums/EnterpriseRiskLevel.java`
|
||||||
|
新增实体风险等级枚举。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/enums/EnterpriseSource.java`
|
||||||
|
新增企业来源枚举。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiEnumController.java`
|
||||||
|
新增风险等级与企业来源选项接口。
|
||||||
|
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiEnterpriseBaseInfoMapper.java`
|
||||||
|
补充分页查询与批量导入方法声明。
|
||||||
|
- `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiEnterpriseBaseInfoMapper.xml`
|
||||||
|
补充分页查询、结果映射、批量插入 SQL。
|
||||||
|
|
||||||
|
**SQL**
|
||||||
|
|
||||||
|
- `sql/migration/2026-04-17-add-enterprise-base-info-menu.sql`
|
||||||
|
新增“实体库管理”菜单和功能权限。
|
||||||
|
- `sql/migration/2026-04-17-add-enterprise-base-info-dict-or-enum-seed.sql`
|
||||||
|
如需初始化与导入模板一致的固定值说明,可在脚本中补充注释性或字典性数据;若最终走纯枚举接口,则只保留菜单 SQL。
|
||||||
|
|
||||||
|
**测试**
|
||||||
|
|
||||||
|
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiEnterpriseBaseInfoServiceImplTest.java`
|
||||||
|
校验新增、编辑、删除、详情和枚举值校验。
|
||||||
|
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiEnterpriseBaseInfoImportServiceImplTest.java`
|
||||||
|
校验导入重复失败、Excel 内重复失败和状态回写。
|
||||||
|
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiEnterpriseBaseInfoMapperTest.java`
|
||||||
|
校验分页 SQL 和结果映射关键片段。
|
||||||
|
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/controller/CcdiEnumControllerTest.java`
|
||||||
|
校验新增的枚举选项接口。
|
||||||
|
|
||||||
|
## 实施任务
|
||||||
|
|
||||||
|
### Task 1: 搭建实体库管理 DTO / VO / Excel 契约
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiEnterpriseBaseInfoQueryDTO.java`
|
||||||
|
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiEnterpriseBaseInfoAddDTO.java`
|
||||||
|
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiEnterpriseBaseInfoEditDTO.java`
|
||||||
|
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiEnterpriseBaseInfoVO.java`
|
||||||
|
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/EnterpriseBaseInfoImportFailureVO.java`
|
||||||
|
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiEnterpriseBaseInfoExcel.java`
|
||||||
|
- Reference: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/CcdiEnterpriseBaseInfo.java`
|
||||||
|
- Reference: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryEntityExcel.java`
|
||||||
|
|
||||||
|
- [x] 定义 QueryDTO,包含 `enterpriseName`、`socialCreditCode`、`enterpriseType`、`enterpriseNature`、`industryClass`、`status`、`riskLevel`、`entSource`。
|
||||||
|
- [x] 定义 AddDTO / EditDTO,完整覆盖单表维护字段,并给 `socialCreditCode`、`enterpriseName`、`status`、`riskLevel`、`entSource`、`dataSource` 加基础校验。
|
||||||
|
- [x] 在 EditDTO 中保持主键为必填,不新增改主键语义字段。
|
||||||
|
- [x] 定义 VO,补齐列表和详情所需字段,并预留 `createTime` 供前端表格展示。
|
||||||
|
- [x] 定义 Excel 对象,列顺序与页面表单一致,并为 `enterpriseType`、`enterpriseNature`、`legalCertType` 使用现有字典下拉;`riskLevel`、`entSource`、`dataSource` 保持文本列,后续由导入服务做枚举校验。
|
||||||
|
|
||||||
|
### Task 2: 补齐风险等级与企业来源枚举出口
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/enums/EnterpriseRiskLevel.java`
|
||||||
|
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/enums/EnterpriseSource.java`
|
||||||
|
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiEnumController.java`
|
||||||
|
|
||||||
|
- [x] 新增 `EnterpriseRiskLevel` 枚举,口径固定为 `1/2/3` 对应高/中/低风险,并提供 `getCode()`、`getDesc()`、`getDescByCode()`、`contains()`。
|
||||||
|
- [x] 新增 `EnterpriseSource` 枚举,口径固定为 `GENERAL`、`EMP_RELATION`、`CREDIT_CUSTOMER`、`INTERMEDIARY`、`BOTH`,并提供与现有 `DataSource` 一致的方法。
|
||||||
|
- [x] 在 `CcdiEnumController` 中新增 `/enterpriseRiskLevel` 与 `/enterpriseSource` 两个接口,返回 `EnumOptionVO` 列表。
|
||||||
|
- [x] 保持现有 `/dataSource` 不变,避免前端重复造轮子。
|
||||||
|
|
||||||
|
### Task 3: 实现分页查询与 CRUD 服务链路
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiEnterpriseBaseInfoMapper.java`
|
||||||
|
- Modify: `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiEnterpriseBaseInfoMapper.xml`
|
||||||
|
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiEnterpriseBaseInfoService.java`
|
||||||
|
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiEnterpriseBaseInfoServiceImpl.java`
|
||||||
|
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiEnterpriseBaseInfoController.java`
|
||||||
|
- Reference: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiBaseStaffController.java`
|
||||||
|
- Reference: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiBaseStaffServiceImpl.java`
|
||||||
|
|
||||||
|
- [x] 在 Mapper 中新增分页查询方法,按 QueryDTO 动态拼装筛选条件。
|
||||||
|
- [x] 在 Mapper XML 中新增结果映射和 `selectEnterpriseBaseInfoPage` SQL,输出 `create_time`、`risk_level`、`ent_source`、`data_source` 等字段。
|
||||||
|
- [x] 在 Service 接口中定义分页、详情、新增、编辑、删除、导出列表、导入任务提交方法。
|
||||||
|
- [x] 在 ServiceImpl 中实现主键唯一校验、编辑存在性校验、枚举值校验和删除批量处理。
|
||||||
|
- [x] 新建 Controller,接口路径统一使用 `/ccdi/enterpriseBaseInfo`,返回风格完全对齐员工信息维护。
|
||||||
|
- [x] 导入模板下载复用 `EasyExcelUtil.importTemplateWithDictDropdown`。
|
||||||
|
|
||||||
|
### Task 4: 实现异步导入与失败记录查询
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiEnterpriseBaseInfoImportService.java`
|
||||||
|
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiEnterpriseBaseInfoImportServiceImpl.java`
|
||||||
|
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiEnterpriseBaseInfoServiceImpl.java`
|
||||||
|
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiEnterpriseBaseInfoController.java`
|
||||||
|
- Reference: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiBaseStaffImportServiceImpl.java`
|
||||||
|
- Reference: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiIntermediaryEntityImportServiceImpl.java`
|
||||||
|
|
||||||
|
- [x] 在 ServiceImpl 中提交导入任务,Redis key 建议使用 `import:enterpriseBaseInfo:{taskId}`。
|
||||||
|
- [x] 在导入服务中实现 Excel 行校验,数据库重复与 Excel 内重复统一生成失败记录。
|
||||||
|
- [x] 新增 `riskLevel`、`entSource`、`dataSource` 枚举校验,拒绝非法值。
|
||||||
|
- [x] 成功记录分批批量插入;导入不支持更新,不提供 `updateSupport` 分支逻辑。
|
||||||
|
- [x] 失败记录写入 Redis,状态统一支持 `PROCESSING`、`SUCCESS`、`PARTIAL_SUCCESS`。
|
||||||
|
- [x] Controller 补 `/importData`、`/importStatus/{taskId}`、`/importFailures/{taskId}` 三个接口,分页失败记录方式与员工信息维护一致。
|
||||||
|
|
||||||
|
### Task 5: 补菜单 SQL 和权限口径
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Create: `sql/migration/2026-04-17-add-enterprise-base-info-menu.sql`
|
||||||
|
- Reference: `sql/ccdi_staff_fmy_relation_menu.sql`
|
||||||
|
- Reference: `sql/migration/2026-04-13-add-ccdi-account-info-menu.sql`
|
||||||
|
|
||||||
|
- [x] 在“信息维护”目录下新增“实体库管理”菜单。
|
||||||
|
- [x] 菜单 path 固定为 `enterpriseBaseInfo`,component 固定为 `ccdiEnterpriseBaseInfo/index`。
|
||||||
|
- [x] 功能权限至少包含 `list`、`query`、`add`、`edit`、`remove`、`import`。
|
||||||
|
- [x] SQL 保持幂等写法,避免重复插入菜单。
|
||||||
|
|
||||||
|
### Task 6: 补后端测试与验证命令
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Create: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiEnterpriseBaseInfoServiceImplTest.java`
|
||||||
|
- Create: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiEnterpriseBaseInfoImportServiceImplTest.java`
|
||||||
|
- Create: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiEnterpriseBaseInfoMapperTest.java`
|
||||||
|
- Create: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/controller/CcdiEnumControllerTest.java`
|
||||||
|
|
||||||
|
- [x] 为新增、编辑、删除、详情和枚举值校验补服务测试。
|
||||||
|
- [x] 为导入数据库重复失败、Excel 内重复失败补导入服务测试。
|
||||||
|
- [x] 为 Mapper XML 的分页查询关键 SQL 补测试或最小断言。
|
||||||
|
- [x] 为新增枚举接口补 Controller 测试。
|
||||||
|
- [x] 执行后端验证命令并记录结果。
|
||||||
|
|
||||||
|
## 验证命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mvn -pl ccdi-info-collection -Dtest=CcdiEnterpriseBaseInfoServiceImplTest,CcdiEnterpriseBaseInfoImportServiceImplTest,CcdiEnterpriseBaseInfoMapperTest,CcdiEnumControllerTest test
|
||||||
|
mvn -pl ccdi-info-collection -DskipTests compile
|
||||||
|
```
|
||||||
|
|
||||||
|
## 执行结果
|
||||||
|
|
||||||
|
- 实际测试命令:`mvn -pl ccdi-info-collection -am -Dsurefire.failIfNoSpecifiedTests=false -Dtest=CcdiEnterpriseBaseInfoServiceImplTest,CcdiEnterpriseBaseInfoImportServiceImplTest,CcdiEnterpriseBaseInfoMapperTest,CcdiEnumControllerTest test`
|
||||||
|
- 测试结果:`BUILD SUCCESS`,共执行 11 个测试,`Failures: 0, Errors: 0, Skipped: 0`
|
||||||
|
- 实际编译命令:`mvn -pl ccdi-info-collection -am -DskipTests compile`
|
||||||
|
- 编译结果:`BUILD SUCCESS`
|
||||||
|
|
||||||
|
## 完成标准
|
||||||
|
|
||||||
|
- 后端新增独立 `/ccdi/enterpriseBaseInfo` 管理接口
|
||||||
|
- 列表、详情、新增、编辑、删除链路可用
|
||||||
|
- 导入严格新增,数据库重复与 Excel 内重复都进入失败记录
|
||||||
|
- `riskLevel`、`entSource`、`dataSource` 均有统一选项口径
|
||||||
|
- 菜单 SQL 与权限标识已补齐
|
||||||
|
- 后端定向测试与编译验证已执行并记录结果
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
# 实体库管理前端实施计划
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** 新增独立的实体库管理前端页面,打通查询、新增、查看、编辑、删除、导入、导入状态轮询与失败记录查看。
|
||||||
|
|
||||||
|
**Architecture:** 继续沿用员工信息维护的单页大文件实现方式,新建 `ccdiEnterpriseBaseInfo` 页面和独立 API 文件,不改造现有中介页面。选项数据统一从 `ccdiEnum` 拉取,列表、弹窗、导入和失败记录交互整体对齐员工信息维护,避免页面内再维护一套业务语义。
|
||||||
|
|
||||||
|
**Tech Stack:** Vue 2, Element UI, JavaScript, npm, nvm, Markdown
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 文件结构与职责
|
||||||
|
|
||||||
|
**前端源码**
|
||||||
|
|
||||||
|
- `ruoyi-ui/src/views/ccdiEnterpriseBaseInfo/index.vue`
|
||||||
|
实体库管理主页面,负责搜索、表格、编辑弹窗、详情弹窗、导入和失败记录。
|
||||||
|
- `ruoyi-ui/src/api/ccdiEnterpriseBaseInfo.js`
|
||||||
|
新增实体库管理接口封装。
|
||||||
|
- `ruoyi-ui/src/api/ccdiEnum.js`
|
||||||
|
补风险等级与企业来源选项请求方法。
|
||||||
|
|
||||||
|
**依赖参考**
|
||||||
|
|
||||||
|
- `ruoyi-ui/src/views/ccdiBaseStaff/index.vue`
|
||||||
|
作为页面结构、导入轮询、失败记录和工具栏交互模板。
|
||||||
|
- `ruoyi-ui/src/views/ccdiIntermediary/index.vue`
|
||||||
|
参考实体导入失败记录展示字段。
|
||||||
|
- `ruoyi-ui/src/api/ccdiBaseStaff.js`
|
||||||
|
参考单表管理 API 风格。
|
||||||
|
|
||||||
|
## 实施任务
|
||||||
|
|
||||||
|
### Task 1: 搭建实体库管理 API 与选项加载
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Create: `ruoyi-ui/src/api/ccdiEnterpriseBaseInfo.js`
|
||||||
|
- Modify: `ruoyi-ui/src/api/ccdiEnum.js`
|
||||||
|
|
||||||
|
- [x] 在新 API 文件中定义 `listEnterpriseBaseInfo`、`getEnterpriseBaseInfo`、`addEnterpriseBaseInfo`、`updateEnterpriseBaseInfo`、`delEnterpriseBaseInfo`、`importTemplate`、`importData`、`getImportStatus`、`getImportFailures`。
|
||||||
|
- [x] 在 `ccdiEnum.js` 中新增 `getEnterpriseRiskLevelOptions` 与 `getEnterpriseSourceOptions`。
|
||||||
|
- [x] 继续复用现有 `getCorpTypeOptions`、`getCorpNatureOptions`、`getCertTypeOptions`、`getDataSourceOptions`。
|
||||||
|
|
||||||
|
### Task 2: 搭建页面骨架与查询表单
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Create: `ruoyi-ui/src/views/ccdiEnterpriseBaseInfo/index.vue`
|
||||||
|
- Reference: `ruoyi-ui/src/views/ccdiBaseStaff/index.vue`
|
||||||
|
|
||||||
|
- [x] 初始化页面数据结构,至少包含 `loading`、`enterpriseBaseInfoList`、`queryParams`、`form`、`rules`、`open`、`detailOpen`、`upload`、`showFailureButton`。
|
||||||
|
- [x] 查询区按设计文档落 `enterpriseName`、`socialCreditCode`、`enterpriseType`、`enterpriseNature`、`industryClass`、`status`、`riskLevel`、`entSource`。
|
||||||
|
- [x] 在 `created` 或首屏初始化流程中并发拉取主体类型、企业性质、证件类型、风险等级、企业来源、数据来源选项。
|
||||||
|
- [x] 搜索、重置、分页方法命名保持员工页一致,降低后续维护成本。
|
||||||
|
|
||||||
|
### Task 3: 完成列表、详情与编辑弹窗
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Modify: `ruoyi-ui/src/views/ccdiEnterpriseBaseInfo/index.vue`
|
||||||
|
|
||||||
|
- [x] 列表区展示企业名称、统一社会信用代码、企业类型、企业性质、行业分类、所属行业、法定代表人、经营状态、风险等级、企业来源、数据来源、创建时间。
|
||||||
|
- [x] 通过格式化方法把 `riskLevel`、`entSource`、`dataSource` 展示成中文描述,不直接露出编码。
|
||||||
|
- [x] 实现详情弹窗,只读展示与表单同口径字段。
|
||||||
|
- [x] 实现新增/编辑弹窗,编辑态禁用统一社会信用代码输入框。
|
||||||
|
- [x] 表单中补齐 `status`、`riskLevel`、`entSource`、`dataSource` 四个可维护字段。
|
||||||
|
- [x] 提交时保持最短路径,不做额外参数转换层,只在需要时把空字符串标准化。
|
||||||
|
|
||||||
|
### Task 4: 完成删除、导入与失败记录流程
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Modify: `ruoyi-ui/src/views/ccdiEnterpriseBaseInfo/index.vue`
|
||||||
|
|
||||||
|
- [x] 删除逻辑对齐员工页,支持单条删除和批量删除。
|
||||||
|
- [x] 新增导入弹窗配置,上传地址指向 `/ccdi/enterpriseBaseInfo/importData`。
|
||||||
|
- [x] 导入完成后缓存最近一次任务号,建议 key 使用 `enterprise_base_info_import_last_task`。
|
||||||
|
- [x] 增加导入状态轮询逻辑,状态结束后刷新列表并按结果决定是否显示“查看导入失败记录”按钮。
|
||||||
|
- [x] 新增失败记录弹窗,至少展示企业名称、统一社会信用代码、企业类型、企业性质、风险等级、企业来源、失败原因。
|
||||||
|
- [x] 提供“清除历史记录”能力,行为与员工页保持一致。
|
||||||
|
|
||||||
|
### Task 5: 补页面校验和展示细节
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Modify: `ruoyi-ui/src/views/ccdiEnterpriseBaseInfo/index.vue`
|
||||||
|
|
||||||
|
- [x] 为统一社会信用代码增加 18 位格式校验。
|
||||||
|
- [x] 为企业名称、经营状态、风险等级、企业来源、数据来源增加必填校验。
|
||||||
|
- [x] 新增 `formatRiskLevel`、`formatEnterpriseSource`、`formatDataSource`、`formatStatus` 等展示方法。
|
||||||
|
- [x] 详情和列表统一复用格式化方法,避免页面出现双口径文本。
|
||||||
|
|
||||||
|
### Task 6: 执行前端构建验证
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Modify: `docs/plans/frontend/2026-04-17-enterprise-base-info-management-frontend-implementation.md`
|
||||||
|
在执行阶段补实际验证结果。
|
||||||
|
|
||||||
|
- [x] 使用 `nvm` 切换 Node 版本,优先使用当前仓库已验证可构建的版本。
|
||||||
|
- [x] 执行生产构建,确认页面编译通过。
|
||||||
|
- [x] 若有构建阻塞,记录真实错误,不引入额外兼容方案。
|
||||||
|
|
||||||
|
## 验证命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui
|
||||||
|
source ~/.nvm/nvm.sh && nvm use 14.21.3
|
||||||
|
npm run build:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
## 执行结果
|
||||||
|
|
||||||
|
- 实际执行命令:`cd /Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui && source ~/.nvm/nvm.sh && nvm use 14.21.3 && npm run build:prod`
|
||||||
|
- 构建结果:`BUILD SUCCESS`
|
||||||
|
- 备注:构建过程中仅有既有包体积告警(asset size / entrypoint size limit),未出现语法或模块解析错误
|
||||||
|
|
||||||
|
## 完成标准
|
||||||
|
|
||||||
|
- 前端新增独立“实体库管理”页面与 API 文件
|
||||||
|
- 查询、分页、详情、新增、编辑、删除链路可用
|
||||||
|
- 风险等级、企业来源、数据来源全部以统一选项口径展示和提交
|
||||||
|
- 导入轮询、失败记录、历史任务缓存可用
|
||||||
|
- 已使用 `nvm` 切换 Node 版本并完成前端构建验证
|
||||||
78
ruoyi-ui/src/api/ccdiEnterpriseBaseInfo.js
Normal file
78
ruoyi-ui/src/api/ccdiEnterpriseBaseInfo.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询实体库列表
|
||||||
|
export function listEnterpriseBaseInfo(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/enterpriseBaseInfo/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询实体库详细
|
||||||
|
export function getEnterpriseBaseInfo(socialCreditCode) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/enterpriseBaseInfo/' + socialCreditCode,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增实体库
|
||||||
|
export function addEnterpriseBaseInfo(data) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/enterpriseBaseInfo',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改实体库
|
||||||
|
export function updateEnterpriseBaseInfo(data) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/enterpriseBaseInfo',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除实体库
|
||||||
|
export function delEnterpriseBaseInfo(socialCreditCodes) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/enterpriseBaseInfo/' + socialCreditCodes,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载导入模板
|
||||||
|
export function importTemplate() {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/enterpriseBaseInfo/importTemplate',
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导入实体库
|
||||||
|
export function importData(data) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/enterpriseBaseInfo/importData',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询导入状态
|
||||||
|
export function getImportStatus(taskId) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/enterpriseBaseInfo/importStatus/' + taskId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询导入失败记录
|
||||||
|
export function getImportFailures(taskId, pageNum, pageSize) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/enterpriseBaseInfo/importFailures/' + taskId,
|
||||||
|
method: 'get',
|
||||||
|
params: { pageNum, pageSize }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -89,3 +89,23 @@ export function getDataSourceOptions() {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询实体风险等级选项
|
||||||
|
*/
|
||||||
|
export function getEnterpriseRiskLevelOptions() {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/enum/enterpriseRiskLevel',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询企业来源选项
|
||||||
|
*/
|
||||||
|
export function getEnterpriseSourceOptions() {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/enum/enterpriseSource',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
977
ruoyi-ui/src/views/ccdiEnterpriseBaseInfo/index.vue
Normal file
977
ruoyi-ui/src/views/ccdiEnterpriseBaseInfo/index.vue
Normal file
@@ -0,0 +1,977 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form ref="queryForm" :model="queryParams" size="small" :inline="true" v-show="showSearch" label-width="110px">
|
||||||
|
<el-form-item label="企业名称" prop="enterpriseName">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.enterpriseName"
|
||||||
|
placeholder="请输入企业名称"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="统一社会信用代码" prop="socialCreditCode">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.socialCreditCode"
|
||||||
|
placeholder="请输入统一社会信用代码"
|
||||||
|
clearable
|
||||||
|
maxlength="18"
|
||||||
|
style="width: 240px"
|
||||||
|
@input="queryParams.socialCreditCode = normalizeUpperCode(queryParams.socialCreditCode)"
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="企业类型" prop="enterpriseType">
|
||||||
|
<el-select v-model="queryParams.enterpriseType" placeholder="请选择企业类型" clearable style="width: 240px">
|
||||||
|
<el-option
|
||||||
|
v-for="item in corpTypeOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="企业性质" prop="enterpriseNature">
|
||||||
|
<el-select v-model="queryParams.enterpriseNature" placeholder="请选择企业性质" clearable style="width: 240px">
|
||||||
|
<el-option
|
||||||
|
v-for="item in corpNatureOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="行业分类" prop="industryClass">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.industryClass"
|
||||||
|
placeholder="请输入行业分类"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="经营状态" prop="status">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.status"
|
||||||
|
placeholder="请输入经营状态"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="风险等级" prop="riskLevel">
|
||||||
|
<el-select v-model="queryParams.riskLevel" placeholder="请选择风险等级" clearable style="width: 240px">
|
||||||
|
<el-option
|
||||||
|
v-for="item in riskLevelOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="企业来源" prop="entSource">
|
||||||
|
<el-select v-model="queryParams.entSource" placeholder="请选择企业来源" clearable style="width: 240px">
|
||||||
|
<el-option
|
||||||
|
v-for="item in enterpriseSourceOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="el-icon-plus"
|
||||||
|
size="mini"
|
||||||
|
@click="handleAdd"
|
||||||
|
v-hasPermi="['ccdi:enterpriseBaseInfo:add']"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
icon="el-icon-delete"
|
||||||
|
size="mini"
|
||||||
|
:disabled="multiple"
|
||||||
|
@click="handleDelete"
|
||||||
|
v-hasPermi="['ccdi:enterpriseBaseInfo:remove']"
|
||||||
|
>删除</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
icon="el-icon-upload2"
|
||||||
|
size="mini"
|
||||||
|
@click="handleImport"
|
||||||
|
v-hasPermi="['ccdi:enterpriseBaseInfo:import']"
|
||||||
|
>导入</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5" v-if="showFailureButton">
|
||||||
|
<el-tooltip :content="getLastImportTooltip()" placement="top">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-warning"
|
||||||
|
size="mini"
|
||||||
|
@click="viewImportFailures"
|
||||||
|
>查看导入失败记录</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="enterpriseBaseInfoList" @selection-change="handleSelectionChange">
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="企业名称" align="center" prop="enterpriseName" min-width="180" show-overflow-tooltip />
|
||||||
|
<el-table-column label="统一社会信用代码" align="center" prop="socialCreditCode" width="180" show-overflow-tooltip />
|
||||||
|
<el-table-column label="企业类型" align="center" prop="enterpriseType" min-width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column label="企业性质" align="center" prop="enterpriseNature" min-width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column label="行业分类" align="center" prop="industryClass" min-width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column label="所属行业" align="center" prop="industryName" min-width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column label="法定代表人" align="center" prop="legalRepresentative" width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column label="经营状态" align="center" prop="status" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ formatStatus(scope.row.status) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="风险等级" align="center" prop="riskLevel" width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ formatRiskLevel(scope.row.riskLevel) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="企业来源" align="center" prop="entSource" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ formatEnterpriseSource(scope.row.entSource) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="数据来源" align="center" prop="dataSource" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ formatDataSource(scope.row.dataSource) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-view"
|
||||||
|
@click="handleDetail(scope.row)"
|
||||||
|
v-hasPermi="['ccdi:enterpriseBaseInfo:query']"
|
||||||
|
>详情</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-edit"
|
||||||
|
@click="handleUpdate(scope.row)"
|
||||||
|
v-hasPermi="['ccdi:enterpriseBaseInfo:edit']"
|
||||||
|
>编辑</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
@click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['ccdi:enterpriseBaseInfo:remove']"
|
||||||
|
>删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-show="total > 0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<el-dialog :title="title" :visible.sync="open" width="1100px" append-to-body>
|
||||||
|
<el-form ref="form" :model="form" :rules="rules" label-width="140px">
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="统一社会信用代码" prop="socialCreditCode">
|
||||||
|
<el-input
|
||||||
|
v-model="form.socialCreditCode"
|
||||||
|
placeholder="请输入统一社会信用代码"
|
||||||
|
maxlength="18"
|
||||||
|
:disabled="!isAdd"
|
||||||
|
@input="form.socialCreditCode = normalizeUpperCode(form.socialCreditCode)"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="企业名称" prop="enterpriseName">
|
||||||
|
<el-input v-model="form.enterpriseName" placeholder="请输入企业名称" maxlength="200" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="企业类型" prop="enterpriseType">
|
||||||
|
<el-select v-model="form.enterpriseType" placeholder="请选择企业类型" clearable style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in corpTypeOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="企业性质" prop="enterpriseNature">
|
||||||
|
<el-select v-model="form.enterpriseNature" placeholder="请选择企业性质" clearable style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in corpNatureOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="行业分类" prop="industryClass">
|
||||||
|
<el-input v-model="form.industryClass" placeholder="请输入行业分类" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="所属行业" prop="industryName">
|
||||||
|
<el-input v-model="form.industryName" placeholder="请输入所属行业" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="成立日期" prop="establishDate">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.establishDate"
|
||||||
|
type="date"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
placeholder="请选择成立日期"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="注册地址" prop="registerAddress">
|
||||||
|
<el-input v-model="form.registerAddress" placeholder="请输入注册地址" maxlength="500" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="法定代表人" prop="legalRepresentative">
|
||||||
|
<el-input v-model="form.legalRepresentative" placeholder="请输入法定代表人" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="法定代表人证件类型" prop="legalCertType">
|
||||||
|
<el-select v-model="form.legalCertType" placeholder="请选择证件类型" clearable style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in certTypeOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="法定代表人证件号码" prop="legalCertNo">
|
||||||
|
<el-input v-model="form.legalCertNo" placeholder="请输入法定代表人证件号码" maxlength="50" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="经营状态" prop="status">
|
||||||
|
<el-input v-model="form.status" placeholder="请输入经营状态" maxlength="50" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="风险等级" prop="riskLevel">
|
||||||
|
<el-select v-model="form.riskLevel" placeholder="请选择风险等级" style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in riskLevelOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="企业来源" prop="entSource">
|
||||||
|
<el-select v-model="form.entSource" placeholder="请选择企业来源" style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in enterpriseSourceOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="数据来源" prop="dataSource">
|
||||||
|
<el-select v-model="form.dataSource" placeholder="请选择数据来源" style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in dataSourceOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="股东1" prop="shareholder1">
|
||||||
|
<el-input v-model="form.shareholder1" placeholder="请输入股东1" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="股东2" prop="shareholder2">
|
||||||
|
<el-input v-model="form.shareholder2" placeholder="请输入股东2" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="股东3" prop="shareholder3">
|
||||||
|
<el-input v-model="form.shareholder3" placeholder="请输入股东3" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="股东4" prop="shareholder4">
|
||||||
|
<el-input v-model="form.shareholder4" placeholder="请输入股东4" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="股东5" prop="shareholder5">
|
||||||
|
<el-input v-model="form.shareholder5" placeholder="请输入股东5" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog title="实体库详情" :visible.sync="detailOpen" width="1000px" append-to-body>
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="统一社会信用代码">{{ detailData.socialCreditCode || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="企业名称">{{ detailData.enterpriseName || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="企业类型">{{ detailData.enterpriseType || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="企业性质">{{ detailData.enterpriseNature || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="行业分类">{{ detailData.industryClass || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="所属行业">{{ detailData.industryName || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="成立日期">{{ parseTime(detailData.establishDate, '{y}-{m}-{d}') || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="注册地址">{{ detailData.registerAddress || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="法定代表人">{{ detailData.legalRepresentative || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="法定代表人证件类型">{{ detailData.legalCertType || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="法定代表人证件号码">{{ detailData.legalCertNo || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="经营状态">{{ formatStatus(detailData.status) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="风险等级">{{ formatRiskLevel(detailData.riskLevel) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="企业来源">{{ formatEnterpriseSource(detailData.entSource) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="数据来源">{{ formatDataSource(detailData.dataSource) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="创建时间">{{ parseTime(detailData.createTime) || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="股东1">{{ detailData.shareholder1 || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="股东2">{{ detailData.shareholder2 || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="股东3">{{ detailData.shareholder3 || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="股东4">{{ detailData.shareholder4 || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="股东5">{{ detailData.shareholder5 || '-' }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="detailOpen = false">关 闭</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
:title="upload.title"
|
||||||
|
:visible.sync="upload.open"
|
||||||
|
width="400px"
|
||||||
|
append-to-body
|
||||||
|
@close="handleImportDialogClose"
|
||||||
|
v-loading="upload.isUploading"
|
||||||
|
element-loading-text="正在导入数据,请稍候..."
|
||||||
|
element-loading-spinner="el-icon-loading"
|
||||||
|
element-loading-background="rgba(0, 0, 0, 0.7)"
|
||||||
|
>
|
||||||
|
<el-upload
|
||||||
|
ref="upload"
|
||||||
|
:limit="1"
|
||||||
|
accept=".xlsx, .xls"
|
||||||
|
:headers="upload.headers"
|
||||||
|
:action="upload.url"
|
||||||
|
:disabled="upload.isUploading"
|
||||||
|
:on-progress="handleFileUploadProgress"
|
||||||
|
:on-success="handleFileSuccess"
|
||||||
|
:auto-upload="false"
|
||||||
|
drag
|
||||||
|
>
|
||||||
|
<i class="el-icon-upload"></i>
|
||||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
|
<div class="el-upload__tip" slot="tip">
|
||||||
|
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline;" @click="downloadImportTemplate">下载模板</el-link>
|
||||||
|
</div>
|
||||||
|
<div class="el-upload__tip" slot="tip">
|
||||||
|
<span>仅允许导入"xls"或"xlsx"格式文件。</span>
|
||||||
|
</div>
|
||||||
|
</el-upload>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitFileForm" :loading="upload.isUploading">确 定</el-button>
|
||||||
|
<el-button @click="upload.open = false" :disabled="upload.isUploading">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog title="实体库导入失败记录" :visible.sync="failureDialogVisible" width="1200px" append-to-body>
|
||||||
|
<el-alert
|
||||||
|
v-if="lastImportInfo"
|
||||||
|
:title="lastImportInfo"
|
||||||
|
type="info"
|
||||||
|
:closable="false"
|
||||||
|
style="margin-bottom: 15px"
|
||||||
|
/>
|
||||||
|
<el-table :data="failureList" v-loading="failureLoading">
|
||||||
|
<el-table-column label="企业名称" prop="enterpriseName" align="center" min-width="180" />
|
||||||
|
<el-table-column label="统一社会信用代码" prop="socialCreditCode" align="center" min-width="180" />
|
||||||
|
<el-table-column label="企业类型" prop="enterpriseType" align="center" min-width="120" />
|
||||||
|
<el-table-column label="企业性质" prop="enterpriseNature" align="center" min-width="120" />
|
||||||
|
<el-table-column label="风险等级" prop="riskLevel" align="center" min-width="100" />
|
||||||
|
<el-table-column label="企业来源" prop="entSource" align="center" min-width="120" />
|
||||||
|
<el-table-column
|
||||||
|
label="失败原因"
|
||||||
|
prop="errorMessage"
|
||||||
|
align="center"
|
||||||
|
min-width="220"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
/>
|
||||||
|
</el-table>
|
||||||
|
<pagination
|
||||||
|
v-show="failureTotal > 0"
|
||||||
|
:total="failureTotal"
|
||||||
|
:page.sync="failureQueryParams.pageNum"
|
||||||
|
:limit.sync="failureQueryParams.pageSize"
|
||||||
|
@pagination="getFailureList"
|
||||||
|
/>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="failureDialogVisible = false">关 闭</el-button>
|
||||||
|
<el-button type="danger" plain @click="clearImportHistory">清除历史记录</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
addEnterpriseBaseInfo,
|
||||||
|
delEnterpriseBaseInfo,
|
||||||
|
getEnterpriseBaseInfo,
|
||||||
|
getImportFailures,
|
||||||
|
getImportStatus,
|
||||||
|
listEnterpriseBaseInfo,
|
||||||
|
updateEnterpriseBaseInfo
|
||||||
|
} from "@/api/ccdiEnterpriseBaseInfo";
|
||||||
|
import {
|
||||||
|
getCertTypeOptions,
|
||||||
|
getCorpNatureOptions,
|
||||||
|
getCorpTypeOptions,
|
||||||
|
getDataSourceOptions,
|
||||||
|
getEnterpriseRiskLevelOptions,
|
||||||
|
getEnterpriseSourceOptions
|
||||||
|
} from "@/api/ccdiEnum";
|
||||||
|
import { getToken } from "@/utils/auth";
|
||||||
|
|
||||||
|
const socialCreditCodePattern = /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "EnterpriseBaseInfo",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: true,
|
||||||
|
ids: [],
|
||||||
|
single: true,
|
||||||
|
multiple: true,
|
||||||
|
showSearch: true,
|
||||||
|
total: 0,
|
||||||
|
enterpriseBaseInfoList: [],
|
||||||
|
title: "",
|
||||||
|
open: false,
|
||||||
|
detailOpen: false,
|
||||||
|
isAdd: true,
|
||||||
|
detailData: {},
|
||||||
|
corpTypeOptions: [],
|
||||||
|
corpNatureOptions: [],
|
||||||
|
certTypeOptions: [],
|
||||||
|
riskLevelOptions: [],
|
||||||
|
enterpriseSourceOptions: [],
|
||||||
|
dataSourceOptions: [],
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
enterpriseName: null,
|
||||||
|
socialCreditCode: null,
|
||||||
|
enterpriseType: null,
|
||||||
|
enterpriseNature: null,
|
||||||
|
industryClass: null,
|
||||||
|
status: null,
|
||||||
|
riskLevel: null,
|
||||||
|
entSource: null
|
||||||
|
},
|
||||||
|
form: {},
|
||||||
|
rules: {
|
||||||
|
socialCreditCode: [
|
||||||
|
{ required: true, message: "统一社会信用代码不能为空", trigger: "blur" },
|
||||||
|
{ pattern: socialCreditCodePattern, message: "请输入正确的18位统一社会信用代码", trigger: "blur" }
|
||||||
|
],
|
||||||
|
enterpriseName: [
|
||||||
|
{ required: true, message: "企业名称不能为空", trigger: "blur" },
|
||||||
|
{ max: 200, message: "企业名称长度不能超过200个字符", trigger: "blur" }
|
||||||
|
],
|
||||||
|
status: [
|
||||||
|
{ required: true, message: "经营状态不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
riskLevel: [
|
||||||
|
{ required: true, message: "请选择风险等级", trigger: "change" }
|
||||||
|
],
|
||||||
|
entSource: [
|
||||||
|
{ required: true, message: "请选择企业来源", trigger: "change" }
|
||||||
|
],
|
||||||
|
dataSource: [
|
||||||
|
{ required: true, message: "请选择数据来源", trigger: "change" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
upload: {
|
||||||
|
open: false,
|
||||||
|
title: "",
|
||||||
|
isUploading: false,
|
||||||
|
headers: { Authorization: "Bearer " + getToken() },
|
||||||
|
url: process.env.VUE_APP_BASE_API + "/ccdi/enterpriseBaseInfo/importData"
|
||||||
|
},
|
||||||
|
pollingTimer: null,
|
||||||
|
showFailureButton: false,
|
||||||
|
currentTaskId: null,
|
||||||
|
failureDialogVisible: false,
|
||||||
|
failureList: [],
|
||||||
|
failureLoading: false,
|
||||||
|
failureTotal: 0,
|
||||||
|
failureQueryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
lastImportInfo() {
|
||||||
|
var savedTask = this.getImportTaskFromStorage();
|
||||||
|
if (savedTask && savedTask.totalCount) {
|
||||||
|
return "导入时间: " + this.parseTime(savedTask.saveTime) +
|
||||||
|
" | 总数: " + savedTask.totalCount + "条" +
|
||||||
|
" | 成功: " + savedTask.successCount + "条" +
|
||||||
|
" | 失败: " + savedTask.failureCount + "条";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
this.loadOptions();
|
||||||
|
this.restoreImportState();
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.pollingTimer) {
|
||||||
|
clearInterval(this.pollingTimer);
|
||||||
|
this.pollingTimer = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadOptions() {
|
||||||
|
Promise.all([
|
||||||
|
getCorpTypeOptions(),
|
||||||
|
getCorpNatureOptions(),
|
||||||
|
getCertTypeOptions(),
|
||||||
|
getEnterpriseRiskLevelOptions(),
|
||||||
|
getEnterpriseSourceOptions(),
|
||||||
|
getDataSourceOptions()
|
||||||
|
]).then(([corpTypeRes, corpNatureRes, certTypeRes, riskLevelRes, enterpriseSourceRes, dataSourceRes]) => {
|
||||||
|
this.corpTypeOptions = corpTypeRes.data || [];
|
||||||
|
this.corpNatureOptions = corpNatureRes.data || [];
|
||||||
|
this.certTypeOptions = certTypeRes.data || [];
|
||||||
|
this.riskLevelOptions = riskLevelRes.data || [];
|
||||||
|
this.enterpriseSourceOptions = enterpriseSourceRes.data || [];
|
||||||
|
this.dataSourceOptions = dataSourceRes.data || [];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getList() {
|
||||||
|
this.loading = true;
|
||||||
|
listEnterpriseBaseInfo(this.queryParams).then(response => {
|
||||||
|
this.enterpriseBaseInfoList = response.rows;
|
||||||
|
this.total = response.total;
|
||||||
|
this.loading = false;
|
||||||
|
}).catch(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
reset() {
|
||||||
|
this.form = {
|
||||||
|
socialCreditCode: null,
|
||||||
|
enterpriseName: null,
|
||||||
|
enterpriseType: null,
|
||||||
|
enterpriseNature: null,
|
||||||
|
industryClass: null,
|
||||||
|
industryName: null,
|
||||||
|
establishDate: null,
|
||||||
|
registerAddress: null,
|
||||||
|
legalRepresentative: null,
|
||||||
|
legalCertType: null,
|
||||||
|
legalCertNo: null,
|
||||||
|
shareholder1: null,
|
||||||
|
shareholder2: null,
|
||||||
|
shareholder3: null,
|
||||||
|
shareholder4: null,
|
||||||
|
shareholder5: null,
|
||||||
|
status: null,
|
||||||
|
riskLevel: null,
|
||||||
|
entSource: null,
|
||||||
|
dataSource: null
|
||||||
|
};
|
||||||
|
this.resetForm("form");
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.open = false;
|
||||||
|
this.reset();
|
||||||
|
},
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNum = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
resetQuery() {
|
||||||
|
this.resetForm("queryForm");
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
handleSelectionChange(selection) {
|
||||||
|
this.ids = selection.map(item => item.socialCreditCode);
|
||||||
|
this.single = selection.length !== 1;
|
||||||
|
this.multiple = !selection.length;
|
||||||
|
},
|
||||||
|
handleAdd() {
|
||||||
|
this.reset();
|
||||||
|
this.isAdd = true;
|
||||||
|
this.open = true;
|
||||||
|
this.title = "新增实体库";
|
||||||
|
},
|
||||||
|
handleDetail(row) {
|
||||||
|
getEnterpriseBaseInfo(row.socialCreditCode).then(response => {
|
||||||
|
this.detailData = response.data || {};
|
||||||
|
this.detailOpen = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleUpdate(row) {
|
||||||
|
this.reset();
|
||||||
|
this.isAdd = false;
|
||||||
|
var socialCreditCode = row.socialCreditCode || this.ids[0];
|
||||||
|
getEnterpriseBaseInfo(socialCreditCode).then(response => {
|
||||||
|
this.form = response.data || {};
|
||||||
|
this.open = true;
|
||||||
|
this.title = "编辑实体库";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
submitForm() {
|
||||||
|
this.$refs["form"].validate(valid => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var payload = this.normalizePayload(this.form);
|
||||||
|
if (this.isAdd) {
|
||||||
|
addEnterpriseBaseInfo(payload).then(() => {
|
||||||
|
this.$modal.msgSuccess("新增成功");
|
||||||
|
this.open = false;
|
||||||
|
this.getList();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
updateEnterpriseBaseInfo(payload).then(() => {
|
||||||
|
this.$modal.msgSuccess("修改成功");
|
||||||
|
this.open = false;
|
||||||
|
this.getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleDelete(row) {
|
||||||
|
var socialCreditCodes = row && row.socialCreditCode ? row.socialCreditCode : this.ids;
|
||||||
|
this.$modal.confirm('是否确认删除统一社会信用代码为"' + socialCreditCodes + '"的数据项?').then(function() {
|
||||||
|
return delEnterpriseBaseInfo(socialCreditCodes);
|
||||||
|
}).then(() => {
|
||||||
|
this.getList();
|
||||||
|
this.$modal.msgSuccess("删除成功");
|
||||||
|
}).catch(() => {});
|
||||||
|
},
|
||||||
|
handleImport() {
|
||||||
|
this.upload.title = "实体库数据导入";
|
||||||
|
this.upload.open = true;
|
||||||
|
},
|
||||||
|
handleImportDialogClose() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.upload) {
|
||||||
|
this.$refs.upload.clearFiles();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
downloadImportTemplate() {
|
||||||
|
this.download('ccdi/enterpriseBaseInfo/importTemplate', {}, '实体库管理模板_' + new Date().getTime() + '.xlsx');
|
||||||
|
},
|
||||||
|
handleFileUploadProgress() {
|
||||||
|
this.upload.isUploading = true;
|
||||||
|
},
|
||||||
|
handleFileSuccess(response) {
|
||||||
|
this.upload.isUploading = false;
|
||||||
|
this.upload.open = false;
|
||||||
|
if (response.code !== 200) {
|
||||||
|
this.$modal.msgError(response.msg || "导入失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!response.data || !response.data.taskId) {
|
||||||
|
this.$modal.msgError("导入任务创建失败:缺少任务ID");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.pollingTimer) {
|
||||||
|
clearInterval(this.pollingTimer);
|
||||||
|
this.pollingTimer = null;
|
||||||
|
}
|
||||||
|
this.clearImportTaskFromStorage();
|
||||||
|
this.currentTaskId = response.data.taskId;
|
||||||
|
this.showFailureButton = false;
|
||||||
|
this.saveImportTaskToStorage({
|
||||||
|
taskId: response.data.taskId,
|
||||||
|
status: 'PROCESSING',
|
||||||
|
hasFailures: false
|
||||||
|
});
|
||||||
|
this.$notify({
|
||||||
|
title: '导入任务已提交',
|
||||||
|
message: '正在后台处理中,处理完成后将通知您',
|
||||||
|
type: 'info',
|
||||||
|
duration: 3000
|
||||||
|
});
|
||||||
|
this.startImportStatusPolling(response.data.taskId);
|
||||||
|
},
|
||||||
|
startImportStatusPolling(taskId) {
|
||||||
|
var pollCount = 0;
|
||||||
|
var maxPolls = 150;
|
||||||
|
this.pollingTimer = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
pollCount++;
|
||||||
|
if (pollCount > maxPolls) {
|
||||||
|
clearInterval(this.pollingTimer);
|
||||||
|
this.pollingTimer = null;
|
||||||
|
this.$modal.msgWarning('导入任务处理超时,请联系管理员');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var response = await getImportStatus(taskId);
|
||||||
|
if (response.data && response.data.status !== 'PROCESSING') {
|
||||||
|
clearInterval(this.pollingTimer);
|
||||||
|
this.pollingTimer = null;
|
||||||
|
this.handleImportComplete(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
clearInterval(this.pollingTimer);
|
||||||
|
this.pollingTimer = null;
|
||||||
|
this.$modal.msgError('查询导入状态失败: ' + error.message);
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
|
handleImportComplete(statusResult) {
|
||||||
|
this.saveImportTaskToStorage({
|
||||||
|
taskId: statusResult.taskId,
|
||||||
|
status: statusResult.status,
|
||||||
|
hasFailures: statusResult.failureCount > 0,
|
||||||
|
totalCount: statusResult.totalCount,
|
||||||
|
successCount: statusResult.successCount,
|
||||||
|
failureCount: statusResult.failureCount
|
||||||
|
});
|
||||||
|
this.getList();
|
||||||
|
if (statusResult.status === 'SUCCESS') {
|
||||||
|
this.showFailureButton = false;
|
||||||
|
this.$notify({
|
||||||
|
title: '导入完成',
|
||||||
|
message: '全部成功!共导入' + statusResult.totalCount + '条数据',
|
||||||
|
type: 'success',
|
||||||
|
duration: 5000
|
||||||
|
});
|
||||||
|
} else if (statusResult.failureCount > 0) {
|
||||||
|
this.showFailureButton = true;
|
||||||
|
this.currentTaskId = statusResult.taskId;
|
||||||
|
this.$notify({
|
||||||
|
title: '导入完成',
|
||||||
|
message: '成功' + statusResult.successCount + '条,失败' + statusResult.failureCount + '条',
|
||||||
|
type: 'warning',
|
||||||
|
duration: 5000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
viewImportFailures() {
|
||||||
|
this.failureDialogVisible = true;
|
||||||
|
this.failureQueryParams.pageNum = 1;
|
||||||
|
this.getFailureList();
|
||||||
|
},
|
||||||
|
getFailureList() {
|
||||||
|
if (!this.currentTaskId) {
|
||||||
|
this.failureList = [];
|
||||||
|
this.failureTotal = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.failureLoading = true;
|
||||||
|
getImportFailures(this.currentTaskId, this.failureQueryParams.pageNum, this.failureQueryParams.pageSize).then(response => {
|
||||||
|
this.failureList = response.rows;
|
||||||
|
this.failureTotal = response.total;
|
||||||
|
this.failureLoading = false;
|
||||||
|
}).catch(error => {
|
||||||
|
this.failureLoading = false;
|
||||||
|
this.$modal.msgError('查询失败记录失败: ' + error.message);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
submitFileForm() {
|
||||||
|
this.$refs.upload.submit();
|
||||||
|
},
|
||||||
|
saveImportTaskToStorage(taskData) {
|
||||||
|
try {
|
||||||
|
localStorage.setItem('enterprise_base_info_import_last_task', JSON.stringify({
|
||||||
|
saveTime: Date.now(),
|
||||||
|
...taskData
|
||||||
|
}));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存导入任务状态失败:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getImportTaskFromStorage() {
|
||||||
|
try {
|
||||||
|
var data = localStorage.getItem('enterprise_base_info_import_last_task');
|
||||||
|
if (!data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var task = JSON.parse(data);
|
||||||
|
if (!task || !task.taskId) {
|
||||||
|
this.clearImportTaskFromStorage();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var sevenDays = 7 * 24 * 60 * 60 * 1000;
|
||||||
|
if (task.saveTime && Date.now() - task.saveTime > sevenDays) {
|
||||||
|
this.clearImportTaskFromStorage();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return task;
|
||||||
|
} catch (error) {
|
||||||
|
this.clearImportTaskFromStorage();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clearImportTaskFromStorage() {
|
||||||
|
try {
|
||||||
|
localStorage.removeItem('enterprise_base_info_import_last_task');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('清除导入任务状态失败:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
restoreImportState() {
|
||||||
|
var savedTask = this.getImportTaskFromStorage();
|
||||||
|
if (!savedTask) {
|
||||||
|
this.showFailureButton = false;
|
||||||
|
this.currentTaskId = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.currentTaskId = savedTask.taskId;
|
||||||
|
this.showFailureButton = !!savedTask.hasFailures;
|
||||||
|
},
|
||||||
|
clearImportHistory() {
|
||||||
|
this.$confirm('确认清除上次导入记录?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
this.clearImportTaskFromStorage();
|
||||||
|
this.showFailureButton = false;
|
||||||
|
this.currentTaskId = null;
|
||||||
|
this.failureDialogVisible = false;
|
||||||
|
this.$message.success('已清除');
|
||||||
|
}).catch(() => {});
|
||||||
|
},
|
||||||
|
getLastImportTooltip() {
|
||||||
|
var savedTask = this.getImportTaskFromStorage();
|
||||||
|
if (savedTask && savedTask.saveTime) {
|
||||||
|
return '上次导入: ' + this.parseTime(savedTask.saveTime, '{y}-{m}-{d} {h}:{i}');
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
normalizeUpperCode(value) {
|
||||||
|
if (!value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return String(value).replace(/\s+/g, '').toUpperCase();
|
||||||
|
},
|
||||||
|
normalizePayload(form) {
|
||||||
|
var payload = {};
|
||||||
|
Object.keys(form).forEach(key => {
|
||||||
|
var value = form[key];
|
||||||
|
if (value === "") {
|
||||||
|
payload[key] = null;
|
||||||
|
} else if (key === "socialCreditCode") {
|
||||||
|
payload[key] = this.normalizeUpperCode(value);
|
||||||
|
} else {
|
||||||
|
payload[key] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return payload;
|
||||||
|
},
|
||||||
|
getOptionLabel(options, value) {
|
||||||
|
if (!value) {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
var matched = (options || []).find(item => item.value === value);
|
||||||
|
return matched ? matched.label : value;
|
||||||
|
},
|
||||||
|
formatRiskLevel(value) {
|
||||||
|
return this.getOptionLabel(this.riskLevelOptions, value);
|
||||||
|
},
|
||||||
|
formatEnterpriseSource(value) {
|
||||||
|
return this.getOptionLabel(this.enterpriseSourceOptions, value);
|
||||||
|
},
|
||||||
|
formatDataSource(value) {
|
||||||
|
return this.getOptionLabel(this.dataSourceOptions, value);
|
||||||
|
},
|
||||||
|
formatStatus(value) {
|
||||||
|
return value || "-";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.el-upload__tip {
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :title="title" :visible.sync="dialogVisible" width="680px" append-to-body @close="handleClose">
|
||||||
|
<el-form ref="formRef" :model="localForm" :rules="rules" label-width="140px">
|
||||||
|
<el-form-item label="所属中介">
|
||||||
|
<el-input :value="ownerName" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="统一社会信用代码" prop="socialCreditCode">
|
||||||
|
<el-input v-model="localForm.socialCreditCode" placeholder="请输入统一社会信用代码" maxlength="18" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="关联角色/职务">
|
||||||
|
<el-input v-model="localForm.relationPersonPost" placeholder="请输入关联角色/职务" maxlength="100" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="localForm.remark" type="textarea" :rows="3" maxlength="500" show-word-limit />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
||||||
|
<el-button @click="handleClose">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "EnterpriseRelationEditDialog",
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
ownerName: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
localForm: {},
|
||||||
|
rules: {
|
||||||
|
socialCreditCode: [{ required: true, message: "统一社会信用代码不能为空", trigger: "blur" }]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible: {
|
||||||
|
immediate: true,
|
||||||
|
handler(val) {
|
||||||
|
this.dialogVisible = val;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dialogVisible(val) {
|
||||||
|
this.$emit("update:visible", val);
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
immediate: true,
|
||||||
|
deep: true,
|
||||||
|
handler(val) {
|
||||||
|
this.localForm = { ...val };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleSubmit() {
|
||||||
|
this.$refs.formRef.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
this.$emit("submit", { ...this.localForm });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleClose() {
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$emit("close");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :title="title" :visible.sync="dialogVisible" width="820px" append-to-body @close="handleClose">
|
||||||
|
<el-form ref="formRef" :model="localForm" :rules="rules" label-width="120px">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="所属中介">
|
||||||
|
<el-input :value="ownerName" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="亲属关系" prop="personSubType">
|
||||||
|
<el-select v-model="localForm.personSubType" placeholder="请选择亲属关系" clearable style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in filteredRelationOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="姓名" prop="name">
|
||||||
|
<el-input v-model="localForm.name" placeholder="请输入姓名" maxlength="100" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="证件号" prop="personId">
|
||||||
|
<el-input v-model="localForm.personId" placeholder="请输入证件号码" maxlength="50" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="人员类型">
|
||||||
|
<el-select v-model="localForm.personType" placeholder="请选择人员类型" clearable style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in indivTypeOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="证件类型">
|
||||||
|
<el-select v-model="localForm.idType" placeholder="请选择证件类型" clearable style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in certTypeOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="性别">
|
||||||
|
<el-select v-model="localForm.gender" placeholder="请选择性别" clearable style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in genderOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="手机号码">
|
||||||
|
<el-input v-model="localForm.mobile" placeholder="请输入手机号码" maxlength="20" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item label="联系地址">
|
||||||
|
<el-input v-model="localForm.contactAddress" placeholder="请输入联系地址" maxlength="200" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="所在公司">
|
||||||
|
<el-input v-model="localForm.company" placeholder="请输入所在公司" maxlength="200" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="职位">
|
||||||
|
<el-input v-model="localForm.position" placeholder="请输入职位" maxlength="100" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="localForm.remark" type="textarea" :rows="3" maxlength="500" show-word-limit />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
||||||
|
<el-button @click="handleClose">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "RelativeEditDialog",
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
ownerName: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
relationTypeOptions: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
indivTypeOptions: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
genderOptions: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
certTypeOptions: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
localForm: {},
|
||||||
|
rules: {
|
||||||
|
name: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
|
||||||
|
personId: [{ required: true, message: "证件号不能为空", trigger: "blur" }],
|
||||||
|
personSubType: [{ required: true, message: "亲属关系不能为空", trigger: "change" }]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
filteredRelationOptions() {
|
||||||
|
return this.relationTypeOptions.filter(item => item.value !== "本人");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible: {
|
||||||
|
immediate: true,
|
||||||
|
handler(val) {
|
||||||
|
this.dialogVisible = val;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dialogVisible(val) {
|
||||||
|
this.$emit("update:visible", val);
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
immediate: true,
|
||||||
|
deep: true,
|
||||||
|
handler(val) {
|
||||||
|
this.localForm = { ...val };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleSubmit() {
|
||||||
|
this.$refs.formRef.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
this.$emit("submit", { ...this.localForm });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleClose() {
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$emit("close");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
199
sql/migration/2026-04-17-add-enterprise-base-info-menu.sql
Normal file
199
sql/migration/2026-04-17-add-enterprise-base-info-menu.sql
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
-- 实体库管理菜单
|
||||||
|
-- 挂载到“信息维护”目录下,可重复执行
|
||||||
|
|
||||||
|
SET @parent_menu_id = (
|
||||||
|
SELECT menu_id
|
||||||
|
FROM sys_menu
|
||||||
|
WHERE menu_name = '信息维护'
|
||||||
|
AND parent_id = 0
|
||||||
|
LIMIT 1
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO sys_menu (
|
||||||
|
menu_name,
|
||||||
|
parent_id,
|
||||||
|
order_num,
|
||||||
|
path,
|
||||||
|
component,
|
||||||
|
is_frame,
|
||||||
|
is_cache,
|
||||||
|
menu_type,
|
||||||
|
visible,
|
||||||
|
status,
|
||||||
|
perms,
|
||||||
|
icon,
|
||||||
|
create_by,
|
||||||
|
create_time,
|
||||||
|
update_by,
|
||||||
|
update_time,
|
||||||
|
remark
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'实体库管理',
|
||||||
|
@parent_menu_id,
|
||||||
|
12,
|
||||||
|
'enterpriseBaseInfo',
|
||||||
|
'ccdiEnterpriseBaseInfo/index',
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
'C',
|
||||||
|
'0',
|
||||||
|
'0',
|
||||||
|
'ccdi:enterpriseBaseInfo:list',
|
||||||
|
'documentation',
|
||||||
|
'admin',
|
||||||
|
NOW(),
|
||||||
|
'',
|
||||||
|
NULL,
|
||||||
|
'实体库管理菜单'
|
||||||
|
FROM dual
|
||||||
|
WHERE @parent_menu_id IS NOT NULL
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM sys_menu
|
||||||
|
WHERE parent_id = @parent_menu_id
|
||||||
|
AND path = 'enterpriseBaseInfo'
|
||||||
|
);
|
||||||
|
|
||||||
|
SET @menu_id = (
|
||||||
|
SELECT menu_id
|
||||||
|
FROM sys_menu
|
||||||
|
WHERE parent_id = @parent_menu_id
|
||||||
|
AND path = 'enterpriseBaseInfo'
|
||||||
|
LIMIT 1
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO sys_menu (
|
||||||
|
menu_name,
|
||||||
|
parent_id,
|
||||||
|
order_num,
|
||||||
|
path,
|
||||||
|
component,
|
||||||
|
is_frame,
|
||||||
|
is_cache,
|
||||||
|
menu_type,
|
||||||
|
visible,
|
||||||
|
status,
|
||||||
|
perms,
|
||||||
|
icon,
|
||||||
|
create_by,
|
||||||
|
create_time,
|
||||||
|
remark
|
||||||
|
)
|
||||||
|
SELECT '实体库查询', @menu_id, 1, '', '', 1, 0, 'F', '0', '0', 'ccdi:enterpriseBaseInfo:query', '#', 'admin', NOW(), ''
|
||||||
|
FROM dual
|
||||||
|
WHERE @menu_id IS NOT NULL
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM sys_menu
|
||||||
|
WHERE parent_id = @menu_id
|
||||||
|
AND perms = 'ccdi:enterpriseBaseInfo:query'
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO sys_menu (
|
||||||
|
menu_name,
|
||||||
|
parent_id,
|
||||||
|
order_num,
|
||||||
|
path,
|
||||||
|
component,
|
||||||
|
is_frame,
|
||||||
|
is_cache,
|
||||||
|
menu_type,
|
||||||
|
visible,
|
||||||
|
status,
|
||||||
|
perms,
|
||||||
|
icon,
|
||||||
|
create_by,
|
||||||
|
create_time,
|
||||||
|
remark
|
||||||
|
)
|
||||||
|
SELECT '实体库新增', @menu_id, 2, '', '', 1, 0, 'F', '0', '0', 'ccdi:enterpriseBaseInfo:add', '#', 'admin', NOW(), ''
|
||||||
|
FROM dual
|
||||||
|
WHERE @menu_id IS NOT NULL
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM sys_menu
|
||||||
|
WHERE parent_id = @menu_id
|
||||||
|
AND perms = 'ccdi:enterpriseBaseInfo:add'
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO sys_menu (
|
||||||
|
menu_name,
|
||||||
|
parent_id,
|
||||||
|
order_num,
|
||||||
|
path,
|
||||||
|
component,
|
||||||
|
is_frame,
|
||||||
|
is_cache,
|
||||||
|
menu_type,
|
||||||
|
visible,
|
||||||
|
status,
|
||||||
|
perms,
|
||||||
|
icon,
|
||||||
|
create_by,
|
||||||
|
create_time,
|
||||||
|
remark
|
||||||
|
)
|
||||||
|
SELECT '实体库修改', @menu_id, 3, '', '', 1, 0, 'F', '0', '0', 'ccdi:enterpriseBaseInfo:edit', '#', 'admin', NOW(), ''
|
||||||
|
FROM dual
|
||||||
|
WHERE @menu_id IS NOT NULL
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM sys_menu
|
||||||
|
WHERE parent_id = @menu_id
|
||||||
|
AND perms = 'ccdi:enterpriseBaseInfo:edit'
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO sys_menu (
|
||||||
|
menu_name,
|
||||||
|
parent_id,
|
||||||
|
order_num,
|
||||||
|
path,
|
||||||
|
component,
|
||||||
|
is_frame,
|
||||||
|
is_cache,
|
||||||
|
menu_type,
|
||||||
|
visible,
|
||||||
|
status,
|
||||||
|
perms,
|
||||||
|
icon,
|
||||||
|
create_by,
|
||||||
|
create_time,
|
||||||
|
remark
|
||||||
|
)
|
||||||
|
SELECT '实体库删除', @menu_id, 4, '', '', 1, 0, 'F', '0', '0', 'ccdi:enterpriseBaseInfo:remove', '#', 'admin', NOW(), ''
|
||||||
|
FROM dual
|
||||||
|
WHERE @menu_id IS NOT NULL
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM sys_menu
|
||||||
|
WHERE parent_id = @menu_id
|
||||||
|
AND perms = 'ccdi:enterpriseBaseInfo:remove'
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO sys_menu (
|
||||||
|
menu_name,
|
||||||
|
parent_id,
|
||||||
|
order_num,
|
||||||
|
path,
|
||||||
|
component,
|
||||||
|
is_frame,
|
||||||
|
is_cache,
|
||||||
|
menu_type,
|
||||||
|
visible,
|
||||||
|
status,
|
||||||
|
perms,
|
||||||
|
icon,
|
||||||
|
create_by,
|
||||||
|
create_time,
|
||||||
|
remark
|
||||||
|
)
|
||||||
|
SELECT '实体库导入', @menu_id, 5, '', '', 1, 0, 'F', '0', '0', 'ccdi:enterpriseBaseInfo:import', '#', 'admin', NOW(), ''
|
||||||
|
FROM dual
|
||||||
|
WHERE @menu_id IS NOT NULL
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM sys_menu
|
||||||
|
WHERE parent_id = @menu_id
|
||||||
|
AND perms = 'ccdi:enterpriseBaseInfo:import'
|
||||||
|
);
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS `ccdi_intermediary_enterprise_relation` (
|
||||||
|
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||||
|
`intermediary_biz_id` VARCHAR(64) NOT NULL COMMENT '所属中介biz_id',
|
||||||
|
`social_credit_code` VARCHAR(18) NOT NULL COMMENT '统一社会信用代码',
|
||||||
|
`relation_person_post` VARCHAR(100) DEFAULT NULL COMMENT '关联角色/职务',
|
||||||
|
`remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
|
||||||
|
`created_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
|
||||||
|
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`updated_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
|
||||||
|
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `uk_intermediary_enterprise` (`intermediary_biz_id`, `social_credit_code`),
|
||||||
|
KEY `idx_intermediary_biz_id` (`intermediary_biz_id`),
|
||||||
|
KEY `idx_social_credit_code` (`social_credit_code`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='中介关联机构关系表';
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- 如当前环境通过数据字典维护 person_sub_type,请补齐以下固定值:
|
||||||
|
-- 本人、配偶、子女、父母、兄弟姐妹、其他
|
||||||
|
--
|
||||||
|
-- 具体 dict_type 请按现网实际配置填写后执行。
|
||||||
15
tongweb_62318.properties
Normal file
15
tongweb_62318.properties
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#TongTech License properties
|
||||||
|
#Fri Apr 17 16:39:03 CST 2026
|
||||||
|
application.location=/Users/wkc/Desktop/ccdi/ccdi
|
||||||
|
license.create.date=2024-12-10
|
||||||
|
license.customer.name=\u6D59\u6C5F\u519C\u6751\u5546\u4E1A\u8054\u5408\u94F6\u884C\u80A1\u4EFD\u6709\u9650\u516C\u53F8
|
||||||
|
license.end.date=-1
|
||||||
|
license.extern.properties.name=validateType,order_number,license_info
|
||||||
|
license.extern.properties.value=file,2024-2121,uc3Y29XJfVtZtZTbmF72t3V405cxamrXBnM0P0vqrrLnJjQ0T0Mt93avL/euwcmvgpWN09qZhbWX25eO9U91ptOrcWNK1XJz6z9waqNC5L40d09ybfrmrDP352Ny76fqyPauv06+ru7f+bTwG99zvHOS8bQvJub/rL3JkoKbfbnZXJmVyVtYwMjPTIjEyQtMsaWMQpnNlNlbkPTX2lTE5EwNsaWOApnNlNlb5cGX3RmVsU9czZQZWFmVhpjcfZGdGVT0yF0Z0LTMDITEwEyLuZFCmVXRl9kYxClPS01ByRXX1Y3b2RmFtRfTUb2ZT12Vi5nVXX1ClRnNpZlcfTnb25mVyVtYuMCPTclRX5FCQVVX0N1VO9DTKYmVD0GlwluZUV1PQpXJk9IYyZVd2FD0K9JZfTWVFd051F4XlcjbWJQpU0tMFZGV19W9ul0atYmPUVk5FVkCWRVV19U9OJTSJQ0X0x0U9VOQLWUWFlTU1lLbSMmSmhkNHlBRrcVdG8kNtUxYCT2RHFTc5lperM2WUFkkvU3M3MzTDBldOlqeTb3YUVGx3VWT1WkaERHhilxOTM0T0l1FrdBS1aUWG4GE5FtaLMyUXZUlz8zM0UnSCs0lDM5RDVFRzJDBzZmOoRkNFdEt6YwNKTkTXA1ZFVXXJT0UlNElD5fTDRTRU5TdU1YdROEL2xUhvV3OLY3bTVmhMpZUJU2QXF2I1VYdxTjWVVm9jZKUPWUMXFHNrFJeJZDU29mM2hKQpUmUVJGIxwwOVSUaXFXQy9JU4cFdlkGJQY4SCYWYjFkJndiaCVFMlNk1QZQTwQWRDJ0th1YMwaHYmEzQrB2aWTTRmpgpOA5dfVkRVd0lPVSUMSUTl9kNFNFTyaWPU0G5mNwaieUdUJ0NiZjNVbnOC90tNYyb2S3djNmh4BidmNlRnBk1PdCShdDYUdS9mNMSiMnYzVml2pSameEY2NStCZtRvU3dloGgvQyU0TmcTlTlMJVYhc3VEp01EpYRwUGNUUWZ5daVxU3blZzg3dnR2UncnR2U4RkU2CkSUc19W5FVTSURVJ0xJ9OXOQ0Q0VG1iU9WFcDYWNktah2M3blbjNlZsZndjOTdXFTFHNQS0SzUE4FVpdqR1dEL2RWgvpMSabVZkJlhRJFRMZUTUJ0NGdwUGbGZitjFE01bZSlRzZHZ4RMUFd2cHhEZqtZbwR2clQUgxFsb0Z1ZFVW5tJvUwWEd2gjVog1eKYUaUdHYK5JUXX1TkVlNJZFUfTET05U5DlDRTVURV9jJi49SmbHR2pU5UFwVUK0ZTBFE5pmd3ZGOEdXppU1VTNEb09UtntCRycUaHUmR1ovVYNGUU1HFy1vVsZXYlBmt1lsNVZDVUNUNyJQeHUXZlF2pzVMVlVjVmNWx2VxWZaUSEh1FlJ0bmRmbENkRV9VWiRVT3R01apMUIMkWjdW8K5JTXX1TkVlNJZFUfTET05U5DlDRTVURV9Ulw49bhMWcW5HdRdZNaK0UEp3AyU0TwY0Wm1md6tDMpN0cDRVBK11aKR0VTZkI3RocKUXRm5Vl6llcpMWaXJXRLZOOaZDOGZ1R0gychWURVJk5JR5VNYXQTl250dGYheFOG1FZog4RFZWMkRmtK1QRCaUclJlNYNFRHSWTFpFUKxYRXX1TkVlNJZFUfTET05U5DlDRTVURV9Hho49T5aTempVMwFhU1b1Vi9HR4YzO1dDNks05HhEQxY2VUZXlMNybyVmVEl3dNlLbYSGbGlWxMVNWUcEZXpVN0w5NVZDVGFUw4NMSUOWbkRjV21QaMbESVhGx1w3MiY1WmJXB6o0NjS1T2tWxjNSeRY0UzV0g2VhR5Z0RWlzkKRMdXX1TkVlNJZFUfTET05U5DlDRTVURV9Hdt49apUHZVNnhlpxQ5MENGNnh1VYN3aDQ2QW5qRqd4K1cXYk9ZdHW4VzeE9XVHB6YmM3Wk1DYwVLdqS1aTNUtjhINicVeUV1JBZRZxTGYWdTVytuepR1QVVXZlNoSVOFdVlVkzRqdPcjOW9HBll6Ota2dHFGV6dtN6c1ekN2UKdwc\n
|
||||||
|
license.file.content=uc3Y29XJfVtZtZTbmF72t3V405cxamrXBnM0P0vqrrLnJjQ0T0Mt93avL/euwcmvgpWN09qZhbWX25eO9U91ptOrcWNK1XJz6z9waqNC5L40d09ybfrmrDP352Ny76fqyPauv06+ru7f+bTwG99zvHOS8bQvJub/rL3JkoKbfbnZXJmVyVtYwMjPTIjEyQtMsaWMQpnNlNlbkPTX2lTE5EwNsaWOApnNlNlb5cGX3RmVsU9czZQZWFmVhpjcfZGdGVT0yF0Z0LTMDITEwEyLuZFCmVXRl9kYxClPS01ByRXX1Y3b2RmFtRfTUb2ZT12Vi5nVXX1ClRnNpZlcfTnb25mVyVtYuMCPTclRX5FCQVVX0N1VO9DTKYmVD0GlwluZUV1PQpXJk9IYyZVd2FD0K9JZfTWVFd051F4XlcjbWJQpU0tMFZGV19W9ul0atYmPUVk5FVkCWRVV19U9OJTSJQ0X0x0U9VOQLWUWFlTU1lLbSMmSmhkNHlBRrcVdG8kNtUxYCT2RHFTc5lperM2WUFkkvU3M3MzTDBldOlqeTb3YUVGx3VWT1WkaERHhilxOTM0T0l1FrdBS1aUWG4GE5FtaLMyUXZUlz8zM0UnSCs0lDM5RDVFRzJDBzZmOoRkNFdEt6YwNKTkTXA1ZFVXXJT0UlNElD5fTDRTRU5TdU1YdROEL2xUhvV3OLY3bTVmhMpZUJU2QXF2I1VYdxTjWVVm9jZKUPWUMXFHNrFJeJZDU29mM2hKQpUmUVJGIxwwOVSUaXFXQy9JU4cFdlkGJQY4SCYWYjFkJndiaCVFMlNk1QZQTwQWRDJ0th1YMwaHYmEzQrB2aWTTRmpgpOA5dfVkRVd0lPVSUMSUTl9kNFNFTyaWPU0G5mNwaieUdUJ0NiZjNVbnOC90tNYyb2S3djNmh4BidmNlRnBk1PdCShdDYUdS9mNMSiMnYzVml2pSameEY2NStCZtRvU3dloGgvQyU0TmcTlTlMJVYhc3VEp01EpYRwUGNUUWZ5daVxU3blZzg3dnR2UncnR2U4RkU2CkSUc19W5FVTSURVJ0xJ9OXOQ0Q0VG1iU9WFcDYWNktah2M3blbjNlZsZndjOTdXFTFHNQS0SzUE4FVpdqR1dEL2RWgvpMSabVZkJlhRJFRMZUTUJ0NGdwUGbGZitjFE01bZSlRzZHZ4RMUFd2cHhEZqtZbwR2clQUgxFsb0Z1ZFVW5tJvUwWEd2gjVog1eKYUaUdHYK5JUXX1TkVlNJZFUfTET05U5DlDRTVURV9jJi49SmbHR2pU5UFwVUK0ZTBFE5pmd3ZGOEdXppU1VTNEb09UtntCRycUaHUmR1ovVYNGUU1HFy1vVsZXYlBmt1lsNVZDVUNUNyJQeHUXZlF2pzVMVlVjVmNWx2VxWZaUSEh1FlJ0bmRmbENkRV9VWiRVT3R01apMUIMkWjdW8K5JTXX1TkVlNJZFUfTET05U5DlDRTVURV9Ulw49bhMWcW5HdRdZNaK0UEp3AyU0TwY0Wm1md6tDMpN0cDRVBK11aKR0VTZkI3RocKUXRm5Vl6llcpMWaXJXRLZOOaZDOGZ1R0gychWURVJk5JR5VNYXQTl250dGYheFOG1FZog4RFZWMkRmtK1QRCaUclJlNYNFRHSWTFpFUKxYRXX1TkVlNJZFUfTET05U5DlDRTVURV9Hho49T5aTempVMwFhU1b1Vi9HR4YzO1dDNks05HhEQxY2VUZXlMNybyVmVEl3dNlLbYSGbGlWxMVNWUcEZXpVN0w5NVZDVGFUw4NMSUOWbkRjV21QaMbESVhGx1w3MiY1WmJXB6o0NjS1T2tWxjNSeRY0UzV0g2VhR5Z0RWlzkKRMdXX1TkVlNJZFUfTET05U5DlDRTVURV9Hdt49apUHZVNnhlpxQ5MENGNnh1VYN3aDQ2QW5qRqd4K1cXYk9ZdHW4VzeE9XVHB6YmM3Wk1DYwVLdqS1aTNUtjhINicVeUV1JBZRZxTGYWdTVytuepR1QVVXZlNoSVOFdVlVkzRqdPcjOW9HBll6Ota2dHFGV6dtN6c1ekN2UKdwc\n
|
||||||
|
license.file.path=classpath\:license.dat
|
||||||
|
license.max.number=-1
|
||||||
|
license.project.name=\u6D59\u6C5F\u519C\u6751\u5546\u4E1A\u8054\u5408\u94F6\u884C\u80A1\u4EFD\u6709\u9650\u516C\u53F8\u5173\u4E8E\u56FD\u4EA7\u5316\u5E94\u7528\u670D\u52A1\u5668\u4E2D\u95F4\u4EF6\u91C7\u8D2D
|
||||||
|
license.type=release
|
||||||
|
license.validate.type=file
|
||||||
|
server.number=7.0.E.7
|
||||||
Reference in New Issue
Block a user