新增员工党员字段

This commit is contained in:
wkc
2026-04-17 11:04:52 +08:00
parent 3286795f98
commit 03a4acb63a
23 changed files with 453 additions and 68 deletions

View File

@@ -43,6 +43,10 @@ public class CcdiBaseStaff implements Serializable {
/** 入职时间 */
private Date hireDate;
/** 是否党员0-否 1-是 */
@TableField("is_party_member")
private Integer partyMember;
/** 状态 */
private String status;

View File

@@ -53,6 +53,10 @@ public class CcdiBaseStaffAddDTO implements Serializable {
/** 入职时间 */
private Date hireDate;
/** 是否党员0-否 1-是 */
@NotNull(message = "是否党员不能为空")
private Integer partyMember;
/** 状态 */
@NotBlank(message = "状态不能为空")
private String status;

View File

@@ -52,6 +52,10 @@ public class CcdiBaseStaffEditDTO implements Serializable {
/** 入职时间 */
private Date hireDate;
/** 是否党员0-否 1-是 */
@NotNull(message = "是否党员不能为空")
private Integer partyMember;
/** 状态 */
private String status;

View File

@@ -63,8 +63,15 @@ public class CcdiBaseStaffExcel implements Serializable {
@ColumnWidth(15)
private Date hireDate;
/** 是否党员 */
@ExcelProperty(value = "是否党员", index = 7)
@ColumnWidth(12)
@DictDropdown(dictType = "ccdi_yes_no_flag")
@Required
private Integer partyMember;
/** 状态 */
@ExcelProperty(value = "状态", index = 7)
@ExcelProperty(value = "状态", index = 8)
@ColumnWidth(10)
@DictDropdown(dictType = "ccdi_employee_status")
@Required

View File

@@ -44,6 +44,9 @@ public class CcdiBaseStaffVO implements Serializable {
/** 入职时间 */
private Date hireDate;
/** 是否党员0-否 1-是 */
private Integer partyMember;
/** 状态 */
private String status;

View File

@@ -32,6 +32,9 @@ public class ImportFailureVO {
@Schema(description = "年收入")
private BigDecimal annualIncome;
@Schema(description = "是否党员0-否 1-是")
private Integer partyMember;
@Schema(description = "状态")
private String status;

View File

@@ -320,6 +320,9 @@ public class CcdiBaseStaffImportServiceImpl implements ICcdiBaseStaffImportServi
if (StringUtils.isEmpty(addDTO.getPhone())) {
throw new RuntimeException("电话不能为空");
}
if (addDTO.getPartyMember() == null) {
throw new RuntimeException("是否党员不能为空");
}
if (StringUtils.isEmpty(addDTO.getStatus())) {
throw new RuntimeException("状态不能为空");
}
@@ -357,6 +360,9 @@ public class CcdiBaseStaffImportServiceImpl implements ICcdiBaseStaffImportServi
if (!"0".equals(addDTO.getStatus()) && !"1".equals(addDTO.getStatus())) {
throw new RuntimeException("状态只能填写'在职'或'离职'");
}
if (addDTO.getPartyMember() != 0 && addDTO.getPartyMember() != 1) {
throw new RuntimeException("是否党员只能填写'0'或'1'");
}
validateAnnualIncome(addDTO.getAnnualIncome(), "年收入");
}

View File

@@ -112,7 +112,7 @@ public class CcdiBaseStaffServiceImpl implements ICcdiBaseStaffService {
CcdiBaseStaff staff = baseStaffMapper.selectById(staffId);
CcdiBaseStaffVO vo = convertToVO(staff);
if (staff != null) {
vo.setAssetInfoList(assetInfoService.selectByFamilyId(staff.getIdCard()).stream().map(asset -> {
vo.setAssetInfoList(assetInfoService.selectByFamilyIdAndPersonId(staff.getIdCard(), staff.getIdCard()).stream().map(asset -> {
CcdiAssetInfoVO assetInfoVO = new CcdiAssetInfoVO();
BeanUtils.copyProperties(asset, assetInfoVO);
return assetInfoVO;
@@ -131,6 +131,7 @@ public class CcdiBaseStaffServiceImpl implements ICcdiBaseStaffService {
@Transactional
public int insertBaseStaff(CcdiBaseStaffAddDTO addDTO) {
validateAnnualIncome(addDTO.getAnnualIncome(), "年收入");
validatePartyMember(addDTO.getPartyMember(), "是否党员");
// 检查员工ID唯一性
if (baseStaffMapper.selectById(addDTO.getStaffId()) != null) {
throw new RuntimeException("该员工ID已存在");
@@ -161,6 +162,7 @@ public class CcdiBaseStaffServiceImpl implements ICcdiBaseStaffService {
@Transactional
public int updateBaseStaff(CcdiBaseStaffEditDTO editDTO) {
validateAnnualIncome(editDTO.getAnnualIncome(), "年收入");
validatePartyMember(editDTO.getPartyMember(), "是否党员");
CcdiBaseStaff existing = baseStaffMapper.selectById(editDTO.getStaffId());
if (existing == null) {
throw new RuntimeException("员工不存在");
@@ -291,4 +293,13 @@ public class CcdiBaseStaffServiceImpl implements ICcdiBaseStaffService {
}
}
private void validatePartyMember(Integer partyMember, String fieldLabel) {
if (partyMember == null) {
throw new RuntimeException(fieldLabel + "不能为空");
}
if (partyMember != 0 && partyMember != 1) {
throw new RuntimeException(fieldLabel + "只能填写'0'或'1'");
}
}
}

View File

@@ -14,13 +14,14 @@
<result property="phone" column="phone"/>
<result property="annualIncome" column="annual_income"/>
<result property="hireDate" column="hire_date"/>
<result property="partyMember" column="is_party_member"/>
<result property="status" column="status"/>
<result property="createTime" column="create_time"/>
</resultMap>
<select id="selectBaseStaffPageWithDept" resultMap="CcdiBaseStaffVOResult">
SELECT
e.staff_id, e.name, e.dept_id, e.id_card, e.phone, e.annual_income, e.hire_date, e.status, e.create_time,
e.staff_id, e.name, e.dept_id, e.id_card, e.phone, e.annual_income, e.hire_date, e.is_party_member, e.status, e.create_time,
d.dept_name
FROM ccdi_base_staff e
LEFT JOIN sys_dept d ON e.dept_id = d.dept_id
@@ -47,12 +48,12 @@
<!-- 批量插入或更新员工信息只更新非null字段 -->
<insert id="insertOrUpdateBatch" parameterType="java.util.List">
INSERT INTO ccdi_base_staff
(staff_id, name, dept_id, id_card, phone, annual_income, hire_date, status,
(staff_id, name, dept_id, id_card, phone, annual_income, hire_date, is_party_member, status,
create_time, create_by, update_by, update_time)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.staffId}, #{item.name}, #{item.deptId}, #{item.idCard},
#{item.phone}, #{item.annualIncome}, #{item.hireDate}, #{item.status}, NOW(),
#{item.phone}, #{item.annualIncome}, #{item.hireDate}, #{item.partyMember}, #{item.status}, NOW(),
#{item.createBy}, #{item.updateBy}, NOW())
</foreach>
ON DUPLICATE KEY UPDATE
@@ -61,6 +62,7 @@
phone = COALESCE(VALUES(phone), phone),
annual_income = COALESCE(VALUES(annual_income), annual_income),
hire_date = COALESCE(VALUES(hire_date), hire_date),
is_party_member = COALESCE(VALUES(is_party_member), is_party_member),
status = COALESCE(VALUES(status), status),
update_by = COALESCE(VALUES(update_by), update_by),
update_time = NOW()
@@ -69,12 +71,12 @@
<!-- 批量插入员工信息 -->
<insert id="insertBatch" parameterType="java.util.List">
INSERT INTO ccdi_base_staff
(staff_id, name, dept_id, id_card, phone, annual_income, hire_date, status,
(staff_id, name, dept_id, id_card, phone, annual_income, hire_date, is_party_member, status,
create_time, create_by, update_by, update_time)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.staffId}, #{item.name}, #{item.deptId}, #{item.idCard},
#{item.phone}, #{item.annualIncome}, #{item.hireDate}, #{item.status}, NOW(),
#{item.phone}, #{item.annualIncome}, #{item.hireDate}, #{item.partyMember}, #{item.status}, NOW(),
#{item.createBy}, #{item.updateBy}, NOW())
</foreach>
</insert>

View File

@@ -17,6 +17,8 @@ class CcdiBaseStaffMapperTest {
assertTrue(xml.contains("annual_income"), xml);
assertTrue(xml.contains("#{item.annualIncome}"), xml);
assertTrue(xml.contains("is_party_member"), xml);
assertTrue(xml.contains("#{item.partyMember}"), xml);
}
}
}

View File

@@ -27,6 +27,28 @@ class CcdiBaseStaffImportServiceImplTest {
assertDoesNotThrow(() -> service.validateStaffData(buildDto(new BigDecimal("12345.67")), false, Collections.emptySet(), Collections.emptySet()));
}
@Test
void validateStaffData_shouldAllowPartyMemberValuesZeroAndOne() {
CcdiBaseStaffAddDTO nonPartyMember = buildDto(null);
nonPartyMember.setPartyMember(0);
CcdiBaseStaffAddDTO partyMember = buildDto(null);
partyMember.setPartyMember(1);
assertDoesNotThrow(() -> service.validateStaffData(nonPartyMember, false, Collections.emptySet(), Collections.emptySet()));
assertDoesNotThrow(() -> service.validateStaffData(partyMember, false, Collections.emptySet(), Collections.emptySet()));
}
@Test
void validateStaffData_shouldRejectInvalidPartyMemberValue() {
CcdiBaseStaffAddDTO dto = buildDto(null);
dto.setPartyMember(2);
RuntimeException exception = assertThrows(RuntimeException.class,
() -> service.validateStaffData(dto, false, Set.of(), Set.of()));
assertEquals("是否党员只能填写'0'或'1'", exception.getMessage());
}
@Test
void validateStaffData_shouldRejectNegativeAnnualIncome() {
RuntimeException exception = assertThrows(RuntimeException.class,
@@ -51,6 +73,7 @@ class CcdiBaseStaffImportServiceImplTest {
dto.setIdCard("320101199001010014");
dto.setPhone("13812345678");
dto.setStatus("0");
dto.setPartyMember(1);
dto.setAnnualIncome(annualIncome);
return dto;
}

View File

@@ -55,6 +55,7 @@ class CcdiBaseStaffServiceImplTest {
addDTO.setIdCard("320101199001010011");
addDTO.setPhone("13812345678");
addDTO.setStatus("0");
addDTO.setPartyMember(1);
addDTO.setAnnualIncome(new BigDecimal("12345.67"));
addDTO.setAssetInfoList(List.of(
buildAssetDto("房产"),
@@ -70,6 +71,7 @@ class CcdiBaseStaffServiceImplTest {
assertEquals(1, result);
ArgumentCaptor<CcdiBaseStaff> staffCaptor = ArgumentCaptor.forClass(CcdiBaseStaff.class);
verify(baseStaffMapper).insert(staffCaptor.capture());
assertEquals(1, staffCaptor.getValue().getPartyMember());
assertEquals(new BigDecimal("12345.67"), staffCaptor.getValue().getAnnualIncome());
ArgumentCaptor<List<CcdiAssetInfoDTO>> captor = ArgumentCaptor.forClass(List.class);
verify(assetInfoService).replaceByFamilyId(eq("320101199001010011"), captor.capture());
@@ -92,6 +94,7 @@ class CcdiBaseStaffServiceImplTest {
editDTO.setIdCard("320101199001010011");
editDTO.setPhone("13812345678");
editDTO.setStatus("0");
editDTO.setPartyMember(0);
editDTO.setAnnualIncome(new BigDecimal("45678.90"));
editDTO.setAssetInfoList(List.of(buildAssetDto("车辆")));
@@ -104,6 +107,7 @@ class CcdiBaseStaffServiceImplTest {
assertEquals(1, result);
ArgumentCaptor<CcdiBaseStaff> staffCaptor = ArgumentCaptor.forClass(CcdiBaseStaff.class);
verify(baseStaffMapper).updateById(staffCaptor.capture());
assertEquals(0, staffCaptor.getValue().getPartyMember());
assertEquals(new BigDecimal("45678.90"), staffCaptor.getValue().getAnnualIncome());
verify(assetInfoService, never()).deleteByFamilyId("320101199001010011");
verify(assetInfoService).replaceByFamilyId("320101199001010011", editDTO.getAssetInfoList());
@@ -122,6 +126,7 @@ class CcdiBaseStaffServiceImplTest {
editDTO.setIdCard("320101199001010011");
editDTO.setPhone("13812345678");
editDTO.setStatus("0");
editDTO.setPartyMember(1);
editDTO.setAssetInfoList(List.of(buildAssetDto("车辆")));
when(baseStaffMapper.selectById(1001L)).thenReturn(existing);
@@ -135,17 +140,18 @@ class CcdiBaseStaffServiceImplTest {
}
@Test
void selectBaseStaffById_shouldReturnAssetInfoList() {
void selectBaseStaffById_shouldReturnSelfOwnedAssetInfoList() {
CcdiBaseStaff staff = new CcdiBaseStaff();
staff.setStaffId(1001L);
staff.setName("张三");
staff.setIdCard("320101199001010011");
staff.setStatus("0");
staff.setPartyMember(1);
staff.setAnnualIncome(new BigDecimal("88888.88"));
CcdiAssetInfo assetInfo = new CcdiAssetInfo();
assetInfo.setFamilyId("320101199001010011");
assetInfo.setPersonId("320101199201010022");
assetInfo.setPersonId("320101199001010011");
assetInfo.setAssetMainType("车辆");
assetInfo.setAssetSubType("小汽车");
assetInfo.setAssetName("家庭车辆");
@@ -153,14 +159,16 @@ class CcdiBaseStaffServiceImplTest {
assetInfo.setAssetStatus("正常");
when(baseStaffMapper.selectById(1001L)).thenReturn(staff);
when(assetInfoService.selectByFamilyId("320101199001010011")).thenReturn(List.of(assetInfo));
when(assetInfoService.selectByFamilyIdAndPersonId("320101199001010011", "320101199001010011"))
.thenReturn(List.of(assetInfo));
CcdiBaseStaffVO result = service.selectBaseStaffById(1001L);
assertNotNull(result.getAssetInfoList());
assertEquals(1, result.getPartyMember());
assertEquals(new BigDecimal("88888.88"), result.getAnnualIncome());
assertEquals(1, result.getAssetInfoList().size());
assertEquals("320101199201010022", result.getAssetInfoList().get(0).getPersonId());
assertEquals("320101199001010011", result.getAssetInfoList().get(0).getPersonId());
assertEquals("车辆", result.getAssetInfoList().get(0).getAssetMainType());
}

View File

@@ -2,6 +2,7 @@ package com.ruoyi.info.collection.utils;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.info.collection.domain.excel.CcdiBaseStaffExcel;
import com.ruoyi.info.collection.domain.excel.CcdiAssetInfoExcel;
import com.ruoyi.info.collection.domain.excel.CcdiStaffFmyRelationExcel;
import org.apache.poi.ss.usermodel.CellStyle;
@@ -72,6 +73,31 @@ class EasyExcelUtilTemplateTest {
}
}
@Test
void importTemplateWithDictDropdown_shouldAddPartyMemberDropdownToBaseStaffTemplate() throws Exception {
MockHttpServletResponse response = new MockHttpServletResponse();
try (MockedStatic<DictUtils> mocked = mockStatic(DictUtils.class)) {
mocked.when(() -> DictUtils.getDictCache("ccdi_employee_status"))
.thenReturn(List.of(
buildDictData("在职", "0"),
buildDictData("离职", "1")
));
mocked.when(() -> DictUtils.getDictCache("ccdi_yes_no_flag"))
.thenReturn(List.of(
buildDictData("", "1"),
buildDictData("", "0")
));
EasyExcelUtil.importTemplateWithDictDropdown(response, CcdiBaseStaffExcel.class, "员工信息");
}
try (Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(response.getContentAsByteArray()))) {
Sheet sheet = workbook.getSheetAt(0);
assertTrue(hasValidationOnColumn(sheet, 7), "是否党员列应包含下拉校验");
}
}
private void assertTextColumn(Sheet sheet, int columnIndex) {
CellStyle style = sheet.getColumnStyle(columnIndex);
assertNotNull(style, "文本列应设置默认样式");
@@ -90,9 +116,13 @@ class EasyExcelUtilTemplateTest {
}
private SysDictData buildDictData(String label) {
return buildDictData(label, label);
}
private SysDictData buildDictData(String label, String value) {
SysDictData dictData = new SysDictData();
dictData.setDictLabel(label);
dictData.setDictValue(label);
dictData.setDictValue(value);
return dictData;
}
}