327 lines
7.7 KiB
Vue
327 lines
7.7 KiB
Vue
|
|
<template>
|
|||
|
|
<div class="container">
|
|||
|
|
<Breadcrumb :items="['menu.list', '公共组件Demo']" />
|
|||
|
|
|
|||
|
|
<!-- 使用 SearchTable 公共组件 -->
|
|||
|
|
<SearchTable
|
|||
|
|
:form-model="formModel"
|
|||
|
|
:form-items="formItems"
|
|||
|
|
:data="tableData"
|
|||
|
|
:columns="columns"
|
|||
|
|
:loading="loading"
|
|||
|
|
:pagination="pagination"
|
|||
|
|
title="公共组件演示"
|
|||
|
|
search-button-text="查询"
|
|||
|
|
reset-button-text="重置"
|
|||
|
|
download-button-text="导出"
|
|||
|
|
refresh-tooltip-text="刷新数据"
|
|||
|
|
density-tooltip-text="表格密度"
|
|||
|
|
column-setting-tooltip-text="列设置"
|
|||
|
|
@search="handleSearch"
|
|||
|
|
@reset="handleReset"
|
|||
|
|
@page-change="handlePageChange"
|
|||
|
|
@refresh="handleRefresh"
|
|||
|
|
@download="handleDownload"
|
|||
|
|
>
|
|||
|
|
<!-- 工具栏左侧按钮 -->
|
|||
|
|
<template #toolbar-left>
|
|||
|
|
<a-button type="primary" @click="handleAdd">
|
|||
|
|
<template #icon>
|
|||
|
|
<icon-plus />
|
|||
|
|
</template>
|
|||
|
|
新增
|
|||
|
|
</a-button>
|
|||
|
|
<a-button status="success" @click="handleBatchDelete">
|
|||
|
|
<template #icon>
|
|||
|
|
<icon-delete />
|
|||
|
|
</template>
|
|||
|
|
批量删除
|
|||
|
|
</a-button>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<!-- 表格自定义列:序号 -->
|
|||
|
|
<template #index="{ rowIndex }">
|
|||
|
|
{{ rowIndex + 1 + (pagination.current - 1) * pagination.pageSize }}
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<!-- 表格自定义列:状态 -->
|
|||
|
|
<template #status="{ record }">
|
|||
|
|
<a-tag :color="record.status === 'active' ? 'green' : 'red'">
|
|||
|
|
{{ record.status === 'active' ? '启用' : '禁用' }}
|
|||
|
|
</a-tag>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<!-- 表格自定义列:头像 -->
|
|||
|
|
<template #avatar="{ record }">
|
|||
|
|
<a-avatar :style="{ backgroundColor: record.avatarColor }">
|
|||
|
|
{{ record.name.charAt(0) }}
|
|||
|
|
</a-avatar>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<!-- 表格自定义列:操作 -->
|
|||
|
|
<template #operations="{ record }">
|
|||
|
|
<a-space>
|
|||
|
|
<a-button type="text" size="small" @click="handleView(record)">
|
|||
|
|
查看
|
|||
|
|
</a-button>
|
|||
|
|
<a-button type="text" size="small" @click="handleEdit(record)">
|
|||
|
|
编辑
|
|||
|
|
</a-button>
|
|||
|
|
<a-popconfirm content="确定要删除吗?" @ok="handleDelete(record)">
|
|||
|
|
<a-button type="text" size="small" status="danger">
|
|||
|
|
删除
|
|||
|
|
</a-button>
|
|||
|
|
</a-popconfirm>
|
|||
|
|
</a-space>
|
|||
|
|
</template>
|
|||
|
|
</SearchTable>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script lang="ts" setup>
|
|||
|
|
import { computed, ref, reactive } from 'vue'
|
|||
|
|
import { Message } from '@arco-design/web-vue'
|
|||
|
|
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface'
|
|||
|
|
import type { FormItem } from '@/components/search-form/types'
|
|||
|
|
|
|||
|
|
// 定义表格数据类型
|
|||
|
|
interface UserRecord {
|
|||
|
|
id: number
|
|||
|
|
name: string
|
|||
|
|
email: string
|
|||
|
|
department: string
|
|||
|
|
role: string
|
|||
|
|
status: 'active' | 'inactive'
|
|||
|
|
avatarColor: string
|
|||
|
|
createdAt: string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 模拟数据生成
|
|||
|
|
const generateMockData = (count: number): UserRecord[] => {
|
|||
|
|
const departments = ['技术部', '产品部', '运营部', '市场部', '财务部']
|
|||
|
|
const roles = ['管理员', '普通用户', '访客']
|
|||
|
|
const names = ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十']
|
|||
|
|
const colors = ['#165DFF', '#0FC6C2', '#722ED1', '#F53F3F', '#FF7D00', '#00B42A']
|
|||
|
|
|
|||
|
|
return Array.from({ length: count }, (_, i) => ({
|
|||
|
|
id: i + 1,
|
|||
|
|
name: names[i % names.length] + (Math.floor(i / names.length) || ''),
|
|||
|
|
email: `user${i + 1}@example.com`,
|
|||
|
|
department: departments[i % departments.length],
|
|||
|
|
role: roles[i % roles.length],
|
|||
|
|
status: i % 3 === 0 ? 'inactive' : 'active',
|
|||
|
|
avatarColor: colors[i % colors.length],
|
|||
|
|
createdAt: `2024-${String((i % 12) + 1).padStart(2, '0')}-${String((i % 28) + 1).padStart(2, '0')}`,
|
|||
|
|
}))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 状态管理
|
|||
|
|
const loading = ref(false)
|
|||
|
|
const tableData = ref<UserRecord[]>([])
|
|||
|
|
const formModel = ref({
|
|||
|
|
name: '',
|
|||
|
|
department: '',
|
|||
|
|
status: '',
|
|||
|
|
email: '',
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
const pagination = reactive({
|
|||
|
|
current: 1,
|
|||
|
|
pageSize: 10,
|
|||
|
|
total: 0,
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 表单项配置
|
|||
|
|
const formItems = computed<FormItem[]>(() => [
|
|||
|
|
{
|
|||
|
|
field: 'name',
|
|||
|
|
label: '用户名',
|
|||
|
|
type: 'input',
|
|||
|
|
placeholder: '请输入用户名',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
field: 'email',
|
|||
|
|
label: '邮箱',
|
|||
|
|
type: 'input',
|
|||
|
|
placeholder: '请输入邮箱',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
field: 'department',
|
|||
|
|
label: '部门',
|
|||
|
|
type: 'select',
|
|||
|
|
placeholder: '请选择部门',
|
|||
|
|
options: [
|
|||
|
|
{ label: '技术部', value: '技术部' },
|
|||
|
|
{ label: '产品部', value: '产品部' },
|
|||
|
|
{ label: '运营部', value: '运营部' },
|
|||
|
|
{ label: '市场部', value: '市场部' },
|
|||
|
|
{ label: '财务部', value: '财务部' },
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
field: 'status',
|
|||
|
|
label: '状态',
|
|||
|
|
type: 'select',
|
|||
|
|
placeholder: '请选择状态',
|
|||
|
|
options: [
|
|||
|
|
{ label: '启用', value: 'active' },
|
|||
|
|
{ label: '禁用', value: 'inactive' },
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
])
|
|||
|
|
|
|||
|
|
// 表格列配置
|
|||
|
|
const columns = computed<TableColumnData[]>(() => [
|
|||
|
|
{
|
|||
|
|
title: '序号',
|
|||
|
|
dataIndex: 'index',
|
|||
|
|
slotName: 'index',
|
|||
|
|
width: 80,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
title: '头像',
|
|||
|
|
dataIndex: 'avatar',
|
|||
|
|
slotName: 'avatar',
|
|||
|
|
width: 80,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
title: '用户名',
|
|||
|
|
dataIndex: 'name',
|
|||
|
|
width: 120,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
title: '邮箱',
|
|||
|
|
dataIndex: 'email',
|
|||
|
|
width: 200,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
title: '部门',
|
|||
|
|
dataIndex: 'department',
|
|||
|
|
width: 120,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
title: '角色',
|
|||
|
|
dataIndex: 'role',
|
|||
|
|
width: 100,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
title: '状态',
|
|||
|
|
dataIndex: 'status',
|
|||
|
|
slotName: 'status',
|
|||
|
|
width: 100,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
title: '创建时间',
|
|||
|
|
dataIndex: 'createdAt',
|
|||
|
|
width: 120,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
title: '操作',
|
|||
|
|
dataIndex: 'operations',
|
|||
|
|
slotName: 'operations',
|
|||
|
|
width: 200,
|
|||
|
|
fixed: 'right',
|
|||
|
|
},
|
|||
|
|
])
|
|||
|
|
|
|||
|
|
// 模拟异步获取数据
|
|||
|
|
const fetchData = async () => {
|
|||
|
|
loading.value = true
|
|||
|
|
|
|||
|
|
// 模拟网络延迟
|
|||
|
|
await new Promise(resolve => setTimeout(resolve, 500))
|
|||
|
|
|
|||
|
|
let data = generateMockData(86)
|
|||
|
|
|
|||
|
|
// 根据搜索条件过滤
|
|||
|
|
if (formModel.value.name) {
|
|||
|
|
data = data.filter(item => item.name.includes(formModel.value.name))
|
|||
|
|
}
|
|||
|
|
if (formModel.value.email) {
|
|||
|
|
data = data.filter(item => item.email.includes(formModel.value.email))
|
|||
|
|
}
|
|||
|
|
if (formModel.value.department) {
|
|||
|
|
data = data.filter(item => item.department === formModel.value.department)
|
|||
|
|
}
|
|||
|
|
if (formModel.value.status) {
|
|||
|
|
data = data.filter(item => item.status === formModel.value.status)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新分页
|
|||
|
|
pagination.total = data.length
|
|||
|
|
|
|||
|
|
// 分页截取
|
|||
|
|
const start = (pagination.current - 1) * pagination.pageSize
|
|||
|
|
const end = start + pagination.pageSize
|
|||
|
|
tableData.value = data.slice(start, end)
|
|||
|
|
|
|||
|
|
loading.value = false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 事件处理
|
|||
|
|
const handleSearch = () => {
|
|||
|
|
pagination.current = 1
|
|||
|
|
fetchData()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleReset = () => {
|
|||
|
|
formModel.value = {
|
|||
|
|
name: '',
|
|||
|
|
department: '',
|
|||
|
|
status: '',
|
|||
|
|
email: '',
|
|||
|
|
}
|
|||
|
|
pagination.current = 1
|
|||
|
|
fetchData()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handlePageChange = (current: number) => {
|
|||
|
|
pagination.current = current
|
|||
|
|
fetchData()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleRefresh = () => {
|
|||
|
|
fetchData()
|
|||
|
|
Message.success('数据已刷新')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleDownload = () => {
|
|||
|
|
Message.info('导出功能开发中...')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleAdd = () => {
|
|||
|
|
Message.info('新增功能开发中...')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleBatchDelete = () => {
|
|||
|
|
Message.warning('请先选择要删除的数据')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleView = (record: UserRecord) => {
|
|||
|
|
Message.info(`查看用户:${record.name}`)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleEdit = (record: UserRecord) => {
|
|||
|
|
Message.info(`编辑用户:${record.name}`)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleDelete = (record: UserRecord) => {
|
|||
|
|
Message.success(`已删除用户:${record.name}`)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化加载数据
|
|||
|
|
fetchData()
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<script lang="ts">
|
|||
|
|
export default {
|
|||
|
|
name: 'SearchTableDemo',
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style scoped lang="less">
|
|||
|
|
.container {
|
|||
|
|
padding: 0 20px 20px 20px;
|
|||
|
|
}
|
|||
|
|
</style>
|