生产模块拆分为前缫/后缫;修复菜单卡顿与重复请求;支持 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:
@@ -0,0 +1,275 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
using F9WebAiTest.Domain.Enums.SYS.Employees;
|
||||
using F9WebAiTest.Domain.Events.SYS.Employees;
|
||||
|
||||
namespace F9WebAiTest.Domain.Entities.SYS.Employees;
|
||||
|
||||
/// <summary>
|
||||
/// 职工档案:部门/工种/岗位 + 基本信息 + 合同社保 + 教育经历 + 生产信息(班次/工作组/顺序号)。
|
||||
/// 转正、离职、调岗、重新入职等通过行为方法变更,并单独记录变更/调岗历史。
|
||||
/// </summary>
|
||||
[Table(Name = "sys_employee")]
|
||||
public class Employee : AggregateRoot
|
||||
{
|
||||
/// <summary>所属部门 Id</summary>
|
||||
[Column(Name = "dep_id")] public long DepId { get; private set; }
|
||||
|
||||
/// <summary>工种 Id</summary>
|
||||
[Column(Name = "worktype_id")] public long WorktypeId { get; private set; }
|
||||
|
||||
/// <summary>在职状态</summary>
|
||||
[Column(Name = "work_status")] public Employee_WorkStatus_Enum WorkStatus { get; private set; }
|
||||
|
||||
/// <summary>工号</summary>
|
||||
[Column(Name = "code")] public string Code { get; private set; }
|
||||
|
||||
/// <summary>姓名</summary>
|
||||
[Column(Name = "name")] public string Name { get; private set; }
|
||||
|
||||
/// <summary>岗位</summary>
|
||||
[Column(Name = "gangwei")] public string Gangwei { get; private set; }
|
||||
|
||||
/// <summary>电话</summary>
|
||||
[Column(Name = "phone")] public string Phone { get; private set; }
|
||||
|
||||
/// <summary>身份证号</summary>
|
||||
[Column(Name = "idcard")] public string IdCard { get; private set; }
|
||||
|
||||
/// <summary>出生日期</summary>
|
||||
[Column(Name = "birth_date")] public DateTime? BirthDate { get; private set; }
|
||||
|
||||
/// <summary>住址</summary>
|
||||
[Column(Name = "address")] public string Address { get; private set; }
|
||||
|
||||
/// <summary>性别</summary>
|
||||
[Column(Name = "gender")] public string Gender { get; private set; }
|
||||
|
||||
/// <summary>民族</summary>
|
||||
[Column(Name = "minzu")] public string Minzu { get; private set; }
|
||||
|
||||
/// <summary>婚姻状态</summary>
|
||||
[Column(Name = "hunyin_status")] public string HunyinStatus { get; private set; }
|
||||
|
||||
/// <summary>户籍</summary>
|
||||
[Column(Name = "huji")] public string Huji { get; private set; }
|
||||
|
||||
/// <summary>入职日期</summary>
|
||||
[Column(Name = "ruzhi_date")] public DateTime? RuzhiDate { get; private set; }
|
||||
|
||||
/// <summary>离职日期</summary>
|
||||
[Column(Name = "lizhi_date")] public DateTime? LizhiDate { get; private set; }
|
||||
|
||||
/// <summary>转正日期</summary>
|
||||
[Column(Name = "zhuanzheng_date")] public DateTime? ZhuanzhengDate { get; private set; }
|
||||
|
||||
/// <summary>是否已转正</summary>
|
||||
[Column(Name = "is_zhuanzheng")] public bool IsZhuanzheng { get; private set; }
|
||||
|
||||
/// <summary>紧急联系人</summary>
|
||||
[Column(Name = "jinji_lianxiren")] public string JinjiLianxiren { get; private set; }
|
||||
|
||||
/// <summary>紧急联系人电话</summary>
|
||||
[Column(Name = "jinji_lianxiren_phone")] public string JinjiLianxirenPhone { get; private set; }
|
||||
|
||||
/// <summary>合同类型</summary>
|
||||
[Column(Name = "hetong_type")] public string HetongType { get; private set; }
|
||||
|
||||
/// <summary>劳动合同开始日期</summary>
|
||||
[Column(Name = "hetong_start_date")] public DateTime? HetongStartDate { get; private set; }
|
||||
|
||||
/// <summary>劳动合同结束日期</summary>
|
||||
[Column(Name = "hetong_end_date")] public DateTime? HetongEndDate { get; private set; }
|
||||
|
||||
/// <summary>退休日期</summary>
|
||||
[Column(Name = "tuixiu_date")] public DateTime? TuixiuDate { get; private set; }
|
||||
|
||||
/// <summary>社保参保日期</summary>
|
||||
[Column(Name = "shebao_date")] public DateTime? ShebaoDate { get; private set; }
|
||||
|
||||
/// <summary>社保参保情况说明</summary>
|
||||
[Column(Name = "shebao_desc")] public string ShebaoDesc { get; private set; }
|
||||
|
||||
/// <summary>银行卡号</summary>
|
||||
[Column(Name = "bankcard_code")] public string BankcardCode { get; private set; }
|
||||
|
||||
/// <summary>毕业院校</summary>
|
||||
[Column(Name = "biye_yuanxiao")] public string BiyeYuanxiao { get; private set; }
|
||||
|
||||
/// <summary>专业</summary>
|
||||
[Column(Name = "zhuanye")] public string Zhuanye { get; private set; }
|
||||
|
||||
/// <summary>学历</summary>
|
||||
[Column(Name = "xueli")] public string Xueli { get; private set; }
|
||||
|
||||
/// <summary>班次(甲/乙)</summary>
|
||||
[Column(Name = "banci")] public Prod_Banci_Enum? Banci { get; private set; }
|
||||
|
||||
/// <summary>工作组</summary>
|
||||
[Column(Name = "work_group")] public string WorkGroup { get; private set; }
|
||||
|
||||
/// <summary>顺序号</summary>
|
||||
[Column(Name = "sort")] public int Sort { get; private set; }
|
||||
|
||||
/// <summary>姓名拼音(简拼)</summary>
|
||||
[Column(Name = "name_pinyin")] public string NamePinyin { get; private set; }
|
||||
|
||||
/// <summary>备注</summary>
|
||||
[Column(Name = "memo")] public string Memo { get; private set; }
|
||||
|
||||
/// <summary>离职原因</summary>
|
||||
[Column(Name = "lizhi_yuanyin")] public string LizhiYuanyin { get; private set; }
|
||||
|
||||
public Employee() { }
|
||||
|
||||
public Employee(long id, long depId, long worktypeId, Employee_WorkStatus_Enum workStatus, 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, Prod_Banci_Enum? banci, string workGroup,
|
||||
int sort, string namePinyin, string memo, string lizhiYuanyin)
|
||||
{
|
||||
Id = id;
|
||||
DepId = depId;
|
||||
WorktypeId = worktypeId;
|
||||
WorkStatus = workStatus;
|
||||
Code = code;
|
||||
Name = name;
|
||||
Gangwei = gangwei;
|
||||
Phone = phone;
|
||||
IdCard = idCard;
|
||||
BirthDate = birthDate;
|
||||
Address = address;
|
||||
Gender = gender;
|
||||
Minzu = minzu;
|
||||
HunyinStatus = hunyinStatus;
|
||||
Huji = huji;
|
||||
RuzhiDate = ruzhiDate;
|
||||
LizhiDate = lizhiDate;
|
||||
ZhuanzhengDate = zhuanzhengDate;
|
||||
IsZhuanzheng = isZhuanzheng;
|
||||
JinjiLianxiren = jinjiLianxiren;
|
||||
JinjiLianxirenPhone = jinjiLianxirenPhone;
|
||||
HetongType = hetongType;
|
||||
HetongStartDate = hetongStartDate;
|
||||
HetongEndDate = hetongEndDate;
|
||||
TuixiuDate = tuixiuDate;
|
||||
ShebaoDate = shebaoDate;
|
||||
ShebaoDesc = shebaoDesc;
|
||||
BankcardCode = bankcardCode;
|
||||
BiyeYuanxiao = biyeYuanxiao;
|
||||
Zhuanye = zhuanye;
|
||||
Xueli = xueli;
|
||||
Banci = banci;
|
||||
WorkGroup = workGroup;
|
||||
Sort = sort;
|
||||
NamePinyin = namePinyin;
|
||||
Memo = memo;
|
||||
LizhiYuanyin = lizhiYuanyin;
|
||||
AddDomainEvent(new Employee_ChangedDomainEvent(Id));
|
||||
}
|
||||
|
||||
/// <summary>修改基本信息(部门/工种/班次通过调岗变更)</summary>
|
||||
public void Update(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)
|
||||
{
|
||||
Code = code;
|
||||
Name = name;
|
||||
Gangwei = gangwei;
|
||||
Phone = phone;
|
||||
IdCard = idCard;
|
||||
BirthDate = birthDate;
|
||||
Address = address;
|
||||
Gender = gender;
|
||||
Minzu = minzu;
|
||||
HunyinStatus = hunyinStatus;
|
||||
Huji = huji;
|
||||
RuzhiDate = ruzhiDate;
|
||||
JinjiLianxiren = jinjiLianxiren;
|
||||
JinjiLianxirenPhone = jinjiLianxirenPhone;
|
||||
HetongType = hetongType;
|
||||
HetongStartDate = hetongStartDate;
|
||||
HetongEndDate = hetongEndDate;
|
||||
TuixiuDate = tuixiuDate;
|
||||
ShebaoDate = shebaoDate;
|
||||
ShebaoDesc = shebaoDesc;
|
||||
BankcardCode = bankcardCode;
|
||||
BiyeYuanxiao = biyeYuanxiao;
|
||||
Zhuanye = zhuanye;
|
||||
Xueli = xueli;
|
||||
NamePinyin = namePinyin;
|
||||
Memo = memo;
|
||||
AddDomainEvent(new Employee_ChangedDomainEvent(Id));
|
||||
}
|
||||
|
||||
/// <summary>转正</summary>
|
||||
public void Zhuanzheng(DateTime date)
|
||||
{
|
||||
IsZhuanzheng = true;
|
||||
ZhuanzhengDate = date.Date;
|
||||
AddDomainEvent(new Employee_ChangedDomainEvent(Id));
|
||||
}
|
||||
|
||||
/// <summary>取消转正</summary>
|
||||
public void ZhuanzhengCancel()
|
||||
{
|
||||
IsZhuanzheng = false;
|
||||
ZhuanzhengDate = null;
|
||||
AddDomainEvent(new Employee_ChangedDomainEvent(Id));
|
||||
}
|
||||
|
||||
/// <summary>离职</summary>
|
||||
public void Lizhi(DateTime date, string yuanyin)
|
||||
{
|
||||
WorkStatus = Employee_WorkStatus_Enum.离职;
|
||||
LizhiDate = date.Date;
|
||||
LizhiYuanyin = yuanyin ?? string.Empty;
|
||||
AddDomainEvent(new Employee_ChangedDomainEvent(Id));
|
||||
}
|
||||
|
||||
/// <summary>取消离职</summary>
|
||||
public void LizhiCancel()
|
||||
{
|
||||
WorkStatus = Employee_WorkStatus_Enum.在职;
|
||||
LizhiDate = null;
|
||||
LizhiYuanyin = string.Empty;
|
||||
AddDomainEvent(new Employee_ChangedDomainEvent(Id));
|
||||
}
|
||||
|
||||
/// <summary>调岗</summary>
|
||||
public void Tiaogang(long depId, long worktypeId, string gangwei, Prod_Banci_Enum? banci)
|
||||
{
|
||||
DepId = depId;
|
||||
WorktypeId = worktypeId;
|
||||
if (!string.IsNullOrWhiteSpace(gangwei)) Gangwei = gangwei;
|
||||
if (banci.HasValue) Banci = banci;
|
||||
AddDomainEvent(new Employee_ChangedDomainEvent(Id));
|
||||
}
|
||||
|
||||
/// <summary>重新入职(离职人员按新部门/工种入职)</summary>
|
||||
public void RenewRuzhi(DateTime date, long depId, long worktypeId, string gangwei, Prod_Banci_Enum? banci)
|
||||
{
|
||||
WorkStatus = Employee_WorkStatus_Enum.在职;
|
||||
DepId = depId;
|
||||
WorktypeId = worktypeId;
|
||||
RuzhiDate = date.Date;
|
||||
LizhiDate = null;
|
||||
LizhiYuanyin = string.Empty;
|
||||
if (!string.IsNullOrWhiteSpace(gangwei)) Gangwei = gangwei;
|
||||
if (banci.HasValue) Banci = banci;
|
||||
AddDomainEvent(new Employee_ChangedDomainEvent(Id));
|
||||
}
|
||||
|
||||
/// <summary>修改生产信息(工作组 / 顺序号)</summary>
|
||||
public void UpdateSc(string workGroup, int sort)
|
||||
{
|
||||
WorkGroup = workGroup ?? string.Empty;
|
||||
Sort = sort;
|
||||
AddDomainEvent(new Employee_ChangedDomainEvent(Id));
|
||||
}
|
||||
|
||||
public void Deleted() => AddDomainEvent(new Employee_ChangedDomainEvent(Id));
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
using F9WebAiTest.Domain.Enums.SYS.Employees;
|
||||
|
||||
namespace F9WebAiTest.Domain.Entities.SYS.Employees;
|
||||
|
||||
/// <summary>职工变更记录(入职/调岗/转正/离职/再入职)</summary>
|
||||
[Table(Name = "sys_employee_change_record")]
|
||||
public class EmployeeChangeRecord : BusinessEntity
|
||||
{
|
||||
[Column(Name = "employee_id")] public long EmployeeId { get; private set; }
|
||||
|
||||
/// <summary>变更日期</summary>
|
||||
[Column(Name = "date")] public DateTime Date { get; private set; }
|
||||
|
||||
/// <summary>变更类型</summary>
|
||||
[Column(Name = "change_status")] public Employee_ChangeStatus_Enum ChangeStatus { get; private set; }
|
||||
|
||||
/// <summary>变更说明(部门、岗位等)</summary>
|
||||
[Column(Name = "change_shuoming")] public string ChangeShuoming { get; private set; }
|
||||
|
||||
/// <summary>变更原因</summary>
|
||||
[Column(Name = "change_yuanyin")] public string ChangeYuanyin { get; private set; }
|
||||
|
||||
public EmployeeChangeRecord() { }
|
||||
|
||||
public EmployeeChangeRecord(long id, long employeeId, DateTime date, Employee_ChangeStatus_Enum changeStatus,
|
||||
string changeShuoming, string changeYuanyin)
|
||||
{
|
||||
Id = id;
|
||||
EmployeeId = employeeId;
|
||||
Date = date;
|
||||
ChangeStatus = changeStatus;
|
||||
ChangeShuoming = changeShuoming;
|
||||
ChangeYuanyin = changeYuanyin;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
|
||||
namespace F9WebAiTest.Domain.Entities.SYS.Employees;
|
||||
|
||||
/// <summary>职工调岗记录(记录调岗前后的部门与工种)</summary>
|
||||
[Table(Name = "sys_employee_tiaogang_record")]
|
||||
public class EmployeeTiaogangRecord : BusinessEntity
|
||||
{
|
||||
[Column(Name = "employee_id")] public long EmployeeId { get; private set; }
|
||||
|
||||
[Column(Name = "old_depid")] public long OldDepId { get; private set; }
|
||||
|
||||
[Column(Name = "old_worktypeid")] public long OldWorktypeId { get; private set; }
|
||||
|
||||
[Column(Name = "new_depid")] public long NewDepId { get; private set; }
|
||||
|
||||
[Column(Name = "new_worktypeid")] public long NewWorktypeId { get; private set; }
|
||||
|
||||
/// <summary>调岗日期</summary>
|
||||
[Column(Name = "tiaogang_date")] public DateTime TiaogangDate { get; private set; }
|
||||
|
||||
public EmployeeTiaogangRecord() { }
|
||||
|
||||
public EmployeeTiaogangRecord(long id, long employeeId, long oldDepId, long oldWorktypeId, long newDepId,
|
||||
long newWorktypeId, DateTime tiaogangDate)
|
||||
{
|
||||
Id = id;
|
||||
EmployeeId = employeeId;
|
||||
OldDepId = oldDepId;
|
||||
OldWorktypeId = oldWorktypeId;
|
||||
NewDepId = newDepId;
|
||||
NewWorktypeId = newWorktypeId;
|
||||
TiaogangDate = tiaogangDate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace F9WebAiTest.Domain.Enums.SYS.Employees;
|
||||
|
||||
/// <summary>职工在职状态(与 F9 的 Employee_WorkStatus_Enum 一致)</summary>
|
||||
public enum Employee_WorkStatus_Enum
|
||||
{
|
||||
在职 = 0,
|
||||
离职 = 1
|
||||
}
|
||||
|
||||
/// <summary>生产班次(与 F9 的 Prod_Banci_Enum 一致)</summary>
|
||||
public enum Prod_Banci_Enum
|
||||
{
|
||||
甲 = 1,
|
||||
乙 = 2
|
||||
}
|
||||
|
||||
/// <summary>职工变更记录类型(与 F9 的 Employee_ChangeStatus_Enum 一致)</summary>
|
||||
public enum Employee_ChangeStatus_Enum
|
||||
{
|
||||
新入职 = 1,
|
||||
调岗 = 2,
|
||||
离职 = 3,
|
||||
再入职 = 4,
|
||||
转正 = 5
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
using F9WebAiTest.Domain.Entities;
|
||||
|
||||
namespace F9WebAiTest.Domain.Events.SYS.Employees;
|
||||
|
||||
public record Employee_ChangedDomainEvent(long employeeId) : DomainEvent;
|
||||
@@ -0,0 +1,12 @@
|
||||
using F9WebAiTest.Domain.Entities.SYS.Employees;
|
||||
|
||||
namespace F9WebAiTest.Domain.Interfaces.SYS.Employees;
|
||||
|
||||
/// <summary>职工写仓储(聚合根仓储)</summary>
|
||||
public interface IEmployeeWriteRepository : IDInterface
|
||||
{
|
||||
Task<Employee> GetByIdAsync(long id, CancellationToken cancellationToken);
|
||||
Task<bool> AddAsync(Employee entity);
|
||||
Task<bool> UpdateAsync(Employee entity);
|
||||
Task<bool> SoftDeleteAsync(long id);
|
||||
}
|
||||
Reference in New Issue
Block a user