feat: 重构操作按钮为下拉菜单并新增工单详情弹窗

- 重构角色、菜单、项目方案、客户账号页面的操作按钮,将多个操作整合为下拉菜单
- 统一使用 Modal.confirm 替代 Popconfirm 解决下拉菜单内锚定问题
- 新增勘察工单详情弹窗,支持查看工单完整信息
- 调整操作列宽度和对齐方式,优化表格布局
- 统一中文 locale 配置,使用 dayjs 中文 locale
This commit is contained in:
andyesfly committed 2026-09-26 14:09:57 +08:00
1 parent ae79d5157b
commit e03fb019c5
6 files changed
+497 -230

No files matched your search

+42 -16
View File
@@ -30,19 +30,18 @@
</template>
<template v-else-if="column.key === 'action'">
<a-space>
<a-button type="link" size="small" @click="handleAdd(record)">
<PlusOutlined />新增子菜单
</a-button>
<a-button type="link" size="small" @click="handleEdit(record)">
<EditOutlined />编辑
</a-button>
<a-popconfirm title="确定删除该菜单?" ok-text="确定" cancel-text="取消" @confirm="handleDelete(record)">
<a-button type="link" size="small" danger>
<DeleteOutlined />删除
</a-button>
</a-popconfirm>
</a-space>
<div class="row-actions">
<a-button type="primary" size="small" @click="handleEdit(record)">编辑</a-button>
<a-dropdown trigger="click">
<a-button type="link" size="small">更多 <DownOutlined /></a-button>
<template #overlay>
<a-menu @click="({ key }) => handleMore(key as string, record)">
<a-menu-item key="addChild">新增子菜单</a-menu-item>
<a-menu-item key="delete" danger>删除</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</div>
</template>
</template>
</a-table>
@@ -100,8 +99,8 @@
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue';
import { message } from 'ant-design-vue';
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons-vue';
import { message, Modal } from 'ant-design-vue';
import { PlusOutlined, DownOutlined } from '@ant-design/icons-vue';
import { menuApi } from '@/api/menu';
import { useTableScroll } from '@/composables/useTableScroll';
@@ -134,7 +133,7 @@ const columns = [
{ title: '排序', dataIndex: 'sortOrder', key: 'sortOrder', width: 80, align: 'center' as const },
{ title: '权限标识', dataIndex: 'permission', key: 'permission', width: 150 },
{ title: '可见性', dataIndex: 'visible', key: 'visible', width: 90, align: 'center' as const },
{ title: '操作', key: 'action', width: 240, fixed: 'right' as const },
{ title: '操作', key: 'action', width: 150, align: 'center' as const, fixed: 'right' as const },
];
// 上级菜单树(编辑时排除自身及后代节点,防止循环引用)
@@ -300,6 +299,25 @@ async function handleDelete(record: MenuItem) {
message.error('删除失败');
}
}
// 「更多」下拉分发:删除需二次确认,popconfirm 在 dropdown 内无法正常锚定,改用 Modal.confirm
function handleMore(key: string, record: MenuItem) {
if (key === 'addChild') return handleAdd(record);
if (key === 'delete') return confirmDelete(record);
}
function confirmDelete(record: MenuItem) {
Modal.confirm({
title: '确认删除该菜单?',
content: `菜单「${record.menuName}」将被删除。`,
okText: '确认删除',
okType: 'danger',
cancelText: '取消',
onOk() {
return handleDelete(record);
},
});
}
</script>
<style scoped lang="less">
@@ -333,6 +351,14 @@ async function handleDelete(record: MenuItem) {
overflow: hidden;
}
.row-actions {
display: flex;
align-items: center;
justify-content: center;
gap: 2px;
flex-wrap: nowrap;
}
:deep(.ant-btn-link) {
padding: 0 4px;
}
+43 -27
View File
@@ -49,24 +49,18 @@
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<a-button type="link" size="small" @click="handlePermission(record)">
<KeyOutlined />权限配置
</a-button>
<a-button type="link" size="small" @click="handleEdit(record)">
<EditOutlined />编辑
</a-button>
<a-popconfirm
title="确定删除该角色?"
ok-text="确定"
cancel-text="取消"
@confirm="handleDelete(record)"
>
<a-button type="link" size="small" danger>
<DeleteOutlined />删除
</a-button>
</a-popconfirm>
</a-space>
<div class="row-actions">
<a-button type="primary" size="small" @click="handlePermission(record)">权限配置</a-button>
<a-dropdown trigger="click">
<a-button type="link" size="small">更多 <DownOutlined /></a-button>
<template #overlay>
<a-menu @click="({ key }) => handleMore(key as string, record)">
<a-menu-item key="edit">编辑</a-menu-item>
<a-menu-item key="delete" danger>删除</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</div>
</template>
</template>
</a-table>
@@ -138,14 +132,8 @@
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue';
import { message } from 'ant-design-vue';
import {
PlusOutlined,
SearchOutlined,
KeyOutlined,
EditOutlined,
DeleteOutlined,
} from '@ant-design/icons-vue';
import { message, Modal } from 'ant-design-vue';
import { PlusOutlined, SearchOutlined, DownOutlined } from '@ant-design/icons-vue';
import { roleApi, type RoleInfo } from '@/api/role';
import { useTableScroll } from '@/composables/useTableScroll';
import dayjs from 'dayjs';
@@ -207,7 +195,8 @@ const columns = [
title: '操作',
dataIndex: 'action',
key: 'action',
width: 280,
width: 190,
align: 'center' as const,
fixed: 'right' as const,
},
];
@@ -345,6 +334,25 @@ async function handleDelete(record: RoleInfo) {
}
}
// 「更多」下拉分发:删除需二次确认,popconfirm 在 dropdown 内无法正常锚定,改用 Modal.confirm
function handleMore(key: string, record: RoleInfo) {
if (key === 'edit') return handleEdit(record);
if (key === 'delete') return confirmDelete(record);
}
function confirmDelete(record: RoleInfo) {
Modal.confirm({
title: '确认删除该角色?',
content: `角色「${record.roleName}」将被删除。`,
okText: '确认删除',
okType: 'danger',
cancelText: '取消',
onOk() {
return handleDelete(record);
},
});
}
function handleViewUsers(_record: RoleInfo) {
message.info('查看用户功能开发中');
}
@@ -448,6 +456,14 @@ onMounted(() => {
height: 100%;
}
.row-actions {
display: flex;
align-items: center;
justify-content: center;
gap: 2px;
flex-wrap: nowrap;
}
:deep(.ant-btn-link) {
padding: 0 4px;
}