|
|
@@ -1,14 +1,13 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, onMounted } from 'vue';
|
|
|
+import { ref, onMounted, computed } from 'vue';
|
|
|
import { VxeUI } from 'vxe-pc-ui';
|
|
|
-import { notification } from 'ant-design-vue';
|
|
|
import type { ConditioningSchemeModel } from '@/model/care.model';
|
|
|
import { getConditioningSchemeItemsMethod } from '@/request/api/care.api';
|
|
|
type ConditioningModel = Partial<ConditioningSchemeModel>;
|
|
|
const props = defineProps<{ data: ConditioningModel }>();
|
|
|
|
|
|
-const emit = defineEmits(['submit', 'onSubmit']);
|
|
|
-
|
|
|
+const emit = defineEmits(['submit', 'onSubmit', 'close']);
|
|
|
+const selectedProjectsValue = ref<any[]>([]);
|
|
|
// 定义项目接口
|
|
|
interface ProjectItem {
|
|
|
id: string | number;
|
|
|
@@ -28,16 +27,80 @@ const superiorProjects = ref<Organization[]>([]);
|
|
|
// 本级项目数据
|
|
|
const currentProjects = ref<ProjectItem[]>([]);
|
|
|
|
|
|
-// 关闭弹窗
|
|
|
+// ===== 全选相关逻辑 =====
|
|
|
+// 上级项目是否全部选中
|
|
|
+const isAllSuperiorChecked = computed(() => {
|
|
|
+
|
|
|
+ const allProjects = superiorProjects.value.flatMap((org) => org.projects);
|
|
|
+ console.log(allProjects, 'allProjects111111',superiorProjects.value);
|
|
|
+ if (allProjects.length === 0) return false;
|
|
|
+ return allProjects.every((p) => p.checked);
|
|
|
+});
|
|
|
+
|
|
|
+// 上级项目是否部分选中(用于半选中状态)
|
|
|
+const isSomeSuperiorChecked = computed(() => {
|
|
|
+ const allProjects = superiorProjects.value.flatMap((org) => org.projects);
|
|
|
+ const someChecked = allProjects.some((p) => p.checked);
|
|
|
+ return someChecked && !isAllSuperiorChecked.value;
|
|
|
+});
|
|
|
+
|
|
|
+// 切换上级项目全选
|
|
|
+const handleSuperiorCheckAllChange = (checked: boolean) => {
|
|
|
+ superiorProjects.value.forEach((org) => {
|
|
|
+ org.projects.forEach((project) => {
|
|
|
+ project.checked = checked;
|
|
|
+ });
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 某机构是否全部选中
|
|
|
+const isOrgAllChecked = (org: Organization) => {
|
|
|
+ if (!org.projects || org.projects.length === 0) return false;
|
|
|
+ return org.projects.every((p) => p.checked);
|
|
|
+};
|
|
|
+
|
|
|
+// 某机构是否部分选中
|
|
|
+const isOrgIndeterminate = (org: Organization) => {
|
|
|
+ const someChecked = org.projects?.some((p) => p.checked);
|
|
|
+ return !!someChecked && !isOrgAllChecked(org);
|
|
|
+};
|
|
|
+
|
|
|
+// 切换某机构全选
|
|
|
+const handleOrgCheckAllChange = (org: Organization, checked: boolean) => {
|
|
|
+ org.projects.forEach((project) => {
|
|
|
+ project.checked = checked;
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 本级项目是否全部选中
|
|
|
+const isAllCurrentChecked = computed(() => {
|
|
|
+ if (currentProjects.value.length === 0) return false;
|
|
|
+ return currentProjects.value.every((p) => p.checked);
|
|
|
+});
|
|
|
+
|
|
|
+// 本级项目是否部分选中
|
|
|
+const isSomeCurrentChecked = computed(() => {
|
|
|
+ const someChecked = currentProjects.value.some((p) => p.checked);
|
|
|
+ return someChecked && !isAllCurrentChecked.value;
|
|
|
+});
|
|
|
+
|
|
|
+// 切换本级项目全选
|
|
|
+const handleCurrentCheckAllChange = (checked: boolean) => {
|
|
|
+ currentProjects.value.forEach((project) => {
|
|
|
+ project.checked = checked;
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 关闭弹窗(取消时使用)
|
|
|
function handleClose() {
|
|
|
+ emit('close');
|
|
|
VxeUI.modal.close('custom-configuration-modal');
|
|
|
}
|
|
|
|
|
|
-// 取消
|
|
|
+// 取消:仅关闭弹窗并让父组件回滚勾选状态
|
|
|
function handleCancel() {
|
|
|
handleClose();
|
|
|
}
|
|
|
-
|
|
|
// 确认
|
|
|
function handleConfirm() {
|
|
|
// 收集选中的项目数据
|
|
|
@@ -68,16 +131,19 @@ function handleConfirm() {
|
|
|
originalData: props.data,
|
|
|
selectedProjects: selectedProjects,
|
|
|
};
|
|
|
+
|
|
|
// 必须选择一个项目
|
|
|
- if (selectedProjects.length <= 0 && selectedProjects.length <= 0) {
|
|
|
- notification.error({
|
|
|
- message: '请至少选择一个项目',
|
|
|
- });
|
|
|
- return;
|
|
|
- }
|
|
|
+ // if (selectedProjects.length <= 0 && selectedProjects.length <= 0) {
|
|
|
+ // notification.error({
|
|
|
+ // message: '请至少选择一个项目',
|
|
|
+ // });
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
emit('submit', result);
|
|
|
emit('onSubmit', result);
|
|
|
- handleClose();
|
|
|
+ selectedProjectsValue.value = selectedProjects;
|
|
|
+ // 确认时直接关闭弹窗,父组件通过 onSubmit 已经处理勾选状态
|
|
|
+ VxeUI.modal.close('custom-configuration-modal');
|
|
|
}
|
|
|
// 获取定制项目列表
|
|
|
const getCustomProjectList = async () => {
|
|
|
@@ -127,10 +193,29 @@ onMounted(() => {
|
|
|
<div class="content-wrapper">
|
|
|
<!-- 上级项目 - 左侧 -->
|
|
|
<div class="section section-left" v-if="superiorProjects.length > 0">
|
|
|
- <div class="section-title">上级项目</div>
|
|
|
+ <div class="section-title section-title-with-checkbox">
|
|
|
+ <span>上级项目</span>
|
|
|
+ <a-checkbox
|
|
|
+ :checked="isAllSuperiorChecked"
|
|
|
+ :indeterminate="isSomeSuperiorChecked"
|
|
|
+ @change="(e: any) => handleSuperiorCheckAllChange(e.target.checked)"
|
|
|
+ style="margin-left: 20px;"
|
|
|
+ >
|
|
|
+ 全选
|
|
|
+ </a-checkbox>
|
|
|
+ </div>
|
|
|
<div class="organizations">
|
|
|
<div v-for="org in superiorProjects" :key="org.id" class="organization-item">
|
|
|
- <div class="org-name">{{ org.name }}</div>
|
|
|
+ <div class="org-header">
|
|
|
+ <div class="org-name">{{ org.name }}</div>
|
|
|
+ <a-checkbox
|
|
|
+ :checked="isOrgAllChecked(org)"
|
|
|
+ :indeterminate="isOrgIndeterminate(org)"
|
|
|
+ @change="(e: any) => handleOrgCheckAllChange(org, e.target.checked)"
|
|
|
+ >
|
|
|
+ 全选
|
|
|
+ </a-checkbox>
|
|
|
+ </div>
|
|
|
<div class="projects-list">
|
|
|
<a-checkbox v-for="project in org.projects" :key="project.id" v-model:checked="project.checked" class="project-checkbox">
|
|
|
{{ project.name }}
|
|
|
@@ -142,7 +227,17 @@ onMounted(() => {
|
|
|
|
|
|
<!-- 本级项目 - 右侧 -->
|
|
|
<div class="section section-right" v-if="currentProjects.length > 0">
|
|
|
- <div class="section-title">本级项目</div>
|
|
|
+ <div class="section-title section-title-with-checkbox">
|
|
|
+ <span>本级项目</span>
|
|
|
+ <a-checkbox
|
|
|
+ :checked="isAllCurrentChecked"
|
|
|
+ :indeterminate="isSomeCurrentChecked"
|
|
|
+ @change="(e: any) => handleCurrentCheckAllChange(e.target.checked)"
|
|
|
+ style="margin-left: 20px;"
|
|
|
+ >
|
|
|
+ 全选
|
|
|
+ </a-checkbox>
|
|
|
+ </div>
|
|
|
<div class="projects-list">
|
|
|
<a-checkbox v-for="project in currentProjects" :key="project.id" v-model:checked="project.checked" class="project-checkbox">
|
|
|
{{ project.name }}
|
|
|
@@ -211,7 +306,7 @@ onMounted(() => {
|
|
|
|
|
|
.section-title {
|
|
|
font-size: 16px;
|
|
|
- font-weight: 500;
|
|
|
+ font-weight: 800;
|
|
|
margin-bottom: 16px;
|
|
|
color: #333;
|
|
|
}
|
|
|
@@ -226,9 +321,9 @@ onMounted(() => {
|
|
|
.organization-item {
|
|
|
.org-name {
|
|
|
font-size: 15px;
|
|
|
- font-weight: 500;
|
|
|
- margin-bottom: 12px;
|
|
|
+ // font-weight: 500;
|
|
|
color: black;
|
|
|
+ margin-right: 20px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -244,7 +339,11 @@ onMounted(() => {
|
|
|
color: #333;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+.org-header{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
.footer-buttons {
|
|
|
display: flex;
|
|
|
justify-content: center;
|