|
|
|
@ -270,7 +270,7 @@ |
|
|
|
|
|
|
|
<el-dialog v-model="saveDialogVisible" title="保存样式至方案" width="400px"> |
|
|
|
<el-form label-width="80px"> |
|
|
|
<el-form-item label="所属方案"> |
|
|
|
<el-form-item label="所属方案" required> |
|
|
|
<el-select |
|
|
|
v-model="saveForm.group_name" |
|
|
|
filterable |
|
|
|
@ -282,7 +282,7 @@ |
|
|
|
<el-option v-for="g in existingGroups" :key="g.id" :label="g.group_name" :value="g.group_name"/> |
|
|
|
</el-select> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="配置名称"> |
|
|
|
<el-form-item label="配置名称" required> |
|
|
|
<el-input v-model="saveForm.canvas_name" placeholder="请输入配置名称"/> |
|
|
|
</el-form-item> |
|
|
|
</el-form> |
|
|
|
@ -304,7 +304,7 @@ import { |
|
|
|
deleteGraphStyle, |
|
|
|
batchDeleteGraphStyle, |
|
|
|
deleteGraphStyleGroup, |
|
|
|
applyGraphStyleGroup // 新增导入 |
|
|
|
applyGraphStyleGroup |
|
|
|
} from '@/api/style'; |
|
|
|
import {ElMessageBox, ElMessage} from 'element-plus'; |
|
|
|
import {markRaw} from 'vue'; |
|
|
|
@ -597,19 +597,18 @@ export default { |
|
|
|
})) |
|
|
|
})); |
|
|
|
|
|
|
|
// --- 核心改动:初始加载同步逻辑 --- |
|
|
|
this.activeCollapseNames = []; |
|
|
|
this.usingConfigIds = []; |
|
|
|
|
|
|
|
this.styleGroups.forEach(group => { |
|
|
|
if (group.is_active) { |
|
|
|
// 1. 自动展开激活方案 |
|
|
|
this.activeCollapseNames.push(group.id); |
|
|
|
// 2. 将激活方案下的所有配置加入渲染列表 |
|
|
|
const ids = group.configs.map(c => c.id); |
|
|
|
this.usingConfigIds = [...this.usingConfigIds, ...ids]; |
|
|
|
} |
|
|
|
}); |
|
|
|
// 仅在初始加载且没有选中项时执行自动同步逻辑 |
|
|
|
if (this.usingConfigIds.length === 0) { |
|
|
|
this.styleGroups.forEach(group => { |
|
|
|
if (group.is_active) { |
|
|
|
if (!this.activeCollapseNames.includes(group.id)) { |
|
|
|
this.activeCollapseNames.push(group.id); |
|
|
|
} |
|
|
|
const ids = group.configs.map(c => c.id); |
|
|
|
this.usingConfigIds = [...this.usingConfigIds, ...ids]; |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
this.updateAllElements(); |
|
|
|
} |
|
|
|
@ -638,25 +637,63 @@ export default { |
|
|
|
} |
|
|
|
this.updateAllElements(); |
|
|
|
}, |
|
|
|
|
|
|
|
/** |
|
|
|
* 修改后的应用全案方法 |
|
|
|
* 逻辑:保留当前已手动选中的配置,新方案中冲突的配置不予应用 |
|
|
|
*/ |
|
|
|
async applyWholeGroup(group) { |
|
|
|
try { |
|
|
|
// 1. 调用后端接口更新激活状态 |
|
|
|
// 1. 获取当前正在使用的所有配置项对象 |
|
|
|
const currentlyUsingConfigs = []; |
|
|
|
this.styleGroups.forEach(g => { |
|
|
|
g.configs.forEach(c => { |
|
|
|
if (this.usingConfigIds.includes(c.id)) { |
|
|
|
currentlyUsingConfigs.push(c); |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
// 2. 提取出当前已选中的标签列表 (例如: ['疾病', '药品']) |
|
|
|
const currentlySelectedLabels = currentlyUsingConfigs.map(c => c.current_label); |
|
|
|
|
|
|
|
// 3. 过滤新方案:如果新方案里的配置标签 已经存在于当前已选列表中,则剔除 |
|
|
|
const filteredNewConfigIds = group.configs |
|
|
|
.filter(newConf => !currentlySelectedLabels.includes(newConf.current_label)) |
|
|
|
.map(newConf => newConf.id); |
|
|
|
|
|
|
|
// 4. 将过滤后的新 ID 追加到现有的选中列表中 |
|
|
|
this.usingConfigIds = [...this.usingConfigIds, ...filteredNewConfigIds]; |
|
|
|
|
|
|
|
// 5. 调用后端接口更新激活状态(保持后端数据同步) |
|
|
|
const res = await applyGraphStyleGroup(group.id); |
|
|
|
if (res.code === 200) { |
|
|
|
// 2. 刷新列表(fetchConfigs 会自动同步 usingConfigIds 和 expanded 状态) |
|
|
|
// 重新获取列表以刷新 UI 状态(如“已应用”按钮状态) |
|
|
|
await this.fetchConfigs(); |
|
|
|
ElMessage.success(`方案【${group.group_name}】已成功应用全案`); |
|
|
|
ElMessage.success(`方案【${group.group_name}】已应用,已保留您手动选择的标签`); |
|
|
|
} |
|
|
|
} catch (err) { |
|
|
|
console.error(err); |
|
|
|
ElMessage.error("应用全案失败"); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
handleSaveClick() { |
|
|
|
this.fetchGroupNames(); |
|
|
|
this.saveForm.canvas_name = Date.now().toString(); |
|
|
|
this.saveForm.canvas_name = `${this.activeTags}_${Date.now()}`; |
|
|
|
this.saveDialogVisible = true; |
|
|
|
}, |
|
|
|
async confirmSave() { |
|
|
|
if (!this.saveForm.group_name || !this |
|
|
|
.saveForm.group_name.trim()) { |
|
|
|
return this.$message.warning("请选择或输入方案名称" |
|
|
|
); |
|
|
|
} |
|
|
|
if (!this.saveForm.canvas_name || !this |
|
|
|
.saveForm.canvas_name.trim()) { |
|
|
|
return this.$message.warning("请输入配置名称" |
|
|
|
); |
|
|
|
} |
|
|
|
const payload = { |
|
|
|
canvas_name: this.saveForm.canvas_name, |
|
|
|
group_name: this.saveForm.group_name, |
|
|
|
@ -779,30 +816,32 @@ export default { |
|
|
|
.knowledge-graph-container { |
|
|
|
display: flex; |
|
|
|
height: 100vh; |
|
|
|
background-color: #f3f3f3; /* 全局背景改为 f3f3f3 */ |
|
|
|
background-color: #f3f3f3; |
|
|
|
overflow: hidden; |
|
|
|
} |
|
|
|
|
|
|
|
.control-panel { |
|
|
|
width: 260px; |
|
|
|
background: #ffffff; |
|
|
|
border-right: 1px solid #e2e8f0; |
|
|
|
box-shadow: 4px 0 12px rgba(0, 0, 0, 0.08); |
|
|
|
padding: 10px; |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
overflow-y: auto; |
|
|
|
flex-shrink: 0; |
|
|
|
z-index: 5; |
|
|
|
} |
|
|
|
|
|
|
|
.config-list-panel { |
|
|
|
width: 320px; |
|
|
|
background: #ffffff; |
|
|
|
border-left: 1px solid #ffffff; |
|
|
|
box-shadow: -4px 0 12px rgba(0, 0, 0, 0.08); |
|
|
|
padding: 18px; |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
flex-shrink: 0; |
|
|
|
position: relative; |
|
|
|
z-index: 5; |
|
|
|
} |
|
|
|
|
|
|
|
.panel-header-container { |
|
|
|
@ -1037,7 +1076,8 @@ export default { |
|
|
|
} |
|
|
|
|
|
|
|
.config-card:hover { |
|
|
|
background-color: #e2e4e6 !important; |
|
|
|
background-color: #eff6ff !important; |
|
|
|
outline: 1.5px solid #1559f3; |
|
|
|
} |
|
|
|
|
|
|
|
.card-using { |
|
|
|
@ -1052,22 +1092,23 @@ export default { |
|
|
|
|
|
|
|
.card-left { |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
align-items: flex-start; |
|
|
|
flex: 1; |
|
|
|
min-width: 0; |
|
|
|
gap: 8px; |
|
|
|
} |
|
|
|
|
|
|
|
.checkbox-wrapper { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
margin-right: 12px; |
|
|
|
padding-right: 10px; |
|
|
|
border-right: 1px solid #d1d5db; |
|
|
|
justify-content: flex-start; |
|
|
|
margin-right: 0; |
|
|
|
padding-right: 0; |
|
|
|
border-right: none; |
|
|
|
flex-shrink: 0; |
|
|
|
height: 20px; |
|
|
|
height: auto; |
|
|
|
} |
|
|
|
|
|
|
|
.config-checkbox { |
|
|
|
margin: 0; |
|
|
|
cursor: pointer; |
|
|
|
@ -1234,6 +1275,31 @@ export default { |
|
|
|
background-color: #1559f3 !important; |
|
|
|
border-color: #1559f3 !important; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
:deep(.el-dialog) { |
|
|
|
--el-color-primary: #ebf0ff !important; |
|
|
|
--el-input-hover-border-color: #ebf0ff !important; |
|
|
|
--el-input-focus-border-color: #ebf0ff !important; |
|
|
|
--el-border-color-hover: #ebf0ff !important; |
|
|
|
} |
|
|
|
|
|
|
|
:deep(.el-dialog .el-input__wrapper) { |
|
|
|
box-shadow: 0 0 0 1px #ebf0ff inset !important; |
|
|
|
background-color: #ffffff !important; |
|
|
|
} |
|
|
|
|
|
|
|
:deep(.el-dialog .el-input.is-focus .el-input__wrapper), |
|
|
|
:deep(.el-dialog .el-input__wrapper.is-focus), |
|
|
|
:deep(.el-dialog .el-select .el-input__wrapper.is-focus), |
|
|
|
:deep(.el-dialog .el-select:hover .el-input__wrapper) { |
|
|
|
box-shadow: 0 0 0 1px #ebf0ff inset !important; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
:deep(.el-dialog .el-input__inner) { |
|
|
|
outline: none !important; |
|
|
|
} |
|
|
|
</style> |
|
|
|
|
|
|
|
<style> |
|
|
|
|