feat: enhance employee CRUD with search, filters, and security module

This commit is contained in:
2026-05-07 13:48:00 +08:00
parent c00db75c13
commit 2d56bc2889
13 changed files with 693 additions and 131 deletions

View File

@@ -31,7 +31,7 @@
</div>
<div class="hero-stat">
<span>角色数量</span>
<strong>{{ selectedEmployee.roles.length }}</strong>
<strong>{{ roleCount }}</strong>
</div>
</div>
</section>
@@ -49,39 +49,48 @@
<div class="form-grid">
<label class="field">
<span>员工姓名</span>
<input :value="selectedEmployee.name" />
<input v-model="employeeForm.name" />
</label>
<label class="field">
<span>员工编号</span>
<input :value="selectedEmployee.employeeNo" />
<input v-model="employeeForm.employeeNo" readonly />
</label>
<label class="field">
<span>性别</span>
<input :value="selectedEmployee.gender" />
<input v-model="employeeForm.gender" />
</label>
<label class="field">
<span>年龄</span>
<input :value="selectedEmployee.age" />
<input :value="detailAge" readonly />
</label>
<label class="field">
<span>出生日期</span>
<input :value="selectedEmployee.birthDate" />
<input v-model="employeeForm.birthDate" type="date" />
</label>
<label class="field">
<span>手机号</span>
<input :value="selectedEmployee.phone" />
<input v-model="employeeForm.phone" />
</label>
<label class="field">
<span>邮箱</span>
<input :value="selectedEmployee.email" />
<input v-model="employeeForm.email" type="email" />
</label>
<label class="field">
<span>密码设置</span>
<input
v-model="employeeForm.password"
type="password"
autocomplete="new-password"
placeholder="留空则不修改"
/>
</label>
<label class="field">
<span>入职日期</span>
<input :value="selectedEmployee.joinDate" />
<input v-model="employeeForm.joinDate" type="date" />
</label>
<label class="field">
<span>办公地点</span>
<input :value="selectedEmployee.location" />
<input v-model="employeeForm.location" />
</label>
</div>
</article>
@@ -97,27 +106,27 @@
<div class="form-grid">
<label class="field">
<span>所属部门</span>
<input :value="selectedEmployee.department" />
<input v-model="employeeForm.department" readonly />
</label>
<label class="field">
<span>岗位</span>
<input :value="selectedEmployee.position" />
<input v-model="employeeForm.position" />
</label>
<label class="field">
<span>职级</span>
<input :value="selectedEmployee.grade" />
<input v-model="employeeForm.grade" />
</label>
<label class="field">
<span>直属上级</span>
<input :value="selectedEmployee.manager" />
<input v-model="employeeForm.manager" readonly />
</label>
<label class="field">
<span>财务归口</span>
<input :value="selectedEmployee.financeOwner" />
<input v-model="employeeForm.financeOwner" />
</label>
<label class="field">
<span>成本中心</span>
<input :value="selectedEmployee.costCenter" />
<input v-model="employeeForm.costCenter" />
</label>
</div>
</article>
@@ -128,7 +137,7 @@
<h3>系统角色分配</h3>
<p>为员工分配管理员财务人员使用者高级管理人员等业务角色</p>
</div>
<span class="count-badge">{{ selectedEmployee.roles.length }} 个角色</span>
<span class="count-badge">{{ roleCount }} 个角色</span>
</div>
<div class="role-grid">
@@ -136,9 +145,9 @@
v-for="role in roleOptions"
:key="role.id"
class="role-card"
:class="{ active: selectedEmployee.roles.includes(role.label) }"
:class="{ active: employeeForm.roleCodes.includes(role.code) }"
>
<input type="checkbox" :checked="selectedEmployee.roles.includes(role.label)" />
<input v-model="employeeForm.roleCodes" type="checkbox" :value="role.code" />
<div class="role-copy">
<strong>{{ role.label }}</strong>
<p>{{ role.desc }}</p>
@@ -157,7 +166,7 @@
</div>
</div>
<div class="tag-list">
<span v-for="role in selectedEmployee.roles" :key="role">{{ role }}</span>
<span v-for="role in selectedRoleLabels" :key="role">{{ role }}</span>
</div>
<ul class="bullet-list">
<li v-for="item in selectedEmployee.permissions" :key="item">{{ item }}</li>
@@ -195,23 +204,19 @@
</div>
<footer class="detail-actions">
<button class="back-action" type="button" @click="selectedEmployee = null">
<button class="back-action" type="button" @click="closeEmployeeDetail">
<i class="mdi mdi-arrow-left"></i>
<span>返回员工列表</span>
</button>
<div class="detail-action-group">
<button class="minor-action" type="button">
<i class="mdi mdi-content-save-outline"></i>
<span>保存草稿</span>
</button>
<button class="minor-action" type="button">
<button class="minor-action" type="button" :disabled="disableActionDisabled" @click="disableEmployeeAccount">
<i class="mdi mdi-account-cancel-outline"></i>
<span>停用账号</span>
<span>{{ selectedEmployee.status === '停用' ? '账号已停用' : actionState === 'disable' ? '停用中...' : '停用账号' }}</span>
</button>
<button class="major-action" type="button">
<button class="major-action" type="button" :disabled="actionBusy" @click="saveEmployeeChanges">
<i class="mdi mdi-check-circle-outline"></i>
<span>保存并生效</span>
<span>{{ actionState === 'save' ? '保存中...' : '保存并生效' }}</span>
</button>
</div>
</footer>
@@ -450,7 +455,7 @@
v-for="employee in visibleEmployees"
:key="employee.id"
:class="{ spotlight: employee.spotlight }"
@click="selectedEmployee = employee"
@click="openEmployeeDetail(employee)"
>
<td>
<div class="employee-cell">