feat 表格相关hooks调试, 新增查询器组件

This commit is contained in:
xxm
2022-10-07 21:30:21 +08:00
parent be13e7b425
commit 79bc023011
24 changed files with 461 additions and 3354 deletions

View File

@@ -0,0 +1,82 @@
<template>
<a-form class="query" layout="inline">
<a-row :gutter="gutter">
<query-item
:key="i"
v-show="i < defaultItemCount || toggleSearchStatus"
v-for="(field, i) in fields"
:field="field"
:md="defaultItemMd"
:query-params="queryParams"
/>
<a-col :md="defaultItemMd" :sm="24">
<a-space>
<a-button type="primary" :disabled="disabledQuery" @click="query">查询</a-button>
<a-button @click="reset">重置</a-button>
</a-space>
<a v-show="fields.length > defaultItemCount" @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<up-outlined v-if="toggleSearchStatus" />
<down-outlined v-else />
</a>
</a-col>
</a-row>
</a-form>
</template>
<script lang="ts" setup>
import QueryItem from './QueryItem.vue'
import { ref } from 'vue'
import { DownOutlined, UpOutlined } from '@ant-design/icons-vue'
// 切换搜索条件展开状态
let toggleSearchStatus = ref(false)
const props = defineProps({
fields: {
type: Array,
default: () => {
return []
},
},
// 查询条件
queryParams: {
type: Object,
required: true,
},
// 默认展示几个
defaultItemCount: { type: Number, default: 2 },
defaultItemMd: { type: Number, default: 6 },
// 禁用查询
disabledQuery: { type: Boolean, default: false },
gutter: { type: Number, default: 10 },
})
const emits = defineEmits(['update:modelValue', 'query', 'reset'])
/**
* 查询
*/
function query() {
emits('query')
}
/**
* 重置
*/
function reset() {
emits('reset')
}
/**
* 切换搜索条件展开状态
*/
function handleToggleSearch() {
toggleSearchStatus.value = !toggleSearchStatus.value
}
</script>
<style lang="less" scoped>
/deep/ .ant-form-item {
margin-bottom: 8px;
}
.ant-row {
width: 100%;
}
</style>

View File

@@ -0,0 +1,89 @@
<template>
<a-col :md="field.md || md" :sm="24">
<a-form-item :label="field.name">
<!-- 文本输入 -->
<a-input
allowClear
v-if="field.type === STRING"
:placeholder="field.placeholder ? field.placeholder : '请输入查询值'"
v-model:value="queryParams[field.field]"
/>
<!-- 数字输入 -->
<a-input-number
allowClear
style="width: 100%"
v-else-if="field.type === NUMBER"
:placeholder="field.placeholder ? field.placeholder : '请输入查询值'"
:precision="field.precision ? field.precision : 0"
v-model:value="queryParams[field.field]"
/>
<!-- 布尔 -->
<a-radio-group v-else-if="field.type === BOOLEAN" v-model:value="queryParams[field.field]">
<a-radio :value="true"></a-radio>
<a-radio :value="false"></a-radio>
</a-radio-group>
<!-- 列表 -->
<a-select
allowClear
v-else-if="field.type === LIST"
:placeholder="field.placeholder ? field.placeholder : '请选择查询值'"
v-model:value="queryParams[field.field]"
:options="field.list"
/>
<!-- 日期 -->
<a-date-picker
allowClear
v-else-if="field.type === DATE"
style="width: 100%"
:placeholder="field.placeholder ? field.placeholder : '请选择日期'"
:valueFormat="queryParams.format ? queryParams.format : 'yyyy-MM-DD'"
v-model:value="queryParams[field.field]"
/>
<!-- 时间 -->
<a-time-picker
allowClear
v-else-if="field.type === TIME"
style="width: 100%"
:placeholder="field.placeholder ? field.placeholder : '请选择时间'"
:valueFormat="queryParams.format ? queryParams.format : 'HH:mm:ss'"
v-model:value="queryParams[field.field]"
/>
<!-- 日期时间 -->
<a-date-picker
allowClear
showTime
v-else-if="field.type === DATE_TIME"
style="width: 100%"
:placeholder="field.placeholder ? field.placeholder : '请选择日期时间'"
:valueFormat="queryParams.format ? queryParams.format : 'yyyy-MM-DD HH:mm:ss'"
v-model:value="queryParams[field.field]"
/>
<!-- 默认文本输入 -->
<a-input
allowClear
v-else
:placeholder="field.placeholder ? field.placeholder : '请输入查询值'"
v-model:value="queryParams[field.field]"
/>
</a-form-item>
</a-col>
</template>
<script lang="ts" setup>
import { BOOLEAN, DATE, DATE_TIME, LIST, NUMBER, QueryField, STRING, TIME } from './SuperQueryCode'
const props = withDefaults(
defineProps<{
// 查询字段属性
field: QueryField
// 查询条件
queryParams: object
// md 栅格占位
md: number
}>(),
{
md: 6,
},
)
</script>
<style scoped></style>

