布局框架搭建

This commit is contained in:
2026-01-16 11:19:54 +08:00
parent f33bf735d9
commit 08f97d1a21
10 changed files with 1573 additions and 70 deletions

View File

@@ -0,0 +1,193 @@
<template>
<div class="system-menu">
<a-card title="菜单管理">
<template #extra>
<a-button type="primary" @click="handleAdd">
<PlusOutlined />
新增菜单
</a-button>
</template>
<a-table :columns="columns" :data-source="dataSource" :loading="loading" :pagination="false" row-key="id">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'icon'">
<component :is="record.icon || 'MenuOutlined'" />
</template>
<template v-else-if="column.key === 'type'">
<a-tag :color="getTypeColor(record.type)">
{{ getTypeText(record.type) }}
</a-tag>
</template>
<template v-else-if="column.key === 'status'">
<a-tag :color="record.status === 1 ? 'green' : 'red'">
{{ record.status === 1 ? '正常' : '禁用' }}
</a-tag>
</template>
<template v-else-if="column.key === 'action'">
<a-space>
<a-button type="link" size="small" @click="handleEdit(record)">编辑</a-button>
<a-button type="link" size="small" @click="handleAddChild(record)">新增子菜单</a-button>
<a-button type="link" size="small" danger @click="handleDelete(record)">删除</a-button>
</a-space>
</template>
</template>
</a-table>
</a-card>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { PlusOutlined, MenuOutlined } from '@ant-design/icons-vue'
const columns = [
{
title: '菜单名称',
dataIndex: 'title',
key: 'title'
},
{
title: '图标',
dataIndex: 'icon',
key: 'icon',
width: 80
},
{
title: '路径',
dataIndex: 'path',
key: 'path'
},
{
title: '类型',
dataIndex: 'type',
key: 'type',
width: 100
},
{
title: '排序',
dataIndex: 'sort',
key: 'sort',
width: 80
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100
},
{
title: '操作',
key: 'action',
width: 220
}
]
const dataSource = ref([])
const loading = ref(false)
// 模拟数据
const mockData = [
{
id: 1,
title: '首页',
path: '/home',
icon: 'HomeOutlined',
type: 1,
sort: 1,
status: 1,
children: []
},
{
id: 2,
title: '系统管理',
path: '/system',
icon: 'SettingOutlined',
type: 1,
sort: 2,
status: 1,
children: [
{
id: 21,
title: '用户管理',
path: '/system/user',
icon: 'UserOutlined',
type: 2,
sort: 1,
status: 1
},
{
id: 22,
title: '角色管理',
path: '/system/role',
icon: 'TeamOutlined',
type: 2,
sort: 2,
status: 1
},
{
id: 23,
title: '菜单管理',
path: '/system/menu',
icon: 'MenuOutlined',
type: 2,
sort: 3,
status: 1
}
]
}
]
const loadData = () => {
loading.value = true
// 模拟接口请求
setTimeout(() => {
dataSource.value = mockData
loading.value = false
}, 500)
}
const getTypeColor = (type) => {
const colorMap = {
1: 'blue',
2: 'green',
3: 'orange'
}
return colorMap[type] || 'default'
}
const getTypeText = (type) => {
const textMap = {
1: '目录',
2: '菜单',
3: '按钮'
}
return textMap[type] || '未知'
}
const handleAdd = () => {
message.info('新增菜单功能开发中')
}
const handleEdit = (record) => {
message.info('编辑菜单功能开发中')
}
const handleAddChild = (record) => {
message.info(`新增 ${record.title} 的子菜单功能开发中`)
}
const handleDelete = (record) => {
message.info('删除菜单功能开发中')
}
onMounted(() => {
loadData()
})
</script>
<style scoped lang="scss">
.system-menu {
// 样式
}
</style>

View File

