调整员工信息维护列表和个人资料校验
This commit is contained in:
@@ -28,6 +28,14 @@ public interface CcdiBaseStaffMapper extends BaseMapper<CcdiBaseStaff> {
|
|||||||
Page<CcdiBaseStaffVO> selectBaseStaffPageWithDept(@Param("page") Page<CcdiBaseStaffVO> page,
|
Page<CcdiBaseStaffVO> selectBaseStaffPageWithDept(@Param("page") Page<CcdiBaseStaffVO> page,
|
||||||
@Param("query") CcdiBaseStaffQueryDTO queryDTO);
|
@Param("query") CcdiBaseStaffQueryDTO queryDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询员工详情(包含部门名称)
|
||||||
|
*
|
||||||
|
* @param staffId 员工ID
|
||||||
|
* @return 员工详情
|
||||||
|
*/
|
||||||
|
CcdiBaseStaffVO selectBaseStaffByIdWithDept(@Param("staffId") Long staffId);
|
||||||
|
|
||||||
int insertOrUpdateBatch(@Param("list") List<CcdiBaseStaff> list);
|
int insertOrUpdateBatch(@Param("list") List<CcdiBaseStaff> list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -119,10 +119,10 @@ public class CcdiBaseStaffServiceImpl implements ICcdiBaseStaffService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public CcdiBaseStaffVO selectBaseStaffById(Long staffId) {
|
public CcdiBaseStaffVO selectBaseStaffById(Long staffId) {
|
||||||
CcdiBaseStaff staff = baseStaffMapper.selectById(staffId);
|
CcdiBaseStaffVO vo = baseStaffMapper.selectBaseStaffByIdWithDept(staffId);
|
||||||
CcdiBaseStaffVO vo = convertToVO(staff);
|
if (vo != null) {
|
||||||
if (staff != null) {
|
vo.setStatusDesc(EmployeeStatus.getDescByCode(vo.getStatus()));
|
||||||
vo.setAssetInfoList(assetInfoService.selectByFamilyIdAndPersonId(staff.getIdCard(), staff.getIdCard()).stream().map(asset -> {
|
vo.setAssetInfoList(assetInfoService.selectByFamilyIdAndPersonId(vo.getIdCard(), vo.getIdCard()).stream().map(asset -> {
|
||||||
CcdiAssetInfoVO assetInfoVO = new CcdiAssetInfoVO();
|
CcdiAssetInfoVO assetInfoVO = new CcdiAssetInfoVO();
|
||||||
BeanUtils.copyProperties(asset, assetInfoVO);
|
BeanUtils.copyProperties(asset, assetInfoVO);
|
||||||
return assetInfoVO;
|
return assetInfoVO;
|
||||||
|
|||||||
@@ -42,7 +42,16 @@
|
|||||||
AND e.status = #{query.status}
|
AND e.status = #{query.status}
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
ORDER BY e.create_time DESC, e.staff_id DESC
|
ORDER BY e.hire_date DESC, e.staff_id DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectBaseStaffByIdWithDept" resultMap="CcdiBaseStaffVOResult">
|
||||||
|
SELECT
|
||||||
|
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
|
||||||
|
WHERE e.staff_id = #{staffId}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<!-- 批量插入或更新员工信息(只更新非null字段) -->
|
<!-- 批量插入或更新员工信息(只更新非null字段) -->
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# 员工信息维护列表与详情展示调整实施记录
|
||||||
|
|
||||||
|
## 修改时间
|
||||||
|
|
||||||
|
2026-07-15
|
||||||
|
|
||||||
|
## 修改内容
|
||||||
|
|
||||||
|
1. 员工信息维护列表移除首列多选框。
|
||||||
|
2. 列表“创建时间”列调整为“入职时间”,展示 `hireDate`,空值显示 `-`。
|
||||||
|
3. 列表默认排序由创建时间倒序改为入职时间倒序,同一天按柜员号倒序。
|
||||||
|
4. 列表“身份证号”和“所属部门”列增加最小宽度,避免 18 位身份证号和部门名称显示过窄。
|
||||||
|
5. 员工列表首列增加左侧留白,移除多选框后保持表格视觉间距;入职时间列适当收窄,为前部字段释放横向空间。
|
||||||
|
6. 列表“年收入”字段按万元展示,列名调整为“年收入(万元)”,空值显示 `-`,有效数值保留 2 位小数;详情仍按原字段值展示且不显示小数位。
|
||||||
|
7. 员工详情接口改为关联 `sys_dept` 查询部门名称,修复详情“所属部门”为空的问题。
|
||||||
|
|
||||||
|
## 影响范围
|
||||||
|
|
||||||
|
- 前端页面:`ruoyi-ui/src/views/ccdiBaseStaff/index.vue`
|
||||||
|
- 后端 Mapper:`ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiBaseStaffMapper.java`
|
||||||
|
- 后端 SQL:`ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiBaseStaffMapper.xml`
|
||||||
|
- 后端服务:`ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiBaseStaffServiceImpl.java`
|
||||||
|
|
||||||
|
## 验证情况
|
||||||
|
|
||||||
|
- 后端编译验证:`mvn -pl ccdi-info-collection -am compile -DskipTests` 通过。
|
||||||
|
- 后端打包验证:`mvn -pl ruoyi-admin -am package -DskipTests` 通过。
|
||||||
|
- 后端启动验证:Windows PowerShell 环境缺少 `sh`、`lsof`、`pgrep`,未使用 `bin/restart_java_backend.sh`;改用 Windows 原生命令重启真实 `ruoyi-admin.jar`,`http://127.0.0.1:62318/swagger-ui.html` 返回 200。
|
||||||
|
- 前端环境验证:`.nvmrc` 为 Node 14.21.3,但本机该版本切换后当前会话无法找到 `node/npm`;按项目规则改用 Node 22.22.3 + npm 10.9.8。
|
||||||
|
- 前端构建验证:`npm run build:prod` 通过,存在既有资源体积 warning。
|
||||||
|
- 页面验证:打开真实前端 `http://127.0.0.1:8088/maintain/baseStaff`,确认列表无多选框、表头为“入职时间”、身份证号列完整展示、列表按入职时间倒序展示;点击第一条员工详情,确认“所属部门”显示为部门名称。
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# 个人基本信息联系方式校验调整实施记录
|
||||||
|
|
||||||
|
## 修改时间
|
||||||
|
|
||||||
|
2026-07-16
|
||||||
|
|
||||||
|
## 修改内容
|
||||||
|
|
||||||
|
1. 个人基本信息编辑中,手机号码和邮箱取消必填限制。
|
||||||
|
2. 手机号码和邮箱保留可选格式校验:为空时允许保存;填写后仍需符合对应格式。
|
||||||
|
|
||||||
|
## 影响范围
|
||||||
|
|
||||||
|
- 前端个人资料页:`ruoyi-ui/src/views/system/user/profile/userInfo.vue`
|
||||||
|
|
||||||
|
## 验证情况
|
||||||
|
|
||||||
|
- 前端环境验证:使用 Node 22.22.3 + npm 10.9.8。
|
||||||
|
- 前端构建验证:`npm run build:prod` 通过,存在既有资源体积 warning。
|
||||||
|
- 页面验证:打开真实前端 `http://127.0.0.1:8088/user/profile`,清空手机号码和邮箱输入框并触发失焦,未出现必填提示。本次页面验证未点击保存,未修改用户资料。
|
||||||
@@ -112,14 +112,17 @@
|
|||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="baseStaffList" @selection-change="handleSelectionChange">
|
<el-table v-loading="loading" :data="baseStaffList" class="base-staff-table">
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
|
||||||
<el-table-column label="姓名" align="center" prop="name" :show-overflow-tooltip="true"/>
|
<el-table-column label="姓名" align="center" prop="name" :show-overflow-tooltip="true"/>
|
||||||
<el-table-column label="柜员号" align="center" prop="staffId" :show-overflow-tooltip="true"/>
|
<el-table-column label="柜员号" align="center" prop="staffId" :show-overflow-tooltip="true"/>
|
||||||
<el-table-column label="身份证号" align="center" prop="idCard" :show-overflow-tooltip="true"/>
|
<el-table-column label="身份证号" align="center" prop="idCard" min-width="190" :show-overflow-tooltip="true"/>
|
||||||
<el-table-column label="所属部门" align="center" prop="deptName" :show-overflow-tooltip="true"/>
|
<el-table-column label="所属部门" align="center" prop="deptName" min-width="180" :show-overflow-tooltip="true"/>
|
||||||
<el-table-column label="电话" align="center" prop="phone" width="120"/>
|
<el-table-column label="电话" align="center" prop="phone" width="120"/>
|
||||||
<el-table-column label="年收入" align="center" prop="annualIncome" width="140"/>
|
<el-table-column label="年收入(万元)" align="center" prop="annualIncome" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ formatAnnualIncomeWan(scope.row.annualIncome) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="是否党员" align="center" prop="partyMember" width="100">
|
<el-table-column label="是否党员" align="center" prop="partyMember" width="100">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ formatPartyMember(scope.row.partyMember) }}</span>
|
<span>{{ formatPartyMember(scope.row.partyMember) }}</span>
|
||||||
@@ -131,9 +134,9 @@
|
|||||||
<el-tag v-else type="danger">离职</el-tag>
|
<el-tag v-else type="danger">离职</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
<el-table-column label="入职时间" align="center" prop="hireDate" width="140">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
<span>{{ scope.row.hireDate ? parseTime(scope.row.hireDate, '{y}-{m}-{d}') : '-' }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||||
@@ -340,7 +343,7 @@
|
|||||||
<el-descriptions-item label="身份证号">{{ employeeDetail.idCard || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="身份证号">{{ employeeDetail.idCard || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="电话">{{ employeeDetail.phone || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="电话">{{ employeeDetail.phone || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="年收入">
|
<el-descriptions-item label="年收入">
|
||||||
{{ employeeDetail.annualIncome !== null && employeeDetail.annualIncome !== undefined && employeeDetail.annualIncome !== '' ? employeeDetail.annualIncome : '-' }}
|
{{ formatAnnualIncome(employeeDetail.annualIncome) }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="入职时间">
|
<el-descriptions-item label="入职时间">
|
||||||
{{ employeeDetail.hireDate ? parseTime(employeeDetail.hireDate, '{y}-{m}-{d}') : '-' }}
|
{{ employeeDetail.hireDate ? parseTime(employeeDetail.hireDate, '{y}-{m}-{d}') : '-' }}
|
||||||
@@ -967,6 +970,26 @@ export default {
|
|||||||
maximumFractionDigits: 2
|
maximumFractionDigits: 2
|
||||||
})} 万元`;
|
})} 万元`;
|
||||||
},
|
},
|
||||||
|
formatAnnualIncome(value) {
|
||||||
|
if (value === null || value === undefined || value === "") {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
const amount = Number(value);
|
||||||
|
if (!Number.isFinite(amount)) {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
return amount.toFixed(0);
|
||||||
|
},
|
||||||
|
formatAnnualIncomeWan(value) {
|
||||||
|
if (value === null || value === undefined || value === "") {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
const amount = Number(value);
|
||||||
|
if (!Number.isFinite(amount)) {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
return (amount / 10000).toFixed(2);
|
||||||
|
},
|
||||||
normalizeAnnualIncome(value) {
|
normalizeAnnualIncome(value) {
|
||||||
if (value === null || value === undefined) {
|
if (value === null || value === undefined) {
|
||||||
return null;
|
return null;
|
||||||
@@ -1511,6 +1534,11 @@ export default {
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.base-staff-table ::v-deep .el-table__header-wrapper th:first-child .cell,
|
||||||
|
.base-staff-table ::v-deep .el-table__body-wrapper td:first-child .cell {
|
||||||
|
padding-left: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
/* 详情弹窗样式 */
|
/* 详情弹窗样式 */
|
||||||
.employee-detail-dialog .detail-container {
|
.employee-detail-dialog .detail-container {
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
|
|||||||
@@ -25,6 +25,32 @@
|
|||||||
<script>
|
<script>
|
||||||
import { updateUserProfile } from "@/api/system/user"
|
import { updateUserProfile } from "@/api/system/user"
|
||||||
|
|
||||||
|
const validateOptionalEmail = (rule, value, callback) => {
|
||||||
|
if (!value) {
|
||||||
|
callback()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const emailPattern = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/
|
||||||
|
if (!emailPattern.test(value)) {
|
||||||
|
callback(new Error("请输入正确的邮箱地址"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
|
||||||
|
const validateOptionalPhone = (rule, value, callback) => {
|
||||||
|
if (!value) {
|
||||||
|
callback()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const phonePattern = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/
|
||||||
|
if (!phonePattern.test(value)) {
|
||||||
|
callback(new Error("请输入正确的手机号码"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
user: {
|
user: {
|
||||||
@@ -40,20 +66,10 @@ export default {
|
|||||||
{ required: true, message: "用户昵称不能为空", trigger: "blur" }
|
{ required: true, message: "用户昵称不能为空", trigger: "blur" }
|
||||||
],
|
],
|
||||||
email: [
|
email: [
|
||||||
{ required: true, message: "邮箱地址不能为空", trigger: "blur" },
|
{ validator: validateOptionalEmail, trigger: ["blur", "change"] }
|
||||||
{
|
|
||||||
type: "email",
|
|
||||||
message: "请输入正确的邮箱地址",
|
|
||||||
trigger: ["blur", "change"]
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
phonenumber: [
|
phonenumber: [
|
||||||
{ required: true, message: "手机号码不能为空", trigger: "blur" },
|
{ validator: validateOptionalPhone, trigger: "blur" }
|
||||||
{
|
|
||||||
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
|
||||||
message: "请输入正确的手机号码",
|
|
||||||
trigger: "blur"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user