View File

@@ -0,0 +1,20 @@
// 数字
export const NUMBER = 'number'
// 字符串
export const STRING = 'string'
// 布尔
export const BOOLEAN = 'boolean'
// 日期
export const DATE = 'date'
// 时间
export const TIME = 'time'
// 日期时间
export const DATE_TIME = 'date_time'
// 列表
export const LIST = 'list'
export interface QueryField {
type: string
placeholder: string
field: string
}

View File

@@ -9,10 +9,34 @@ import 'vxe-table/lib/style.css'
*/
export function useTable(app: App) {
app.use(VXETable)
// 给 vue 实例挂载内部对象,例如:
// app.config.globalProperties.$XModal = VXETable.modal
// app.config.globalProperties.$XPrint = VXETable.print
// app.config.globalProperties.$XSaveFile = VXETable.saveFile
// app.config.globalProperties.$XReadFile = VXETable.readFile
}
/**
* 配置
*/
VXETable.setup({
// 表格配置
table: {
resizable: true,
border: true,
stripe: true,
showOverflow: true,
showHeaderOverflow: true,
size: 'medium',
tooltipConfig: {
enterable: true,
},
},
// 工具条配置
toolbar: {
size: null,
custom: true,
buttons: [],
tools: [],
},
// 分页配置
pager: {
border: true,
size: 'medium',
},
})

View File

@@ -1,7 +1,58 @@
import type { App } from 'vue'
import { Button } from './Button'
import { Input, Layout } from 'ant-design-vue'
import {
Layout,
Input,
InputNumber,
Empty,
Select,
Tree,
TreeSelect,
Card,
Form,
Row,
Col,
Modal,
Dropdown,
Radio,
Steps,
Spin,
Menu,
Drawer,
Tooltip,
Tag,
Divider,
DatePicker,
TimePicker,
Descriptions,
Space,
} from 'ant-design-vue'
export function registerGlobComp(app: App) {
app.use(Input).use(Button).use(Layout)
app.use(Input)
app.use(Button)
app.use(Layout)
app.use(InputNumber)
app.use(Tag)
app.use(Space)
app.use(Modal)
app.use(Drawer)
app.use(Row)
app.use(Col)
app.use(Radio)
app.use(Divider)
app.use(DatePicker)
app.use(TimePicker)
app.use(Empty)
app.use(Select)
app.use(Tree)
app.use(TreeSelect)
app.use(Card)
app.use(Menu)
app.use(Tooltip)
app.use(Descriptions)
app.use(Steps)
app.use(Form)
app.use(Spin)
app.use(Dropdown)
}

View File

