<template>
<div>
<div class="flex justify-between items-center py-4 h-14 px-5">
<PageHeader :title="pageTitle" @back="handlegoback" />
<div class="flex gap-2.5">
<el-button type="default" @click="handlegoback">返回</el-button>
<el-button type="primary" @click="handleSave">保存</el-button>
</div>
</div>
<el-form
:model="customForm"
:rules="customRuleSet"
ref="customFormRef"
label-width="120px"
class="flex gap-5 pt-5 border-t tlinter-border items-center pb-5"
>
<el-form-item label="规则集名称" prop="ruleSetName" class="m-0">
<el-input
v-model="customForm.ruleSetName"
placeholder="请输入1-20位规则集名称"
show-word-limit
class="w-60"
/>
</el-form-item>
<el-text
type="primary"
class="mx-1 text-[#409eff] self-center"
style="padding-bottom: 5px"
>
{{ usedRulesText }}
</el-text>
</el-form>
<div class="flex gap-0 p-5 border-t tlinter-border">
<div class="flex flex-col gap-1 w-1/4 border-r tlinter-border pr-5 h-full">
<div class="w-full h-full">
<el-input
v-model="searchQuery"
placeholder="输入规则编号/描述查询"
class="w-full"
suffix-icon="Search"
clearable
/>
</div>
<div class="flex gap-4" label-width="0">
<el-checkbox v-model="isVHDLChecked">VHDL</el-checkbox>
<el-checkbox v-model="isVerilogChecked">Verilog</el-checkbox>
</div>
<h1 class="font-inter text-base font-medium leading-[22px] tracking-0 tlinter-text-one pb-2">规则类别</h1>
<div class="flex flex-col gap-3" label-width="0">
<el-checkbox
v-for="(category, index) in ruleCategories"
:key="index"
v-model="category.checked"
:label="category.name"
class="block !mb-2 w-full"
>
{{ category.name }}
</el-checkbox>
</div>
</div>
<div class="flex-1 w-3/4 custom-form-item">
<el-table
ref="ruleTableRef"
:data="ruleTable"
style="width: 100%"
row-key="id"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55"
reserve-selection
/>
<el-table-column
width="400"
prop="ruleNo"
label="规则编号"
>
<template #header>
<div class="flex items-center gap-2">
<span>规则编号</span>
<el-select
v-model="headerSelectValue"
:placeholder="selectPlaceholder"
style="width: 120px"
@change="handleHeaderSelectChange"
>
<el-option label="启用" value="enableAll"></el-option>
<el-option label="禁用" value="disableAll"></el-option>
</el-select>
</div>
</template>
<template #default="scope">
<el-text
@click="openDrawer(scope.row)"
class="hover:text-primary cursor-pointer"
:class="activeRowId === scope.row.id ? 'el-text--primary' : ''"
>
{{ scope.row.ruleNo }}
</el-text>
</template>
</el-table-column>
<el-table-column
prop="description"
label="描述"
width="420"
/>
<el-table-column
prop="alarmType"
label="告警类型(点击标签可切换)"
>
<template #default="scope">
<el-tag
:type="getTagType(scope.row.alarmType)"
@click="toggleAlarmType(scope.row)"
:class="scope.row.alarmType === '错误' ? 'tag-pink' : 'tag-yellow'"
>
● {{ scope.row.alarmType }}
</el-tag>
</template>
</el-table-column>
</el-table>
</div>
</div>
<el-drawer
v-model="drawerVisible"
:title="drawerTitle"
size="30%"
:before-close="closeDrawer"
>
<RuleDetails :current-row="currentRow" />
</el-drawer>
</div>
</template>
<script setup>
import { ref, computed, reactive, watch, onMounted, nextTick } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { Search } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import RuleDetails from './components/ruleDetails.vue'
import PageHeader from "@/components/PageHeader.vue";
const router = useRouter()
const route = useRoute()
const ruleTableRef = ref(null)
const customFormRef = ref(null)
const headerSelectValue = ref('')
// 搜索关键词
const searchQuery = ref('')
const isVHDLChecked = ref(true)
const isVerilogChecked = ref(false)
// 抽屉相关
const drawerVisible = ref(false)
const currentRow = ref(null)
const drawerTitle = ref('')
const activeRowId = ref(null)
// 表格选中数据
const selectedRows = ref([])
// 页面标题
const pageTitle = computed(() => {
return route.query.ruleSetName || '自定义规则集'
})
// 表单数据(规则集名称)
const customForm = reactive({
ruleSetName: route.query.ruleSetName || ''
})
// 表单校验规则
const customRuleSet = reactive({
ruleSetName: [
{ required: true, message: '请输入规则集名称', trigger: 'blur' },
{ max: 20, message: '规则集名称不能超过20个字符', trigger: 'blur' }
]
})
// 规则类别(左侧筛选)
const ruleCategories = ref([
{ name: 'VHDL编码规则', checked: true },
{ name: 'VHDL同步设计规则', checked: true },
{ name: 'VHDL标头规则', checked: false },
{ name: '规则类别1', checked: false },
{ name: '规则类别2', checked: false },
{ name: '规则类别3', checked: false },
{ name: '规则类别4', checked: false },
{ name: '规则类别5', checked: false },
{ name: '规则类别6', checked: false },
{ name: '规则类别7', checked: false }
])
// 表格原始数据
const ruleData = ref([
{
id: 1,
ruleNo: 'TLR-030001V',
description: 'VHDL源文件应包含头注释',
alarmType: '错误',
category: 'VHDL编码规则',
enable: true
},
{
id: 2,
ruleNo: 'TLR-030002V',
description: '同步设计应遵循时钟域交叉原则',
alarmType: '告警',
category: 'VHDL同步设计规则',
enable: true
},
{
id: 3,
ruleNo: 'TLR-030003V',
description: '标头应包含版本、作者等信息',
alarmType: '告警',
category: 'VHDL标头规则',
enable: false
},
{
id: 4,
ruleNo: 'TLR-030004V',
description: '模块端口声明需指定方向(IN/OUT)',
alarmType: '错误',
category: 'VHDL编码规则',
enable: true
}
])
// 过滤后的表格数据
const ruleTable = computed(() => {
if (!ruleData.value || !ruleCategories.value) return []
const selectedCategoryNames = ruleCategories.value
.filter(cat => cat.checked)
.map(cat => cat.name)
if (selectedCategoryNames.length === 0) return []
let filteredData = ruleData.value.filter(item =>
selectedCategoryNames.includes(item.category)
)
if (searchQuery.value.trim()) {
const keyword = searchQuery.value.trim().toLowerCase()
filteredData = filteredData.filter(item =>
item.ruleNo.toLowerCase().includes(keyword) ||
item.description.toLowerCase().includes(keyword)
)
}
return filteredData
})
const isAllSelectedEnabled = computed(() => {
if (selectedRows.value.length === 0) return false
return selectedRows.value.every(row => row.enable === true)
})
const selectPlaceholder = computed(() => {
return isAllSelectedEnabled.value ? '已启用' : '启用状态'
})
const usedRulesText = computed(() => {
const enabledCount = ruleData.value.filter(rule => rule.enable === true).length
return `已启用${enabledCount}条规则`
})
const getTagType = computed(() => (alarmType) => {
const typeMap = {
'错误': 'danger',
'告警': 'warning'
}
return typeMap[alarmType] || 'info'
})
const handleTableSelection = (tableData) => {
if (!ruleTableRef.value || !tableData || tableData.length === 0) {
return
}
tableData.forEach(row => {
ruleTableRef.value.toggleRowSelection(row, false)
})
tableData.forEach(row => {
if (row.enable) {
ruleTableRef.value.toggleRowSelection(row, true)
}
})
}
// 表格选中事件
const handleSelectionChange = (selection) => {
selectedRows.value = selection
}
// 下拉框操作
const handleHeaderSelectChange = (value) => {
switch (value) {
case 'enableAll':
handleBatchEnable()
break
case 'disableAll':
handleBatchDisable()
break
}
headerSelectValue.value = ''
}
// 批量启用
const handleBatchEnable = () => {
if (selectedRows.value.length === 0) {
ElMessage.warning('请先选择要启用的规则')
return
}
ruleData.value.forEach(row => { row.enable = false })
selectedRows.value.forEach(selectedRow => {
const targetRow = ruleData.value.find(row => row.id === selectedRow.id)
if (targetRow) targetRow.enable = true
})
handleTableSelection(ruleTable.value)
// ElMessage.success(`成功启用${selectedRows.value.length}条规则`)
}
// 批量禁用
const handleBatchDisable = () => {
if (selectedRows.value.length === 0) {
ElMessage.warning('请先选择要禁用的规则')
return
}
selectedRows.value.forEach(selectedRow => {
const targetRow = ruleData.value.find(row => row.id === selectedRow.id)
if (targetRow) targetRow.enable = false
})
handleTableSelection(ruleTable.value)
// ElMessage.success(`成功禁用${selectedRows.value.length}条规则`)
}
// 切换告警类型
const toggleAlarmType = (row) => {
const types = ['错误', '告警']
const currentIdx = types.indexOf(row.alarmType)
row.alarmType = types[(currentIdx + 1) % types.length]
}
// 打开规则详情抽屉
const openDrawer = (row) => {
currentRow.value = row
drawerTitle.value = row.ruleNo
activeRowId.value = row.id
drawerVisible.value = true
}
// 关闭抽屉
const closeDrawer = () => {
currentRow.value = null
drawerTitle.value = ''
activeRowId.value = null
drawerVisible.value = false
}
// 保存规则集
const handleSave = async () => {
const valid = await customFormRef.value.validate()
if (!valid) return
const savedData = {
name: customForm.ruleSetName,
enabledRules: ruleData.value.filter(rule => rule.enable),
totalEnabled: ruleData.value.filter(rule => rule.enable).length,
updateTime: new Date().toLocaleString()
}
console.log('保存规则集数据:', savedData)
ElMessage.success('规则集保存成功')
handlegoback()
}
// 返回上一页
const handlegoback = () => {
router.push("/rules")
}
// 监听表格数据变化
watch(
() => ruleTable.value,
(newTableData) => {
handleTableSelection(newTableData)
},
{ immediate: true, deep: true }
)
// 监听选中数据变化
watch(
() => selectedRows.value,
(newSelected) => {
if (isAllSelectedEnabled.value) {
headerSelectValue.value = 'enableAll'
} else {
const validActions = ['enableAll', 'disableAll']
if (!validActions.includes(headerSelectValue.value)) {
headerSelectValue.value = ''
}
}
},
{ deep: true }
)
// 组件挂载完成后,确保表格选中状态初始化
onMounted(async () => {
await nextTick()
handleTableSelection(ruleTable.value)
})
</script>
<style scoped lang="scss">
:deep(.custom-form-item .el-form-item__content) {
margin-left: 20px !important;
}
// 抽屉样式调整
:deep(.el-drawer__header) {
margin-bottom: 0px !important;
padding: 16px 24px !important;
border-bottom: 1px solid #eee;
}
</style>分析代码,修改代码文件,1.完成VHDL和Verilog改为单选框,并且选择VHDL时,规则类别下面的多选框只显示VHDL的规则类别,选择Verilog时,只显示Verilog的规则类别。2.完成规则类别下面的多选框,点击时表格里面数据只显示当前点击的规则类别里面的编号,点击另一个时,只显示另一个规则类别的规则编号,增加模拟数据完善此功能。并且给当前点击的规则类别增加背景色,选择框显示改为为如图图标,用unocss。编写完整代码显示出来
最新发布