fix(menu): 统一权限验证机制并优化表单布局
- 修复表格头部操作栏权限验证方式,从v-permission指令改为hasButton函数 - 统一表格头部和表格行的权限验证逻辑,确保权限控制一致性 - 优化菜单表单字段布局: * 英文菜单+选择路由并排显示 * 目录类型添加是否固钉字段 * 菜单类型的是否缓存+页面路径并排显示 - 调整input框padding值,改善表单字段间距 - 添加完整的菜单路径显示功能,支持层级路径展示 - 修复空状态组件的权限控制逻辑
This commit is contained in:
parent
ef1acb7368
commit
7b1c300937
@ -73,7 +73,7 @@
|
||||
<!-- 表格头部操作栏 -->
|
||||
<div class="flex items-center justify-between px-4 py-2 border-b border-gray-100">
|
||||
<div class="flex items-center gap-4">
|
||||
<NButton v-permission="PERMISSIONS.MENU.ADD" type="primary" class="px-6 flex items-center" @click="handleAdd">
|
||||
<NButton v-if="hasButton(PERMISSIONS.MENU.ADD)" type="primary" size="medium" class="px-3 flex items-center" @click="handleAdd">
|
||||
<template #icon>
|
||||
<NIcon class="mr-1" style="transform: translateY(-1px)">
|
||||
<icon-park-outline:plus />
|
||||
@ -83,10 +83,11 @@
|
||||
</NButton>
|
||||
|
||||
<NButton
|
||||
v-permission="PERMISSIONS.MENU.DELETE"
|
||||
v-if="hasButton(PERMISSIONS.MENU.DELETE)"
|
||||
type="error"
|
||||
size="medium"
|
||||
:disabled="selectedRows.length === 0"
|
||||
class="px-6 flex items-center"
|
||||
class="px-3 flex items-center"
|
||||
@click="handleBatchDelete"
|
||||
>
|
||||
<template #icon>
|
||||
@ -97,7 +98,7 @@
|
||||
删除
|
||||
</NButton>
|
||||
|
||||
<NButton class="px-6 flex items-center" @click="handleExpandToggle">
|
||||
<NButton size="medium" class="px-3 flex items-center" @click="handleExpandToggle">
|
||||
<template #icon>
|
||||
<NIcon class="mr-1" style="transform: translateY(-1px)">
|
||||
<icon-park-outline:expand-up v-if="isAllExpanded" />
|
||||
@ -130,7 +131,7 @@
|
||||
:bordered="false"
|
||||
:single-line="false"
|
||||
children-key="children"
|
||||
size="large"
|
||||
size="medium"
|
||||
class="custom-table"
|
||||
@update:checked-row-keys="handleRowSelectionChange"
|
||||
@update:expanded-row-keys="handleExpandedKeysChange"
|
||||
@ -142,13 +143,14 @@
|
||||
:type="getEmptyType()"
|
||||
:title="getEmptyTitle()"
|
||||
:description="getEmptyDescription()"
|
||||
:show-action="true"
|
||||
:show-action="getShowEmptyAction()"
|
||||
:action-text="getEmptyActionText()"
|
||||
size="medium"
|
||||
@action="handleEmptyAction"
|
||||
>
|
||||
<template #action>
|
||||
<NButton
|
||||
v-if="getShowEmptyAction()"
|
||||
type="primary"
|
||||
size="medium"
|
||||
round
|
||||
@ -366,7 +368,7 @@
|
||||
</n-grid-item>
|
||||
</n-grid>
|
||||
|
||||
<!-- 英文菜单 + 页面路径 -->
|
||||
<!-- 英文菜单 + 选择路由 -->
|
||||
<n-grid :cols="2" :x-gap="10" class="mb-2">
|
||||
<n-grid-item v-if="formData.menuType !== '3'">
|
||||
<n-form-item label="英文菜单" path="enName">
|
||||
@ -376,11 +378,11 @@
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item v-if="formData.menuType === '2'">
|
||||
<n-form-item label="页面路径" path="component">
|
||||
<n-grid-item v-if="formData.menuType !== '3'">
|
||||
<n-form-item label="选择路由" path="component">
|
||||
<n-input
|
||||
v-model:value="formData.component"
|
||||
placeholder="例如:system/user/index"
|
||||
placeholder="例如:/system/dict/type"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
@ -432,17 +434,29 @@
|
||||
</n-grid-item>
|
||||
</n-grid>
|
||||
|
||||
<!-- 是否缓存 -->
|
||||
<n-form-item label="是否缓存" path="isKeepAlive" class="mb-2">
|
||||
<n-radio-group v-model:value="formData.isKeepAlive">
|
||||
<n-radio value="0">
|
||||
是
|
||||
</n-radio>
|
||||
<n-radio value="1">
|
||||
否
|
||||
</n-radio>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<!-- 是否缓存 + 页面路径 -->
|
||||
<n-grid :cols="2" :x-gap="10" class="mb-2">
|
||||
<n-grid-item>
|
||||
<n-form-item label="是否缓存" path="isKeepAlive">
|
||||
<n-radio-group v-model:value="formData.isKeepAlive">
|
||||
<n-radio value="0">
|
||||
是
|
||||
</n-radio>
|
||||
<n-radio value="1">
|
||||
否
|
||||
</n-radio>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="页面路径" path="component">
|
||||
<n-input
|
||||
v-model:value="formData.component"
|
||||
placeholder="请输入页面路径[system/user/ind]"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
</n-grid>
|
||||
|
||||
<!-- 是否展开 + 是否固钉 -->
|
||||
<n-grid :cols="2" :x-gap="10" class="mb-2">
|
||||
@ -473,18 +487,34 @@
|
||||
</n-grid>
|
||||
</template>
|
||||
|
||||
<!-- 目录类型时显示是否展开 -->
|
||||
<!-- 目录类型时显示是否展开 + 是否固钉 -->
|
||||
<template v-if="formData.menuType === '1'">
|
||||
<n-form-item label="是否展开" path="isSpread" class="mb-2">
|
||||
<n-radio-group v-model:value="formData.isSpread">
|
||||
<n-radio value="0">
|
||||
是
|
||||
</n-radio>
|
||||
<n-radio value="1">
|
||||
否
|
||||
</n-radio>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<n-grid :cols="2" :x-gap="10" class="mb-2">
|
||||
<n-grid-item>
|
||||
<n-form-item label="是否展开" path="isSpread">
|
||||
<n-radio-group v-model:value="formData.isSpread">
|
||||
<n-radio value="0">
|
||||
是
|
||||
</n-radio>
|
||||
<n-radio value="1">
|
||||
否
|
||||
</n-radio>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="是否固钉" path="isAffix">
|
||||
<n-radio-group v-model:value="formData.isAffix">
|
||||
<n-radio value="0">
|
||||
是
|
||||
</n-radio>
|
||||
<n-radio value="1">
|
||||
否
|
||||
</n-radio>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
</n-grid>
|
||||
</template>
|
||||
|
||||
<!-- 外链地址 -->
|
||||
@ -514,7 +544,8 @@ import CoiEmpty from '@/components/common/CoiEmpty.vue'
|
||||
import CoiIcon from '@/components/common/CoiIcon.vue'
|
||||
import IconSelect from '@/components/common/IconSelect.vue'
|
||||
import { PERMISSIONS } from '@/constants/permissions'
|
||||
import { coiMsgBox, coiMsgError, coiMsgSuccess } from '@/utils/coi'
|
||||
import { usePermission } from '@/hooks'
|
||||
import { coiMsgBox, coiMsgError, coiMsgSuccess, coiMsgWarning } from '@/utils/coi'
|
||||
import {
|
||||
addMenu,
|
||||
batchDeleteMenu,
|
||||
@ -531,6 +562,9 @@ import { colord } from 'colord'
|
||||
// 应用状态
|
||||
const appStore = useAppStore()
|
||||
|
||||
// 权限检查
|
||||
const { hasButton } = usePermission()
|
||||
|
||||
// 主题色计算属性
|
||||
const themeColors = computed(() => {
|
||||
const primary = appStore.primaryColor
|
||||
@ -598,13 +632,13 @@ const rules: FormRules = {
|
||||
],
|
||||
parentId: [
|
||||
{
|
||||
required: false, // 改为非必填,因为'0'是有效的顶级菜单值
|
||||
type: 'string',
|
||||
required: true,
|
||||
message: '请选择上级菜单',
|
||||
trigger: ['change', 'blur'],
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
// parentId 应该是一个有效的字符串
|
||||
if (typeof value === 'string' && value.length > 0) {
|
||||
// 允许字符串或数字类型,并确保有效值
|
||||
const stringValue = String(value)
|
||||
if (stringValue && stringValue.length > 0 && stringValue !== 'undefined' && stringValue !== 'null') {
|
||||
callback()
|
||||
}
|
||||
else {
|
||||
@ -728,7 +762,7 @@ const columns: DataTableColumns<MenuVo> = [
|
||||
render: row => row.auth || '-',
|
||||
},
|
||||
{
|
||||
title: '页面路径',
|
||||
title: '选择路由',
|
||||
key: 'component',
|
||||
width: 200,
|
||||
align: 'center',
|
||||
@ -798,16 +832,16 @@ const columns: DataTableColumns<MenuVo> = [
|
||||
const buttons = []
|
||||
|
||||
// 新增子菜单按钮
|
||||
if (row.menuType !== '3') {
|
||||
if (row.menuType !== '3' && hasButton(PERMISSIONS.MENU.ADD)) {
|
||||
buttons.push(h(NTooltip, {
|
||||
trigger: 'hover',
|
||||
}, {
|
||||
default: () => '新增子菜单',
|
||||
trigger: () => h(NButton, {
|
||||
type: 'info',
|
||||
type: 'success',
|
||||
size: 'medium',
|
||||
circle: true,
|
||||
class: 'action-btn action-btn-info',
|
||||
class: 'action-btn action-btn-success',
|
||||
onClick: () => handleAddChild(row),
|
||||
}, {
|
||||
icon: () => h(NIcon, { size: 18 }, { default: () => h(IconParkOutlinePlus) }),
|
||||
@ -816,42 +850,46 @@ const columns: DataTableColumns<MenuVo> = [
|
||||
}
|
||||
|
||||
// 编辑按钮
|
||||
buttons.push(h(NTooltip, {
|
||||
trigger: 'hover',
|
||||
}, {
|
||||
default: () => '编辑',
|
||||
trigger: () => h(NButton, {
|
||||
type: 'primary',
|
||||
size: 'medium',
|
||||
circle: true,
|
||||
class: 'action-btn action-btn-edit',
|
||||
onClick: () => handleEdit(row),
|
||||
}, {
|
||||
icon: () => h(NIcon, { size: 18 }, { default: () => h(IconParkOutlineEdit) }),
|
||||
}),
|
||||
}))
|
||||
|
||||
// 删除按钮
|
||||
buttons.push(h(NPopconfirm, {
|
||||
onPositiveClick: () => handleDelete(row.menuId),
|
||||
negativeText: '取消',
|
||||
positiveText: '确定',
|
||||
}, {
|
||||
default: () => '确定删除此菜单吗?',
|
||||
trigger: () => h(NTooltip, {
|
||||
if (hasButton(PERMISSIONS.MENU.UPDATE)) {
|
||||
buttons.push(h(NTooltip, {
|
||||
trigger: 'hover',
|
||||
}, {
|
||||
default: () => '删除',
|
||||
default: () => '编辑',
|
||||
trigger: () => h(NButton, {
|
||||
type: 'error',
|
||||
type: 'primary',
|
||||
size: 'medium',
|
||||
circle: true,
|
||||
class: 'action-btn action-btn-delete',
|
||||
class: 'action-btn action-btn-edit',
|
||||
onClick: () => handleEdit(row),
|
||||
}, {
|
||||
icon: () => h(NIcon, { size: 18 }, { default: () => h(IconParkOutlineDelete) }),
|
||||
icon: () => h(NIcon, { size: 18 }, { default: () => h(IconParkOutlineEdit) }),
|
||||
}),
|
||||
}),
|
||||
}))
|
||||
}))
|
||||
}
|
||||
|
||||
// 删除按钮
|
||||
if (hasButton(PERMISSIONS.MENU.DELETE)) {
|
||||
buttons.push(h(NPopconfirm, {
|
||||
onPositiveClick: () => handleDelete(row.menuId),
|
||||
negativeText: '取消',
|
||||
positiveText: '确定',
|
||||
}, {
|
||||
default: () => '确定删除此菜单吗?',
|
||||
trigger: () => h(NTooltip, {
|
||||
trigger: 'hover',
|
||||
}, {
|
||||
default: () => '删除',
|
||||
trigger: () => h(NButton, {
|
||||
type: 'error',
|
||||
size: 'medium',
|
||||
circle: true,
|
||||
class: 'action-btn action-btn-delete',
|
||||
}, {
|
||||
icon: () => h(NIcon, { size: 18 }, { default: () => h(IconParkOutlineDelete) }),
|
||||
}),
|
||||
}),
|
||||
}))
|
||||
}
|
||||
|
||||
return h('div', { class: 'flex items-center justify-center gap-2' }, buttons)
|
||||
},
|
||||
@ -908,22 +946,31 @@ function addTreeIndexToMenus(menus: MenuVo[]) {
|
||||
|
||||
// 构建菜单树
|
||||
function buildMenuTree(menus: MenuVo[]): MenuVo[] {
|
||||
const menuMap = new Map<number, MenuVo>()
|
||||
const menuMap = new Map<string, MenuVo>()
|
||||
const result: MenuVo[] = []
|
||||
|
||||
// 先将所有菜单放入map
|
||||
// 先将所有菜单放入map,确保ID为字符串类型
|
||||
menus.forEach((menu) => {
|
||||
menuMap.set(menu.menuId, { ...menu, children: [] })
|
||||
const normalizedMenu = {
|
||||
...menu,
|
||||
menuId: String(menu.menuId),
|
||||
parentId: String(menu.parentId),
|
||||
children: [],
|
||||
}
|
||||
menuMap.set(normalizedMenu.menuId, normalizedMenu)
|
||||
})
|
||||
|
||||
// 构建树形结构
|
||||
menus.forEach((menu) => {
|
||||
const currentMenu = menuMap.get(menu.menuId)!
|
||||
if (menu.parentId === 0) {
|
||||
const menuId = String(menu.menuId)
|
||||
const parentId = String(menu.parentId)
|
||||
const currentMenu = menuMap.get(menuId)!
|
||||
|
||||
if (parentId === '0') {
|
||||
result.push(currentMenu)
|
||||
}
|
||||
else {
|
||||
const parent = menuMap.get(menu.parentId)
|
||||
const parent = menuMap.get(parentId)
|
||||
if (parent) {
|
||||
parent.children = parent.children || []
|
||||
parent.children.push(currentMenu)
|
||||
@ -1028,7 +1075,7 @@ async function getMenuCascaderData() {
|
||||
// 转换菜单数据为级联选择器格式
|
||||
function convertToMenuCascader(menuTree: MenuVo[]): MenuCascaderBo[] {
|
||||
return menuTree.map(menu => ({
|
||||
value: menu.menuId,
|
||||
value: String(menu.menuId), // 确保value为字符串类型
|
||||
label: menu.menuName,
|
||||
children: menu.children && menu.children.length > 0
|
||||
? convertToMenuCascader(menu.children)
|
||||
@ -1036,14 +1083,14 @@ function convertToMenuCascader(menuTree: MenuVo[]): MenuCascaderBo[] {
|
||||
}))
|
||||
}
|
||||
|
||||
// 获取选中菜单的显示文本
|
||||
function getSelectedMenuText() {
|
||||
if (formData.value.parentId === '0') {
|
||||
// 构建菜单完整路径
|
||||
function buildMenuPath(menuId: string): string {
|
||||
if (menuId === '0') {
|
||||
return '最顶级菜单'
|
||||
}
|
||||
|
||||
// 先在顶级菜单中查找
|
||||
const topMenu = topLevelMenus.value.find(menu => menu.value === formData.value.parentId)
|
||||
const topMenu = topLevelMenus.value.find(menu => menu.value === menuId)
|
||||
if (topMenu) {
|
||||
return topMenu.label
|
||||
}
|
||||
@ -1051,9 +1098,9 @@ function getSelectedMenuText() {
|
||||
// 再在子菜单中查找
|
||||
for (const menu of topLevelMenus.value) {
|
||||
if (menu.children?.length) {
|
||||
const subMenu = menu.children.find(child => child.value === formData.value.parentId)
|
||||
const subMenu = menu.children.find(child => child.value === menuId)
|
||||
if (subMenu) {
|
||||
return subMenu.label
|
||||
return `${menu.label} / ${subMenu.label}`
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1061,10 +1108,15 @@ function getSelectedMenuText() {
|
||||
return selectedMenuText.value
|
||||
}
|
||||
|
||||
// 获取选中菜单的显示文本
|
||||
function getSelectedMenuText() {
|
||||
return buildMenuPath(formData.value.parentId)
|
||||
}
|
||||
|
||||
// 处理选择父菜单
|
||||
function handleSelectParent(value: string, label: string) {
|
||||
function handleSelectParent(value: string, _label: string) {
|
||||
formData.value.parentId = value
|
||||
selectedMenuText.value = label
|
||||
selectedMenuText.value = buildMenuPath(value) // 使用完整路径
|
||||
// 关闭弹窗
|
||||
parentSelectorRef.value?.setShow(false)
|
||||
|
||||
@ -1163,28 +1215,7 @@ function handleAdd() {
|
||||
|
||||
// 设置父菜单显示文本的辅助函数
|
||||
function setParentMenuText(parentId: string) {
|
||||
if (parentId === '0') {
|
||||
selectedMenuText.value = '最顶级菜单'
|
||||
return
|
||||
}
|
||||
|
||||
// 在级联数据中查找父菜单名称
|
||||
function findMenuNameById(menus: MenuCascaderBo[], targetId: string): string | null {
|
||||
for (const menu of menus) {
|
||||
if (menu.value === targetId) {
|
||||
return menu.label
|
||||
}
|
||||
if (menu.children?.length) {
|
||||
const found = findMenuNameById(menu.children, targetId)
|
||||
if (found)
|
||||
return found
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const parentMenuName = findMenuNameById(topLevelMenus.value, parentId)
|
||||
selectedMenuText.value = parentMenuName || `菜单ID: ${parentId}`
|
||||
selectedMenuText.value = buildMenuPath(parentId)
|
||||
}
|
||||
|
||||
// 新增子菜单
|
||||
@ -1194,8 +1225,8 @@ function handleAddChild(parentMenu: MenuVo) {
|
||||
resetFormData()
|
||||
|
||||
// 设置父菜单信息
|
||||
formData.value.parentId = parentMenu.menuId // 直接使用字符串,无需转换
|
||||
selectedMenuText.value = parentMenu.menuName // 设置显示文本
|
||||
formData.value.parentId = String(parentMenu.menuId) // 确保转换为字符串类型
|
||||
selectedMenuText.value = buildMenuPath(String(parentMenu.menuId)) // 设置完整路径显示文本
|
||||
|
||||
// 根据父菜单类型智能设置子菜单默认类型
|
||||
if (parentMenu.menuType === '1') {
|
||||
@ -1219,10 +1250,11 @@ function handleEdit(menu: MenuVo) {
|
||||
formData.value = {
|
||||
...menu,
|
||||
sorted: Number(menu.sorted), // 确保 sorted 是数字类型
|
||||
parentId: String(menu.parentId), // 确保 parentId 是字符串类型
|
||||
}
|
||||
|
||||
// 设置父菜单显示文本
|
||||
setParentMenuText(menu.parentId)
|
||||
setParentMenuText(String(menu.parentId))
|
||||
|
||||
menuDialogRef.value?.coiOpen()
|
||||
}
|
||||
@ -1339,9 +1371,21 @@ function handleMenuTypeChange(value: string) {
|
||||
|
||||
// 提交表单
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
await formRef.value?.validate()
|
||||
if (!formRef.value)
|
||||
return
|
||||
|
||||
try {
|
||||
// 先进行表单验证
|
||||
await formRef.value.validate()
|
||||
}
|
||||
catch {
|
||||
// 表单验证失败,提示用户检查填写内容
|
||||
coiMsgWarning('验证失败,请检查填写内容')
|
||||
return
|
||||
}
|
||||
|
||||
// 表单验证通过,执行API调用
|
||||
try {
|
||||
// 保存当前的展开状态
|
||||
const currentExpandedKeys = [...expandedKeys.value]
|
||||
const currentIsAllExpanded = isAllExpanded.value
|
||||
@ -1367,7 +1411,10 @@ async function handleSubmit() {
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof Error) {
|
||||
coiMsgError(error.message || '操作失败')
|
||||
coiMsgError(error.message || (isEdit.value ? '修改失败,请检查网络连接' : '新增失败,请检查网络连接'))
|
||||
}
|
||||
else {
|
||||
coiMsgError(isEdit.value ? '修改失败,请检查网络连接' : '新增失败,请检查网络连接')
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1427,6 +1474,15 @@ function getEmptyActionText() {
|
||||
return hasSearchConditions() ? '重置搜索' : '新增菜单'
|
||||
}
|
||||
|
||||
function getShowEmptyAction() {
|
||||
// 有搜索条件时总是显示重置按钮
|
||||
if (hasSearchConditions()) {
|
||||
return true
|
||||
}
|
||||
// 无数据时只有有新增权限才显示新增按钮
|
||||
return hasButton(PERMISSIONS.MENU.ADD)
|
||||
}
|
||||
|
||||
function handleEmptyAction() {
|
||||
if (hasSearchConditions()) {
|
||||
handleReset()
|
||||
@ -1449,18 +1505,35 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.custom-table {
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.custom-table :deep(.n-data-table-td) {
|
||||
padding: 8px 12px !important;
|
||||
}
|
||||
|
||||
.custom-table :deep(.n-data-table-th) {
|
||||
padding: 8px 12px !important;
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
||||
.custom-table :deep(.n-data-table-thead .n-data-table-th) {
|
||||
background-color: #f8f9fa;
|
||||
font-weight: 600;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.custom-table :deep(.n-data-table-tbody .n-data-table-tr) {
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
.custom-table :deep(.n-data-table-tbody .n-data-table-tr:hover) {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.custom-table :deep(.n-data-table-tbody .n-data-table-td) {
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
background-color: #fff;
|
||||
}
|
||||
@ -1551,6 +1624,17 @@ onMounted(() => {
|
||||
box-shadow: 0 4px 16px rgba(6, 182, 212, 0.4) !important;
|
||||
}
|
||||
|
||||
/* 成功按钮 */
|
||||
.action-btn-success {
|
||||
background: linear-gradient(135deg, #10b981 0%, #059669 100%) !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.action-btn-success:hover {
|
||||
background: linear-gradient(135deg, #059669 0%, #047857 100%) !important;
|
||||
box-shadow: 0 4px 16px rgba(16, 185, 129, 0.4) !important;
|
||||
}
|
||||
|
||||
/* 紧凑表单样式 */
|
||||
.compact-form :deep(.n-form-item) {
|
||||
margin-bottom: 8px !important;
|
||||
@ -1574,13 +1658,13 @@ onMounted(() => {
|
||||
|
||||
.compact-form :deep(.n-input .n-input__input-el),
|
||||
.compact-form :deep(.n-input-number .n-input__input-el) {
|
||||
padding: 8px 12px !important;
|
||||
padding: 2px 1px !important;
|
||||
min-height: 32px !important;
|
||||
}
|
||||
|
||||
.compact-form :deep(.n-cascader .n-cascader-trigger) {
|
||||
min-height: 32px !important;
|
||||
padding: 8px 12px !important;
|
||||
padding: 2px 1px !important;
|
||||
}
|
||||
|
||||
/* 自定义菜单选择器样式 */
|
||||
@ -1602,7 +1686,7 @@ onMounted(() => {
|
||||
|
||||
.column-header {
|
||||
background: #f5f5f5;
|
||||
padding: 8px 12px;
|
||||
padding: 8px 10px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
@ -1617,7 +1701,7 @@ onMounted(() => {
|
||||
.menu-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
padding: 8px 10px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s, color 0.2s;
|
||||
position: relative;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user