生产模块拆分为前缫/后缫;修复菜单卡顿与重复请求;支持 IIS 单站点部署

1. 生产模块按工序拆分为两个一级菜单
   - 生产-前缫(落丝记录)、生产-后缫(纤度检验、黑板检验)
   - 旧的「生产管理」(/prod) 目录及子菜单由种子自动清理,页面组件与权限标识保持不变
   - 消息中心跳转路径、首页快捷入口路径同步更新

2. 职工管理独立为一级菜单(原挂在「基础数据」目录下),并清理历史子菜单

3. 修复侧边栏菜单展开卡顿(基础数据等子项较多的目录尤其明显)
   - 去掉 Element Plus 的 height 过渡动画(会逐帧重排全部子项)
   - 收起时改用 height:0 + visibility:hidden 而非 display:none,子项提前完成布局
   - 菜单区独立滚动并预留滚动条宽度(scrollbar-gutter),消除展开时的横向抖动
   - 菜单项增加 contain 布局隔离,淡入动画改为容器级

4. 修复页面首次打开重复请求
   - 分页组件挂载时会触发一次 current-change,页码未变化时不再重复加载(18 个页面)
   - 职工管理去掉 onMounted 与默认选中部门的重复加载
   - 工种管理、原料庄口的注册表下拉由按 key 多次请求改为一次全量拉取

