feat(users): 组织树支持删除院区与科室
This commit is contained in:
@@ -20,6 +20,8 @@ const emit = defineEmits<{
|
||||
addDepartment: []
|
||||
editCampus: [campus: CampusRecord]
|
||||
editDepartment: [department: DepartmentRecord]
|
||||
deleteCampus: [campus: CampusRecord]
|
||||
deleteDepartment: [department: DepartmentRecord]
|
||||
}>()
|
||||
|
||||
const institutionGroups = computed(() => {
|
||||
@@ -115,8 +117,8 @@ function isDescendantSelected(department: DepartmentRecord): boolean {
|
||||
<span class="org-tree__name">{{ campus.name }}</span>
|
||||
<span class="org-tree__count">{{ departmentsForCampus(campus.id).length }} 科室</span>
|
||||
</button>
|
||||
<div v-if="canManageCampuses" class="org-tree__actions">
|
||||
<button
|
||||
v-if="canManageCampuses"
|
||||
type="button"
|
||||
class="org-tree__edit"
|
||||
:aria-label="`编辑院区${campus.name}`"
|
||||
@@ -124,6 +126,15 @@ function isDescendantSelected(department: DepartmentRecord): boolean {
|
||||
>
|
||||
编辑
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="org-tree__remove"
|
||||
:aria-label="`删除院区${campus.name}`"
|
||||
@click="emit('deleteCampus', campus)"
|
||||
>
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
@@ -142,8 +153,8 @@ function isDescendantSelected(department: DepartmentRecord): boolean {
|
||||
>
|
||||
<span class="org-tree__name">🗂 {{ department.name }}</span>
|
||||
</button>
|
||||
<div v-if="canManageDepartments" class="org-tree__actions">
|
||||
<button
|
||||
v-if="canManageDepartments"
|
||||
type="button"
|
||||
class="org-tree__edit"
|
||||
:aria-label="`编辑科室${department.name}`"
|
||||
@@ -151,6 +162,15 @@ function isDescendantSelected(department: DepartmentRecord): boolean {
|
||||
>
|
||||
编辑
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="org-tree__remove"
|
||||
:aria-label="`删除科室${department.name}`"
|
||||
@click="emit('deleteDepartment', department)"
|
||||
>
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="child in childrenFor(department.id, campus.id)"
|
||||
@@ -165,8 +185,8 @@ function isDescendantSelected(department: DepartmentRecord): boolean {
|
||||
>
|
||||
<span class="org-tree__name">{{ child.name }}</span>
|
||||
</button>
|
||||
<div v-if="canManageDepartments" class="org-tree__actions">
|
||||
<button
|
||||
v-if="canManageDepartments"
|
||||
type="button"
|
||||
class="org-tree__edit"
|
||||
:aria-label="`编辑科室${child.name}`"
|
||||
@@ -174,6 +194,15 @@ function isDescendantSelected(department: DepartmentRecord): boolean {
|
||||
>
|
||||
编辑
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="org-tree__remove"
|
||||
:aria-label="`删除科室${child.name}`"
|
||||
@click="emit('deleteDepartment', child)"
|
||||
>
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<p v-if="!childrenFor(null, campus.id).length" class="org-tree__empty">
|
||||
@@ -371,19 +400,37 @@ function isDescendantSelected(department: DepartmentRecord): boolean {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.org-tree__edit {
|
||||
padding: 3px 6px;
|
||||
margin-right: 6px;
|
||||
color: var(--brand);
|
||||
.org-tree__actions {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.org-tree__edit,
|
||||
.org-tree__remove {
|
||||
padding: 3px 7px;
|
||||
font-size: 10.5px;
|
||||
background: #fff;
|
||||
border: 1px solid #d3e7ee;
|
||||
border-radius: 5px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.org-tree__edit {
|
||||
color: var(--brand);
|
||||
border: 1px solid #d3e7ee;
|
||||
}
|
||||
|
||||
.org-tree__remove {
|
||||
margin-right: 6px;
|
||||
color: var(--err);
|
||||
border: 1px solid #f0cdcd;
|
||||
}
|
||||
|
||||
.org-tree__node:hover .org-tree__edit,
|
||||
.org-tree__node:focus-within .org-tree__edit {
|
||||
.org-tree__node:hover .org-tree__remove,
|
||||
.org-tree__node:focus-within .org-tree__edit,
|
||||
.org-tree__node:focus-within .org-tree__remove {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
import {
|
||||
createCampus,
|
||||
createDepartment,
|
||||
deleteCampus,
|
||||
deleteDepartment,
|
||||
getAllDepartments,
|
||||
getCampuses,
|
||||
updateCampus,
|
||||
@@ -664,6 +666,57 @@ async function saveOrganizationNode(form: OrganizationNodeSave) {
|
||||
}
|
||||
}
|
||||
|
||||
async function removeCampus(campus: CampusRecord) {
|
||||
if (!canManageCampuses.value) return
|
||||
const departmentCount = departments.value.filter(
|
||||
(department) => department.campusId === campus.id,
|
||||
).length
|
||||
const confirmed = await ElMessageBox.confirm(
|
||||
departmentCount
|
||||
? `删除院区“${campus.name}”会同时移除其下 ${departmentCount} 个科室,且无法恢复,是否继续?`
|
||||
: `删除院区“${campus.name}”后无法恢复,是否继续?`,
|
||||
'删除院区',
|
||||
{ type: 'warning', confirmButtonText: '删除', cancelButtonText: '取消' },
|
||||
)
|
||||
.then(() => true)
|
||||
.catch(() => false)
|
||||
if (!confirmed) return
|
||||
|
||||
try {
|
||||
await deleteCampus(campus.id)
|
||||
if (selectedCampusId.value === campus.id) selectedDepartmentId.value = null
|
||||
await appStore.loadCampuses(true)
|
||||
await loadOrganization()
|
||||
ElMessage.success('院区已删除')
|
||||
} catch (error) {
|
||||
ElMessage.error(toUserMessage(error, '院区删除失败,请稍后重试'))
|
||||
}
|
||||
}
|
||||
|
||||
async function removeDepartment(department: DepartmentRecord) {
|
||||
if (!canManageDepartments.value) return
|
||||
const childCount = departments.value.filter((item) => item.parentId === department.id).length
|
||||
const confirmed = await ElMessageBox.confirm(
|
||||
childCount
|
||||
? `删除科室“${department.name}”会同时移除其下 ${childCount} 个下级科室,且无法恢复,是否继续?`
|
||||
: `删除科室“${department.name}”后无法恢复,是否继续?`,
|
||||
'删除科室',
|
||||
{ type: 'warning', confirmButtonText: '删除', cancelButtonText: '取消' },
|
||||
)
|
||||
.then(() => true)
|
||||
.catch(() => false)
|
||||
if (!confirmed) return
|
||||
|
||||
try {
|
||||
await deleteDepartment(department.id)
|
||||
if (selectedDepartmentId.value === department.id) selectedDepartmentId.value = null
|
||||
await loadOrganization()
|
||||
ElMessage.success('科室已删除')
|
||||
} catch (error) {
|
||||
ElMessage.error(toUserMessage(error, '科室删除失败,请稍后重试'))
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => appStore.selectedCampusId,
|
||||
(campusId) => {
|
||||
@@ -724,6 +777,8 @@ onMounted(loadOrganization)
|
||||
@add-department="openAddDepartment"
|
||||
@edit-campus="editCampus"
|
||||
@edit-department="editDepartment"
|
||||
@delete-campus="removeCampus"
|
||||
@delete-department="removeDepartment"
|
||||
/>
|
||||
|
||||
<section class="employee-card">
|
||||
|
||||
Reference in New Issue
Block a user