初始化本地仓库
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
<!-- 角色管理页面 -->
|
||||
<template>
|
||||
<div class="art-full-height">
|
||||
<RoleSearch
|
||||
v-show="showSearchBar"
|
||||
v-model="searchForm"
|
||||
@search="handleSearch"
|
||||
@reset="resetSearchParams"
|
||||
></RoleSearch>
|
||||
|
||||
<ElCard
|
||||
class="art-table-card"
|
||||
shadow="never"
|
||||
:style="{ 'margin-top': showSearchBar ? '12px' : '0' }"
|
||||
>
|
||||
<ArtTableHeader
|
||||
v-model:columns="columnChecks"
|
||||
v-model:showSearchBar="showSearchBar"
|
||||
:loading="loading"
|
||||
@refresh="refreshData"
|
||||
>
|
||||
<template #left>
|
||||
<ElSpace wrap>
|
||||
<ElButton @click="showDialog('add')" v-ripple>新增角色</ElButton>
|
||||
</ElSpace>
|
||||
</template>
|
||||
</ArtTableHeader>
|
||||
|
||||
<!-- 表格 -->
|
||||
<ArtTable
|
||||
:loading="loading"
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
:pagination="pagination"
|
||||
@pagination:size-change="handleSizeChange"
|
||||
@pagination:current-change="handleCurrentChange"
|
||||
>
|
||||
</ArtTable>
|
||||
</ElCard>
|
||||
|
||||
<!-- 角色编辑弹窗 -->
|
||||
<RoleEditDialog
|
||||
v-model="dialogVisible"
|
||||
:dialog-type="dialogType"
|
||||
:role-data="currentRoleData"
|
||||
@success="refreshData"
|
||||
/>
|
||||
|
||||
<!-- 菜单权限弹窗 -->
|
||||
<RolePermissionDialog
|
||||
v-model="permissionDialog"
|
||||
:role-data="currentRoleData"
|
||||
@success="refreshData"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ButtonMoreItem } from '@/components/core/forms/art-button-more/index.vue'
|
||||
import { useTable } from '@/hooks/core/useTable'
|
||||
import { fetchGetRoleList } from '@/apps/demo/api/system-manage'
|
||||
import ArtButtonMore from '@/components/core/forms/art-button-more/index.vue'
|
||||
import RoleSearch from './modules/role-search.vue'
|
||||
import RoleEditDialog from './modules/role-edit-dialog.vue'
|
||||
import RolePermissionDialog from './modules/role-permission-dialog.vue'
|
||||
import { ElTag, ElMessageBox } from 'element-plus'
|
||||
|
||||
defineOptions({ name: 'Role' })
|
||||
|
||||
type RoleListItem = Api.SystemManage.RoleListItem
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = ref({
|
||||
roleName: undefined,
|
||||
roleCode: undefined,
|
||||
description: undefined,
|
||||
enabled: undefined,
|
||||
daterange: undefined
|
||||
})
|
||||
|
||||
const showSearchBar = ref(false)
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const permissionDialog = ref(false)
|
||||
const currentRoleData = ref<RoleListItem | undefined>(undefined)
|
||||
|
||||
const {
|
||||
columns,
|
||||
columnChecks,
|
||||
data,
|
||||
loading,
|
||||
pagination,
|
||||
getData,
|
||||
searchParams,
|
||||
resetSearchParams,
|
||||
handleSizeChange,
|
||||
handleCurrentChange,
|
||||
refreshData
|
||||
} = useTable({
|
||||
// 核心配置
|
||||
core: {
|
||||
apiFn: fetchGetRoleList,
|
||||
apiParams: {
|
||||
current: 1,
|
||||
size: 20
|
||||
},
|
||||
// 排除 apiParams 中的属性
|
||||
excludeParams: ['daterange'],
|
||||
columnsFactory: () => [
|
||||
{
|
||||
prop: 'roleId',
|
||||
label: '角色ID',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
prop: 'roleName',
|
||||
label: '角色名称',
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'roleCode',
|
||||
label: '角色编码',
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'description',
|
||||
label: '角色描述',
|
||||
minWidth: 150,
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'enabled',
|
||||
label: '角色状态',
|
||||
width: 100,
|
||||
formatter: (row) => {
|
||||
const statusConfig = row.enabled
|
||||
? { type: 'success', text: '启用' }
|
||||
: { type: 'warning', text: '禁用' }
|
||||
return h(
|
||||
ElTag,
|
||||
{ type: statusConfig.type as 'success' | 'warning' },
|
||||
() => statusConfig.text
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '创建日期',
|
||||
width: 180,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
prop: 'operation',
|
||||
label: '操作',
|
||||
width: 80,
|
||||
fixed: 'right',
|
||||
formatter: (row) =>
|
||||
h('div', [
|
||||
h(ArtButtonMore, {
|
||||
list: [
|
||||
{
|
||||
key: 'permission',
|
||||
label: '菜单权限',
|
||||
icon: 'ri:user-3-line'
|
||||
},
|
||||
{
|
||||
key: 'edit',
|
||||
label: '编辑角色',
|
||||
icon: 'ri:edit-2-line'
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
label: '删除角色',
|
||||
icon: 'ri:delete-bin-4-line',
|
||||
color: '#f56c6c'
|
||||
}
|
||||
],
|
||||
onClick: (item: ButtonMoreItem) => buttonMoreClick(item, row)
|
||||
})
|
||||
])
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const dialogType = ref<'add' | 'edit'>('add')
|
||||
|
||||
const showDialog = (type: 'add' | 'edit', row?: RoleListItem) => {
|
||||
dialogVisible.value = true
|
||||
dialogType.value = type
|
||||
currentRoleData.value = row
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索处理
|
||||
* @param params 搜索参数
|
||||
*/
|
||||
const handleSearch = (params: Record<string, any>) => {
|
||||
// 处理日期区间参数,把 daterange 转换为 startTime 和 endTime
|
||||
const { daterange, ...filtersParams } = params
|
||||
const [startTime, endTime] = Array.isArray(daterange) ? daterange : [null, null]
|
||||
|
||||
// 搜索参数赋值
|
||||
Object.assign(searchParams, { ...filtersParams, startTime, endTime })
|
||||
getData()
|
||||
}
|
||||
|
||||
const buttonMoreClick = (item: ButtonMoreItem, row: RoleListItem) => {
|
||||
switch (item.key) {
|
||||
case 'permission':
|
||||
showPermissionDialog(row)
|
||||
break
|
||||
case 'edit':
|
||||
showDialog('edit', row)
|
||||
break
|
||||
case 'delete':
|
||||
deleteRole(row)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const showPermissionDialog = (row?: RoleListItem) => {
|
||||
permissionDialog.value = true
|
||||
currentRoleData.value = row
|
||||
}
|
||||
|
||||
const deleteRole = (row: RoleListItem) => {
|
||||
ElMessageBox.confirm(`确定删除角色"${row.roleName}"吗?此操作不可恢复!`, '删除确认', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
// TODO: 调用删除接口
|
||||
ElMessage.success('删除成功')
|
||||
refreshData()
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage.info('已取消删除')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<ElDialog
|
||||
v-model="visible"
|
||||
:title="dialogType === 'add' ? '新增角色' : '编辑角色'"
|
||||
width="30%"
|
||||
align-center
|
||||
@close="handleClose"
|
||||
>
|
||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||
<ElFormItem label="角色名称" prop="roleName">
|
||||
<ElInput v-model="form.roleName" placeholder="请输入角色名称" />
|
||||
</ElFormItem>
|
||||
<ElFormItem label="角色编码" prop="roleCode">
|
||||
<ElInput v-model="form.roleCode" placeholder="请输入角色编码" />
|
||||
</ElFormItem>
|
||||
<ElFormItem label="描述" prop="description">
|
||||
<ElInput
|
||||
v-model="form.description"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入角色描述"
|
||||
/>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="启用">
|
||||
<ElSwitch v-model="form.enabled" />
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
<template #footer>
|
||||
<ElButton @click="handleClose">取消</ElButton>
|
||||
<ElButton type="primary" @click="handleSubmit">提交</ElButton>
|
||||
</template>
|
||||
</ElDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
|
||||
type RoleListItem = Api.SystemManage.RoleListItem
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
dialogType: 'add' | 'edit'
|
||||
roleData?: RoleListItem
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
(e: 'success'): void
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
modelValue: false,
|
||||
dialogType: 'add',
|
||||
roleData: undefined
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
/**
|
||||
* 弹窗显示状态双向绑定
|
||||
*/
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value)
|
||||
})
|
||||
|
||||
/**
|
||||
* 表单验证规则
|
||||
*/
|
||||
const rules = reactive<FormRules>({
|
||||
roleName: [
|
||||
{ required: true, message: '请输入角色名称', trigger: 'blur' },
|
||||
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
|
||||
],
|
||||
roleCode: [
|
||||
{ required: true, message: '请输入角色编码', trigger: 'blur' },
|
||||
{ min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
|
||||
],
|
||||
description: [{ required: true, message: '请输入角色描述', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
const form = reactive<RoleListItem>({
|
||||
roleId: 0,
|
||||
roleName: '',
|
||||
roleCode: '',
|
||||
description: '',
|
||||
createTime: '',
|
||||
enabled: true
|
||||
})
|
||||
|
||||
/**
|
||||
* 监听弹窗打开,初始化表单数据
|
||||
*/
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
if (newVal) initForm()
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* 监听角色数据变化,更新表单
|
||||
*/
|
||||
watch(
|
||||
() => props.roleData,
|
||||
(newData) => {
|
||||
if (newData && props.modelValue) initForm()
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
/**
|
||||
* 初始化表单数据
|
||||
* 根据弹窗类型填充表单或重置表单
|
||||
*/
|
||||
const initForm = () => {
|
||||
if (props.dialogType === 'edit' && props.roleData) {
|
||||
Object.assign(form, props.roleData)
|
||||
} else {
|
||||
Object.assign(form, {
|
||||
roleId: 0,
|
||||
roleName: '',
|
||||
roleCode: '',
|
||||
description: '',
|
||||
createTime: '',
|
||||
enabled: true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭弹窗并重置表单
|
||||
*/
|
||||
const handleClose = () => {
|
||||
visible.value = false
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交表单
|
||||
* 验证通过后调用接口保存数据
|
||||
*/
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
try {
|
||||
await formRef.value.validate()
|
||||
// TODO: 调用新增/编辑接口
|
||||
const message = props.dialogType === 'add' ? '新增成功' : '修改成功'
|
||||
ElMessage.success(message)
|
||||
emit('success')
|
||||
handleClose()
|
||||
} catch (error) {
|
||||
console.log('表单验证失败:', error)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
+254
@@ -0,0 +1,254 @@
|
||||
<template>
|
||||
<ElDialog
|
||||
v-model="visible"
|
||||
title="菜单权限"
|
||||
width="520px"
|
||||
align-center
|
||||
class="el-dialog-border"
|
||||
@close="handleClose"
|
||||
>
|
||||
<ElScrollbar height="70vh">
|
||||
<ElTree
|
||||
ref="treeRef"
|
||||
:data="processedMenuList"
|
||||
show-checkbox
|
||||
node-key="name"
|
||||
:default-expand-all="isExpandAll"
|
||||
:default-checked-keys="[1, 2, 3]"
|
||||
:props="defaultProps"
|
||||
@check="handleTreeCheck"
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<div style="display: flex; align-items: center">
|
||||
<span v-if="data.isAuth">
|
||||
{{ data.label }}
|
||||
</span>
|
||||
<span v-else>{{ defaultProps.label(data) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</ElTree>
|
||||
</ElScrollbar>
|
||||
<template #footer>
|
||||
<ElButton @click="outputSelectedData" style="margin-left: 8px">获取选中数据</ElButton>
|
||||
|
||||
<ElButton @click="toggleExpandAll">{{ isExpandAll ? '全部收起' : '全部展开' }}</ElButton>
|
||||
<ElButton @click="toggleSelectAll" style="margin-left: 8px">{{
|
||||
isSelectAll ? '取消全选' : '全部选择'
|
||||
}}</ElButton>
|
||||
<ElButton type="primary" @click="savePermission">保存</ElButton>
|
||||
</template>
|
||||
</ElDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
import { formatMenuTitle } from '@/utils/router'
|
||||
|
||||
type RoleListItem = Api.SystemManage.RoleListItem
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
roleData?: RoleListItem
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
(e: 'success'): void
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
modelValue: false,
|
||||
roleData: undefined
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
const { menuList } = storeToRefs(useMenuStore())
|
||||
const treeRef = ref()
|
||||
const isExpandAll = ref(true)
|
||||
const isSelectAll = ref(false)
|
||||
|
||||
/**
|
||||
* 弹窗显示状态双向绑定
|
||||
*/
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value)
|
||||
})
|
||||
|
||||
/**
|
||||
* 菜单节点类型
|
||||
*/
|
||||
interface MenuNode {
|
||||
id?: string | number
|
||||
name?: string
|
||||
label?: string
|
||||
meta?: {
|
||||
title?: string
|
||||
authList?: Array<{
|
||||
authMark: string
|
||||
title: string
|
||||
checked?: boolean
|
||||
}>
|
||||
}
|
||||
children?: MenuNode[]
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理菜单数据,将 authList 转换为树形子节点
|
||||
* 递归处理菜单树,将权限列表展开为可选择的子节点
|
||||
*/
|
||||
const processedMenuList = computed(() => {
|
||||
const processNode = (node: MenuNode): MenuNode => {
|
||||
const processed = { ...node }
|
||||
|
||||
// 如果有 authList,将其转换为子节点
|
||||
if (node.meta?.authList?.length) {
|
||||
const authNodes = node.meta.authList.map((auth) => ({
|
||||
id: `${node.id}_${auth.authMark}`,
|
||||
name: `${node.name}_${auth.authMark}`,
|
||||
label: auth.title,
|
||||
authMark: auth.authMark,
|
||||
isAuth: true,
|
||||
checked: auth.checked || false
|
||||
}))
|
||||
|
||||
processed.children = processed.children ? [...processed.children, ...authNodes] : authNodes
|
||||
}
|
||||
|
||||
// 递归处理子节点
|
||||
if (processed.children) {
|
||||
processed.children = processed.children.map(processNode)
|
||||
}
|
||||
|
||||
return processed
|
||||
}
|
||||
|
||||
return (menuList.value as any[]).map(processNode)
|
||||
})
|
||||
|
||||
/**
|
||||
* 树形组件配置
|
||||
*/
|
||||
const defaultProps = {
|
||||
children: 'children',
|
||||
label: (data: any) => formatMenuTitle(data.meta?.title) || data.label || ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听弹窗打开,初始化权限数据
|
||||
*/
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
if (newVal && props.roleData) {
|
||||
// TODO: 根据角色加载对应的权限数据
|
||||
console.log('设置权限:', props.roleData)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* 关闭弹窗并清空选中状态
|
||||
*/
|
||||
const handleClose = () => {
|
||||
visible.value = false
|
||||
treeRef.value?.setCheckedKeys([])
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存权限配置
|
||||
*/
|
||||
const savePermission = () => {
|
||||
// TODO: 调用保存权限接口
|
||||
ElMessage.success('权限保存成功')
|
||||
emit('success')
|
||||
handleClose()
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换全部展开/收起状态
|
||||
*/
|
||||
const toggleExpandAll = () => {
|
||||
const tree = treeRef.value
|
||||
if (!tree) return
|
||||
|
||||
const nodes = tree.store.nodesMap
|
||||
// 这里保留 any,因为 Element Plus 的内部节点类型较复杂
|
||||
Object.values(nodes).forEach((node: any) => {
|
||||
node.expanded = !isExpandAll.value
|
||||
})
|
||||
|
||||
isExpandAll.value = !isExpandAll.value
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换全选/取消全选状态
|
||||
*/
|
||||
const toggleSelectAll = () => {
|
||||
const tree = treeRef.value
|
||||
if (!tree) return
|
||||
|
||||
if (!isSelectAll.value) {
|
||||
const allKeys = getAllNodeKeys(processedMenuList.value)
|
||||
tree.setCheckedKeys(allKeys)
|
||||
} else {
|
||||
tree.setCheckedKeys([])
|
||||
}
|
||||
|
||||
isSelectAll.value = !isSelectAll.value
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归获取所有节点的 key
|
||||
* @param nodes 节点列表
|
||||
* @returns 所有节点的 key 数组
|
||||
*/
|
||||
const getAllNodeKeys = (nodes: MenuNode[]): string[] => {
|
||||
const keys: string[] = []
|
||||
const traverse = (nodeList: MenuNode[]): void => {
|
||||
nodeList.forEach((node) => {
|
||||
if (node.name) keys.push(node.name)
|
||||
if (node.children?.length) traverse(node.children)
|
||||
})
|
||||
}
|
||||
traverse(nodes)
|
||||
return keys
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理树节点选中状态变化
|
||||
* 同步更新全选按钮状态
|
||||
*/
|
||||
const handleTreeCheck = () => {
|
||||
const tree = treeRef.value
|
||||
if (!tree) return
|
||||
|
||||
const checkedKeys = tree.getCheckedKeys()
|
||||
const allKeys = getAllNodeKeys(processedMenuList.value)
|
||||
|
||||
isSelectAll.value = checkedKeys.length === allKeys.length && allKeys.length > 0
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出选中的权限数据到控制台
|
||||
* 用于调试和查看当前选中的权限配置
|
||||
*/
|
||||
const outputSelectedData = () => {
|
||||
const tree = treeRef.value
|
||||
if (!tree) return
|
||||
|
||||
const selectedData = {
|
||||
checkedKeys: tree.getCheckedKeys(),
|
||||
halfCheckedKeys: tree.getHalfCheckedKeys(),
|
||||
checkedNodes: tree.getCheckedNodes(),
|
||||
halfCheckedNodes: tree.getHalfCheckedNodes(),
|
||||
totalChecked: tree.getCheckedKeys().length,
|
||||
totalHalfChecked: tree.getHalfCheckedKeys().length
|
||||
}
|
||||
|
||||
console.log('=== 选中的权限数据 ===', selectedData)
|
||||
ElMessage.success(`已输出选中数据到控制台,共选中 ${selectedData.totalChecked} 个节点`)
|
||||
}
|
||||
</script>
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<ArtSearchBar
|
||||
ref="searchBarRef"
|
||||
v-model="formData"
|
||||
:items="formItems"
|
||||
:rules="rules"
|
||||
@reset="handleReset"
|
||||
@search="handleSearch"
|
||||
>
|
||||
</ArtSearchBar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
modelValue: Record<string, any>
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: Record<string, any>): void
|
||||
(e: 'search', params: Record<string, any>): void
|
||||
(e: 'reset'): void
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
const searchBarRef = ref()
|
||||
|
||||
/**
|
||||
* 表单数据双向绑定
|
||||
*/
|
||||
const formData = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val) => emit('update:modelValue', val)
|
||||
})
|
||||
|
||||
/**
|
||||
* 表单校验规则
|
||||
*/
|
||||
const rules = {}
|
||||
|
||||
/**
|
||||
* 角色状态选项
|
||||
*/
|
||||
const statusOptions = ref([
|
||||
{ label: '启用', value: true },
|
||||
{ label: '禁用', value: false }
|
||||
])
|
||||
|
||||
/**
|
||||
* 搜索表单配置项
|
||||
*/
|
||||
const formItems = computed(() => [
|
||||
{
|
||||
label: '角色名称',
|
||||
key: 'roleName',
|
||||
type: 'input',
|
||||
placeholder: '请输入角色名称',
|
||||
clearable: true
|
||||
},
|
||||
{
|
||||
label: '角色编码',
|
||||
key: 'roleCode',
|
||||
type: 'input',
|
||||
placeholder: '请输入角色编码',
|
||||
clearable: true
|
||||
},
|
||||
{
|
||||
label: '角色描述',
|
||||
key: 'description',
|
||||
type: 'input',
|
||||
placeholder: '请输入角色描述',
|
||||
clearable: true
|
||||
},
|
||||
{
|
||||
label: '角色状态',
|
||||
key: 'enabled',
|
||||
type: 'select',
|
||||
props: {
|
||||
placeholder: '请选择状态',
|
||||
options: statusOptions.value,
|
||||
clearable: true
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '创建日期',
|
||||
key: 'daterange',
|
||||
type: 'datetime',
|
||||
props: {
|
||||
style: { width: '100%' },
|
||||
placeholder: '请选择日期范围',
|
||||
type: 'daterange',
|
||||
rangeSeparator: '至',
|
||||
startPlaceholder: '开始日期',
|
||||
endPlaceholder: '结束日期',
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
shortcuts: [
|
||||
{ text: '今日', value: [new Date(), new Date()] },
|
||||
{ text: '最近一周', value: [new Date(Date.now() - 604800000), new Date()] },
|
||||
{ text: '最近一个月', value: [new Date(Date.now() - 2592000000), new Date()] }
|
||||
]
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
/**
|
||||
* 处理重置事件
|
||||
*/
|
||||
const handleReset = () => {
|
||||
emit('reset')
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理搜索事件
|
||||
* 验证表单后触发搜索
|
||||
*/
|
||||
const handleSearch = async () => {
|
||||
await searchBarRef.value.validate()
|
||||
emit('search', formData.value)
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user