@@ -1,8 +1,80 @@
import { PageParams } from '/#/web'
import { TablePageModel } from '/#/web'
import { reactive, toRefs } from 'vue'
import { PageResult } from '/#/axios'
/**
* 重置当前页数
* 获取数据对象
*/
export function resetPage(pages: PageParams) {
pages.current = 1
export default function (queryPageCallback: CallableFunction) {
// 数据内容
const model = reactive({
pages: {
size: 10,
current: 1,
},
queryParam: {},
loading: false,
batchOperateFlag: false,
superQueryFlag: false,
pagination: {},
} as TablePageModel)
// 拆分
const { loading, batchOperateFlag, superQueryFlag } = toRefs(model)
// 不可以被重新赋值, 否则会失去绑定
const { pages, pagination } = model
// 普通查询
function query() {
model.superQueryFlag = false
resetPage()
queryPageCallback()
}
// 表格翻页或变动
function handleTableChange({ currentPage, pageSize }) {
pages.current = currentPage
pages.size = pageSize
queryPageCallback()
}
// 重置当前页数
function resetPage() {
pages.current = 1
}
// 分页查询返回结果处理
function pageQueryResHandel(res: PageResult) {
pagination.current = Number(res.current)
pagination.size = Number(res.size)
pagination.total = Number(res.total)
pagination.records = res.records
model.loading = false
}
// 重置查询
function resetQuery() {
resetQueryParams()
queryPageCallback()
}
// 重置查询参数
function resetQueryParams() {
model.superQueryFlag = false
model.queryParam = {}
}
// ok按钮
function handleOk() {
queryPageCallback()
}
return {
model,
loading,
pages,
pagination,
batchOperateFlag,
superQueryFlag,
query,
resetPage,
pageQueryResHandel,
handleTableChange,
resetQuery,
resetQueryParams,
handleOk,
}
}

View File

@@ -0,0 +1,19 @@
<template>
<a-modal :visible="visible"> 123 </a-modal>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const visible = ref(false)
const i = ref(3)
const emits = defineEmits(['ok'])
function edit() {
console.log(123)
}
defineExpose({
visible,
})
</script>
<style scoped></style>

View File

@@ -1,103 +1,85 @@
<template>
<div class="m-5 p-3 bg-white">
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="10">
<a-col :md="6" :sm="24">
<a-form-item label="编码">
<a-input v-model="queryParam.code" placeholder="请输入编码" />
</a-form-item>
</a-col>
<a-col :md="6" :sm="24">
<a-form-item label="名称">
<a-input v-model="queryParam.name" placeholder="请输入名称" />
</a-form-item>
</a-col>
<a-col :md="6" :sm="24">
<a-space>
<a-button type="primary" @click="query">查询</a-button>
<a-button @click="resetQuery">重置</a-button>
</a-space>
</a-col>
</a-row>
</a-form>
<div>
<div class="m-3 p-3 pt-5 bg-white">
<b-query :query-params="model.queryParam" :fields="fields" @query="queryPage" @reset="resetQueryParams" />
</div>
<vxe-toolbar>
<template #buttons>
<a-button type="primary" icon="plus" @click="add">新建</a-button>
<a-button @click="getPage">查询</a-button>
</template>
</vxe-toolbar>
<vxe-table row-id="id" :data="pagination.records" :loading="loading">
<vxe-column type="seq" width="60" />
<vxe-column field="code" title="编码" />
<vxe-column field="name" title="名称" />
<vxe-column field="captcha" title="系统内置">
<template #default="{ row }">
<a-tag v-if="row.system" color="green"></a-tag>
<a-tag v-else color="red"></a-tag>
<div class="m-3 p-3 bg-white">
<vxe-toolbar>
<template #buttons>
<a-space>
<a-button type="primary" @click="add">新建</a-button>
<a-button @click="queryPage">查询</a-button>
</a-space>
</template>
</vxe-column>
<vxe-column field="enable" title="启用状态">
<template #default="{ row }">
<a-tag v-if="row.enable" color="green">启用</a-tag>
<a-tag v-else color="red">停用</a-tag>
</template>
</vxe-column>
<vxe-column field="description" title="描述" />
<vxe-column field="createTime" title="创建时间" />
</vxe-table>
<vxe-pager
size="medium"
:loading="loading"
:current-page="pagination.current"
:page-size="pagination.size"
:total="pagination.total"
@page-change="handleTableChange"
/>
</vxe-toolbar>
<vxe-table row-id="id" :data="pagination.records" :loading="loading">
<vxe-column type="seq" width="60" />
<vxe-column field="code" title="编码" />
<vxe-column field="name" title="名称" />
<vxe-column field="captcha" title="系统内置">
<template #default="{ row }">
<a-tag v-if="row.system" color="green"></a-tag>
<a-tag v-else color="red"></a-tag>
</template>
</vxe-column>
<vxe-column field="enable" title="启用状态">
<template #default="{ row }">
<a-tag v-if="row.enable" color="green">启用</a-tag>
<a-tag v-else color="red">停用</a-tag>
</template>
</vxe-column>
<vxe-column field="description" title="描述" />
<vxe-column field="createTime" title="创建时间" />
</vxe-table>
<vxe-pager
size="medium"
:loading="loading"
:current-page="pagination.current"
:page-size="pagination.size"
:total="pagination.total"
@page-change="handleTableChange"
/>
<client-edit ref="clientEdit" @ok="queryPage" />
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, reactive, toRefs } from 'vue'
import { onMounted, ref } from 'vue'
import { page } from '/@/views/modules/system/client/Client.api'
import { PageResult } from '/#/axios'
// 初始化
function init() {
getPage()
}
import useTable from '/@/hooks/bootx/useTable'
import ClientEdit from './ClientEdit.vue'
import BQuery from '/@/components/Bootx/Query/BQuery.vue'
import { STRING } from '/@/components/Bootx/Query/SuperQueryCode'
// 使用hooks
const { handleTableChange, pageQueryResHandel, resetQueryParams, pagination, pages, model, loading } = useTable(queryPage)
const clientEdit = ref()
// 查询条件
const fields = [
{ field: 'code', type: STRING, name: '编码', placeholder: '请输入数据源编码' },
{ field: 'name', type: STRING, name: '名称', placeholder: '请输入数据源名称' },
]
onMounted(() => {
init()
queryPage()
})
const pageParam = reactive({
size: 10,
current: 1,
})
const queryParam = reactive({})
const model = reactive({
loading: false,
pagination: { size: 10, current: 1, total: 0, records: [] } as PageResult,
})
const { loading, pagination } = toRefs(model)
// 分页
function getPage() {
// 分页查询
function queryPage() {
model.loading = true
page({
...queryParam,
...pageParam,
...model.queryParam,
...pages,
}).then(({ data }) => {
model.pagination = data
model.loading = false
pageQueryResHandel(data)
})
}
// 页面变动
function handleTableChange({ currentPage, pageSize }) {
pageParam.current = currentPage
pageParam.size = pageSize
init()
// 新增
function add() {
clientEdit.value.visible = true
}
</script>
<style scoped></style>
<style lang="less" scoped></style>