|
@@ -1,11 +1,13 @@
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import { ref, watch } from 'vue';
|
|
|
|
|
|
|
+import { ref, watch, nextTick, h, onMounted, reactive } from 'vue';
|
|
|
import { type VxeTablePropTypes, type VxeTableEvents, VxeUI } from 'vxe-table';
|
|
import { type VxeTablePropTypes, type VxeTableEvents, VxeUI } from 'vxe-table';
|
|
|
import { getDictionaryMethod } from '@/request/api/dictionary.api';
|
|
import { getDictionaryMethod } from '@/request/api/dictionary.api';
|
|
|
-import { getConditioningDeviceDetailMethod, updateConditioningSchemeMethod } from '@/request/api/care.api';
|
|
|
|
|
|
|
+import { getConditioningDeviceDetailMethod, updateConditioningSchemeMethod, getConditioningSchemeItemsMethod } from '@/request/api/care.api';
|
|
|
import type { ConditioningSchemeModel } from '@/model/care.model';
|
|
import type { ConditioningSchemeModel } from '@/model/care.model';
|
|
|
import { useRequest } from 'alova/client';
|
|
import { useRequest } from 'alova/client';
|
|
|
import { notification } from 'ant-design-vue';
|
|
import { notification } from 'ant-design-vue';
|
|
|
|
|
+import { MenuUnfoldOutlined } from '@ant-design/icons-vue';
|
|
|
|
|
+import CustomConfiguration from '@/service/CustomConfiguration.vue';
|
|
|
type ConditioningModel = Partial<ConditioningSchemeModel>;
|
|
type ConditioningModel = Partial<ConditioningSchemeModel>;
|
|
|
|
|
|
|
|
// 定义表格行数据类型
|
|
// 定义表格行数据类型
|
|
@@ -16,7 +18,11 @@ interface TableRowData {
|
|
|
knowledgeCpShowType: string;
|
|
knowledgeCpShowType: string;
|
|
|
showCount: number;
|
|
showCount: number;
|
|
|
isChecked: boolean;
|
|
isChecked: boolean;
|
|
|
|
|
+ selectedCpIds?: string[];
|
|
|
|
|
+ isShowForInfer: string;
|
|
|
isNewRow?: boolean; // 用于标识是否是新添加的行
|
|
isNewRow?: boolean; // 用于标识是否是新添加的行
|
|
|
|
|
+ showListIcon?: boolean; // 是否显示列表图标
|
|
|
|
|
+ previousChecked?: boolean; // 上一次的勾选状态,用于判断状态变化
|
|
|
}
|
|
}
|
|
|
const emits = defineEmits<{
|
|
const emits = defineEmits<{
|
|
|
submit: [success: boolean, data?: Array<TableRowData>];
|
|
submit: [success: boolean, data?: Array<TableRowData>];
|
|
@@ -73,6 +79,7 @@ const addRow = () => {
|
|
|
knowledgeCpShowType: '1', // 1-展示 2-不展示 3-定制项目无结果时展示
|
|
knowledgeCpShowType: '1', // 1-展示 2-不展示 3-定制项目无结果时展示
|
|
|
showCount: globalItemLimit.value,
|
|
showCount: globalItemLimit.value,
|
|
|
isChecked: false,
|
|
isChecked: false,
|
|
|
|
|
+ isShowForInfer: 'N',
|
|
|
isHaveForInfer: null,
|
|
isHaveForInfer: null,
|
|
|
isCustomize: false,
|
|
isCustomize: false,
|
|
|
isNewRow: true, //新行
|
|
isNewRow: true, //新行
|
|
@@ -89,6 +96,7 @@ const deleteRow = (row: any) => {
|
|
|
|
|
|
|
|
// 保存
|
|
// 保存
|
|
|
const saveData = async () => {
|
|
const saveData = async () => {
|
|
|
|
|
+ console.log(tableData.value, '保存数据');
|
|
|
// 数据验证和格式化
|
|
// 数据验证和格式化
|
|
|
formattedData = tableData.value.map((row) => ({
|
|
formattedData = tableData.value.map((row) => ({
|
|
|
...row,
|
|
...row,
|
|
@@ -110,16 +118,16 @@ const saveData = async () => {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!props.data.orgId) {
|
|
|
|
|
|
|
+ if (!props.data.insId) {
|
|
|
notification.error({
|
|
notification.error({
|
|
|
- message: '未找到组织ID',
|
|
|
|
|
|
|
+ message: '未找到机构ID',
|
|
|
});
|
|
});
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 使用 async/await 确保正确处理成功和失败
|
|
// 使用 async/await 确保正确处理成功和失败
|
|
|
try {
|
|
try {
|
|
|
- await submit(props.data.orgId, formattedData);
|
|
|
|
|
|
|
+ await submit(props.data.insId, formattedData);
|
|
|
// 成功时通知父组件
|
|
// 成功时通知父组件
|
|
|
emits('submit', true, formattedData);
|
|
emits('submit', true, formattedData);
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
@@ -146,8 +154,7 @@ const rowConfig = reactive<VxeTablePropTypes.RowConfig>({
|
|
|
drag: true,
|
|
drag: true,
|
|
|
});
|
|
});
|
|
|
const columnConfig = reactive<VxeTablePropTypes.ColumnConfig>({});
|
|
const columnConfig = reactive<VxeTablePropTypes.ColumnConfig>({});
|
|
|
-const rowDragstartEvent: VxeTableEvents.RowDragstart = ({ row }) => {
|
|
|
|
|
-};
|
|
|
|
|
|
|
+const rowDragstartEvent: VxeTableEvents.RowDragstart = ({ row }) => {};
|
|
|
|
|
|
|
|
const rowDragendEvent: VxeTableEvents.RowDragend = ({ newRow, oldRow }) => {
|
|
const rowDragendEvent: VxeTableEvents.RowDragend = ({ newRow, oldRow }) => {
|
|
|
const oldIndex = tableData.value.indexOf(oldRow as TableRowData);
|
|
const oldIndex = tableData.value.indexOf(oldRow as TableRowData);
|
|
@@ -159,10 +166,14 @@ const rowDragendEvent: VxeTableEvents.RowDragend = ({ newRow, oldRow }) => {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
const organizationName = ref('');
|
|
const organizationName = ref('');
|
|
|
|
|
+const insName = ref('');
|
|
|
|
|
+const insId = ref<number>(0);
|
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
|
getConditioningProgramType();
|
|
getConditioningProgramType();
|
|
|
const res: any = await getConditioningDeviceDetailMethod(props.data);
|
|
const res: any = await getConditioningDeviceDetailMethod(props.data);
|
|
|
organizationName.value = res.orgName ?? '';
|
|
organizationName.value = res.orgName ?? '';
|
|
|
|
|
+ insName.value = res.insName ?? '';
|
|
|
|
|
+ insId.value = res.insId ?? 0;
|
|
|
tableData.value = res.items ?? [];
|
|
tableData.value = res.items ?? [];
|
|
|
tableData.value.forEach((row) => {
|
|
tableData.value.forEach((row) => {
|
|
|
// 只有 isHaveForInfer 不是 null 的情况下才是定制项目
|
|
// 只有 isHaveForInfer 不是 null 的情况下才是定制项目
|
|
@@ -171,13 +182,14 @@ onMounted(async () => {
|
|
|
row.isCustomize = false;
|
|
row.isCustomize = false;
|
|
|
} else if (row.isHaveForInfer === 'Y') {
|
|
} else if (row.isHaveForInfer === 'Y') {
|
|
|
// 是定制项目且展示
|
|
// 是定制项目且展示
|
|
|
- row.isChecked = true;
|
|
|
|
|
row.isCustomize = true;
|
|
row.isCustomize = true;
|
|
|
|
|
+ row.showListIcon = true; // 已勾选,显示列表图标
|
|
|
} else if (row.isHaveForInfer === 'N') {
|
|
} else if (row.isHaveForInfer === 'N') {
|
|
|
// 是定制项目但不展示
|
|
// 是定制项目但不展示
|
|
|
- row.isChecked = false;
|
|
|
|
|
row.isCustomize = true;
|
|
row.isCustomize = true;
|
|
|
|
|
+ row.showListIcon = false; // 未勾选,隐藏列表图标
|
|
|
}
|
|
}
|
|
|
|
|
+ row.showListIcon = row.previousChecked = row.isChecked = row.isShowForInfer == 'Y' ? true : false;
|
|
|
});
|
|
});
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -362,12 +374,66 @@ const handleItemLimitPaste = (params: any) => {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
+// 处理复选框变化
|
|
|
|
|
+function handleCheckboxChange(row: TableRowData) {
|
|
|
|
|
+ const wasChecked = row.previousChecked ?? false;
|
|
|
|
|
+ const isChecked = row.isChecked;
|
|
|
|
|
+
|
|
|
|
|
+ // 更新 previousChecked
|
|
|
|
|
+ row.previousChecked = isChecked;
|
|
|
|
|
+
|
|
|
|
|
+ // 从不勾选到勾选:显示列表图标并自动打开详情编辑
|
|
|
|
|
+ if (!wasChecked && isChecked) {
|
|
|
|
|
+ row.showListIcon = true;
|
|
|
|
|
+ row.isChecked = true;
|
|
|
|
|
+ row.isShowForInfer = 'Y';
|
|
|
|
|
+ // 延迟一下,确保UI更新后再打开弹窗
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ handleCustomProjectTrue(row);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ // 从勾选到不勾选:隐藏列表图标
|
|
|
|
|
+ else if (wasChecked && !isChecked) {
|
|
|
|
|
+ row.showListIcon = false;
|
|
|
|
|
+ row.isChecked = false;
|
|
|
|
|
+ row.isShowForInfer = 'N';
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleCustomProjectTrue = (row: any) => {
|
|
|
|
|
+ VxeUI.modal.open({
|
|
|
|
|
+ title: '定制项目',
|
|
|
|
|
+ width: 1100,
|
|
|
|
|
+ height: 750,
|
|
|
|
|
+ id: 'custom-configuration-modal',
|
|
|
|
|
+ remember: true,
|
|
|
|
|
+ storage: true,
|
|
|
|
|
+ slots: {
|
|
|
|
|
+ default() {
|
|
|
|
|
+ return h(CustomConfiguration, {
|
|
|
|
|
+ data: { ...row, insId: insId.value },
|
|
|
|
|
+ onSubmit: (data: any) => {
|
|
|
|
|
+ tableData.value.forEach((item: any) => {
|
|
|
|
|
+ if (item.conditioningProgramType === row.conditioningProgramType) {
|
|
|
|
|
+ item.selectedCpIds = data.selectedProjects.map((item: any) => item.projectId) as string[];
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ VxeUI.modal.close('custom-configuration-modal');
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
<template>
|
|
|
<div class="edit-configured">
|
|
<div class="edit-configured">
|
|
|
<!-- 组织名称 -->
|
|
<!-- 组织名称 -->
|
|
|
- <div class="organization-name">组织名称:{{ organizationName }}</div>
|
|
|
|
|
|
|
+ <div class="flex">
|
|
|
|
|
+ <div class="organization-name mr-15" v-if="organizationName">组织名称:{{ organizationName }}</div>
|
|
|
|
|
+ <div class="organization-name" v-if="insName">机构名称:{{ insName }}</div>
|
|
|
|
|
+ </div>
|
|
|
<!-- 表格 -->
|
|
<!-- 表格 -->
|
|
|
<vxe-table
|
|
<vxe-table
|
|
|
border
|
|
border
|
|
@@ -406,9 +472,13 @@ const handleItemLimitPaste = (params: any) => {
|
|
|
<vxe-column field="isHaveForInfer" title="定制项目" width="160" align="center">
|
|
<vxe-column field="isHaveForInfer" title="定制项目" width="160" align="center">
|
|
|
<template #default="{ row }">
|
|
<template #default="{ row }">
|
|
|
<div class="custom-project-indicator">
|
|
<div class="custom-project-indicator">
|
|
|
- <div v-if="row.isCustomize" class="custom-project-true">
|
|
|
|
|
- <a-checkbox v-model:checked="row.isChecked">展示</a-checkbox>
|
|
|
|
|
|
|
+ <div v-if="row.isCustomize" class="custom-project-true-container">
|
|
|
|
|
+ <a-checkbox v-model:checked="row.isChecked" @change="handleCheckboxChange(row)"> 展示 </a-checkbox>
|
|
|
|
|
+ <div v-if="row.showListIcon" class="flex items-center custom-project-true" @click="handleCustomProjectTrue(row)">
|
|
|
|
|
+ <MenuUnfoldOutlined />
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+
|
|
|
<div v-else class="custom-project-false">
|
|
<div v-else class="custom-project-false">
|
|
|
<div class="red-x-icon">×</div>
|
|
<div class="red-x-icon">×</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -490,7 +560,7 @@ const handleItemLimitPaste = (params: any) => {
|
|
|
<!-- 底部操作按钮 -->
|
|
<!-- 底部操作按钮 -->
|
|
|
<div class="action-buttons">
|
|
<div class="action-buttons">
|
|
|
<vxe-button @click="cancelEdit">取消</vxe-button>
|
|
<vxe-button @click="cancelEdit">取消</vxe-button>
|
|
|
- <vxe-button type="primary" status="warning" @click="saveData">保存</vxe-button>
|
|
|
|
|
|
|
+ <vxe-button type="primary" status="warning" @click="saveData" :loading="submitting">保存</vxe-button>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
@@ -517,7 +587,10 @@ const handleItemLimitPaste = (params: any) => {
|
|
|
justify-content: center;
|
|
justify-content: center;
|
|
|
gap: 8px;
|
|
gap: 8px;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+.custom-project-true-container {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+}
|
|
|
.custom-project-true {
|
|
.custom-project-true {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|