|
@@ -42,17 +42,17 @@ import { Employee, Department, Position, Contract, Certificate, EmployeeStatus }
|
|
<form [formGroup]="employeeForm" (ngSubmit)="onSubmit()" class="employee-form">
|
|
<form [formGroup]="employeeForm" (ngSubmit)="onSubmit()" class="employee-form">
|
|
<div class="form-row">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
- <label>员工姓名 *</label>
|
|
|
|
|
|
+ <label>员工姓名 <span class="required-mark">*</span></label>
|
|
<input matInput formControlName="name" placeholder="请输入姓名">
|
|
<input matInput formControlName="name" placeholder="请输入姓名">
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
- <label>工号 *</label>
|
|
|
|
|
|
+ <label>工号 <span class="required-mark">*</span></label>
|
|
<input matInput formControlName="employeeId" placeholder="请输入工号">
|
|
<input matInput formControlName="employeeId" placeholder="请输入工号">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
- <label>部门 *</label>
|
|
|
|
|
|
+ <label>部门 <span class="required-mark">*</span></label>
|
|
<mat-select formControlName="department">
|
|
<mat-select formControlName="department">
|
|
<mat-option *ngFor="let dept of departments" [value]="dept.name">
|
|
<mat-option *ngFor="let dept of departments" [value]="dept.name">
|
|
{{ dept.name }}
|
|
{{ dept.name }}
|
|
@@ -60,17 +60,17 @@ import { Employee, Department, Position, Contract, Certificate, EmployeeStatus }
|
|
</mat-select>
|
|
</mat-select>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
- <label>岗位 *</label>
|
|
|
|
|
|
+ <label>岗位 <span class="required-mark">*</span></label>
|
|
<input matInput formControlName="position" placeholder="请输入岗位">
|
|
<input matInput formControlName="position" placeholder="请输入岗位">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
- <label>手机号码 *</label>
|
|
|
|
|
|
+ <label>手机号码 <span class="required-mark">*</span></label>
|
|
<input matInput formControlName="phone" placeholder="请输入手机号码">
|
|
<input matInput formControlName="phone" placeholder="请输入手机号码">
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
- <label>邮箱 *</label>
|
|
|
|
|
|
+ <label>邮箱 <span class="required-mark">*</span></label>
|
|
<input matInput formControlName="email" placeholder="请输入邮箱">
|
|
<input matInput formControlName="email" placeholder="请输入邮箱">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@@ -91,13 +91,13 @@ import { Employee, Department, Position, Contract, Certificate, EmployeeStatus }
|
|
</div>
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
- <label>入职日期 *</label>
|
|
|
|
|
|
+ <label>入职日期 <span class="required-mark">*</span></label>
|
|
<input matInput [matDatepicker]="hireDatePicker" formControlName="hireDate">
|
|
<input matInput [matDatepicker]="hireDatePicker" formControlName="hireDate">
|
|
<mat-datepicker-toggle matSuffix [for]="hireDatePicker"></mat-datepicker-toggle>
|
|
<mat-datepicker-toggle matSuffix [for]="hireDatePicker"></mat-datepicker-toggle>
|
|
<mat-datepicker #hireDatePicker></mat-datepicker>
|
|
<mat-datepicker #hireDatePicker></mat-datepicker>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
- <label>状态 *</label>
|
|
|
|
|
|
+ <label>状态 <span class="required-mark">*</span></label>
|
|
<mat-select formControlName="status">
|
|
<mat-select formControlName="status">
|
|
<mat-option value="在职">在职</mat-option>
|
|
<mat-option value="在职">在职</mat-option>
|
|
<mat-option value="试用期">试用期</mat-option>
|
|
<mat-option value="试用期">试用期</mat-option>
|
|
@@ -116,39 +116,84 @@ import { Employee, Department, Position, Contract, Certificate, EmployeeStatus }
|
|
display: flex;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
align-items: center;
|
|
- margin-bottom: 24px;
|
|
|
|
- padding-bottom: 16px;
|
|
|
|
- border-bottom: 1px solid #e5e7eb;
|
|
|
|
|
|
+ margin-bottom: 32px;
|
|
|
|
+ padding-bottom: 20px;
|
|
|
|
+ border-bottom: 2px solid #e5e7eb;
|
|
}
|
|
}
|
|
|
|
+
|
|
.close-btn {
|
|
.close-btn {
|
|
background: none;
|
|
background: none;
|
|
border: none;
|
|
border: none;
|
|
cursor: pointer;
|
|
cursor: pointer;
|
|
- color: #6b7280;
|
|
|
|
- padding: 4px;
|
|
|
|
|
|
+ color: #9ca3af;
|
|
|
|
+ padding: 6px;
|
|
|
|
+ border-radius: 50%;
|
|
|
|
+ transition: all 0.2s ease;
|
|
|
|
+
|
|
|
|
+ &:hover {
|
|
|
|
+ color: #1f2937;
|
|
|
|
+ background-color: #f3f4f6;
|
|
|
|
+ transform: scale(1.15);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ &:active {
|
|
|
|
+ transform: scale(0.95);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
.employee-form {
|
|
.employee-form {
|
|
- max-width: 600px;
|
|
|
|
|
|
+ max-width: 100%;
|
|
}
|
|
}
|
|
|
|
+
|
|
.form-row {
|
|
.form-row {
|
|
display: flex;
|
|
display: flex;
|
|
- gap: 16px;
|
|
|
|
- margin-bottom: 16px;
|
|
|
|
|
|
+ gap: 24px;
|
|
|
|
+ margin-bottom: 24px;
|
|
|
|
+ flex-wrap: wrap;
|
|
}
|
|
}
|
|
|
|
+
|
|
.form-group {
|
|
.form-group {
|
|
flex: 1;
|
|
flex: 1;
|
|
|
|
+ min-width: 250px;
|
|
}
|
|
}
|
|
|
|
+
|
|
label {
|
|
label {
|
|
display: block;
|
|
display: block;
|
|
- margin-bottom: 4px;
|
|
|
|
- font-weight: 500;
|
|
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
+ font-weight: 600;
|
|
color: #374151;
|
|
color: #374151;
|
|
|
|
+ font-size: 16px;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ .required-mark {
|
|
|
|
+ color: #ef4444;
|
|
|
|
+ font-size: 16px;
|
|
|
|
+ }
|
|
|
|
+
|
|
.dialog-actions {
|
|
.dialog-actions {
|
|
display: flex;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
justify-content: flex-end;
|
|
- gap: 12px;
|
|
|
|
- margin-top: 24px;
|
|
|
|
|
|
+ gap: 16px;
|
|
|
|
+ margin-top: 32px;
|
|
|
|
+ padding-top: 20px;
|
|
|
|
+ border-top: 1px solid #e5e7eb;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 表单元素聚焦效果
|
|
|
|
+ .mat-form-field-appearance-fill .mat-form-field-focus-overlay {
|
|
|
|
+ background-color: rgba(30, 64, 175, 0.05);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 错误状态样式
|
|
|
|
+ .mat-error {
|
|
|
|
+ color: #ef4444;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ margin-top: 4px;
|
|
|
|
+ display: block;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .mat-form-field-invalid .mat-input-element {
|
|
|
|
+ color: #ef4444;
|
|
}
|
|
}
|
|
`]
|
|
`]
|
|
}) class AddEmployeeDialog {
|
|
}) class AddEmployeeDialog {
|
|
@@ -224,7 +269,7 @@ const generateMockEmployees = (): Employee[] => {
|
|
birthDate: new Date(1980 + Math.floor(Math.random() * 20), Math.floor(Math.random() * 12), Math.floor(Math.random() * 28) + 1),
|
|
birthDate: new Date(1980 + Math.floor(Math.random() * 20), Math.floor(Math.random() * 12), Math.floor(Math.random() * 28) + 1),
|
|
hireDate,
|
|
hireDate,
|
|
status,
|
|
status,
|
|
- avatar: `https://via.placeholder.com/40?text=${i}`,
|
|
|
|
|
|
+ avatar: `https://picsum.photos/seed/emp${i}/40/40`,
|
|
contract: {
|
|
contract: {
|
|
id: `contract-${i}`,
|
|
id: `contract-${i}`,
|
|
startDate: hireDate,
|
|
startDate: hireDate,
|
|
@@ -348,7 +393,7 @@ const generateMockEmployees = (): Employee[] => {
|
|
const newEmployee: Employee = {
|
|
const newEmployee: Employee = {
|
|
id: `emp-${Date.now()}`,
|
|
id: `emp-${Date.now()}`,
|
|
...result,
|
|
...result,
|
|
- avatar: `https://via.placeholder.com/40?text=E`,
|
|
|
|
|
|
+ avatar: `https://picsum.photos/seed/emp${Date.now()}/40/40`,
|
|
contract: {
|
|
contract: {
|
|
id: `contract-${Date.now()}`,
|
|
id: `contract-${Date.now()}`,
|
|
startDate: result.hireDate,
|
|
startDate: result.hireDate,
|