@@ -0,0 +1,141 @@
<template>
<div class="system-role">
<a-card title="角色管理">
<template #extra>
<a-button type="primary" @click="handleAdd">
<PlusOutlined />
新增角色
</a-button>
</template>
<a-table :columns="columns" :data-source="dataSource" :loading="loading" :pagination="pagination">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'status'">
<a-tag :color="record.status === 1 ? 'green' : 'red'">
{{ record.status === 1 ? '正常' : '禁用' }}
</a-tag>
</template>
<template v-else-if="column.key === 'action'">
<a-space>
<a-button type="link" size="small" @click="handleEdit(record)">编辑</a-button>
<a-button type="link" size="small" @click="handlePermission(record)">权限</a-button>
<a-button type="link" size="small" danger @click="handleDelete(record)">删除</a-button>
</a-space>
</template>
</template>
</a-table>
</a-card>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { PlusOutlined } from '@ant-design/icons-vue'
const columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 80
},
{
title: '角色名称',
dataIndex: 'roleName',
key: 'roleName'
},
{
title: '角色标识',
dataIndex: 'roleCode',
key: 'roleCode'
},
{
title: '描述',
dataIndex: 'description',
key: 'description'
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime'
},
{
title: '操作',
key: 'action',
width: 180
}
]
const dataSource = ref([])
const loading = ref(false)
const pagination = ref({
current: 1,
pageSize: 10,
total: 0,
showSizeChanger: true,
showTotal: (total) => `${total}`
})
// 模拟数据
const mockData = [
{
id: 1,
roleName: '管理员',
roleCode: 'admin',
description: '系统管理员',
status: 1,
createTime: '2024-01-01 10:00:00'
},
{
id: 2,
roleName: '普通用户',
roleCode: 'user',
description: '普通用户角色',
status: 1,
createTime: '2024-01-02 10:00:00'
}
]
const loadData = () => {
loading.value = true
// 模拟接口请求
setTimeout(() => {
dataSource.value = mockData
pagination.value.total = mockData.length
loading.value = false
}, 500)
}
const handleAdd = () => {
message.info('新增角色功能开发中')
}
const handleEdit = (record) => {
message.info('编辑角色功能开发中')
}
const handlePermission = (record) => {
message.info('权限配置功能开发中')
}
const handleDelete = (record) => {
message.info('删除角色功能开发中')
}
onMounted(() => {
loadData()
})
</script>
<style scoped lang="scss">
.system-role {
// 样式
}
</style>

View File

@@ -0,0 +1,172 @@
<template>
<div class="system-user">
<a-card title="用户管理">
<template #extra>
<a-button type="primary" @click="handleAdd">
<PlusOutlined />
新增用户
</a-button>
</template>
<div class="search-form">
<a-form :model="searchForm" layout="inline">
<a-form-item label="用户名">
<a-input v-model:value="searchForm.username" placeholder="请输入用户名" />
</a-form-item>
<a-form-item label="状态">
<a-select v-model:value="searchForm.status" placeholder="请选择状态" style="width: 120px">
<a-select-option value="">全部</a-select-option>
<a-select-option :value="1">正常</a-select-option>
<a-select-option :value="0">禁用</a-select-option>
</a-select>
</a-form-item>
<a-form-item>
<a-space>
<a-button type="primary" @click="handleSearch">查询</a-button>
<a-button @click="handleReset">重置</a-button>
</a-space>
</a-form-item>
</a-form>
</div>
<a-table :columns="columns" :data-source="dataSource" :loading="loading" :pagination="pagination">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'status'">
<a-tag :color="record.status === 1 ? 'green' : 'red'">
{{ record.status === 1 ? '正常' : '禁用' }}
</a-tag>
</template>
<template v-else-if="column.key === 'action'">
<a-space>
<a-button type="link" size="small" @click="handleEdit(record)">编辑</a-button>
<a-button type="link" size="small" danger @click="handleDelete(record)">删除</a-button>
</a-space>
</template>
</template>
</a-table>
</a-card>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { PlusOutlined } from '@ant-design/icons-vue'
const columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 80
},
{
title: '用户名',
dataIndex: 'username',
key: 'username'
},
{
title: '昵称',
dataIndex: 'nickname',
key: 'nickname'
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime'
},
{
title: '操作',
key: 'action',
width: 150
}
]
const searchForm = ref({
username: '',
status: ''
})
const dataSource = ref([])
const loading = ref(false)
const pagination = ref({
current: 1,
pageSize: 10,
total: 0,
showSizeChanger: true,
showTotal: (total) => `${total}`
})
// 模拟数据
const mockData = [
{
id: 1,
username: 'admin',
nickname: '管理员',
status: 1,
createTime: '2024-01-01 10:00:00'
},
{
id: 2,
username: 'user',
nickname: '普通用户',
status: 1,
createTime: '2024-01-02 10:00:00'
}
]
const loadData = () => {
loading.value = true
// 模拟接口请求
setTimeout(() => {
dataSource.value = mockData
pagination.value.total = mockData.length
loading.value = false
}, 500)
}
const handleSearch = () => {
loadData()
}
const handleReset = () => {
searchForm.value = {
username: '',
status: ''
}
loadData()
}
const handleAdd = () => {
message.info('新增用户功能开发中')
}
const handleEdit = (record) => {
message.info('编辑用户功能开发中')
}
const handleDelete = (record) => {
message.info('删除用户功能开发中')
}
onMounted(() => {
loadData()
})
</script>
<style scoped lang="scss">
.system-user {
.search-form {
margin-bottom: 16px;
padding: 16px;
background-color: #fafafa;
border-radius: 4px;
}
}
</style>