feat 员工亲属关系
This commit is contained in:
27
doc/数据库文档/fix_collation_staff_fmy_relation.sql
Normal file
27
doc/数据库文档/fix_collation_staff_fmy_relation.sql
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
-- 修复员工基础表和员工家庭关系表字符集排序规则
|
||||||
|
-- 问题: ccdi_staff_fmy_relation.person_id (utf8mb4_general_ci) 与 ccdi_base_staff.id_card (utf8mb4_unicode_ci) 字符集不一致
|
||||||
|
-- 解决方案: 统一为 utf8mb4_general_ci
|
||||||
|
-- 执行时间: 2026-02-09
|
||||||
|
|
||||||
|
USE `ruoyi-vue-pro`;
|
||||||
|
|
||||||
|
-- 修改 ccdi_base_staff 表的 id_card 字段字符集,统一为 utf8mb4_general_ci
|
||||||
|
ALTER TABLE `ccdi_base_staff`
|
||||||
|
MODIFY COLUMN `id_card` VARCHAR(100) DEFAULT NULL COLLATE `utf8mb4_general_ci` COMMENT '身份证号';
|
||||||
|
|
||||||
|
-- 验证修改
|
||||||
|
SELECT
|
||||||
|
TABLE_NAME,
|
||||||
|
COLUMN_NAME,
|
||||||
|
CHARACTER_SET_NAME,
|
||||||
|
COLLATION_NAME
|
||||||
|
FROM
|
||||||
|
INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE
|
||||||
|
TABLE_SCHEMA = 'ruoyi-vue-pro'
|
||||||
|
AND TABLE_NAME IN ('ccdi_staff_fmy_relation', 'ccdi_base_staff')
|
||||||
|
AND COLUMN_NAME IN ('person_id', 'id_card')
|
||||||
|
ORDER BY
|
||||||
|
TABLE_NAME, COLUMN_NAME;
|
||||||
|
|
||||||
|
-- 说明: 执行后两个表的字符集应该都显示为 utf8mb4_general_ci
|
||||||
120
doc/数据库文档/verify_collation_fix.sql
Normal file
120
doc/数据库文档/verify_collation_fix.sql
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
-- ========================================
|
||||||
|
-- 验证员工家庭关系表 JOIN 字符集问题修复
|
||||||
|
-- ========================================
|
||||||
|
-- 目的: 验证 ccdi_staff_fmy_relation 与 ccdi_base_staff 表的 JOIN 操作正常
|
||||||
|
-- 创建时间: 2026-02-09
|
||||||
|
-- ========================================
|
||||||
|
|
||||||
|
USE `ccdi`;
|
||||||
|
|
||||||
|
-- 测试 1: 验证字符集统一性
|
||||||
|
-- ========================================
|
||||||
|
SELECT '=== 字符集验证 ===' AS test_section;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
TABLE_NAME AS '表名',
|
||||||
|
COLUMN_NAME AS '字段名',
|
||||||
|
CHARACTER_SET_NAME AS '字符集',
|
||||||
|
COLLATION_NAME AS '排序规则',
|
||||||
|
CASE
|
||||||
|
WHEN COLLATION_NAME = 'utf8mb4_general_ci' THEN '✅ 正确'
|
||||||
|
ELSE '❌ 错误'
|
||||||
|
END AS '状态'
|
||||||
|
FROM
|
||||||
|
INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE
|
||||||
|
TABLE_SCHEMA = 'ccdi'
|
||||||
|
AND TABLE_NAME IN ('ccdi_staff_fmy_relation', 'ccdi_base_staff')
|
||||||
|
AND COLUMN_NAME IN ('person_id', 'id_card')
|
||||||
|
ORDER BY
|
||||||
|
TABLE_NAME, COLUMN_NAME;
|
||||||
|
|
||||||
|
-- 测试 2: 验证 JOIN 操作(模拟实际查询)
|
||||||
|
-- ========================================
|
||||||
|
SELECT '=== JOIN 操作验证 ===' AS test_section;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
r.id,
|
||||||
|
r.person_id,
|
||||||
|
s.name AS person_name,
|
||||||
|
r.relation_type,
|
||||||
|
r.relation_name,
|
||||||
|
r.gender,
|
||||||
|
s.id_card AS staff_id_card,
|
||||||
|
CASE
|
||||||
|
WHEN r.person_id = s.id_card THEN '✅ 匹配成功'
|
||||||
|
ELSE '❌ 匹配失败'
|
||||||
|
END AS join_status
|
||||||
|
FROM
|
||||||
|
ccdi_staff_fmy_relation r
|
||||||
|
LEFT JOIN ccdi_base_staff s ON r.person_id = s.id_card
|
||||||
|
WHERE
|
||||||
|
r.is_emp_family = 1
|
||||||
|
LIMIT 5;
|
||||||
|
|
||||||
|
-- 测试 3: 统计数据
|
||||||
|
-- ========================================
|
||||||
|
SELECT '=== 数据统计 ===' AS test_section;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
COUNT(*) AS total_records,
|
||||||
|
COUNT(s.name) AS matched_records,
|
||||||
|
COUNT(*) - COUNT(s.name) AS unmatched_records,
|
||||||
|
CONCAT(
|
||||||
|
ROUND(COUNT(s.name) / COUNT(*) * 100, 2),
|
||||||
|
'%'
|
||||||
|
) AS match_rate
|
||||||
|
FROM
|
||||||
|
ccdi_staff_fmy_relation r
|
||||||
|
LEFT JOIN ccdi_base_staff s ON r.person_id = s.id_card
|
||||||
|
WHERE
|
||||||
|
r.is_emp_family = 1;
|
||||||
|
|
||||||
|
-- 测试 4: 查找未匹配的记录
|
||||||
|
-- ========================================
|
||||||
|
SELECT '=== 未匹配记录 ===' AS test_section;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
r.id,
|
||||||
|
r.person_id,
|
||||||
|
r.relation_name,
|
||||||
|
'未找到对应员工信息' AS warning
|
||||||
|
FROM
|
||||||
|
ccdi_staff_fmy_relation r
|
||||||
|
LEFT JOIN ccdi_base_staff s ON r.person_id = s.id_card
|
||||||
|
WHERE
|
||||||
|
r.is_emp_family = 1
|
||||||
|
AND s.id_card IS NULL
|
||||||
|
LIMIT 5;
|
||||||
|
|
||||||
|
-- 测试 5: 字符集转换测试
|
||||||
|
-- ========================================
|
||||||
|
SELECT '=== 字符集转换测试 ===' AS test_section;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
r.person_id,
|
||||||
|
s.id_card,
|
||||||
|
CHAR_LENGTH(r.person_id) AS len_person_id,
|
||||||
|
CHAR_LENGTH(s.id_card) AS len_id_card,
|
||||||
|
HEX(r.person_id) AS hex_person_id,
|
||||||
|
HEX(s.id_card) AS hex_id_card,
|
||||||
|
CASE
|
||||||
|
WHEN r.person_id = s.id_card THEN '✅ 完全相等'
|
||||||
|
ELSE '❌ 不相等'
|
||||||
|
END AS compare_result
|
||||||
|
FROM
|
||||||
|
ccdi_staff_fmy_relation r
|
||||||
|
INNER JOIN ccdi_base_staff s ON r.person_id = s.id_card
|
||||||
|
WHERE
|
||||||
|
r.is_emp_family = 1
|
||||||
|
LIMIT 3;
|
||||||
|
|
||||||
|
-- ========================================
|
||||||
|
-- 验证结果说明:
|
||||||
|
-- ========================================
|
||||||
|
-- 1. 字符集验证: 所有字段应显示 ✅ 正确
|
||||||
|
-- 2. JOIN 操作: 应能正常执行,无字符集冲突错误
|
||||||
|
-- 3. 数据统计: 显示匹配率
|
||||||
|
-- 4. 未匹配记录: 显示哪些员工关系记录未关联到员工
|
||||||
|
-- 5. 字符集转换: 验证字段在 JOIN 时能正确比较
|
||||||
|
-- ========================================
|
||||||
@@ -0,0 +1,195 @@
|
|||||||
|
package com.ruoyi.ccdi.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.ccdi.domain.dto.CcdiStaffFmyRelationAddDTO;
|
||||||
|
import com.ruoyi.ccdi.domain.dto.CcdiStaffFmyRelationEditDTO;
|
||||||
|
import com.ruoyi.ccdi.domain.dto.CcdiStaffFmyRelationQueryDTO;
|
||||||
|
import com.ruoyi.ccdi.domain.excel.CcdiStaffFmyRelationExcel;
|
||||||
|
import com.ruoyi.ccdi.domain.vo.CcdiStaffFmyRelationVO;
|
||||||
|
import com.ruoyi.ccdi.domain.vo.ImportResultVO;
|
||||||
|
import com.ruoyi.ccdi.domain.vo.ImportStatusVO;
|
||||||
|
import com.ruoyi.ccdi.domain.vo.StaffFmyRelationImportFailureVO;
|
||||||
|
import com.ruoyi.ccdi.service.ICcdiStaffFmyRelationImportService;
|
||||||
|
import com.ruoyi.ccdi.service.ICcdiStaffFmyRelationService;
|
||||||
|
import com.ruoyi.ccdi.utils.EasyExcelUtil;
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.core.page.PageDomain;
|
||||||
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.common.core.page.TableSupport;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 员工亲属关系Controller
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-09
|
||||||
|
*/
|
||||||
|
@Tag(name = "员工亲属关系管理")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/ccdi/staffFmyRelation")
|
||||||
|
public class CcdiStaffFmyRelationController extends BaseController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ICcdiStaffFmyRelationService relationService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ICcdiStaffFmyRelationImportService relationImportService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询员工亲属关系列表
|
||||||
|
*/
|
||||||
|
@Operation(summary = "查询员工亲属关系列表")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:staffFmyRelation:list')")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public TableDataInfo list(CcdiStaffFmyRelationQueryDTO queryDTO) {
|
||||||
|
// 使用MyBatis Plus分页
|
||||||
|
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||||
|
Page<CcdiStaffFmyRelationVO> page = new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize());
|
||||||
|
Page<CcdiStaffFmyRelationVO> result = relationService.selectRelationPage(page, queryDTO);
|
||||||
|
return getDataTable(result.getRecords(), result.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出员工亲属关系列表
|
||||||
|
*/
|
||||||
|
@Operation(summary = "导出员工亲属关系列表")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:staffFmyRelation:export')")
|
||||||
|
@Log(title = "员工亲属关系", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/export")
|
||||||
|
public void export(HttpServletResponse response, CcdiStaffFmyRelationQueryDTO queryDTO) {
|
||||||
|
List<CcdiStaffFmyRelationExcel> list = relationService.selectRelationListForExport(queryDTO);
|
||||||
|
EasyExcelUtil.exportExcel(response, list, CcdiStaffFmyRelationExcel.class, "员工亲属关系信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取员工亲属关系详细信息
|
||||||
|
*/
|
||||||
|
@Operation(summary = "获取员工亲属关系详细信息")
|
||||||
|
@Parameter(name = "id", description = "主键ID", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:staffFmyRelation:query')")
|
||||||
|
@GetMapping(value = "/{id}")
|
||||||
|
public AjaxResult getInfo(@PathVariable Long id) {
|
||||||
|
return success(relationService.selectRelationById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增员工亲属关系
|
||||||
|
*/
|
||||||
|
@Operation(summary = "新增员工亲属关系")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:staffFmyRelation:add')")
|
||||||
|
@Log(title = "员工亲属关系", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping
|
||||||
|
public AjaxResult add(@Validated @RequestBody CcdiStaffFmyRelationAddDTO addDTO) {
|
||||||
|
return toAjax(relationService.insertRelation(addDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改员工亲属关系
|
||||||
|
*/
|
||||||
|
@Operation(summary = "修改员工亲属关系")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:staffFmyRelation:edit')")
|
||||||
|
@Log(title = "员工亲属关系", businessType = BusinessType.UPDATE)
|
||||||
|
@PutMapping
|
||||||
|
public AjaxResult edit(@Validated @RequestBody CcdiStaffFmyRelationEditDTO editDTO) {
|
||||||
|
return toAjax(relationService.updateRelation(editDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除员工亲属关系
|
||||||
|
*/
|
||||||
|
@Operation(summary = "删除员工亲属关系")
|
||||||
|
@Parameter(name = "ids", description = "主键ID数组", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:staffFmyRelation:remove')")
|
||||||
|
@Log(title = "员工亲属关系", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/{ids}")
|
||||||
|
public AjaxResult remove(@PathVariable Long[] ids) {
|
||||||
|
return toAjax(relationService.deleteRelationByIds(ids));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载带字典下拉框的导入模板
|
||||||
|
* 使用@DictDropdown注解自动添加下拉框
|
||||||
|
*/
|
||||||
|
@Operation(summary = "下载导入模板")
|
||||||
|
@PostMapping("/importTemplate")
|
||||||
|
public void importTemplate(HttpServletResponse response) {
|
||||||
|
EasyExcelUtil.importTemplateWithDictDropdown(response, CcdiStaffFmyRelationExcel.class, "员工亲属关系信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步导入员工亲属关系
|
||||||
|
*/
|
||||||
|
@Operation(summary = "异步导入员工亲属关系")
|
||||||
|
@Parameter(name = "file", description = "导入文件", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:staffFmyRelation:import')")
|
||||||
|
@Log(title = "员工亲属关系", businessType = BusinessType.IMPORT)
|
||||||
|
@PostMapping("/importData")
|
||||||
|
public AjaxResult importData(@Parameter(description = "导入文件") MultipartFile file) throws Exception {
|
||||||
|
List<CcdiStaffFmyRelationExcel> list = EasyExcelUtil.importExcel(file.getInputStream(), CcdiStaffFmyRelationExcel.class);
|
||||||
|
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
return error("至少需要一条数据");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交异步任务
|
||||||
|
String taskId = relationService.importRelation(list);
|
||||||
|
|
||||||
|
// 立即返回,不等待后台任务完成
|
||||||
|
ImportResultVO result = new ImportResultVO();
|
||||||
|
result.setTaskId(taskId);
|
||||||
|
result.setStatus("PROCESSING");
|
||||||
|
result.setMessage("导入任务已提交,正在后台处理");
|
||||||
|
|
||||||
|
return AjaxResult.success("导入任务已提交,正在后台处理", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询导入状态
|
||||||
|
*/
|
||||||
|
@Operation(summary = "查询导入状态")
|
||||||
|
@Parameter(name = "taskId", description = "任务ID", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:staffFmyRelation:import')")
|
||||||
|
@GetMapping("/importStatus/{taskId}")
|
||||||
|
public AjaxResult getImportStatus(@PathVariable String taskId) {
|
||||||
|
ImportStatusVO statusVO = relationImportService.getImportStatus(taskId);
|
||||||
|
return success(statusVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询导入失败记录
|
||||||
|
*/
|
||||||
|
@Operation(summary = "查询导入失败记录")
|
||||||
|
@Parameter(name = "taskId", description = "任务ID", required = true)
|
||||||
|
@Parameter(name = "pageNum", description = "页码", required = false)
|
||||||
|
@Parameter(name = "pageSize", description = "每页条数", required = false)
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:staffFmyRelation:import')")
|
||||||
|
@GetMapping("/importFailures/{taskId}")
|
||||||
|
public TableDataInfo getImportFailures(
|
||||||
|
@PathVariable String taskId,
|
||||||
|
@RequestParam(defaultValue = "1") Integer pageNum,
|
||||||
|
@RequestParam(defaultValue = "10") Integer pageSize) {
|
||||||
|
|
||||||
|
List<StaffFmyRelationImportFailureVO> failures = relationImportService.getImportFailures(taskId);
|
||||||
|
|
||||||
|
// 手动分页
|
||||||
|
int fromIndex = (pageNum - 1) * pageSize;
|
||||||
|
int toIndex = Math.min(fromIndex + pageSize, failures.size());
|
||||||
|
|
||||||
|
List<StaffFmyRelationImportFailureVO> pageData = failures.subList(fromIndex, toIndex);
|
||||||
|
|
||||||
|
return getDataTable(pageData, failures.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package com.ruoyi.ccdi.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 员工亲属关系对象 ccdi_staff_fmy_relation
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-09
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CcdiStaffFmyRelation implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 主键ID */
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 员工身份证号 */
|
||||||
|
private String personId;
|
||||||
|
|
||||||
|
/** 关系类型 */
|
||||||
|
private String relationType;
|
||||||
|
|
||||||
|
/** 关系人姓名 */
|
||||||
|
private String relationName;
|
||||||
|
|
||||||
|
/** 性别:M-男,F-女,O-其他 */
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
/** 出生日期 */
|
||||||
|
private Date birthDate;
|
||||||
|
|
||||||
|
/** 关系人证件类型 */
|
||||||
|
private String relationCertType;
|
||||||
|
|
||||||
|
/** 关系人证件号码 */
|
||||||
|
private String relationCertNo;
|
||||||
|
|
||||||
|
/** 手机号码1 */
|
||||||
|
private String mobilePhone1;
|
||||||
|
|
||||||
|
/** 手机号码2 */
|
||||||
|
private String mobilePhone2;
|
||||||
|
|
||||||
|
/** 微信名称1 */
|
||||||
|
private String wechatNo1;
|
||||||
|
|
||||||
|
/** 微信名称2 */
|
||||||
|
private String wechatNo2;
|
||||||
|
|
||||||
|
/** 微信名称3 */
|
||||||
|
private String wechatNo3;
|
||||||
|
|
||||||
|
/** 详细联系地址 */
|
||||||
|
private String contactAddress;
|
||||||
|
|
||||||
|
/** 关系详细描述 */
|
||||||
|
private String relationDesc;
|
||||||
|
|
||||||
|
/** 生效日期 */
|
||||||
|
private Date effectiveDate;
|
||||||
|
|
||||||
|
/** 失效日期 */
|
||||||
|
private Date invalidDate;
|
||||||
|
|
||||||
|
/** 状态:0-无效,1-有效 */
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/** 数据来源:MANUAL-手工录入,IMPORT-导入 */
|
||||||
|
private String dataSource;
|
||||||
|
|
||||||
|
/** 是否是员工亲属:0-否,1-是 */
|
||||||
|
private Boolean isEmpFamily;
|
||||||
|
|
||||||
|
/** 是否是客户亲属:0-否,1-是 */
|
||||||
|
private Boolean isCustFamily;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/** 更新时间 */
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/** 创建人 */
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private String createdBy;
|
||||||
|
|
||||||
|
/** 更新人 */
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private String updatedBy;
|
||||||
|
}
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
package com.ruoyi.ccdi.domain.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 员工亲属关系新增DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-09
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "员工亲属关系新增")
|
||||||
|
public class CcdiStaffFmyRelationAddDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 员工身份证号 */
|
||||||
|
@NotBlank(message = "员工身份证号不能为空")
|
||||||
|
@Pattern(regexp = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$", message = "员工身份证号格式不正确")
|
||||||
|
@Schema(description = "员工身份证号")
|
||||||
|
private String personId;
|
||||||
|
|
||||||
|
/** 关系类型 */
|
||||||
|
@NotBlank(message = "关系类型不能为空")
|
||||||
|
@Size(max = 50, message = "关系类型长度不能超过50个字符")
|
||||||
|
@Schema(description = "关系类型")
|
||||||
|
private String relationType;
|
||||||
|
|
||||||
|
/** 关系人姓名 */
|
||||||
|
@NotBlank(message = "关系人姓名不能为空")
|
||||||
|
@Size(max = 100, message = "关系人姓名长度不能超过100个字符")
|
||||||
|
@Schema(description = "关系人姓名")
|
||||||
|
private String relationName;
|
||||||
|
|
||||||
|
/** 性别 */
|
||||||
|
@Pattern(regexp = "^[MFO]$", message = "性别只能是M、F或O")
|
||||||
|
@Schema(description = "性别:M-男,F-女,O-其他")
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
/** 出生日期 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Schema(description = "出生日期")
|
||||||
|
private Date birthDate;
|
||||||
|
|
||||||
|
/** 关系人证件类型 */
|
||||||
|
@NotBlank(message = "关系人证件类型不能为空")
|
||||||
|
@Size(max = 50, message = "关系人证件类型长度不能超过50个字符")
|
||||||
|
@Schema(description = "关系人证件类型")
|
||||||
|
private String relationCertType;
|
||||||
|
|
||||||
|
/** 关系人证件号码 */
|
||||||
|
@NotBlank(message = "关系人证件号码不能为空")
|
||||||
|
@Size(max = 100, message = "关系人证件号码长度不能超过100个字符")
|
||||||
|
@Schema(description = "关系人证件号码")
|
||||||
|
private String relationCertNo;
|
||||||
|
|
||||||
|
/** 手机号码1 */
|
||||||
|
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码1格式不正确")
|
||||||
|
@Schema(description = "手机号码1")
|
||||||
|
private String mobilePhone1;
|
||||||
|
|
||||||
|
/** 手机号码2 */
|
||||||
|
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码2格式不正确")
|
||||||
|
@Schema(description = "手机号码2")
|
||||||
|
private String mobilePhone2;
|
||||||
|
|
||||||
|
/** 微信名称1 */
|
||||||
|
@Size(max = 50, message = "微信名称1长度不能超过50个字符")
|
||||||
|
@Schema(description = "微信名称1")
|
||||||
|
private String wechatNo1;
|
||||||
|
|
||||||
|
/** 微信名称2 */
|
||||||
|
@Size(max = 50, message = "微信名称2长度不能超过50个字符")
|
||||||
|
@Schema(description = "微信名称2")
|
||||||
|
private String wechatNo2;
|
||||||
|
|
||||||
|
/** 微信名称3 */
|
||||||
|
@Size(max = 50, message = "微信名称3长度不能超过50个字符")
|
||||||
|
@Schema(description = "微信名称3")
|
||||||
|
private String wechatNo3;
|
||||||
|
|
||||||
|
/** 详细联系地址 */
|
||||||
|
@Size(max = 500, message = "详细联系地址长度不能超过500个字符")
|
||||||
|
@Schema(description = "详细联系地址")
|
||||||
|
private String contactAddress;
|
||||||
|
|
||||||
|
/** 关系详细描述 */
|
||||||
|
@Size(max = 500, message = "关系详细描述长度不能超过500个字符")
|
||||||
|
@Schema(description = "关系详细描述")
|
||||||
|
private String relationDesc;
|
||||||
|
|
||||||
|
/** 生效日期 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Schema(description = "生效日期")
|
||||||
|
private Date effectiveDate;
|
||||||
|
|
||||||
|
/** 失效日期 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Schema(description = "失效日期")
|
||||||
|
private Date invalidDate;
|
||||||
|
|
||||||
|
/** 状态 */
|
||||||
|
@Schema(description = "状态:0-无效,1-有效")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
package com.ruoyi.ccdi.domain.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 员工亲属关系编辑DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-09
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "员工亲属关系编辑")
|
||||||
|
public class CcdiStaffFmyRelationEditDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 主键ID */
|
||||||
|
@NotNull(message = "ID不能为空")
|
||||||
|
@Schema(description = "主键ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 员工身份证号 */
|
||||||
|
@NotBlank(message = "员工身份证号不能为空")
|
||||||
|
@Pattern(regexp = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$", message = "员工身份证号格式不正确")
|
||||||
|
@Schema(description = "员工身份证号")
|
||||||
|
private String personId;
|
||||||
|
|
||||||
|
/** 关系类型 */
|
||||||
|
@NotBlank(message = "关系类型不能为空")
|
||||||
|
@Size(max = 50, message = "关系类型长度不能超过50个字符")
|
||||||
|
@Schema(description = "关系类型")
|
||||||
|
private String relationType;
|
||||||
|
|
||||||
|
/** 关系人姓名 */
|
||||||
|
@NotBlank(message = "关系人姓名不能为空")
|
||||||
|
@Size(max = 100, message = "关系人姓名长度不能超过100个字符")
|
||||||
|
@Schema(description = "关系人姓名")
|
||||||
|
private String relationName;
|
||||||
|
|
||||||
|
/** 性别 */
|
||||||
|
@Pattern(regexp = "^[MFO]$", message = "性别只能是M、F或O")
|
||||||
|
@Schema(description = "性别:M-男,F-女,O-其他")
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
/** 出生日期 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Schema(description = "出生日期")
|
||||||
|
private Date birthDate;
|
||||||
|
|
||||||
|
/** 关系人证件类型 */
|
||||||
|
@NotBlank(message = "关系人证件类型不能为空")
|
||||||
|
@Size(max = 50, message = "关系人证件类型长度不能超过50个字符")
|
||||||
|
@Schema(description = "关系人证件类型")
|
||||||
|
private String relationCertType;
|
||||||
|
|
||||||
|
/** 关系人证件号码 */
|
||||||
|
@NotBlank(message = "关系人证件号码不能为空")
|
||||||
|
@Size(max = 100, message = "关系人证件号码长度不能超过100个字符")
|
||||||
|
@Schema(description = "关系人证件号码")
|
||||||
|
private String relationCertNo;
|
||||||
|
|
||||||
|
/** 手机号码1 */
|
||||||
|
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码1格式不正确")
|
||||||
|
@Schema(description = "手机号码1")
|
||||||
|
private String mobilePhone1;
|
||||||
|
|
||||||
|
/** 手机号码2 */
|
||||||
|
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码2格式不正确")
|
||||||
|
@Schema(description = "手机号码2")
|
||||||
|
private String mobilePhone2;
|
||||||
|
|
||||||
|
/** 微信名称1 */
|
||||||
|
@Size(max = 50, message = "微信名称1长度不能超过50个字符")
|
||||||
|
@Schema(description = "微信名称1")
|
||||||
|
private String wechatNo1;
|
||||||
|
|
||||||
|
/** 微信名称2 */
|
||||||
|
@Size(max = 50, message = "微信名称2长度不能超过50个字符")
|
||||||
|
@Schema(description = "微信名称2")
|
||||||
|
private String wechatNo2;
|
||||||
|
|
||||||
|
/** 微信名称3 */
|
||||||
|
@Size(max = 50, message = "微信名称3长度不能超过50个字符")
|
||||||
|
@Schema(description = "微信名称3")
|
||||||
|
private String wechatNo3;
|
||||||
|
|
||||||
|
/** 详细联系地址 */
|
||||||
|
@Size(max = 500, message = "详细联系地址长度不能超过500个字符")
|
||||||
|
@Schema(description = "详细联系地址")
|
||||||
|
private String contactAddress;
|
||||||
|
|
||||||
|
/** 关系详细描述 */
|
||||||
|
@Size(max = 500, message = "关系详细描述长度不能超过500个字符")
|
||||||
|
@Schema(description = "关系详细描述")
|
||||||
|
private String relationDesc;
|
||||||
|
|
||||||
|
/** 生效日期 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Schema(description = "生效日期")
|
||||||
|
private Date effectiveDate;
|
||||||
|
|
||||||
|
/** 失效日期 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Schema(description = "失效日期")
|
||||||
|
private Date invalidDate;
|
||||||
|
|
||||||
|
/** 状态 */
|
||||||
|
@Schema(description = "状态:0-无效,1-有效")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.ruoyi.ccdi.domain.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 员工亲属关系查询DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-09
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "员工亲属关系查询")
|
||||||
|
public class CcdiStaffFmyRelationQueryDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 员工身份证号 */
|
||||||
|
@Schema(description = "员工身份证号")
|
||||||
|
private String personId;
|
||||||
|
|
||||||
|
/** 员工姓名 */
|
||||||
|
@Schema(description = "员工姓名")
|
||||||
|
private String personName;
|
||||||
|
|
||||||
|
/** 关系类型 */
|
||||||
|
@Schema(description = "关系类型")
|
||||||
|
private String relationType;
|
||||||
|
|
||||||
|
/** 关系人姓名 */
|
||||||
|
@Schema(description = "关系人姓名")
|
||||||
|
private String relationName;
|
||||||
|
|
||||||
|
/** 状态 */
|
||||||
|
@Schema(description = "状态:0-无效,1-有效")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/** 数据来源 */
|
||||||
|
@Schema(description = "数据来源")
|
||||||
|
private String dataSource;
|
||||||
|
|
||||||
|
/** 生效日期开始 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Schema(description = "生效日期开始")
|
||||||
|
private Date effectiveDateStart;
|
||||||
|
|
||||||
|
/** 生效日期结束 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Schema(description = "生效日期结束")
|
||||||
|
private Date effectiveDateEnd;
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
package com.ruoyi.ccdi.domain.excel;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||||
|
import com.ruoyi.common.annotation.DictDropdown;
|
||||||
|
import com.ruoyi.common.annotation.Required;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 员工亲属关系Excel导入导出对象
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-09
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CcdiStaffFmyRelationExcel implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 员工身份证号 */
|
||||||
|
@ExcelProperty(value = "员工身份证号*", index = 0)
|
||||||
|
@ColumnWidth(20)
|
||||||
|
@Required
|
||||||
|
private String personId;
|
||||||
|
|
||||||
|
/** 关系类型 */
|
||||||
|
@ExcelProperty(value = "关系类型*", index = 1)
|
||||||
|
@ColumnWidth(15)
|
||||||
|
@DictDropdown(dictType = "ccdi_relation_type")
|
||||||
|
@Required
|
||||||
|
private String relationType;
|
||||||
|
|
||||||
|
/** 关系人姓名 */
|
||||||
|
@ExcelProperty(value = "关系人姓名*", index = 2)
|
||||||
|
@ColumnWidth(15)
|
||||||
|
@Required
|
||||||
|
private String relationName;
|
||||||
|
|
||||||
|
/** 性别 */
|
||||||
|
@ExcelProperty(value = "性别", index = 3)
|
||||||
|
@ColumnWidth(10)
|
||||||
|
@DictDropdown(dictType = "ccdi_indiv_gender")
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
/** 关系人证件类型 */
|
||||||
|
@ExcelProperty(value = "关系人证件类型*", index = 4)
|
||||||
|
@ColumnWidth(15)
|
||||||
|
@DictDropdown(dictType = "ccdi_certificate_type")
|
||||||
|
@Required
|
||||||
|
private String relationCertType;
|
||||||
|
|
||||||
|
/** 关系人证件号码 */
|
||||||
|
@ExcelProperty(value = "关系人证件号码*", index = 5)
|
||||||
|
@ColumnWidth(20)
|
||||||
|
@Required
|
||||||
|
private String relationCertNo;
|
||||||
|
|
||||||
|
/** 手机号码1 */
|
||||||
|
@ExcelProperty(value = "手机号码1", index = 6)
|
||||||
|
@ColumnWidth(15)
|
||||||
|
private String mobilePhone1;
|
||||||
|
|
||||||
|
/** 手机号码2 */
|
||||||
|
@ExcelProperty(value = "手机号码2", index = 7)
|
||||||
|
@ColumnWidth(15)
|
||||||
|
private String mobilePhone2;
|
||||||
|
|
||||||
|
/** 微信名称1 */
|
||||||
|
@ExcelProperty(value = "微信名称1", index = 8)
|
||||||
|
@ColumnWidth(15)
|
||||||
|
private String wechatNo1;
|
||||||
|
|
||||||
|
/** 微信名称2 */
|
||||||
|
@ExcelProperty(value = "微信名称2", index = 9)
|
||||||
|
@ColumnWidth(15)
|
||||||
|
private String wechatNo2;
|
||||||
|
|
||||||
|
/** 微信名称3 */
|
||||||
|
@ExcelProperty(value = "微信名称3", index = 10)
|
||||||
|
@ColumnWidth(15)
|
||||||
|
private String wechatNo3;
|
||||||
|
|
||||||
|
/** 详细联系地址 */
|
||||||
|
@ExcelProperty(value = "详细联系地址", index = 11)
|
||||||
|
@ColumnWidth(30)
|
||||||
|
private String contactAddress;
|
||||||
|
|
||||||
|
/** 关系详细描述 */
|
||||||
|
@ExcelProperty(value = "关系详细描述", index = 12)
|
||||||
|
@ColumnWidth(30)
|
||||||
|
private String relationDesc;
|
||||||
|
|
||||||
|
/** 生效日期 */
|
||||||
|
@ExcelProperty(value = "生效日期", index = 13)
|
||||||
|
@ColumnWidth(15)
|
||||||
|
private String effectiveDate;
|
||||||
|
|
||||||
|
/** 失效日期 */
|
||||||
|
@ExcelProperty(value = "失效日期", index = 14)
|
||||||
|
@ColumnWidth(15)
|
||||||
|
private String invalidDate;
|
||||||
|
|
||||||
|
/** 状态 */
|
||||||
|
@ExcelProperty(value = "状态", index = 15)
|
||||||
|
@ColumnWidth(10)
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
@ExcelProperty(value = "备注", index = 16)
|
||||||
|
@ColumnWidth(30)
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
package com.ruoyi.ccdi.domain.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 员工亲属关系VO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-09
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "员工亲属关系")
|
||||||
|
public class CcdiStaffFmyRelationVO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 主键ID */
|
||||||
|
@Schema(description = "主键ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 员工身份证号 */
|
||||||
|
@Schema(description = "员工身份证号")
|
||||||
|
private String personId;
|
||||||
|
|
||||||
|
/** 员工姓名 */
|
||||||
|
@Schema(description = "员工姓名")
|
||||||
|
private String personName;
|
||||||
|
|
||||||
|
/** 关系类型 */
|
||||||
|
@Schema(description = "关系类型")
|
||||||
|
private String relationType;
|
||||||
|
|
||||||
|
/** 关系人姓名 */
|
||||||
|
@Schema(description = "关系人姓名")
|
||||||
|
private String relationName;
|
||||||
|
|
||||||
|
/** 性别 */
|
||||||
|
@Schema(description = "性别")
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
/** 性别名称 */
|
||||||
|
@Schema(description = "性别名称")
|
||||||
|
private String genderName;
|
||||||
|
|
||||||
|
/** 出生日期 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Schema(description = "出生日期")
|
||||||
|
private Date birthDate;
|
||||||
|
|
||||||
|
/** 关系人证件类型 */
|
||||||
|
@Schema(description = "关系人证件类型")
|
||||||
|
private String relationCertType;
|
||||||
|
|
||||||
|
/** 关系人证件号码 */
|
||||||
|
@Schema(description = "关系人证件号码")
|
||||||
|
private String relationCertNo;
|
||||||
|
|
||||||
|
/** 手机号码1 */
|
||||||
|
@Schema(description = "手机号码1")
|
||||||
|
private String mobilePhone1;
|
||||||
|
|
||||||
|
/** 手机号码2 */
|
||||||
|
@Schema(description = "手机号码2")
|
||||||
|
private String mobilePhone2;
|
||||||
|
|
||||||
|
/** 微信名称1 */
|
||||||
|
@Schema(description = "微信名称1")
|
||||||
|
private String wechatNo1;
|
||||||
|
|
||||||
|
/** 微信名称2 */
|
||||||
|
@Schema(description = "微信名称2")
|
||||||
|
private String wechatNo2;
|
||||||
|
|
||||||
|
/** 微信名称3 */
|
||||||
|
@Schema(description = "微信名称3")
|
||||||
|
private String wechatNo3;
|
||||||
|
|
||||||
|
/** 详细联系地址 */
|
||||||
|
@Schema(description = "详细联系地址")
|
||||||
|
private String contactAddress;
|
||||||
|
|
||||||
|
/** 关系详细描述 */
|
||||||
|
@Schema(description = "关系详细描述")
|
||||||
|
private String relationDesc;
|
||||||
|
|
||||||
|
/** 生效日期 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Schema(description = "生效日期")
|
||||||
|
private Date effectiveDate;
|
||||||
|
|
||||||
|
/** 失效日期 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Schema(description = "失效日期")
|
||||||
|
private Date invalidDate;
|
||||||
|
|
||||||
|
/** 状态 */
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/** 状态名称 */
|
||||||
|
@Schema(description = "状态名称")
|
||||||
|
private String statusName;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/** 数据来源 */
|
||||||
|
@Schema(description = "数据来源")
|
||||||
|
private String dataSource;
|
||||||
|
|
||||||
|
/** 是否是员工亲属 */
|
||||||
|
@Schema(description = "是否是员工亲属")
|
||||||
|
private Boolean isEmpFamily;
|
||||||
|
|
||||||
|
/** 是否是客户亲属 */
|
||||||
|
@Schema(description = "是否是客户亲属")
|
||||||
|
private Boolean isCustFamily;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/** 更新时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新时间")
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/** 创建人 */
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private String createdBy;
|
||||||
|
|
||||||
|
/** 更新人 */
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private String updatedBy;
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.ruoyi.ccdi.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.ccdi.domain.CcdiStaffFmyRelation;
|
||||||
|
import com.ruoyi.ccdi.domain.dto.CcdiStaffFmyRelationQueryDTO;
|
||||||
|
import com.ruoyi.ccdi.domain.vo.CcdiStaffFmyRelationVO;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 员工亲属关系 数据层
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-09
|
||||||
|
*/
|
||||||
|
public interface CcdiStaffFmyRelationMapper extends BaseMapper<CcdiStaffFmyRelation> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询员工亲属关系列表
|
||||||
|
*
|
||||||
|
* @param page 分页对象
|
||||||
|
* @param queryDTO 查询条件
|
||||||
|
* @return 员工亲属关系VO分页结果
|
||||||
|
*/
|
||||||
|
Page<CcdiStaffFmyRelationVO> selectRelationPage(@Param("page") Page<CcdiStaffFmyRelationVO> page,
|
||||||
|
@Param("query") CcdiStaffFmyRelationQueryDTO queryDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询员工亲属关系详情
|
||||||
|
*
|
||||||
|
* @param id 主键ID
|
||||||
|
* @return 员工亲属关系VO
|
||||||
|
*/
|
||||||
|
CcdiStaffFmyRelationVO selectRelationById(@Param("id") Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询员工亲属关系列表(用于导出)
|
||||||
|
*
|
||||||
|
* @param queryDTO 查询条件
|
||||||
|
* @return 员工亲属关系VO列表
|
||||||
|
*/
|
||||||
|
List<CcdiStaffFmyRelationVO> selectRelationListForExport(@Param("query") CcdiStaffFmyRelationQueryDTO queryDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量插入员工亲属关系数据
|
||||||
|
*
|
||||||
|
* @param list 员工亲属关系列表
|
||||||
|
* @return 插入行数
|
||||||
|
*/
|
||||||
|
int insertBatch(@Param("list") List<CcdiStaffFmyRelation> list);
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.ruoyi.ccdi.service;
|
||||||
|
|
||||||
|
import com.ruoyi.ccdi.domain.excel.CcdiStaffFmyRelationExcel;
|
||||||
|
import com.ruoyi.ccdi.domain.vo.ImportStatusVO;
|
||||||
|
import com.ruoyi.ccdi.domain.vo.StaffFmyRelationImportFailureVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 员工亲属关系异步导入 服务层
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-09
|
||||||
|
*/
|
||||||
|
public interface ICcdiStaffFmyRelationImportService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步导入员工亲属关系数据
|
||||||
|
*
|
||||||
|
* @param excelList Excel实体列表
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @param userName 用户名
|
||||||
|
*/
|
||||||
|
void importRelationAsync(List<CcdiStaffFmyRelationExcel> excelList, String taskId, String userName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询导入失败记录
|
||||||
|
*
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @return 失败记录列表
|
||||||
|
*/
|
||||||
|
List<StaffFmyRelationImportFailureVO> getImportFailures(String taskId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询导入状态
|
||||||
|
*
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @return 导入状态信息
|
||||||
|
*/
|
||||||
|
ImportStatusVO getImportStatus(String taskId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package com.ruoyi.ccdi.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.ccdi.domain.dto.CcdiStaffFmyRelationAddDTO;
|
||||||
|
import com.ruoyi.ccdi.domain.dto.CcdiStaffFmyRelationEditDTO;
|
||||||
|
import com.ruoyi.ccdi.domain.dto.CcdiStaffFmyRelationQueryDTO;
|
||||||
|
import com.ruoyi.ccdi.domain.excel.CcdiStaffFmyRelationExcel;
|
||||||
|
import com.ruoyi.ccdi.domain.vo.CcdiStaffFmyRelationVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 员工亲属关系 服务层
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-09
|
||||||
|
*/
|
||||||
|
public interface ICcdiStaffFmyRelationService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询员工亲属关系列表
|
||||||
|
*
|
||||||
|
* @param queryDTO 查询条件
|
||||||
|
* @return 员工亲属关系VO集合
|
||||||
|
*/
|
||||||
|
List<CcdiStaffFmyRelationVO> selectRelationList(CcdiStaffFmyRelationQueryDTO queryDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询员工亲属关系列表
|
||||||
|
*
|
||||||
|
* @param page 分页对象
|
||||||
|
* @param queryDTO 查询条件
|
||||||
|
* @return 员工亲属关系VO分页结果
|
||||||
|
*/
|
||||||
|
Page<CcdiStaffFmyRelationVO> selectRelationPage(Page<CcdiStaffFmyRelationVO> page, CcdiStaffFmyRelationQueryDTO queryDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询员工亲属关系详情
|
||||||
|
*
|
||||||
|
* @param id 主键ID
|
||||||
|
* @return 员工亲属关系VO
|
||||||
|
*/
|
||||||
|
CcdiStaffFmyRelationVO selectRelationById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增员工亲属关系
|
||||||
|
*
|
||||||
|
* @param addDTO 新增DTO
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int insertRelation(CcdiStaffFmyRelationAddDTO addDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改员工亲属关系
|
||||||
|
*
|
||||||
|
* @param editDTO 编辑DTO
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int updateRelation(CcdiStaffFmyRelationEditDTO editDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除员工亲属关系
|
||||||
|
*
|
||||||
|
* @param ids 需要删除的主键ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int deleteRelationByIds(Long[] ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询员工亲属关系列表(用于导出)
|
||||||
|
*
|
||||||
|
* @param queryDTO 查询条件
|
||||||
|
* @return 员工亲属关系Excel实体集合
|
||||||
|
*/
|
||||||
|
List<CcdiStaffFmyRelationExcel> selectRelationListForExport(CcdiStaffFmyRelationQueryDTO queryDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入员工亲属关系数据(异步)
|
||||||
|
*
|
||||||
|
* @param excelList Excel实体列表
|
||||||
|
* @return 任务ID
|
||||||
|
*/
|
||||||
|
String importRelation(List<CcdiStaffFmyRelationExcel> excelList);
|
||||||
|
}
|
||||||
@@ -0,0 +1,237 @@
|
|||||||
|
package com.ruoyi.ccdi.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.ruoyi.ccdi.domain.CcdiStaffFmyRelation;
|
||||||
|
import com.ruoyi.ccdi.domain.dto.CcdiStaffFmyRelationAddDTO;
|
||||||
|
import com.ruoyi.ccdi.domain.excel.CcdiStaffFmyRelationExcel;
|
||||||
|
import com.ruoyi.ccdi.domain.vo.ImportResult;
|
||||||
|
import com.ruoyi.ccdi.domain.vo.ImportStatusVO;
|
||||||
|
import com.ruoyi.ccdi.domain.vo.StaffFmyRelationImportFailureVO;
|
||||||
|
import com.ruoyi.ccdi.mapper.CcdiStaffFmyRelationMapper;
|
||||||
|
import com.ruoyi.ccdi.service.ICcdiStaffFmyRelationImportService;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
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 org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 员工亲属关系异步导入服务层处理
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-09
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@EnableAsync
|
||||||
|
public class CcdiStaffFmyRelationImportServiceImpl implements ICcdiStaffFmyRelationImportService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CcdiStaffFmyRelationMapper relationMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Async
|
||||||
|
@Transactional
|
||||||
|
public void importRelationAsync(List<CcdiStaffFmyRelationExcel> excelList, String taskId, String userName) {
|
||||||
|
List<CcdiStaffFmyRelation> newRecords = new ArrayList<>();
|
||||||
|
List<StaffFmyRelationImportFailureVO> failures = new ArrayList<>();
|
||||||
|
|
||||||
|
// 用于跟踪Excel文件内已处理的唯一键(personId + relationCertNo)
|
||||||
|
Set<String> processedKeys = new HashSet<>();
|
||||||
|
|
||||||
|
// 分类数据
|
||||||
|
for (int i = 0; i < excelList.size(); i++) {
|
||||||
|
CcdiStaffFmyRelationExcel excel = excelList.get(i);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 转换为AddDTO进行验证
|
||||||
|
CcdiStaffFmyRelationAddDTO addDTO = new CcdiStaffFmyRelationAddDTO();
|
||||||
|
BeanUtils.copyProperties(excel, addDTO);
|
||||||
|
|
||||||
|
// 验证数据
|
||||||
|
validateRelationData(addDTO);
|
||||||
|
|
||||||
|
// 生成唯一键
|
||||||
|
String uniqueKey = excel.getPersonId() + "|" + excel.getRelationCertNo();
|
||||||
|
|
||||||
|
// 检查是否在文件内重复
|
||||||
|
if (processedKeys.contains(uniqueKey)) {
|
||||||
|
throw new RuntimeException(String.format("员工[%s]的关系人[%s]在导入文件中重复", excel.getPersonId(), excel.getRelationCertNo()));
|
||||||
|
}
|
||||||
|
|
||||||
|
CcdiStaffFmyRelation relation = new CcdiStaffFmyRelation();
|
||||||
|
BeanUtils.copyProperties(excel, relation);
|
||||||
|
|
||||||
|
relation.setCreatedBy(userName);
|
||||||
|
relation.setUpdatedBy(userName);
|
||||||
|
relation.setIsEmpFamily(true);
|
||||||
|
relation.setIsCustFamily(false);
|
||||||
|
relation.setDataSource("IMPORT");
|
||||||
|
if (relation.getStatus() == null) {
|
||||||
|
relation.setStatus(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
newRecords.add(relation);
|
||||||
|
processedKeys.add(uniqueKey);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
StaffFmyRelationImportFailureVO failure = new StaffFmyRelationImportFailureVO();
|
||||||
|
BeanUtils.copyProperties(excel, failure);
|
||||||
|
failure.setErrorMessage(e.getMessage());
|
||||||
|
failures.add(failure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量插入新数据
|
||||||
|
if (!newRecords.isEmpty()) {
|
||||||
|
saveBatch(newRecords, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存失败记录到Redis
|
||||||
|
if (!failures.isEmpty()) {
|
||||||
|
String failuresKey = "import:staffFmyRelation:" + taskId + ":failures";
|
||||||
|
redisTemplate.opsForValue().set(failuresKey, failures, 7, TimeUnit.DAYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImportResult result = new ImportResult();
|
||||||
|
result.setTotalCount(excelList.size());
|
||||||
|
result.setSuccessCount(newRecords.size());
|
||||||
|
result.setFailureCount(failures.size());
|
||||||
|
|
||||||
|
// 更新最终状态
|
||||||
|
String finalStatus = result.getFailureCount() == 0 ? "SUCCESS" : "PARTIAL_SUCCESS";
|
||||||
|
updateImportStatus(taskId, finalStatus, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取导入失败记录
|
||||||
|
*
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @return 失败记录列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<StaffFmyRelationImportFailureVO> getImportFailures(String taskId) {
|
||||||
|
String key = "import:staffFmyRelation:" + taskId + ":failures";
|
||||||
|
Object failuresObj = redisTemplate.opsForValue().get(key);
|
||||||
|
|
||||||
|
if (failuresObj == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.parseArray(JSON.toJSONString(failuresObj), StaffFmyRelationImportFailureVO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询导入状态
|
||||||
|
*
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @return 导入状态信息
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ImportStatusVO getImportStatus(String taskId) {
|
||||||
|
String key = "import:staffFmyRelation:" + taskId;
|
||||||
|
Boolean hasKey = redisTemplate.hasKey(key);
|
||||||
|
|
||||||
|
if (Boolean.FALSE.equals(hasKey)) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新导入状态
|
||||||
|
*/
|
||||||
|
private void updateImportStatus(String taskId, String status, ImportResult result) {
|
||||||
|
String key = "import:staffFmyRelation:" + taskId;
|
||||||
|
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(key, statusData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量保存
|
||||||
|
*/
|
||||||
|
private void saveBatch(List<CcdiStaffFmyRelation> list, int batchSize) {
|
||||||
|
// 使用真正的批量插入,分批次执行以提高性能
|
||||||
|
for (int i = 0; i < list.size(); i += batchSize) {
|
||||||
|
int end = Math.min(i + batchSize, list.size());
|
||||||
|
List<CcdiStaffFmyRelation> subList = list.subList(i, end);
|
||||||
|
relationMapper.insertBatch(subList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证员工亲属关系数据
|
||||||
|
*
|
||||||
|
* @param addDTO 新增DTO
|
||||||
|
*/
|
||||||
|
private void validateRelationData(CcdiStaffFmyRelationAddDTO addDTO) {
|
||||||
|
// 验证必填字段
|
||||||
|
if (StringUtils.isEmpty(addDTO.getPersonId())) {
|
||||||
|
throw new RuntimeException("员工身份证号不能为空");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(addDTO.getRelationType())) {
|
||||||
|
throw new RuntimeException("关系类型不能为空");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(addDTO.getRelationName())) {
|
||||||
|
throw new RuntimeException("关系人姓名不能为空");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(addDTO.getRelationCertType())) {
|
||||||
|
throw new RuntimeException("关系人证件类型不能为空");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(addDTO.getRelationCertNo())) {
|
||||||
|
throw new RuntimeException("关系人证件号码不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证身份证号格式
|
||||||
|
if (!addDTO.getPersonId().matches("^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$")) {
|
||||||
|
throw new RuntimeException("员工身份证号格式不正确");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证手机号格式(如果提供)
|
||||||
|
if (StringUtils.isNotEmpty(addDTO.getMobilePhone1()) && !addDTO.getMobilePhone1().matches("^1[3-9]\\d{9}$")) {
|
||||||
|
throw new RuntimeException("手机号码1格式不正确");
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(addDTO.getMobilePhone2()) && !addDTO.getMobilePhone2().matches("^1[3-9]\\d{9}$")) {
|
||||||
|
throw new RuntimeException("手机号码2格式不正确");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证性别值(如果提供)
|
||||||
|
if (StringUtils.isNotEmpty(addDTO.getGender()) && !addDTO.getGender().matches("^[MFO]$")) {
|
||||||
|
throw new RuntimeException("性别只能是M、F或O");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
package com.ruoyi.ccdi.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.ccdi.domain.CcdiStaffFmyRelation;
|
||||||
|
import com.ruoyi.ccdi.domain.dto.CcdiStaffFmyRelationAddDTO;
|
||||||
|
import com.ruoyi.ccdi.domain.dto.CcdiStaffFmyRelationEditDTO;
|
||||||
|
import com.ruoyi.ccdi.domain.dto.CcdiStaffFmyRelationQueryDTO;
|
||||||
|
import com.ruoyi.ccdi.domain.excel.CcdiStaffFmyRelationExcel;
|
||||||
|
import com.ruoyi.ccdi.domain.vo.CcdiStaffFmyRelationVO;
|
||||||
|
import com.ruoyi.ccdi.mapper.CcdiStaffFmyRelationMapper;
|
||||||
|
import com.ruoyi.ccdi.service.ICcdiStaffFmyRelationImportService;
|
||||||
|
import com.ruoyi.ccdi.service.ICcdiStaffFmyRelationService;
|
||||||
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
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.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 员工亲属关系 服务层处理
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-09
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class CcdiStaffFmyRelationServiceImpl implements ICcdiStaffFmyRelationService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CcdiStaffFmyRelationMapper relationMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ICcdiStaffFmyRelationImportService relationImportService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询员工亲属关系列表
|
||||||
|
*
|
||||||
|
* @param queryDTO 查询条件
|
||||||
|
* @return 员工亲属关系VO集合
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public java.util.List<CcdiStaffFmyRelationVO> selectRelationList(CcdiStaffFmyRelationQueryDTO queryDTO) {
|
||||||
|
Page<CcdiStaffFmyRelationVO> page = new Page<>(1, Integer.MAX_VALUE);
|
||||||
|
Page<CcdiStaffFmyRelationVO> resultPage = relationMapper.selectRelationPage(page, queryDTO);
|
||||||
|
return resultPage.getRecords();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询员工亲属关系列表
|
||||||
|
*
|
||||||
|
* @param page 分页对象
|
||||||
|
* @param queryDTO 查询条件
|
||||||
|
* @return 员工亲属关系VO分页结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Page<CcdiStaffFmyRelationVO> selectRelationPage(Page<CcdiStaffFmyRelationVO> page, CcdiStaffFmyRelationQueryDTO queryDTO) {
|
||||||
|
return relationMapper.selectRelationPage(page, queryDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询员工亲属关系列表(用于导出)
|
||||||
|
*
|
||||||
|
* @param queryDTO 查询条件
|
||||||
|
* @return 员工亲属关系Excel实体集合
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public java.util.List<CcdiStaffFmyRelationExcel> selectRelationListForExport(CcdiStaffFmyRelationQueryDTO queryDTO) {
|
||||||
|
return relationMapper.selectRelationListForExport(queryDTO).stream().map(vo -> {
|
||||||
|
CcdiStaffFmyRelationExcel excel = new CcdiStaffFmyRelationExcel();
|
||||||
|
BeanUtils.copyProperties(vo, excel);
|
||||||
|
return excel;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询员工亲属关系详情
|
||||||
|
*
|
||||||
|
* @param id 主键ID
|
||||||
|
* @return 员工亲属关系VO
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CcdiStaffFmyRelationVO selectRelationById(Long id) {
|
||||||
|
return relationMapper.selectRelationById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增员工亲属关系
|
||||||
|
*
|
||||||
|
* @param addDTO 新增DTO
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public int insertRelation(CcdiStaffFmyRelationAddDTO addDTO) {
|
||||||
|
CcdiStaffFmyRelation relation = new CcdiStaffFmyRelation();
|
||||||
|
BeanUtils.copyProperties(addDTO, relation);
|
||||||
|
|
||||||
|
// 设置默认值
|
||||||
|
relation.setIsEmpFamily(true);
|
||||||
|
relation.setIsCustFamily(false);
|
||||||
|
relation.setDataSource("MANUAL");
|
||||||
|
if (relation.getStatus() == null) {
|
||||||
|
relation.setStatus(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = relationMapper.insert(relation);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改员工亲属关系
|
||||||
|
*
|
||||||
|
* @param editDTO 编辑DTO
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public int updateRelation(CcdiStaffFmyRelationEditDTO editDTO) {
|
||||||
|
CcdiStaffFmyRelation relation = new CcdiStaffFmyRelation();
|
||||||
|
BeanUtils.copyProperties(editDTO, relation);
|
||||||
|
int result = relationMapper.updateById(relation);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除员工亲属关系
|
||||||
|
*
|
||||||
|
* @param ids 需要删除的主键ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public int deleteRelationByIds(Long[] ids) {
|
||||||
|
return relationMapper.deleteBatchIds(java.util.List.of(ids));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入员工亲属关系数据(异步)
|
||||||
|
*
|
||||||
|
* @param excelList Excel实体列表
|
||||||
|
* @return 任务ID
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public String importRelation(java.util.List<CcdiStaffFmyRelationExcel> excelList) {
|
||||||
|
if (StringUtils.isNull(excelList) || excelList.isEmpty()) {
|
||||||
|
throw new RuntimeException("至少需要一条数据");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成任务ID
|
||||||
|
String taskId = UUID.randomUUID().toString();
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// 获取当前用户名
|
||||||
|
String userName = SecurityUtils.getUsername();
|
||||||
|
|
||||||
|
// 初始化Redis状态
|
||||||
|
String statusKey = "import:staffFmyRelation:" + taskId;
|
||||||
|
Map<String, Object> statusData = new HashMap<>();
|
||||||
|
statusData.put("taskId", taskId);
|
||||||
|
statusData.put("status", "PROCESSING");
|
||||||
|
statusData.put("totalCount", excelList.size());
|
||||||
|
statusData.put("successCount", 0);
|
||||||
|
statusData.put("failureCount", 0);
|
||||||
|
statusData.put("progress", 0);
|
||||||
|
statusData.put("startTime", startTime);
|
||||||
|
statusData.put("message", "正在处理...");
|
||||||
|
|
||||||
|
redisTemplate.opsForHash().putAll(statusKey, statusData);
|
||||||
|
redisTemplate.expire(statusKey, 7, TimeUnit.DAYS);
|
||||||
|
|
||||||
|
// 调用异步导入服务
|
||||||
|
relationImportService.importRelationAsync(excelList, taskId, userName);
|
||||||
|
|
||||||
|
return taskId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ruoyi.ccdi.mapper.CcdiStaffFmyRelationMapper">
|
||||||
|
|
||||||
|
<!-- 员工亲属关系ResultMap -->
|
||||||
|
<resultMap type="com.ruoyi.ccdi.domain.vo.CcdiStaffFmyRelationVO" id="CcdiStaffFmyRelationVOResult">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="personId" column="person_id"/>
|
||||||
|
<result property="personName" column="person_name"/>
|
||||||
|
<result property="relationType" column="relation_type"/>
|
||||||
|
<result property="relationName" column="relation_name"/>
|
||||||
|
<result property="gender" column="gender"/>
|
||||||
|
<result property="birthDate" column="birth_date"/>
|
||||||
|
<result property="relationCertType" column="relation_cert_type"/>
|
||||||
|
<result property="relationCertNo" column="relation_cert_no"/>
|
||||||
|
<result property="mobilePhone1" column="mobile_phone1"/>
|
||||||
|
<result property="mobilePhone2" column="mobile_phone2"/>
|
||||||
|
<result property="wechatNo1" column="wechat_no1"/>
|
||||||
|
<result property="wechatNo2" column="wechat_no2"/>
|
||||||
|
<result property="wechatNo3" column="wechat_no3"/>
|
||||||
|
<result property="contactAddress" column="contact_address"/>
|
||||||
|
<result property="relationDesc" column="relation_desc"/>
|
||||||
|
<result property="effectiveDate" column="effective_date"/>
|
||||||
|
<result property="invalidDate" column="invalid_date"/>
|
||||||
|
<result property="status" column="status"/>
|
||||||
|
<result property="remark" column="remark"/>
|
||||||
|
<result property="dataSource" column="data_source"/>
|
||||||
|
<result property="isEmpFamily" column="is_emp_family"/>
|
||||||
|
<result property="isCustFamily" column="is_cust_family"/>
|
||||||
|
<result property="createTime" column="create_time"/>
|
||||||
|
<result property="updateTime" column="update_time"/>
|
||||||
|
<result property="createdBy" column="created_by"/>
|
||||||
|
<result property="updatedBy" column="updated_by"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<!-- 分页查询员工亲属关系列表 -->
|
||||||
|
<select id="selectRelationPage" resultMap="CcdiStaffFmyRelationVOResult">
|
||||||
|
SELECT
|
||||||
|
r.id, r.person_id, s.name as person_name, r.relation_type, r.relation_name,
|
||||||
|
r.gender, r.birth_date, r.relation_cert_type, r.relation_cert_no,
|
||||||
|
r.mobile_phone1, r.mobile_phone2, r.wechat_no1, r.wechat_no2, r.wechat_no3,
|
||||||
|
r.contact_address, r.relation_desc, r.effective_date, r.invalid_date,
|
||||||
|
r.status, r.remark, r.data_source, r.is_emp_family, r.is_cust_family,
|
||||||
|
r.created_by, r.create_time, r.updated_by, r.update_time
|
||||||
|
FROM ccdi_staff_fmy_relation r
|
||||||
|
LEFT JOIN ccdi_base_staff s ON r.person_id = s.id_card
|
||||||
|
<where>
|
||||||
|
r.is_emp_family = 1
|
||||||
|
<if test="query.personId != null and query.personId != ''">
|
||||||
|
AND r.person_id = #{query.personId}
|
||||||
|
</if>
|
||||||
|
<if test="query.personName != null and query.personName != ''">
|
||||||
|
AND s.name LIKE CONCAT('%', #{query.personName}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="query.relationType != null and query.relationType != ''">
|
||||||
|
AND r.relation_type = #{query.relationType}
|
||||||
|
</if>
|
||||||
|
<if test="query.relationName != null and query.relationName != ''">
|
||||||
|
AND r.relation_name LIKE CONCAT('%', #{query.relationName}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="query.status != null">
|
||||||
|
AND r.status = #{query.status}
|
||||||
|
</if>
|
||||||
|
<if test="query.dataSource != null and query.dataSource != ''">
|
||||||
|
AND r.data_source = #{query.dataSource}
|
||||||
|
</if>
|
||||||
|
<if test="query.effectiveDateStart != null">
|
||||||
|
AND r.effective_date >= #{query.effectiveDateStart}
|
||||||
|
</if>
|
||||||
|
<if test="query.effectiveDateEnd != null">
|
||||||
|
AND r.effective_date <= #{query.effectiveDateEnd}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
ORDER BY r.create_time DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询员工亲属关系详情 -->
|
||||||
|
<select id="selectRelationById" resultMap="CcdiStaffFmyRelationVOResult">
|
||||||
|
SELECT
|
||||||
|
r.id, r.person_id, s.name as person_name, r.relation_type, r.relation_name,
|
||||||
|
r.gender, r.birth_date, r.relation_cert_type, r.relation_cert_no,
|
||||||
|
r.mobile_phone1, r.mobile_phone2, r.wechat_no1, r.wechat_no2, r.wechat_no3,
|
||||||
|
r.contact_address, r.relation_desc, r.effective_date, r.invalid_date,
|
||||||
|
r.status, r.remark, r.data_source, r.is_emp_family, r.is_cust_family,
|
||||||
|
r.created_by, r.create_time, r.updated_by, r.update_time
|
||||||
|
FROM ccdi_staff_fmy_relation r
|
||||||
|
LEFT JOIN ccdi_base_staff s ON r.person_id = s.id_card
|
||||||
|
WHERE r.id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询员工亲属关系列表(用于导出) -->
|
||||||
|
<select id="selectRelationListForExport" resultMap="CcdiStaffFmyRelationVOResult">
|
||||||
|
SELECT
|
||||||
|
r.id, r.person_id, s.name as person_name, r.relation_type, r.relation_name,
|
||||||
|
r.gender, r.birth_date, r.relation_cert_type, r.relation_cert_no,
|
||||||
|
r.mobile_phone1, r.mobile_phone2, r.wechat_no1, r.wechat_no2, r.wechat_no3,
|
||||||
|
r.contact_address, r.relation_desc, r.effective_date, r.invalid_date,
|
||||||
|
r.status, r.remark, r.data_source, r.is_emp_family, r.is_cust_family,
|
||||||
|
r.created_by, r.create_time, r.updated_by, r.update_time
|
||||||
|
FROM ccdi_staff_fmy_relation r
|
||||||
|
LEFT JOIN ccdi_base_staff s ON r.person_id = s.id_card
|
||||||
|
<where>
|
||||||
|
r.is_emp_family = 1
|
||||||
|
<if test="query.personId != null and query.personId != ''">
|
||||||
|
AND r.person_id = #{query.personId}
|
||||||
|
</if>
|
||||||
|
<if test="query.personName != null and query.personName != ''">
|
||||||
|
AND s.name LIKE CONCAT('%', #{query.personName}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="query.relationType != null and query.relationType != ''">
|
||||||
|
AND r.relation_type = #{query.relationType}
|
||||||
|
</if>
|
||||||
|
<if test="query.relationName != null and query.relationName != ''">
|
||||||
|
AND r.relation_name LIKE CONCAT('%', #{query.relationName}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="query.status != null">
|
||||||
|
AND r.status = #{query.status}
|
||||||
|
</if>
|
||||||
|
<if test="query.dataSource != null and query.dataSource != ''">
|
||||||
|
AND r.data_source = #{query.dataSource}
|
||||||
|
</if>
|
||||||
|
<if test="query.effectiveDateStart != null">
|
||||||
|
AND r.effective_date >= #{query.effectiveDateStart}
|
||||||
|
</if>
|
||||||
|
<if test="query.effectiveDateEnd != null">
|
||||||
|
AND r.effective_date <= #{query.effectiveDateEnd}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
ORDER BY r.create_time DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 批量插入员工亲属关系数据 -->
|
||||||
|
<insert id="insertBatch">
|
||||||
|
INSERT INTO ccdi_staff_fmy_relation
|
||||||
|
(person_id, relation_type, relation_name, gender, birth_date, relation_cert_type, relation_cert_no,
|
||||||
|
mobile_phone1, mobile_phone2, wechat_no1, wechat_no2, wechat_no3, contact_address, relation_desc,
|
||||||
|
effective_date, invalid_date, status, remark, data_source, is_emp_family, is_cust_family,
|
||||||
|
created_by, create_time, updated_by, update_time)
|
||||||
|
VALUES
|
||||||
|
<foreach collection="list" item="item" separator=",">
|
||||||
|
(#{item.personId}, #{item.relationType}, #{item.relationName}, #{item.gender},
|
||||||
|
#{item.birthDate}, #{item.relationCertType}, #{item.relationCertNo}, #{item.mobilePhone1},
|
||||||
|
#{item.mobilePhone2}, #{item.wechatNo1}, #{item.wechatNo2}, #{item.wechatNo3}, #{item.contactAddress},
|
||||||
|
#{item.relationDesc}, #{item.effectiveDate}, #{item.invalidDate}, #{item.status}, #{item.remark},
|
||||||
|
#{item.dataSource}, #{item.isEmpFamily}, #{item.isCustFamily}, #{item.createdBy}, NOW(), #{item.updatedBy}, NOW())
|
||||||
|
</foreach>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
99
ruoyi-ui/src/api/ccdiStaffFmyRelation.js
Normal file
99
ruoyi-ui/src/api/ccdiStaffFmyRelation.js
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询员工亲属关系列表
|
||||||
|
export function listRelation(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/staffFmyRelation/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询员工亲属关系详情
|
||||||
|
export function getRelation(id) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/staffFmyRelation/' + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增员工亲属关系
|
||||||
|
export function addRelation(data) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/staffFmyRelation',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改员工亲属关系
|
||||||
|
export function updateRelation(data) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/staffFmyRelation',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除员工亲属关系
|
||||||
|
export function delRelation(ids) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/staffFmyRelation/' + ids,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出员工亲属关系
|
||||||
|
export function exportRelation(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/staffFmyRelation/export',
|
||||||
|
method: 'post',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载导入模板
|
||||||
|
export function importTemplate() {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/staffFmyRelation/importTemplate',
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导入员工亲属关系
|
||||||
|
export function importData(file, updateSupport) {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('file', file)
|
||||||
|
formData.append('updateSupport', updateSupport)
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/staffFmyRelation/importData',
|
||||||
|
method: 'post',
|
||||||
|
data: formData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询导入状态
|
||||||
|
export function getImportStatus(taskId) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/staffFmyRelation/importStatus/' + taskId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询导入失败记录
|
||||||
|
export function getImportFailures(taskId, pageNum, pageSize) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/staffFmyRelation/importFailures/' + taskId,
|
||||||
|
method: 'get',
|
||||||
|
params: { pageNum, pageSize }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取员工列表(用于下拉选择)
|
||||||
|
export function getStaffList(name) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/staffFmyRelation/staffList',
|
||||||
|
method: 'get',
|
||||||
|
params: { name }
|
||||||
|
})
|
||||||
|
}
|
||||||
988
ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue
Normal file
988
ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue
Normal file
@@ -0,0 +1,988 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
|
||||||
|
<el-form-item label="员工姓名" prop="personName">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.personName"
|
||||||
|
placeholder="请输入员工姓名"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="关系类型" prop="relationType">
|
||||||
|
<el-select v-model="queryParams.relationType" placeholder="请选择关系类型" clearable style="width: 240px">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dict.type.ccdi_relation_type"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="关系人姓名" prop="relationName">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.relationName"
|
||||||
|
placeholder="请输入关系人姓名"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态" prop="status">
|
||||||
|
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 240px">
|
||||||
|
<el-option label="有效" :value="1" />
|
||||||
|
<el-option label="无效" :value="0" />
|
||||||
|
</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:staffFmyRelation:add']"
|
||||||
|
>新增</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:staffFmyRelation:import']"
|
||||||
|
>导入</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-download"
|
||||||
|
size="mini"
|
||||||
|
@click="handleExport"
|
||||||
|
v-hasPermi="['ccdi:staffFmyRelation:export']"
|
||||||
|
>导出</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="relationList" @selection-change="handleSelectionChange">
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="员工姓名" align="center" prop="personName" :show-overflow-tooltip="true"/>
|
||||||
|
<el-table-column label="员工身份证号" align="center" prop="personId" width="180"/>
|
||||||
|
<el-table-column label="关系类型" align="center" prop="relationType" width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.ccdi_relation_type" :value="scope.row.relationType"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="关系人姓名" align="center" prop="relationName" :show-overflow-tooltip="true"/>
|
||||||
|
<el-table-column label="性别" align="center" prop="gender" width="80">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.ccdi_indiv_gender" :value="scope.row.gender"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="手机号码" align="center" prop="mobilePhone1" :show-overflow-tooltip="true"/>
|
||||||
|
<el-table-column label="状态" align="center" prop="status" width="80">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
|
||||||
|
{{ scope.row.status === 1 ? '有效' : '无效' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="160">
|
||||||
|
<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:staffFmyRelation:query']"
|
||||||
|
>详情</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-edit"
|
||||||
|
@click="handleUpdate(scope.row)"
|
||||||
|
v-hasPermi="['ccdi:staffFmyRelation:edit']"
|
||||||
|
>编辑</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
@click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['ccdi:staffFmyRelation: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="800px" append-to-body>
|
||||||
|
<el-form ref="form" :model="form" :rules="rules" label-width="140px">
|
||||||
|
<el-divider content-position="left">基本信息</el-divider>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="员工身份证号" prop="personId">
|
||||||
|
<el-select
|
||||||
|
v-model="form.personId"
|
||||||
|
filterable
|
||||||
|
remote
|
||||||
|
reserve-keyword
|
||||||
|
placeholder="请输入身份证号搜索员工"
|
||||||
|
:remote-method="searchStaff"
|
||||||
|
:loading="staffLoading"
|
||||||
|
:disabled="!isAdd"
|
||||||
|
@focus="handleSelectFocus"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in staffOptions"
|
||||||
|
:key="item.idCard"
|
||||||
|
:label="item.idCard + ' - ' + item.name"
|
||||||
|
:value="item.idCard"
|
||||||
|
>
|
||||||
|
<span style="float: left">{{ item.idCard }}</span>
|
||||||
|
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.name }}</span>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="关系类型" prop="relationType">
|
||||||
|
<el-select v-model="form.relationType" placeholder="请选择关系类型" style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dict.type.ccdi_relation_type"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="关系人姓名" prop="relationName">
|
||||||
|
<el-input v-model="form.relationName" placeholder="请输入关系人姓名" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="性别" prop="gender">
|
||||||
|
<el-select v-model="form.gender" placeholder="请选择性别" style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dict.type.ccdi_indiv_gender"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="关系人证件类型" prop="relationCertType">
|
||||||
|
<el-select v-model="form.relationCertType" placeholder="请选择证件类型" style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dict.type.ccdi_certificate_type"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="关系人证件号码" prop="relationCertNo">
|
||||||
|
<el-input v-model="form.relationCertNo" placeholder="请输入证件号码" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="出生日期" prop="birthDate">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.birthDate"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择日期"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="手机号码1" prop="mobilePhone1">
|
||||||
|
<el-input v-model="form.mobilePhone1" placeholder="请输入手机号码1" maxlength="20" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="手机号码2" prop="mobilePhone2">
|
||||||
|
<el-input v-model="form.mobilePhone2" placeholder="请输入手机号码2" maxlength="20" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="微信名称1" prop="wechatNo1">
|
||||||
|
<el-input v-model="form.wechatNo1" placeholder="请输入微信名称1" maxlength="50" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="微信名称2" prop="wechatNo2">
|
||||||
|
<el-input v-model="form.wechatNo2" placeholder="请输入微信名称2" maxlength="50" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="微信名称3" prop="wechatNo3">
|
||||||
|
<el-input v-model="form.wechatNo3" placeholder="请输入微信名称3" maxlength="50" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="状态" prop="status" v-if="!isAdd">
|
||||||
|
<el-radio-group v-model="form.status">
|
||||||
|
<el-radio :label="1">有效</el-radio>
|
||||||
|
<el-radio :label="0">无效</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12" v-if="!isAdd">
|
||||||
|
<!-- 占位,保持布局对齐 -->
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="生效日期" prop="effectiveDate">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.effectiveDate"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择日期"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="失效日期" prop="invalidDate">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.invalidDate"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择日期"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item label="详细联系地址" prop="contactAddress">
|
||||||
|
<el-input v-model="form.contactAddress" type="textarea" :rows="2" placeholder="请输入详细联系地址" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="关系详细描述" prop="relationDesc">
|
||||||
|
<el-input v-model="form.relationDesc" type="textarea" :rows="2" placeholder="请输入关系详细描述" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="cancel">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitForm">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 详情对话框 -->
|
||||||
|
<el-dialog title="员工亲属关系详情" :visible.sync="detailOpen" width="800px" append-to-body>
|
||||||
|
<div class="detail-container">
|
||||||
|
<el-divider content-position="left">基本信息</el-divider>
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="员工姓名">{{ relationDetail.personName || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="员工身份证号">{{ relationDetail.personId || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="关系类型">
|
||||||
|
<dict-tag :options="dict.type.ccdi_relation_type" :value="relationDetail.relationType"/>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="关系人姓名">{{ relationDetail.relationName || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="性别">
|
||||||
|
<dict-tag :options="dict.type.ccdi_indiv_gender" :value="relationDetail.gender"/>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="关系人证件类型">{{ relationDetail.relationCertType || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="关系人证件号码" :span="2">{{ relationDetail.relationCertNo || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="出生日期">{{ relationDetail.birthDate || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="手机号码1">{{ relationDetail.mobilePhone1 || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="手机号码2">{{ relationDetail.mobilePhone2 || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="微信名称1">{{ relationDetail.wechatNo1 || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="微信名称2">{{ relationDetail.wechatNo2 || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="微信名称3">{{ relationDetail.wechatNo3 || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="详细联系地址" :span="2">{{ relationDetail.contactAddress || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="关系详细描述" :span="2">{{ relationDetail.relationDesc || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="生效日期">{{ relationDetail.effectiveDate || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="失效日期">{{ relationDetail.invalidDate || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="状态">
|
||||||
|
<el-tag :type="relationDetail.status === 1 ? 'success' : 'danger'">
|
||||||
|
{{ relationDetail.status === 1 ? '有效' : '无效' }}
|
||||||
|
</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="数据来源">{{ relationDetail.dataSource || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="备注" :span="2">{{ relationDetail.remark || '-' }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
|
||||||
|
<el-divider content-position="left">审计信息</el-divider>
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="创建时间">
|
||||||
|
{{ relationDetail.createTime ? parseTime(relationDetail.createTime) : '-' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="创建人">{{ relationDetail.createdBy || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="更新时间">
|
||||||
|
{{ relationDetail.updateTime ? parseTime(relationDetail.updateTime) : '-' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="更新人">{{ relationDetail.updatedBy || '-' }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</div>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="detailOpen = false" icon="el-icon-close">关 闭</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 导入对话框 -->
|
||||||
|
<el-dialog
|
||||||
|
:title="upload.title"
|
||||||
|
:visible.sync="upload.open"
|
||||||
|
width="400px"
|
||||||
|
append-to-body
|
||||||
|
@close="handleImportDialogClose"
|
||||||
|
>
|
||||||
|
<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="importTemplate">下载模板</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="personId" align="center" width="180"/>
|
||||||
|
<el-table-column label="关系类型" prop="relationType" align="center" width="100"/>
|
||||||
|
<el-table-column label="关系人姓名" prop="relationName" align="center" width="120"/>
|
||||||
|
<el-table-column label="失败原因" prop="errorMessage" align="center" min-width="200" :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 {
|
||||||
|
addRelation,
|
||||||
|
delRelation,
|
||||||
|
getImportFailures,
|
||||||
|
getImportStatus,
|
||||||
|
getRelation,
|
||||||
|
listRelation,
|
||||||
|
updateRelation
|
||||||
|
} from "@/api/ccdiStaffFmyRelation";
|
||||||
|
import {listBaseStaff} from "@/api/ccdiBaseStaff";
|
||||||
|
import {getToken} from "@/utils/auth";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "StaffFmyRelation",
|
||||||
|
dicts: ['ccdi_relation_type', 'ccdi_indiv_gender', 'ccdi_certificate_type'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 选中数组
|
||||||
|
ids: [],
|
||||||
|
// 非单个禁用
|
||||||
|
single: true,
|
||||||
|
// 非多个禁用
|
||||||
|
multiple: true,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 员工亲属关系表格数据
|
||||||
|
relationList: [],
|
||||||
|
// 弹出层标题
|
||||||
|
title: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
open: false,
|
||||||
|
// 是否显示详情弹出层
|
||||||
|
detailOpen: false,
|
||||||
|
// 员工亲属关系详情
|
||||||
|
relationDetail: {},
|
||||||
|
// 是否为新增操作
|
||||||
|
isAdd: false,
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
personName: null,
|
||||||
|
relationType: null,
|
||||||
|
relationName: null,
|
||||||
|
status: null
|
||||||
|
},
|
||||||
|
// 表单参数
|
||||||
|
form: {},
|
||||||
|
// 表单校验
|
||||||
|
rules: {
|
||||||
|
personId: [
|
||||||
|
{ required: true, message: "员工身份证号不能为空", trigger: "blur" },
|
||||||
|
{ pattern: /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/, message: "请输入正确的18位身份证号", trigger: "blur" }
|
||||||
|
],
|
||||||
|
relationType: [
|
||||||
|
{ required: true, message: "关系类型不能为空", trigger: "change" }
|
||||||
|
],
|
||||||
|
relationName: [
|
||||||
|
{ required: true, message: "关系人姓名不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
relationCertType: [
|
||||||
|
{ required: true, message: "关系人证件类型不能为空", trigger: "change" }
|
||||||
|
],
|
||||||
|
relationCertNo: [
|
||||||
|
{ required: true, message: "关系人证件号码不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
mobilePhone1: [
|
||||||
|
{ pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号码", trigger: "blur" }
|
||||||
|
],
|
||||||
|
mobilePhone2: [
|
||||||
|
{ pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号码", trigger: "blur" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// 导入参数
|
||||||
|
upload: {
|
||||||
|
// 是否显示弹出层
|
||||||
|
open: false,
|
||||||
|
// 弹出层标题
|
||||||
|
title: "",
|
||||||
|
// 是否禁用上传
|
||||||
|
isUploading: false,
|
||||||
|
// 设置上传的请求头部
|
||||||
|
headers: { Authorization: "Bearer " + getToken() },
|
||||||
|
// 上传的地址
|
||||||
|
url: process.env.VUE_APP_BASE_API + "/ccdi/staffFmyRelation/importData"
|
||||||
|
},
|
||||||
|
// 导入轮询定时器
|
||||||
|
importPollingTimer: null,
|
||||||
|
// 是否显示查看失败记录按钮
|
||||||
|
showFailureButton: false,
|
||||||
|
// 当前导入任务ID
|
||||||
|
currentTaskId: null,
|
||||||
|
// 失败记录对话框
|
||||||
|
failureDialogVisible: false,
|
||||||
|
failureList: [],
|
||||||
|
failureLoading: false,
|
||||||
|
failureTotal: 0,
|
||||||
|
failureQueryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10
|
||||||
|
},
|
||||||
|
// 员工选项
|
||||||
|
staffOptions: [],
|
||||||
|
staffLoading: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
/**
|
||||||
|
* 上次导入信息摘要
|
||||||
|
*/
|
||||||
|
lastImportInfo() {
|
||||||
|
const savedTask = this.getImportTaskFromStorage();
|
||||||
|
if (savedTask && savedTask.totalCount) {
|
||||||
|
return `导入时间: ${this.parseTime(savedTask.saveTime)} | 总数: ${savedTask.totalCount}条 | 成功: ${savedTask.successCount}条 | 失败: ${savedTask.failureCount}条`;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
this.restoreImportState();
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.importPollingTimer) {
|
||||||
|
clearInterval(this.importPollingTimer);
|
||||||
|
this.importPollingTimer = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询员工亲属关系列表 */
|
||||||
|
getList() {
|
||||||
|
this.loading = true;
|
||||||
|
listRelation(this.queryParams).then(response => {
|
||||||
|
this.relationList = response.rows;
|
||||||
|
this.total = response.total;
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 搜索员工 */
|
||||||
|
searchStaff(query) {
|
||||||
|
this.staffLoading = true;
|
||||||
|
// 如果输入为空,查询所有员工;否则根据身份证号模糊查询
|
||||||
|
const params = query !== '' ? { idCard: query, pageNum: 1, pageSize: 10 } : { pageNum: 1, pageSize: 10 };
|
||||||
|
listBaseStaff(params).then(response => {
|
||||||
|
this.staffOptions = response.rows;
|
||||||
|
this.staffLoading = false;
|
||||||
|
}).catch(() => {
|
||||||
|
this.staffLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 下拉框获得焦点时加载员工列表 */
|
||||||
|
handleSelectFocus() {
|
||||||
|
// 如果选项列表为空,自动加载所有员工
|
||||||
|
if (!this.staffOptions || this.staffOptions.length === 0) {
|
||||||
|
this.searchStaff('');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 恢复导入状态
|
||||||
|
*/
|
||||||
|
restoreImportState() {
|
||||||
|
const savedTask = this.getImportTaskFromStorage();
|
||||||
|
if (!savedTask) {
|
||||||
|
this.showFailureButton = false;
|
||||||
|
this.currentTaskId = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (savedTask.hasFailures && savedTask.taskId) {
|
||||||
|
this.currentTaskId = savedTask.taskId;
|
||||||
|
this.showFailureButton = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 获取上次导入的提示信息
|
||||||
|
*/
|
||||||
|
getLastImportTooltip() {
|
||||||
|
const savedTask = this.getImportTaskFromStorage();
|
||||||
|
if (savedTask && savedTask.saveTime) {
|
||||||
|
const date = new Date(savedTask.saveTime);
|
||||||
|
const timeStr = this.parseTime(date, '{y}-{m}-{d} {h}:{i}');
|
||||||
|
return `上次导入: ${timeStr}`;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
// 取消按钮
|
||||||
|
cancel() {
|
||||||
|
this.open = false;
|
||||||
|
this.reset();
|
||||||
|
},
|
||||||
|
// 表单重置
|
||||||
|
reset() {
|
||||||
|
this.form = {
|
||||||
|
id: null,
|
||||||
|
personId: null,
|
||||||
|
relationType: null,
|
||||||
|
relationName: null,
|
||||||
|
gender: null,
|
||||||
|
birthDate: null,
|
||||||
|
relationCertType: null,
|
||||||
|
relationCertNo: null,
|
||||||
|
mobilePhone1: null,
|
||||||
|
mobilePhone2: null,
|
||||||
|
wechatNo1: null,
|
||||||
|
wechatNo2: null,
|
||||||
|
wechatNo3: null,
|
||||||
|
contactAddress: null,
|
||||||
|
relationDesc: null,
|
||||||
|
effectiveDate: null,
|
||||||
|
invalidDate: null,
|
||||||
|
status: 1,
|
||||||
|
remark: null
|
||||||
|
};
|
||||||
|
this.staffOptions = [];
|
||||||
|
this.resetForm("form");
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNum = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.resetForm("queryForm");
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
/** 多选框选中数据 */
|
||||||
|
handleSelectionChange(selection) {
|
||||||
|
this.ids = selection.map(item => item.id);
|
||||||
|
this.single = selection.length !== 1;
|
||||||
|
this.multiple = !selection.length;
|
||||||
|
},
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
handleAdd() {
|
||||||
|
this.reset();
|
||||||
|
this.open = true;
|
||||||
|
this.title = "添加员工亲属关系";
|
||||||
|
this.isAdd = true;
|
||||||
|
},
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
handleUpdate(row) {
|
||||||
|
this.reset();
|
||||||
|
const id = row.id || this.ids[0];
|
||||||
|
getRelation(id).then(response => {
|
||||||
|
this.form = response.data;
|
||||||
|
// 加载员工信息以支持下拉显示
|
||||||
|
if (this.form.personId) {
|
||||||
|
this.searchStaff(this.form.personId);
|
||||||
|
}
|
||||||
|
this.open = true;
|
||||||
|
this.title = "修改员工亲属关系";
|
||||||
|
this.isAdd = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 详情按钮操作 */
|
||||||
|
handleDetail(row) {
|
||||||
|
const id = row.id;
|
||||||
|
getRelation(id).then(response => {
|
||||||
|
this.relationDetail = response.data;
|
||||||
|
this.detailOpen = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
submitForm() {
|
||||||
|
this.$refs["form"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (this.isAdd) {
|
||||||
|
addRelation(this.form).then(response => {
|
||||||
|
this.$modal.msgSuccess("新增成功");
|
||||||
|
this.open = false;
|
||||||
|
this.getList();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
updateRelation(this.form).then(response => {
|
||||||
|
this.$modal.msgSuccess("修改成功");
|
||||||
|
this.open = false;
|
||||||
|
this.getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
handleDelete(row) {
|
||||||
|
const ids = row.id || this.ids;
|
||||||
|
this.$modal.confirm('是否确认删除该数据项?').then(function() {
|
||||||
|
return delRelation(ids);
|
||||||
|
}).then(() => {
|
||||||
|
this.getList();
|
||||||
|
this.$modal.msgSuccess("删除成功");
|
||||||
|
}).catch(() => {});
|
||||||
|
},
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
handleExport() {
|
||||||
|
this.download('ccdi/staffFmyRelation/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `员工亲属关系_${new Date().getTime()}.xlsx`);
|
||||||
|
},
|
||||||
|
/** 导入按钮操作 */
|
||||||
|
handleImport() {
|
||||||
|
this.upload.title = "员工亲属关系数据导入";
|
||||||
|
this.upload.open = true;
|
||||||
|
},
|
||||||
|
/** 下载模板操作 */
|
||||||
|
importTemplate() {
|
||||||
|
this.download('ccdi/staffFmyRelation/importTemplate', {}, `员工亲属关系导入模板_${new Date().getTime()}.xlsx`);
|
||||||
|
},
|
||||||
|
// 文件上传中处理
|
||||||
|
handleFileUploadProgress(event, file, fileList) {
|
||||||
|
this.upload.isUploading = true;
|
||||||
|
},
|
||||||
|
// 文件上传成功处理
|
||||||
|
handleFileSuccess(response, file, fileList) {
|
||||||
|
this.upload.isUploading = false;
|
||||||
|
this.upload.open = false;
|
||||||
|
|
||||||
|
if (response.code === 200) {
|
||||||
|
if (!response.data || !response.data.taskId) {
|
||||||
|
this.$modal.msgError('导入任务创建失败:缺少任务ID');
|
||||||
|
this.upload.isUploading = false;
|
||||||
|
this.upload.open = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const taskId = response.data.taskId;
|
||||||
|
|
||||||
|
if (this.importPollingTimer) {
|
||||||
|
clearInterval(this.importPollingTimer);
|
||||||
|
this.importPollingTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clearImportTaskFromStorage();
|
||||||
|
|
||||||
|
this.saveImportTaskToStorage({
|
||||||
|
taskId: taskId,
|
||||||
|
status: 'PROCESSING',
|
||||||
|
timestamp: Date.now(),
|
||||||
|
hasFailures: false
|
||||||
|
});
|
||||||
|
|
||||||
|
this.showFailureButton = false;
|
||||||
|
this.currentTaskId = taskId;
|
||||||
|
|
||||||
|
this.$notify({
|
||||||
|
title: '导入任务已提交',
|
||||||
|
message: '正在后台处理中,处理完成后将通知您',
|
||||||
|
type: 'info',
|
||||||
|
duration: 3000
|
||||||
|
});
|
||||||
|
|
||||||
|
this.startImportStatusPolling(taskId);
|
||||||
|
} else {
|
||||||
|
this.$modal.msgError(response.msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 开始轮询导入状态 */
|
||||||
|
startImportStatusPolling(taskId) {
|
||||||
|
let pollCount = 0;
|
||||||
|
const maxPolls = 150;
|
||||||
|
|
||||||
|
this.importPollingTimer = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
pollCount++;
|
||||||
|
|
||||||
|
if (pollCount > maxPolls) {
|
||||||
|
clearInterval(this.importPollingTimer);
|
||||||
|
this.$modal.msgWarning('导入任务处理超时,请联系管理员');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await getImportStatus(taskId);
|
||||||
|
|
||||||
|
if (response.data && response.data.status !== 'PROCESSING') {
|
||||||
|
clearInterval(this.importPollingTimer);
|
||||||
|
this.handleImportComplete(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
clearInterval(this.importPollingTimer);
|
||||||
|
this.$modal.msgError('查询导入状态失败: ' + error.message);
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
|
/** 查询失败记录列表 */
|
||||||
|
getFailureList() {
|
||||||
|
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;
|
||||||
|
if (error.response && error.response.status === 404) {
|
||||||
|
this.$modal.msgWarning('导入记录已过期,无法查看失败记录');
|
||||||
|
this.clearImportTaskFromStorage();
|
||||||
|
this.showFailureButton = false;
|
||||||
|
this.currentTaskId = null;
|
||||||
|
this.failureDialogVisible = false;
|
||||||
|
} else {
|
||||||
|
this.$modal.msgError('查询失败记录失败');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 查看导入失败记录 */
|
||||||
|
viewImportFailures() {
|
||||||
|
this.failureDialogVisible = true;
|
||||||
|
this.getFailureList();
|
||||||
|
},
|
||||||
|
/** 处理导入完成 */
|
||||||
|
handleImportComplete(statusResult) {
|
||||||
|
this.saveImportTaskToStorage({
|
||||||
|
taskId: statusResult.taskId,
|
||||||
|
status: statusResult.status,
|
||||||
|
hasFailures: statusResult.failureCount > 0,
|
||||||
|
totalCount: statusResult.totalCount,
|
||||||
|
successCount: statusResult.successCount,
|
||||||
|
failureCount: statusResult.failureCount
|
||||||
|
});
|
||||||
|
|
||||||
|
if (statusResult.status === 'SUCCESS') {
|
||||||
|
this.$notify({
|
||||||
|
title: '导入完成',
|
||||||
|
message: `全部成功!共导入${statusResult.totalCount}条数据`,
|
||||||
|
type: 'success',
|
||||||
|
duration: 5000
|
||||||
|
});
|
||||||
|
this.showFailureButton = false;
|
||||||
|
this.getList();
|
||||||
|
} else if (statusResult.failureCount > 0) {
|
||||||
|
this.$notify({
|
||||||
|
title: '导入完成',
|
||||||
|
message: `成功${statusResult.successCount}条,失败${statusResult.failureCount}条`,
|
||||||
|
type: 'warning',
|
||||||
|
duration: 5000
|
||||||
|
});
|
||||||
|
this.showFailureButton = true;
|
||||||
|
this.currentTaskId = statusResult.taskId;
|
||||||
|
this.getList();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 提交上传文件
|
||||||
|
submitFileForm() {
|
||||||
|
this.$refs.upload.submit();
|
||||||
|
},
|
||||||
|
// 关闭导入对话框
|
||||||
|
handleImportDialogClose() {
|
||||||
|
this.upload.isUploading = false;
|
||||||
|
this.$refs.upload.clearFiles();
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 保存导入任务到localStorage
|
||||||
|
*/
|
||||||
|
saveImportTaskToStorage(taskData) {
|
||||||
|
try {
|
||||||
|
const data = {
|
||||||
|
...taskData,
|
||||||
|
saveTime: Date.now()
|
||||||
|
};
|
||||||
|
localStorage.setItem('staff_fmy_relation_import_last_task', JSON.stringify(data));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存导入任务状态失败:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 从localStorage读取导入任务
|
||||||
|
*/
|
||||||
|
getImportTaskFromStorage() {
|
||||||
|
try {
|
||||||
|
const data = localStorage.getItem('staff_fmy_relation_import_last_task');
|
||||||
|
if (!data) return null;
|
||||||
|
|
||||||
|
const task = JSON.parse(data);
|
||||||
|
if (!task || !task.taskId) {
|
||||||
|
this.clearImportTaskFromStorage();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sevenDays = 7 * 24 * 60 * 60 * 1000;
|
||||||
|
if (Date.now() - task.saveTime > sevenDays) {
|
||||||
|
this.clearImportTaskFromStorage();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return task;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('读取导入任务状态失败:', error);
|
||||||
|
this.clearImportTaskFromStorage();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 清除导入历史记录
|
||||||
|
*/
|
||||||
|
clearImportHistory() {
|
||||||
|
this.$confirm('确认清除上次导入记录?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
this.clearImportTaskFromStorage();
|
||||||
|
this.showFailureButton = false;
|
||||||
|
this.currentTaskId = null;
|
||||||
|
this.failureDialogVisible = false;
|
||||||
|
this.$message.success('已清除');
|
||||||
|
}).catch(() => {});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 清除localStorage中的导入任务
|
||||||
|
*/
|
||||||
|
clearImportTaskFromStorage() {
|
||||||
|
try {
|
||||||
|
localStorage.removeItem('staff_fmy_relation_import_last_task');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('清除导入任务状态失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.detail-container {
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
44
sql/ccdi_staff_fmy_relation.sql
Normal file
44
sql/ccdi_staff_fmy_relation.sql
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
-- 员工亲属关系表
|
||||||
|
-- 创建时间: 2026-02-09
|
||||||
|
-- 说明: 存储员工家庭成员关系信息,仅处理员工家庭关系(is_emp_family=1)
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `ccdi_staff_fmy_relation` (
|
||||||
|
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||||
|
`person_id` VARCHAR(100) NOT NULL COMMENT '员工身份证号',
|
||||||
|
`relation_type` VARCHAR(50) NOT NULL COMMENT '关系类型(配偶、子女、父母、兄弟姐妹等)',
|
||||||
|
`relation_name` VARCHAR(100) NOT NULL COMMENT '关系人姓名',
|
||||||
|
`gender` CHAR(1) DEFAULT NULL COMMENT '性别:M-男,F-女,O-其他',
|
||||||
|
`birth_date` DATE DEFAULT NULL COMMENT '关系人出生日期',
|
||||||
|
`relation_cert_type` VARCHAR(50) NOT NULL COMMENT '关系人证件类型',
|
||||||
|
`relation_cert_no` VARCHAR(50) NOT NULL COMMENT '关系人证件号码',
|
||||||
|
`mobile_phone1` VARCHAR(20) DEFAULT NULL COMMENT '手机号码1',
|
||||||
|
`mobile_phone2` VARCHAR(20) DEFAULT NULL COMMENT '手机号码2',
|
||||||
|
`wechat_no1` VARCHAR(50) DEFAULT NULL COMMENT '微信名称1',
|
||||||
|
`wechat_no2` VARCHAR(50) DEFAULT NULL COMMENT '微信名称2',
|
||||||
|
`wechat_no3` VARCHAR(50) DEFAULT NULL COMMENT '微信名称3',
|
||||||
|
`contact_address` VARCHAR(500) DEFAULT NULL COMMENT '详细联系地址',
|
||||||
|
`relation_desc` VARCHAR(500) DEFAULT NULL COMMENT '关系详细描述',
|
||||||
|
`status` INT(11) NOT NULL DEFAULT 1 COMMENT '状态:0-无效,1-有效',
|
||||||
|
`effective_date` DATETIME DEFAULT NULL COMMENT '关系生效日期',
|
||||||
|
`invalid_date` DATETIME DEFAULT NULL COMMENT '关系失效日期',
|
||||||
|
`remark` TEXT DEFAULT NULL COMMENT '备注信息',
|
||||||
|
`data_source` VARCHAR(50) DEFAULT NULL COMMENT '数据来源:MANUAL-手工录入,SYSTEM-系统同步,IMPORT-批量导入,API-接口获取',
|
||||||
|
`is_emp_family` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否是员工的家庭关系:0-否 1-是',
|
||||||
|
`is_cust_family` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否是信贷客户的家庭关系:0-否 1-是',
|
||||||
|
`created_by` VARCHAR(100) NOT NULL COMMENT '记录创建人',
|
||||||
|
`updated_by` VARCHAR(100) DEFAULT NULL COMMENT '记录更新人',
|
||||||
|
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
|
||||||
|
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录更新时间',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `uk_person_cert` (`person_id`, `relation_cert_no`) COMMENT '员工身份证号+关系人证件号码唯一',
|
||||||
|
KEY `idx_person_id` (`person_id`) COMMENT '员工身份证号索引',
|
||||||
|
KEY `idx_relation_cert_no` (`relation_cert_no`) COMMENT '关系人证件号码索引',
|
||||||
|
KEY `idx_status` (`status`) COMMENT '状态索引',
|
||||||
|
KEY `idx_data_source` (`data_source`) COMMENT '数据来源索引'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='员工家庭关系表';
|
||||||
|
|
||||||
|
-- 测试数据
|
||||||
|
-- INSERT INTO `ccdi_staff_fmy_relation`
|
||||||
|
-- (`person_id`, `relation_type`, `relation_name`, `gender`, `birth_date`, `relation_cert_type`, `relation_cert_no`, `mobile_phone1`, `contact_address`, `status`, `data_source`, `is_emp_family`, `is_cust_family`, `created_by`)
|
||||||
|
-- VALUES
|
||||||
|
-- ('110101199001011234', '配偶', '张三', 'M', '1990-05-15', '身份证', '110101199001015678', '13800138000', '北京市朝阳区', 1, 'MANUAL', 1, 0, 'admin');
|
||||||
45
sql/ccdi_staff_fmy_relation_menu.sql
Normal file
45
sql/ccdi_staff_fmy_relation_menu.sql
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
-- 添加员工亲属关系维护菜单
|
||||||
|
-- 注意: 执行前请确认已存在"信息维护"父菜单
|
||||||
|
-- 如果不存在,请先执行以下语句创建父菜单:
|
||||||
|
-- INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||||||
|
-- VALUES (2000, '信息维护', 0, 4, 'dpc', NULL, '', '', 1, 0, 'M', '0', '0', '', 'example', 'admin', NOW(), '信息维护目录');
|
||||||
|
|
||||||
|
-- 查询信息维护父菜单ID
|
||||||
|
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)
|
||||||
|
VALUES
|
||||||
|
('员工亲属关系维护', @parent_menu_id, 3, 'staffFmyRelation', 'ccdiStaffFmyRelation/index', 1, 0, 'C', '0', '0', 'ccdi:staffFmyRelation:list', 'peoples', 'admin', NOW(), '', NULL, '员工亲属关系信息管理菜单');
|
||||||
|
|
||||||
|
-- 获取刚插入的菜单ID
|
||||||
|
SET @menu_id = LAST_INSERT_ID();
|
||||||
|
|
||||||
|
-- 添加按钮权限
|
||||||
|
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) VALUES
|
||||||
|
('亲属关系查询', @menu_id, 1, '', '', 1, 0, 'F', '0', '0', 'ccdi:staffFmyRelation:query', '#', 'admin', NOW(), ''),
|
||||||
|
('亲属关系新增', @menu_id, 2, '', '', 1, 0, 'F', '0', '0', 'ccdi:staffFmyRelation:add', '#', 'admin', NOW(), ''),
|
||||||
|
('亲属关系修改', @menu_id, 3, '', '', 1, 0, 'F', '0', '0', 'ccdi:staffFmyRelation:edit', '#', 'admin', NOW(), ''),
|
||||||
|
('亲属关系删除', @menu_id, 4, '', '', 1, 0, 'F', '0', '0', 'ccdi:staffFmyRelation:remove', '#', 'admin', NOW(), ''),
|
||||||
|
('亲属关系导出', @menu_id, 5, '', '', 1, 0, 'F', '0', '0', 'ccdi:staffFmyRelation:export', '#', 'admin', NOW(), ''),
|
||||||
|
('亲属关系导入', @menu_id, 6, '', '', 1, 0, 'F', '0', '0', 'ccdi:staffFmyRelation:import', '#', 'admin', NOW(), '');
|
||||||
|
|
||||||
|
-- 查询结果验证
|
||||||
|
SELECT
|
||||||
|
m.menu_id AS '菜单ID',
|
||||||
|
m.menu_name AS '菜单名称',
|
||||||
|
m.parent_id AS '父菜单ID',
|
||||||
|
p.menu_name AS '父菜单名称',
|
||||||
|
m.order_num AS '显示顺序',
|
||||||
|
m.path AS '路由地址',
|
||||||
|
m.component AS '组件路径',
|
||||||
|
m.menu_type AS '菜单类型',
|
||||||
|
m.perms AS '权限标识',
|
||||||
|
m.icon AS '菜单图标',
|
||||||
|
m.visible AS '显示状态',
|
||||||
|
m.status AS '菜单状态',
|
||||||
|
m.create_time AS '创建时间'
|
||||||
|
FROM sys_menu m
|
||||||
|
LEFT JOIN sys_menu p ON m.parent_id = p.menu_id
|
||||||
|
WHERE m.menu_name = '员工亲属关系维护' OR m.parent_id = @menu_id
|
||||||
|
ORDER BY m.parent_id, m.order_num;
|
||||||
4
test_result.json
Normal file
4
test_result.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"msg": "\r\n### Error querying database. Cause: java.sql.SQLSyntaxErrorException: Unknown column 'r.contact_phone' in 'field list'\r\n### The error may exist in file [D:\\ccdi\\ccdi\\ruoyi-ccdi\\target\\classes\\mapper\\ccdi\\CcdiStaffFmyRelationMapper.xml]\r\n### The error may involve defaultParameterMap\r\n### The error occurred while setting parameters\r\n### SQL: SELECT r.id, r.person_id, s.name as person_name, r.relation_type, r.relation_name, r.gender, r.relation_cert_type, r.relation_cert_no, r.contact_phone, r.address, r.occupation, r.work_unit, r.effective_date, r.expiry_date, r.status, r.remark, r.data_source, r.is_emp_family, r.is_cust_family, r.created_by, r.create_time, r.updated_by, r.update_time FROM ccdi_staff_fmy_relation r LEFT JOIN ccdi_base_staff s ON r.person_id = s.person_id WHERE r.is_emp_family = 1 ORDER BY r.create_time DESC LIMIT ?\r\n### Cause: java.sql.SQLSyntaxErrorException: Unknown column 'r.contact_phone' in 'field list'\n; bad SQL grammar []",
|
||||||
|
"code": 500
|
||||||
|
}
|
||||||
264
test_staff_fmy_relation_dropdown.py
Normal file
264
test_staff_fmy_relation_dropdown.py
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
"""
|
||||||
|
员工亲属关系功能测试脚本
|
||||||
|
测试员工身份证号字段改造后的功能
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
BASE_URL = "http://localhost:8080"
|
||||||
|
|
||||||
|
# 登录获取 token
|
||||||
|
def login():
|
||||||
|
url = f"{BASE_URL}/login/test"
|
||||||
|
data = {
|
||||||
|
"username": "admin",
|
||||||
|
"password": "admin123"
|
||||||
|
}
|
||||||
|
response = requests.post(url, json=data)
|
||||||
|
result = response.json()
|
||||||
|
if result.get("code") == 200:
|
||||||
|
token = result.get("token")
|
||||||
|
print("✓ 登录成功")
|
||||||
|
return token
|
||||||
|
else:
|
||||||
|
print(f"✗ 登录失败: {result.get('msg')}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 获取请求头
|
||||||
|
def get_headers(token):
|
||||||
|
return {
|
||||||
|
"Authorization": f"Bearer {token}",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 测试1: 查询员工列表(用于下拉选择)
|
||||||
|
def test_list_staff():
|
||||||
|
print("\n【测试1】查询员工列表")
|
||||||
|
url = f"{BASE_URL}/ccdi/baseStaff/list"
|
||||||
|
params = {
|
||||||
|
"pageNum": 1,
|
||||||
|
"pageSize": 10
|
||||||
|
}
|
||||||
|
response = requests.get(url, params=params, headers=get_headers(token))
|
||||||
|
result = response.json()
|
||||||
|
if result.get("code") == 200:
|
||||||
|
rows = result.get("rows", [])
|
||||||
|
print(f"✓ 查询成功,共 {len(rows)} 条员工记录")
|
||||||
|
if rows:
|
||||||
|
print(f" 示例: {rows[0].get('name')} - {rows[0].get('idCard')}")
|
||||||
|
return rows[0].get("idCard") # 返回第一个员工的身份证号
|
||||||
|
else:
|
||||||
|
print(" 警告: 暂无员工数据")
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
print(f"✗ 查询失败: {result.get('msg')}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 测试2: 根据身份证号搜索员工
|
||||||
|
def test_search_staff(keyword):
|
||||||
|
print(f"\n【测试2】根据身份证号搜索员工: {keyword}")
|
||||||
|
url = f"{BASE_URL}/ccdi/baseStaff/list"
|
||||||
|
params = {
|
||||||
|
"idCard": keyword,
|
||||||
|
"pageNum": 1,
|
||||||
|
"pageSize": 10
|
||||||
|
}
|
||||||
|
response = requests.get(url, params=params, headers=get_headers(token))
|
||||||
|
result = response.json()
|
||||||
|
if result.get("code") == 200:
|
||||||
|
rows = result.get("rows", [])
|
||||||
|
print(f"✓ 搜索成功,找到 {len(rows)} 条记录")
|
||||||
|
for row in rows[:3]: # 只显示前3条
|
||||||
|
print(f" - {row.get('name')} - {row.get('idCard')}")
|
||||||
|
return rows
|
||||||
|
else:
|
||||||
|
print(f"✗ 搜索失败: {result.get('msg')}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
# 测试3: 查询已有亲属关系(避免重复插入)
|
||||||
|
def test_get_existing_relation(person_id):
|
||||||
|
print(f"\n【测试3】查询已有员工亲属关系")
|
||||||
|
url = f"{BASE_URL}/ccdi/staffFmyRelation/list"
|
||||||
|
params = {
|
||||||
|
"personId": person_id,
|
||||||
|
"pageNum": 1,
|
||||||
|
"pageSize": 1
|
||||||
|
}
|
||||||
|
response = requests.get(url, params=params, headers=get_headers(token))
|
||||||
|
result = response.json()
|
||||||
|
if result.get("code") == 200:
|
||||||
|
rows = result.get("rows", [])
|
||||||
|
if rows:
|
||||||
|
relation_id = rows[0].get("id")
|
||||||
|
print(f"✓ 找到已有记录, ID: {relation_id}")
|
||||||
|
return relation_id
|
||||||
|
else:
|
||||||
|
print(" 未找到已有记录,准备新增测试数据")
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
print(f"✗ 查询失败: {result.get('msg')}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 测试4: 新增员工亲属关系(如果没有现有数据)
|
||||||
|
def test_add_relation(person_id):
|
||||||
|
print(f"\n【测试4】新增员工亲属关系")
|
||||||
|
url = f"{BASE_URL}/ccdi/staffFmyRelation"
|
||||||
|
import random
|
||||||
|
random_suffix = random.randint(10000, 99999)
|
||||||
|
data = {
|
||||||
|
"personId": person_id,
|
||||||
|
"relationType": "01", # 配偶
|
||||||
|
"relationName": "测试亲属",
|
||||||
|
"gender": "M",
|
||||||
|
"relationCertType": "01", # 身份证
|
||||||
|
"relationCertNo": f"11010119900101{random_suffix}", # 随机生成避免重复
|
||||||
|
"status": 1
|
||||||
|
}
|
||||||
|
response = requests.post(url, json=data, headers=get_headers(token))
|
||||||
|
result = response.json()
|
||||||
|
if result.get("code") == 200:
|
||||||
|
# 若依框架新增接口返回的是 "操作成功" 消息,没有返回ID
|
||||||
|
# 需要通过查询列表来获取新增的记录
|
||||||
|
print(f"✓ 新增成功")
|
||||||
|
# 查询列表获取最新记录的ID
|
||||||
|
list_url = f"{BASE_URL}/ccdi/staffFmyRelation/list"
|
||||||
|
list_params = {
|
||||||
|
"personId": person_id,
|
||||||
|
"pageNum": 1,
|
||||||
|
"pageSize": 1
|
||||||
|
}
|
||||||
|
list_response = requests.get(list_url, params=list_params, headers=get_headers(token))
|
||||||
|
list_result = list_response.json()
|
||||||
|
if list_result.get("rows"):
|
||||||
|
relation_id = list_result.get("rows")[0].get("id")
|
||||||
|
print(f" 获取到记录ID: {relation_id}")
|
||||||
|
return relation_id
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
print(f"✗ 新增失败: {result.get('msg')}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 测试5: 查询员工亲属关系列表
|
||||||
|
def test_list_relations(person_id):
|
||||||
|
print(f"\n【测试5】查询员工亲属关系列表")
|
||||||
|
url = f"{BASE_URL}/ccdi/staffFmyRelation/list"
|
||||||
|
params = {
|
||||||
|
"personId": person_id,
|
||||||
|
"pageNum": 1,
|
||||||
|
"pageSize": 10
|
||||||
|
}
|
||||||
|
response = requests.get(url, params=params, headers=get_headers(token))
|
||||||
|
result = response.json()
|
||||||
|
if result.get("code") == 200:
|
||||||
|
rows = result.get("rows", [])
|
||||||
|
total = result.get("total", 0)
|
||||||
|
print(f"✓ 查询成功,共 {total} 条记录")
|
||||||
|
for row in rows:
|
||||||
|
print(f" - {row.get('personName')}({row.get('personId')}) 的{row.get('relationType')} - {row.get('relationName')}")
|
||||||
|
return rows
|
||||||
|
else:
|
||||||
|
print(f"✗ 查询失败: {result.get('msg')}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
# 测试6: 查询亲属关系详情
|
||||||
|
def test_get_relation_detail(relation_id):
|
||||||
|
print(f"\n【测试6】查询亲属关系详情: ID={relation_id}")
|
||||||
|
url = f"{BASE_URL}/ccdi/staffFmyRelation/{relation_id}"
|
||||||
|
response = requests.get(url, headers=get_headers(token))
|
||||||
|
result = response.json()
|
||||||
|
if result.get("code") == 200:
|
||||||
|
data = result.get("data")
|
||||||
|
print(f"✓ 查询成功")
|
||||||
|
print(f" 员工: {data.get('personName')}({data.get('personId')})")
|
||||||
|
print(f" 关系: {data.get('relationType')} - {data.get('relationName')}")
|
||||||
|
print(f" 状态: {'有效' if data.get('status') == 1 else '无效'}")
|
||||||
|
return data
|
||||||
|
else:
|
||||||
|
print(f"✗ 查询失败: {result.get('msg')}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 测试7: 编辑员工亲属关系(只修改非身份证号字段)
|
||||||
|
def test_update_relation(relation_id):
|
||||||
|
print(f"\n【测试7】编辑员工亲属关系: ID={relation_id}")
|
||||||
|
url = f"{BASE_URL}/ccdi/staffFmyRelation"
|
||||||
|
data = {
|
||||||
|
"id": relation_id,
|
||||||
|
"relationName": "测试亲属(已修改)",
|
||||||
|
"mobilePhone1": "13800138000",
|
||||||
|
"status": 1
|
||||||
|
}
|
||||||
|
response = requests.put(url, json=data, headers=get_headers(token))
|
||||||
|
result = response.json()
|
||||||
|
if result.get("code") == 200:
|
||||||
|
print(f"✓ 修改成功")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"✗ 修改失败: {result.get('msg')}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 测试8: 删除员工亲属关系
|
||||||
|
def test_delete_relation(relation_id):
|
||||||
|
print(f"\n【测试8】删除员工亲属关系: ID={relation_id}")
|
||||||
|
url = f"{BASE_URL}/ccdi/staffFmyRelation/{relation_id}"
|
||||||
|
response = requests.delete(url, headers=get_headers(token))
|
||||||
|
result = response.json()
|
||||||
|
if result.get("code") == 200:
|
||||||
|
print(f"✓ 删除成功")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"✗ 删除失败: {result.get('msg')}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 主测试流程
|
||||||
|
def main():
|
||||||
|
global token
|
||||||
|
print("=" * 60)
|
||||||
|
print("员工亲属关系功能测试")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# 登录
|
||||||
|
token = login()
|
||||||
|
if not token:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 测试1: 查询员工列表
|
||||||
|
person_id = test_list_staff()
|
||||||
|
if not person_id:
|
||||||
|
print("\n提示: 请先在系统中添加员工数据")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 测试2: 搜索员工
|
||||||
|
test_search_staff(person_id[:6]) # 使用身份证号前6位搜索
|
||||||
|
|
||||||
|
# 测试3: 查询已有亲属关系
|
||||||
|
relation_id = test_get_existing_relation(person_id)
|
||||||
|
|
||||||
|
# 如果没有已有记录,则新增
|
||||||
|
if not relation_id:
|
||||||
|
relation_id = test_add_relation(person_id)
|
||||||
|
if not relation_id:
|
||||||
|
print("\n提示: 无法获取测试记录ID,跳过后续测试")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 测试5: 查询亲属关系列表
|
||||||
|
test_list_relations(person_id)
|
||||||
|
|
||||||
|
# 测试6: 查询详情
|
||||||
|
test_get_relation_detail(relation_id)
|
||||||
|
|
||||||
|
# 测试7: 编辑亲属关系
|
||||||
|
test_update_relation(relation_id)
|
||||||
|
|
||||||
|
# 测试8: 再次查看详情(验证修改)
|
||||||
|
test_get_relation_detail(relation_id)
|
||||||
|
|
||||||
|
# 清理测试数据(仅限新增的数据)
|
||||||
|
print("\n【清理】测试结束(保留现有数据)")
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("测试完成!")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
105
test_staff_fmy_relation_fix.py
Normal file
105
test_staff_fmy_relation_fix.py
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
# 配置
|
||||||
|
BASE_URL = "http://localhost:8080"
|
||||||
|
LOGIN_URL = f"{BASE_URL}/login/test"
|
||||||
|
LIST_URL = f"{BASE_URL}/ccdi/staffFmyRelation/list"
|
||||||
|
|
||||||
|
# 测试账号
|
||||||
|
test_user = {
|
||||||
|
"username": "admin",
|
||||||
|
"password": "admin123"
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_fix():
|
||||||
|
"""测试修复是否成功"""
|
||||||
|
print("=" * 60)
|
||||||
|
print("开始测试员工家庭关系接口修复")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# Step 1: 获取token
|
||||||
|
print("\n[1/2] 正在登录获取token...")
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
login_response = requests.post(LOGIN_URL, json=test_user, headers=headers)
|
||||||
|
|
||||||
|
if login_response.status_code != 200:
|
||||||
|
print(f"❌ 登录失败: {login_response.status_code}")
|
||||||
|
print(login_response.text)
|
||||||
|
return False
|
||||||
|
|
||||||
|
login_data = login_response.json()
|
||||||
|
if login_data.get("code") != 200:
|
||||||
|
print(f"❌ 登录失败: {login_data.get('msg')}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
token = login_data.get("token")
|
||||||
|
print(f"✅ 登录成功,获取到token: {token[:20]}...")
|
||||||
|
|
||||||
|
# Step 2: 调用分页查询接口
|
||||||
|
print("\n[2/2] 正在测试分页查询接口...")
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"Bearer {token}"
|
||||||
|
}
|
||||||
|
|
||||||
|
params = {
|
||||||
|
"pageNum": 1,
|
||||||
|
"pageSize": 10,
|
||||||
|
"isEmpFamily": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
list_response = requests.get(LIST_URL, params=params, headers=headers)
|
||||||
|
|
||||||
|
print(f"\n响应状态码: {list_response.status_code}")
|
||||||
|
|
||||||
|
if list_response.status_code != 200:
|
||||||
|
print(f"❌ 接口调用失败")
|
||||||
|
print(list_response.text)
|
||||||
|
return False
|
||||||
|
|
||||||
|
result = list_response.json()
|
||||||
|
|
||||||
|
# 保存完整响应
|
||||||
|
with open("test_result.json", "w", encoding="utf-8") as f:
|
||||||
|
json.dump(result, f, ensure_ascii=False, indent=2)
|
||||||
|
|
||||||
|
print(f"\n完整响应已保存到 test_result.json")
|
||||||
|
|
||||||
|
if result.get("code") == 200:
|
||||||
|
rows = result.get("rows", [])
|
||||||
|
total = result.get("total", 0)
|
||||||
|
|
||||||
|
print(f"✅ 接口调用成功!")
|
||||||
|
print(f" - 数据总数: {total}")
|
||||||
|
print(f" - 当前页记录数: {len(rows)}")
|
||||||
|
|
||||||
|
if rows:
|
||||||
|
print(f"\n示例数据 (第一条):")
|
||||||
|
first_row = rows[0]
|
||||||
|
for key, value in first_row.items():
|
||||||
|
if key not in ["createTime", "updateTime"]:
|
||||||
|
print(f" {key}: {value}")
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("✅ 修复验证成功!数据库字段映射问题已解决")
|
||||||
|
print("=" * 60)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"❌ 接口返回错误: {result.get('msg')}")
|
||||||
|
print(f"错误详情: {result}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
success = test_fix()
|
||||||
|
exit(0 if success else 1)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 测试过程中发生异常: {str(e)}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
exit(1)
|
||||||
Reference in New Issue
Block a user