5. 后端增加前端静态托管与 SPA 路由回退,支持 IIS 单站点部署(前后端同源)
6. 新增部署脚本 deploy-iis.ps1(首次部署)与 update-iis.ps1(更新发布)
This commit is contained in:
yanpeng200212
2026-10-12 14:09:59 +08:00
parent 2ffb83830c
commit c3e2665257
47 changed files with 59270 additions and 109 deletions
@@ -0,0 +1,324 @@
using F9WebAiTest.Application.Common.Exceptions;
using F9WebAiTest.Application.Dtos.SYS.Employees;
using F9WebAiTest.Application.Interfaces.Repositories.SYS.Employees;
using F9WebAiTest.Application.Interfaces.SnowflakeID;
using F9WebAiTest.Domain.Entities.SYS.Employees;
using F9WebAiTest.Domain.Enums.SYS.Employees;
using F9WebAiTest.Domain.Interfaces.SYS.Employees;
using MediatR;
namespace F9WebAiTest.Application.CQRS.SYS.Employees.Commands;
/// <summary>新增职工(同时写一条"新入职"变更记录)</summary>
public record Employee_CreateCommand(
long DepId, long WorktypeId, string Code, string Name, string Gangwei, string Phone, string IdCard,
DateTime? BirthDate, string Address, string Gender, string Minzu, string HunyinStatus, string Huji,
DateTime? RuzhiDate, string JinjiLianxiren, string JinjiLianxirenPhone, string HetongType,
DateTime? HetongStartDate, DateTime? HetongEndDate, DateTime? TuixiuDate, DateTime? ShebaoDate, string ShebaoDesc,
string BankcardCode, string BiyeYuanxiao, string Zhuanye, string Xueli, Prod_Banci_Enum? Banci, string WorkGroup,
int Sort, string NamePinyin, string Memo) : IRequest<long>;
public class CreateEmployeeCommandHandler(
IEmployeeWriteRepository repository,
IEmployeeReadRepository readRepository,
ISnowflakeIdGenerator snowflakeIdGenerator,
IPublisher eventBus) : IRequestHandler<Employee_CreateCommand, long>
{
public async Task<long> Handle(Employee_CreateCommand command, CancellationToken cancellationToken)
{
if (command.DepId <= 0) throw new F9OperationException("请选择部门");
if (string.IsNullOrWhiteSpace(command.Name)) throw new F9OperationException("请输入姓名");
var entity = new Employee(snowflakeIdGenerator.CreateId(), command.DepId, command.WorktypeId,
Employee_WorkStatus_Enum.在职, command.Code ?? string.Empty, command.Name.Trim(),
command.Gangwei ?? string.Empty, command.Phone ?? string.Empty, command.IdCard ?? string.Empty,
command.BirthDate, command.Address ?? string.Empty, command.Gender ?? string.Empty, command.Minzu ?? string.Empty,
command.HunyinStatus ?? string.Empty, command.Huji ?? string.Empty, command.RuzhiDate, null, null, false,
command.JinjiLianxiren ?? string.Empty, command.JinjiLianxirenPhone ?? string.Empty,
command.HetongType ?? string.Empty, command.HetongStartDate, command.HetongEndDate, command.TuixiuDate,
command.ShebaoDate, command.ShebaoDesc ?? string.Empty, command.BankcardCode ?? string.Empty,
command.BiyeYuanxiao ?? string.Empty, command.Zhuanye ?? string.Empty, command.Xueli ?? string.Empty,
command.Banci, command.WorkGroup ?? string.Empty, command.Sort, command.NamePinyin ?? string.Empty,
command.Memo ?? string.Empty, string.Empty);
var result = await repository.AddAsync(entity);
if (result == false) throw new F9OperationException("职工", "新增");
// 变更记录:新入职
var depName = await readRepository.GetDepNameAsync(entity.DepId);
var worktypeName = await readRepository.GetWorktypeNameAsync(entity.WorktypeId);
await readRepository.AddChangeRecordAsync(new EmployeeChangeRecordDto(0, entity.Id,
entity.RuzhiDate ?? DateTime.Now.Date, Employee_ChangeStatus_Enum.新入职, "",
$"{depName},{worktypeName}", "新入职"));
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
entity.ClearDomainEvents();
return entity.Id;
}
}
/// <summary>修改职工基本信息</summary>
public record Employee_UpdateCommand(
long Id, string Code, string Name, string Gangwei, string Phone, string IdCard, DateTime? BirthDate,
string Address, string Gender, string Minzu, string HunyinStatus, string Huji, DateTime? RuzhiDate,
string JinjiLianxiren, string JinjiLianxirenPhone, string HetongType, DateTime? HetongStartDate,
DateTime? HetongEndDate, DateTime? TuixiuDate, DateTime? ShebaoDate, string ShebaoDesc, string BankcardCode,
string BiyeYuanxiao, string Zhuanye, string Xueli, string NamePinyin, string Memo) : IRequest<bool>;
public class UpdateEmployeeCommandHandler(
IEmployeeWriteRepository repository,
IPublisher eventBus) : IRequestHandler<Employee_UpdateCommand, bool>
{
public async Task<bool> Handle(Employee_UpdateCommand command, CancellationToken cancellationToken)
{
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
?? throw new F9NotFoundException("职工不存在");
if (string.IsNullOrWhiteSpace(command.Name)) throw new F9OperationException("请输入姓名");
entity.Update(command.Code ?? string.Empty, command.Name.Trim(), command.Gangwei ?? string.Empty,
command.Phone ?? string.Empty, command.IdCard ?? string.Empty, command.BirthDate, command.Address ?? string.Empty,
command.Gender ?? string.Empty, command.Minzu ?? string.Empty, command.HunyinStatus ?? string.Empty,
command.Huji ?? string.Empty, command.RuzhiDate, command.JinjiLianxiren ?? string.Empty,
command.JinjiLianxirenPhone ?? string.Empty, command.HetongType ?? string.Empty, command.HetongStartDate,
command.HetongEndDate, command.TuixiuDate, command.ShebaoDate, command.ShebaoDesc ?? string.Empty,
command.BankcardCode ?? string.Empty, command.BiyeYuanxiao ?? string.Empty, command.Zhuanye ?? string.Empty,
command.Xueli ?? string.Empty, command.NamePinyin ?? string.Empty, command.Memo ?? string.Empty);
var result = await repository.UpdateAsync(entity);
if (result == false) throw new F9OperationException("职工", "修改");
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
entity.ClearDomainEvents();
return true;
}
}
/// <summary>删除职工</summary>
public record Employee_DelCommand(long Id) : IRequest<bool>;
public class DelEmployeeCommandHandler(
IEmployeeWriteRepository repository,
IPublisher eventBus) : IRequestHandler<Employee_DelCommand, bool>
{
public async Task<bool> Handle(Employee_DelCommand command, CancellationToken cancellationToken)
{
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
?? throw new F9NotFoundException("职工不存在");
var result = await repository.SoftDeleteAsync(command.Id);
if (result == false) throw new F9OperationException("职工", "删除");
entity.Deleted();
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
entity.ClearDomainEvents();
return true;
}
}
/// <summary>转正(写"转正"变更记录)</summary>
public record Employee_ZhuanzhengCommand(long Id, DateTime ZhuanzhengDate) : IRequest<bool>;
public class ZhuanzhengCommandHandler(
IEmployeeWriteRepository repository,
IEmployeeReadRepository readRepository,
IPublisher eventBus) : IRequestHandler<Employee_ZhuanzhengCommand, bool>
{
public async Task<bool> Handle(Employee_ZhuanzhengCommand command, CancellationToken cancellationToken)
{
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
?? throw new F9NotFoundException("职工不存在");
if (entity.IsZhuanzheng) throw new F9OperationException("该职工已转正");
entity.Zhuanzheng(command.ZhuanzhengDate);
var result = await repository.UpdateAsync(entity);
if (result == false) throw new F9OperationException("转正", "操作");
var depName = await readRepository.GetDepNameAsync(entity.DepId);
var worktypeName = await readRepository.GetWorktypeNameAsync(entity.WorktypeId);
await readRepository.AddChangeRecordAsync(new EmployeeChangeRecordDto(0, entity.Id, command.ZhuanzhengDate,
Employee_ChangeStatus_Enum.转正, "", $"{depName},{worktypeName}", "转正"));
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
entity.ClearDomainEvents();
return true;
}
}
/// <summary>取消转正</summary>
public record Employee_ZhuanzhengCancelCommand(long Id) : IRequest<bool>;
public class ZhuanzhengCancelCommandHandler(
IEmployeeWriteRepository repository,
IPublisher eventBus) : IRequestHandler<Employee_ZhuanzhengCancelCommand, bool>
{
public async Task<bool> Handle(Employee_ZhuanzhengCancelCommand command, CancellationToken cancellationToken)
{
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
?? throw new F9NotFoundException("职工不存在");
entity.ZhuanzhengCancel();
var result = await repository.UpdateAsync(entity);
if (result == false) throw new F9OperationException("取消转正", "操作");
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
entity.ClearDomainEvents();
return true;
}
}
/// <summary>离职(写"离职"变更记录)</summary>
public record Employee_LizhiCommand(long Id, DateTime LizhiDate, string LizhiYuanyin) : IRequest<bool>;
public class LizhiCommandHandler(
IEmployeeWriteRepository repository,
IEmployeeReadRepository readRepository,
IPublisher eventBus) : IRequestHandler<Employee_LizhiCommand, bool>
{
public async Task<bool> Handle(Employee_LizhiCommand command, CancellationToken cancellationToken)
{
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
?? throw new F9NotFoundException("职工不存在");
if (entity.WorkStatus == Employee_WorkStatus_Enum.离职) throw new F9OperationException("该职工已离职");
entity.Lizhi(command.LizhiDate, command.LizhiYuanyin);
var result = await repository.UpdateAsync(entity);
if (result == false) throw new F9OperationException("离职", "操作");
var depName = await readRepository.GetDepNameAsync(entity.DepId);
var worktypeName = await readRepository.GetWorktypeNameAsync(entity.WorktypeId);
await readRepository.AddChangeRecordAsync(new EmployeeChangeRecordDto(0, entity.Id, command.LizhiDate,
Employee_ChangeStatus_Enum.离职, "", $"{depName},{worktypeName}", command.LizhiYuanyin ?? string.Empty));
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
entity.ClearDomainEvents();
return true;
}
}
/// <summary>取消离职</summary>
public record Employee_LizhiCancelCommand(long Id) : IRequest<bool>;
public class LizhiCancelCommandHandler(
IEmployeeWriteRepository repository,
IPublisher eventBus) : IRequestHandler<Employee_LizhiCancelCommand, bool>
{
public async Task<bool> Handle(Employee_LizhiCancelCommand command, CancellationToken cancellationToken)
{
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
?? throw new F9NotFoundException("职工不存在");
entity.LizhiCancel();
var result = await repository.UpdateAsync(entity);
if (result == false) throw new F9OperationException("取消离职", "操作");
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
entity.ClearDomainEvents();
return true;
}
}
/// <summary>调岗(写调岗记录 + 变更记录)</summary>
public record Employee_TiaogangCommand(long Id, long DepId, long WorkTypeId, DateTime Date, string GangweiName,
Prod_Banci_Enum? Sc_Banci) : IRequest<bool>;
public class TiaogangCommandHandler(
IEmployeeWriteRepository repository,
IEmployeeReadRepository readRepository,
IPublisher eventBus) : IRequestHandler<Employee_TiaogangCommand, bool>
{
public async Task<bool> Handle(Employee_TiaogangCommand command, CancellationToken cancellationToken)
{
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
?? throw new F9NotFoundException("职工不存在");
if (command.DepId <= 0) throw new F9OperationException("请选择部门");
if (entity.WorkStatus == Employee_WorkStatus_Enum.离职) throw new F9OperationException("离职人员请使用「重新入职」");
var oldDepId = entity.DepId;
var oldWorktypeId = entity.WorktypeId;
entity.Tiaogang(command.DepId, command.WorkTypeId, command.GangweiName, command.Sc_Banci);
var result = await repository.UpdateAsync(entity);
if (result == false) throw new F9OperationException("调岗", "操作");
await readRepository.AddTiaogangRecordAsync(entity.Id, oldDepId, oldWorktypeId, command.DepId,
command.WorkTypeId, command.Date);
var depName = await readRepository.GetDepNameAsync(command.DepId);
var worktypeName = await readRepository.GetWorktypeNameAsync(command.WorkTypeId);
await readRepository.AddChangeRecordAsync(new EmployeeChangeRecordDto(0, entity.Id, command.Date,
Employee_ChangeStatus_Enum.调岗, "", $"{depName},{worktypeName}", "调动"));
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
entity.ClearDomainEvents();
return true;
}
}
/// <summary>重新入职(离职人员)</summary>
public record Employee_RenewRuzhiCommand(long Id, long DepId, long WorkTypeId, DateTime Date, string GangweiName,
Prod_Banci_Enum? Sc_Banci) : IRequest<bool>;
public class RenewRuzhiCommandHandler(
IEmployeeWriteRepository repository,
IEmployeeReadRepository readRepository,
IPublisher eventBus) : IRequestHandler<Employee_RenewRuzhiCommand, bool>
{
public async Task<bool> Handle(Employee_RenewRuzhiCommand command, CancellationToken cancellationToken)
{
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
?? throw new F9NotFoundException("职工不存在");
if (entity.WorkStatus != Employee_WorkStatus_Enum.离职) throw new F9OperationException("请选择离职人员");
if (command.DepId <= 0) throw new F9OperationException("请选择部门");
var oldDepId = entity.DepId;
var oldWorktypeId = entity.WorktypeId;
entity.RenewRuzhi(command.Date, command.DepId, command.WorkTypeId, command.GangweiName, command.Sc_Banci);
var result = await repository.UpdateAsync(entity);
if (result == false) throw new F9OperationException("重新入职", "操作");
await readRepository.AddTiaogangRecordAsync(entity.Id, oldDepId, oldWorktypeId, command.DepId,
command.WorkTypeId, command.Date);
var depName = await readRepository.GetDepNameAsync(command.DepId);
var worktypeName = await readRepository.GetWorktypeNameAsync(command.WorkTypeId);
await readRepository.AddChangeRecordAsync(new EmployeeChangeRecordDto(0, entity.Id, command.Date,
Employee_ChangeStatus_Enum.再入职, "", $"{depName},{worktypeName}", "再入职"));
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
entity.ClearDomainEvents();
return true;
}
}
/// <summary>修改生产信息(工作组 / 顺序号)</summary>
public record Employee_UpdateScCommand(long Id, string Sc_WorkGroup, int Sc_Sort) : IRequest<bool>;
public class UpdateScCommandHandler(
IEmployeeWriteRepository repository,
IPublisher eventBus) : IRequestHandler<Employee_UpdateScCommand, bool>
{
public async Task<bool> Handle(Employee_UpdateScCommand command, CancellationToken cancellationToken)
{
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
?? throw new F9NotFoundException("职工不存在");
entity.UpdateSc(command.Sc_WorkGroup, command.Sc_Sort);
var result = await repository.UpdateAsync(entity);
if (result == false) throw new F9OperationException("生产信息", "修改");
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
entity.ClearDomainEvents();
return true;
}
}
@@ -0,0 +1,50 @@
using F9WebAiTest.Application.Common;
using F9WebAiTest.Application.Dtos.SYS.Employees;
using F9WebAiTest.Application.Interfaces.Repositories.SYS.Employees;
using F9WebAiTest.Domain.Enums.SYS.Employees;
using MediatR;
namespace F9WebAiTest.Application.CQRS.SYS.Employees.Queries;
/// <summary>职工分页查询(部门含子部门 + 工种 + 在职状态 + 班次 + 关键字)</summary>
public record GetEmployeePagedQuery(long DepId = 0, long WorktypeId = 0, Employee_WorkStatus_Enum? WorkStatus = null,
Prod_Banci_Enum? Banci = null, string Like = "", int PageIndex = 1, int PageSize = 20)
: IRequest<PageResult<EmployeeReadDto_View>>;
public class GetEmployeePagedQueryHandler(IEmployeeReadRepository readRepository)
: IRequestHandler<GetEmployeePagedQuery, PageResult<EmployeeReadDto_View>>
{
public async Task<PageResult<EmployeeReadDto_View>> Handle(GetEmployeePagedQuery query, CancellationToken ct)
=> await readRepository.GetPagedAsync(query.DepId, query.WorktypeId, query.WorkStatus, query.Banci,
query.Like, query.PageIndex, query.PageSize);
}
/// <summary>按 Id 查询职工(编辑回显)</summary>
public record GetEmployeeByIdQuery(long Id) : IRequest<EmployeeReadDto_Edit>;
public class GetEmployeeByIdQueryHandler(IEmployeeReadRepository readRepository)
: IRequestHandler<GetEmployeeByIdQuery, EmployeeReadDto_Edit>
{
public async Task<EmployeeReadDto_Edit> Handle(GetEmployeeByIdQuery query, CancellationToken ct)
=> await readRepository.GetByIdForEditAsync(query.Id);
}
/// <summary>职工变更记录</summary>
public record GetEmployeeChangeRecordsQuery(long EmployeeId) : IRequest<List<EmployeeChangeRecordDto>>;
public class GetEmployeeChangeRecordsQueryHandler(IEmployeeReadRepository readRepository)
: IRequestHandler<GetEmployeeChangeRecordsQuery, List<EmployeeChangeRecordDto>>
{
public async Task<List<EmployeeChangeRecordDto>> Handle(GetEmployeeChangeRecordsQuery query, CancellationToken ct)
=> await readRepository.GetChangeRecordsAsync(query.EmployeeId);
}
/// <summary>职工调岗记录</summary>
public record GetEmployeeTiaogangRecordsQuery(long EmployeeId) : IRequest<List<EmployeeTiaogangRecordDto>>;
public class GetEmployeeTiaogangRecordsQueryHandler(IEmployeeReadRepository readRepository)
: IRequestHandler<GetEmployeeTiaogangRecordsQuery, List<EmployeeTiaogangRecordDto>>
{
public async Task<List<EmployeeTiaogangRecordDto>> Handle(GetEmployeeTiaogangRecordsQuery query, CancellationToken ct)
=> await readRepository.GetTiaogangRecordsAsync(query.EmployeeId);
}
@@ -0,0 +1,110 @@
using F9WebAiTest.Domain.Enums.SYS.Employees;
namespace F9WebAiTest.Application.Dtos.SYS.Employees;
/// <summary>职工列表读模型</summary>
public record EmployeeReadDto_View(
long Id,
long DepId,
string DepName,
long WorktypeId,
string WorktypeName,
Prod_Banci_Enum? Banci,
string BanciName,
string Gangwei,
Employee_WorkStatus_Enum WorkStatus,
bool IsZhuanzheng,
string Code,
string Name,
string Gender,
int Nianling,
string IdCard,
string Phone,
DateTime? BirthDate,
DateTime? RuzhiDate,
DateTime? ZhuanzhengDate,
DateTime? LizhiDate,
string LizhiYuanyin,
string WorkGroup,
int Sort,
string BankcardCode,
string HetongType,
DateTime? HetongStartDate,
DateTime? HetongEndDate,
DateTime? TuixiuDate,
DateTime? ShebaoDate,
string Minzu,
string HunyinStatus,
string Xueli,
string Huji,
string Address,
string JinjiLianxiren,
string JinjiLianxirenPhone,
string BiyeYuanxiao,
string Zhuanye,
string NamePinyin,
string Memo);
/// <summary>职工编辑读模型</summary>
public record EmployeeReadDto_Edit(
long Id,
long DepId,
long WorktypeId,
Employee_WorkStatus_Enum WorkStatus,
Prod_Banci_Enum? Banci,
string Code,
string Name,
string Gangwei,
string Phone,
string IdCard,
DateTime? BirthDate,
string Address,
string Gender,
string Minzu,
string HunyinStatus,
string Huji,
DateTime? RuzhiDate,
DateTime? LizhiDate,
DateTime? ZhuanzhengDate,
bool IsZhuanzheng,
string JinjiLianxiren,
string JinjiLianxirenPhone,
string HetongType,
DateTime? HetongStartDate,
DateTime? HetongEndDate,
DateTime? TuixiuDate,
DateTime? ShebaoDate,
string ShebaoDesc,
string BankcardCode,
string BiyeYuanxiao,
string Zhuanye,
string Xueli,
string WorkGroup,
int Sort,
string NamePinyin,
string Memo,
string LizhiYuanyin);
/// <summary>职工变更记录读模型</summary>
public record EmployeeChangeRecordDto(
long Id,
long EmployeeId,
DateTime Date,
Employee_ChangeStatus_Enum ChangeStatus,
string ChangeStatusName,
string ChangeShuoming,
string ChangeYuanyin);
/// <summary>职工调岗记录读模型</summary>
public record EmployeeTiaogangRecordDto(
long Id,
long EmployeeId,
long OldDepId,
string OldDepName,
long OldWorktypeId,
string OldWorktypeName,
long NewDepId,
string NewDepName,
long NewWorktypeId,
string NewWorktypeName,
DateTime TiaogangDate);
@@ -8,7 +8,8 @@ public record WorkTypeReadDto_View(
string BizType,
string SccbFenlei,
bool IsActive,
string DepartmentNames);
string DepartmentNames,
List<long> DepartmentIds);
/// <summary>工种编辑读模型</summary>
public record WorkTypeReadDto_Edit(
@@ -0,0 +1,35 @@
using F9WebAiTest.Application.Common;
using F9WebAiTest.Application.Dtos.SYS.Employees;
using F9WebAiTest.Domain.Enums.SYS.Employees;
using F9WebAiTest.Domain.Interfaces;
namespace F9WebAiTest.Application.Interfaces.Repositories.SYS.Employees;
/// <summary>职工读仓储(返回读模型 DTO)</summary>
public interface IEmployeeReadRepository : IDInterface
{
/// <summary>分页查询(部门含子部门;workStatus/banci 为 null 表示全部)</summary>
Task<PageResult<EmployeeReadDto_View>> GetPagedAsync(long depId, long worktypeId,
Employee_WorkStatus_Enum? workStatus, Prod_Banci_Enum? banci, string keyword, int pageIndex, int pageSize);
Task<EmployeeReadDto_Edit> GetByIdForEditAsync(long id);
/// <summary>变更记录(按日期倒序)</summary>
Task<List<EmployeeChangeRecordDto>> GetChangeRecordsAsync(long employeeId);
/// <summary>调岗记录(按日期倒序)</summary>
Task<List<EmployeeTiaogangRecordDto>> GetTiaogangRecordsAsync(long employeeId);
/// <summary>写变更记录</summary>
Task<bool> AddChangeRecordAsync(EmployeeChangeRecordDto record);
/// <summary>写调岗记录</summary>
Task<bool> AddTiaogangRecordAsync(long employeeId, long oldDepId, long oldWorktypeId, long newDepId,
long newWorktypeId, DateTime date);
/// <summary>部门名称(用于变更记录说明)</summary>
Task<string> GetDepNameAsync(long depId);
/// <summary>工种名称(用于变更记录说明)</summary>
Task<string> GetWorktypeNameAsync(long worktypeId);
}