|
@@ -1,18 +1,52 @@
|
|
|
<template>
|
|
|
<hc-new-dialog v-model="linkModal" is-table title="关联构建编码" widths="72rem" @close="closeModal">
|
|
|
- <div class="h-full">
|
|
|
+ <div class="link-dialog-box h-full p-2">
|
|
|
<hc-page-split>
|
|
|
<template #left>
|
|
|
<hc-card>
|
|
|
- <el-radio-group v-model="leftRadio">
|
|
|
- <el-radio :value="3">Option A</el-radio>
|
|
|
- <el-radio :value="6">Option B</el-radio>
|
|
|
- <el-radio :value="9">Option C</el-radio>
|
|
|
+ <el-radio-group v-model="leftRadio" class="flex flex-col" style="align-items: start;">
|
|
|
+ <div v-for="value in sourceData" :key="value.id">
|
|
|
+ <el-radio :value="value.id">
|
|
|
+ {{ value.name }}
|
|
|
+ </el-radio>
|
|
|
+ </div>
|
|
|
</el-radio-group>
|
|
|
</hc-card>
|
|
|
</template>
|
|
|
<hc-card>
|
|
|
- 其它内容
|
|
|
+ <hc-search-input
|
|
|
+ v-model="queryValue"
|
|
|
+ placeholder="请输入节点关键词"
|
|
|
+ @search="searchTreeClick"
|
|
|
+ />
|
|
|
+
|
|
|
+
|
|
|
+ <el-scrollbar class="mt-4 h-[calc(100%-60px)]">
|
|
|
+ <el-tree
|
|
|
+ ref="treeRef"
|
|
|
+ :data="treeData"
|
|
|
+ :props="treeProps"
|
|
|
+ :default-expand-all="true"
|
|
|
+ :filter-node-method="filterNode"
|
|
|
+ node-key="id"
|
|
|
+ check-strictly
|
|
|
+ @node-click="handleNodeClick"
|
|
|
+ >
|
|
|
+ <!-- 自定义节点内容,使用单选框 -->
|
|
|
+ <template #default="{ node, data }">
|
|
|
+ <span class="custom-tree-node">
|
|
|
+ <!-- 使用单选框替代复选框 -->
|
|
|
+ <el-radio
|
|
|
+ v-model="selectedNodeId"
|
|
|
+ :value="data.id"
|
|
|
+ :disabled="data.nodeType === 6"
|
|
|
+ class="mr-2"
|
|
|
+ />
|
|
|
+ <span>{{ node.label }}</span>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-tree>
|
|
|
+ </el-scrollbar>
|
|
|
</hc-card>
|
|
|
</hc-page-split>
|
|
|
</div>
|
|
@@ -20,30 +54,168 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref, watch } from 'vue'
|
|
|
-
|
|
|
+import { computed, ref, watch } from 'vue'
|
|
|
|
|
|
// 接收父组件传入的属性
|
|
|
-const props = defineProps({
|
|
|
-
|
|
|
-})
|
|
|
+const props = defineProps({})
|
|
|
|
|
|
const emit = defineEmits(['close', 'save'])
|
|
|
|
|
|
+// 对话框显示状态
|
|
|
const linkModal = defineModel('modelValue', {
|
|
|
default: false,
|
|
|
})
|
|
|
+
|
|
|
+// 左侧单选框值
|
|
|
+const leftRadio = ref('1')
|
|
|
+const sourceData = ref([
|
|
|
+ { id: '1', name: '一工区' },
|
|
|
+ { id: '2', name: '二工区' },
|
|
|
+ { id: '4', name: '四工区' },
|
|
|
+ { id: '5', name: '五工区' },
|
|
|
+ { id: '6', name: '六工区' },
|
|
|
+ { id: '7', name: '二期工程' },
|
|
|
+])
|
|
|
+
|
|
|
+// 搜索关键词
|
|
|
+const queryValue = ref('')
|
|
|
+
|
|
|
+// 树形组件引用
|
|
|
+const treeRef = ref(null)
|
|
|
+
|
|
|
+// 选中的节点ID(改为单个值,而非数组)
|
|
|
+const selectedNode = ref('')
|
|
|
+
|
|
|
+// 树形结构配置
|
|
|
+const treeProps = {
|
|
|
+ label: 'name',
|
|
|
+ children: 'children',
|
|
|
+}
|
|
|
+
|
|
|
+// 树形数据 - 模拟数据
|
|
|
+const treeData = ref([
|
|
|
+ {
|
|
|
+ id: 1,
|
|
|
+ name: '路基工程',
|
|
|
+ children: [
|
|
|
+ { id: 11, name: 'K54+467.791~K54+707.3 路基工程' },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 2,
|
|
|
+ name: '涵洞通道',
|
|
|
+ children: [
|
|
|
+ { id: 21, name: 'K54+469~K54+721.5 涵洞通道' },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 3,
|
|
|
+ name: '人字预制装配护坡',
|
|
|
+ children: [
|
|
|
+ { id: 31, name: '人字预制装配护坡' },
|
|
|
+ { id: 32, name: '人字预制装配护坡 (右侧)' },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 4,
|
|
|
+ name: '路肩墙',
|
|
|
+ children: [
|
|
|
+ { id: 41, name: '路肩墙' },
|
|
|
+ { id: 42, name: '人字预制装配护坡 (右侧)' },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 5,
|
|
|
+ name: '其他工程',
|
|
|
+ children: [
|
|
|
+ { id: 51, name: '喷射植草' },
|
|
|
+ { id: 52, name: '人字预制装配护坡 (右侧)' },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+])
|
|
|
+
|
|
|
+// 监听对话框显示状态
|
|
|
watch(() => linkModal.value, (val) => {
|
|
|
-
|
|
|
+ if (val) {
|
|
|
+ // 对话框打开时的初始化操作
|
|
|
+ selectedNode.value = ''
|
|
|
+ queryValue.value = ''
|
|
|
+ loadTreeDataByWorkArea(leftRadio.value)
|
|
|
+ }
|
|
|
})
|
|
|
-const closeModal = ()=>{
|
|
|
+
|
|
|
+// 根据工区加载树形数据
|
|
|
+const loadTreeDataByWorkArea = (workArea) => {
|
|
|
+ console.log(`加载${workArea}对应的树形数据`)
|
|
|
+ // 实际项目中这里应该是接口请求
|
|
|
+}
|
|
|
+
|
|
|
+// 关闭对话框
|
|
|
+const closeModal = () => {
|
|
|
linkModal.value = false
|
|
|
-
|
|
|
emit('close')
|
|
|
}
|
|
|
-const leftRadio = ref('3')
|
|
|
+
|
|
|
+// 搜索树形节点
|
|
|
+const searchTreeClick = () => {
|
|
|
+ treeRef.value.filter(queryValue.value)
|
|
|
+}
|
|
|
+
|
|
|
+// 节点过滤方法
|
|
|
+const filterNode = (value, data) => {
|
|
|
+ if (!value) return true
|
|
|
+ return data.name.toLowerCase().includes(value.toLowerCase())
|
|
|
+}
|
|
|
+
|
|
|
+// 处理节点点击事件
|
|
|
+const handleNodeClick = (data) => {
|
|
|
+ // 如果是叶子节点才允许选中
|
|
|
+ if (!data.children || data.children.length === 0) {
|
|
|
+ selectedNode.value = data.id
|
|
|
+ }
|
|
|
+}
|
|
|
+const selectedNodeId = ref(null)
|
|
|
+// 确认关联
|
|
|
+const confirmLink = () => {
|
|
|
+ if (!selectedNode.value) {
|
|
|
+ // 提示用户未选择节点
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 找到选中的节点数据
|
|
|
+ const findSelectedNode = (nodes, id) => {
|
|
|
+ for (const node of nodes) {
|
|
|
+ if (node.id === id) return node
|
|
|
+ if (node.children) {
|
|
|
+ const found = findSelectedNode(node.children, id)
|
|
|
+ if (found) return found
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null
|
|
|
+ }
|
|
|
+
|
|
|
+ const selectedData = findSelectedNode(treeData.value, selectedNode.value)
|
|
|
+
|
|
|
+ // 触发保存事件,将选中的数据传递给父组件
|
|
|
+ emit('save', selectedData)
|
|
|
+ closeModal()
|
|
|
+}
|
|
|
+
|
|
|
+// 监听左侧工区变化,重新加载数据
|
|
|
+watch(leftRadio, (newVal) => {
|
|
|
+ loadTreeDataByWorkArea(newVal)
|
|
|
+ selectedNode.value = ''
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
+// 调整单选框与文字的对齐方式
|
|
|
+:deep(.el-radio) {
|
|
|
+ vertical-align: middle;
|
|
|
+}
|
|
|
|
|
|
-</style>
|
|
|
+.custom-tree-node {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+</style>
|