feat(users): 组织树支持删除院区与科室
This commit is contained in:
@@ -20,6 +20,8 @@ const emit = defineEmits<{
|
|||||||
addDepartment: []
|
addDepartment: []
|
||||||
editCampus: [campus: CampusRecord]
|
editCampus: [campus: CampusRecord]
|
||||||
editDepartment: [department: DepartmentRecord]
|
editDepartment: [department: DepartmentRecord]
|
||||||
|
deleteCampus: [campus: CampusRecord]
|
||||||
|
deleteDepartment: [department: DepartmentRecord]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const institutionGroups = computed(() => {
|
const institutionGroups = computed(() => {
|
||||||
@@ -115,15 +117,24 @@ function isDescendantSelected(department: DepartmentRecord): boolean {
|
|||||||
<span class="org-tree__name">{{ campus.name }}</span>
|
<span class="org-tree__name">{{ campus.name }}</span>
|
||||||
<span class="org-tree__count">{{ departmentsForCampus(campus.id).length }} 科室</span>
|
<span class="org-tree__count">{{ departmentsForCampus(campus.id).length }} 科室</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<div v-if="canManageCampuses" class="org-tree__actions">
|
||||||
v-if="canManageCampuses"
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="org-tree__edit"
|
class="org-tree__edit"
|
||||||
:aria-label="`编辑院区${campus.name}`"
|
:aria-label="`编辑院区${campus.name}`"
|
||||||
@click="emit('editCampus', campus)"
|
@click="emit('editCampus', campus)"
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="org-tree__remove"
|
||||||
|
:aria-label="`删除院区${campus.name}`"
|
||||||
|
@click="emit('deleteCampus', campus)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -142,15 +153,24 @@ function isDescendantSelected(department: DepartmentRecord): boolean {
|
|||||||
>
|
>
|
||||||
<span class="org-tree__name">🗂 {{ department.name }}</span>
|
<span class="org-tree__name">🗂 {{ department.name }}</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<div v-if="canManageDepartments" class="org-tree__actions">
|
||||||
v-if="canManageDepartments"
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="org-tree__edit"
|
class="org-tree__edit"
|
||||||
:aria-label="`编辑科室${department.name}`"
|
:aria-label="`编辑科室${department.name}`"
|
||||||
@click="emit('editDepartment', department)"
|
@click="emit('editDepartment', department)"
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="org-tree__remove"
|
||||||
|
:aria-label="`删除科室${department.name}`"
|
||||||
|
@click="emit('deleteDepartment', department)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-for="child in childrenFor(department.id, campus.id)"
|
v-for="child in childrenFor(department.id, campus.id)"
|
||||||
@@ -165,15 +185,24 @@ function isDescendantSelected(department: DepartmentRecord): boolean {
|
|||||||
>
|
>
|
||||||
<span class="org-tree__name">{{ child.name }}</span>
|
<span class="org-tree__name">{{ child.name }}</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<div v-if="canManageDepartments" class="org-tree__actions">
|
||||||
v-if="canManageDepartments"
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="org-tree__edit"
|
class="org-tree__edit"
|
||||||
:aria-label="`编辑科室${child.name}`"
|
:aria-label="`编辑科室${child.name}`"
|
||||||
@click="emit('editDepartment', child)"
|
@click="emit('editDepartment', child)"
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="org-tree__remove"
|
||||||
|
:aria-label="`删除科室${child.name}`"
|
||||||
|
@click="emit('deleteDepartment', child)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<p v-if="!childrenFor(null, campus.id).length" class="org-tree__empty">
|
<p v-if="!childrenFor(null, campus.id).length" class="org-tree__empty">
|
||||||
@@ -371,19 +400,37 @@ function isDescendantSelected(department: DepartmentRecord): boolean {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.org-tree__edit {
|
.org-tree__actions {
|
||||||
padding: 3px 6px;
|
display: flex;
|
||||||
margin-right: 6px;
|
flex: 0 0 auto;
|
||||||
color: var(--brand);
|
gap: 4px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.org-tree__edit,
|
||||||
|
.org-tree__remove {
|
||||||
|
padding: 3px 7px;
|
||||||
font-size: 10.5px;
|
font-size: 10.5px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border: 1px solid #d3e7ee;
|
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
opacity: 0;
|
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: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;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, ref, watch } from 'vue'
|
import { computed, onMounted, ref, watch } from 'vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createCampus,
|
createCampus,
|
||||||
createDepartment,
|
createDepartment,
|
||||||
|
deleteCampus,
|
||||||
|
deleteDepartment,
|
||||||
getAllDepartments,
|
getAllDepartments,
|
||||||
getCampuses,
|
getCampuses,
|
||||||
updateCampus,
|
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(
|
watch(
|
||||||
() => appStore.selectedCampusId,
|
() => appStore.selectedCampusId,
|
||||||
(campusId) => {
|
(campusId) => {
|
||||||
@@ -724,6 +777,8 @@ onMounted(loadOrganization)
|
|||||||
@add-department="openAddDepartment"
|
@add-department="openAddDepartment"
|
||||||
@edit-campus="editCampus"
|
@edit-campus="editCampus"
|
||||||
@edit-department="editDepartment"
|
@edit-department="editDepartment"
|
||||||
|
@delete-campus="removeCampus"
|
||||||
|
@delete-department="removeDepartment"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<section class="employee-card">
|
<section class="employee-card">
|
||||||
|
|||||||
Reference in New Issue
Block a user