康来智慧冷链-后端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

359 lines
13 KiB

<template>
<div ref="wrapRef" :class="[prefixCls, [`${prefixCls}-form-container`]]">
<AForm ref="queryFormElRef"
:model="state.queryParams"
layout="inline"
:colon="false"
:labelCol="{ style: { width: '80px', 'margin-bottom': '5px' } }"
:wrapperCol="{ style: { width: '300px', 'margin-bottom': '5px' } }"
>
<AFormItem label="参数名称" name="name">
<a-input v-model:value="state.queryParams.name"
allowClear
placeholder="请输入参数名称"
/>
</AFormItem>
<AFormItem label="参数键" name="key">
<a-input v-model:value="state.queryParams.key"
allowClear
placeholder="请输入参数键"/>
</AFormItem>
<AFormItem label="系统内置" name="isSys">
<ASelect v-model:value="state.queryParams.isSys"
placeholder="请选择"
allowClear
>
<ASelectOption key="0"></ASelectOption>
<ASelectOption key="1"></ASelectOption>
</ASelect>
</AFormItem>
<AFormItem label="创建时间">
<ARangePicker v-model:value="state.dateRange"
style="width: '100%'"
valueFormat="YYYY-MM-DD"
:placeholder="['开始日期', '结束日期']"
/>
</AFormItem>
<AFormItem>
<a-button type="primary"
class="mr-2"
@click="handleQuery"
>搜索</a-button>
<a-button type="default"
class="mr-2"
@click="resetQuery"
>重置</a-button>
</AFormItem>
</AForm>
<ATable ref="tableElRef"
v-bind="state.tableProps"
:loading="state.loading"
:size="state.selectedKeys[0]"
:dataSource="state.dataSource"
:columns="columns"
:bordered="true"
:scroll="{
x: '100%',
y: state.tableHeight,
scrollToFirstRowOnChange: true
}"
:rowSelection="getRowSelectionRef"
:pagination="getPaginationInfo"
@change="handleTablePaginationChange"
>
<template #title>
<div style="width: 100%">
<div class="flex items-center">
<BasicTitle>{{ '参数配置列表' }}</BasicTitle>
<div :class="`${headerPrefixCls}__toolbar`">
<a-button v-auth="['config_add']"
type="primary"
@click="handleAdd()"
>新增参数</a-button>
<a-button v-auth="['config_edit']"
type="primary"
:disabled="state.single"
@click="handleEdit()"
>修改参数</a-button>
<a-button v-auth="['config_del']"
type="primary"
:disabled="state.multiple"
@click="handleDel()"
>删除参数</a-button>
<ADivider type="vertical"/>
<div class="table-settings">
<!--重做-->
<ATooltip placement="top">
<template #title>
<span>{{ t('common.redo') }}</span>
</template>
<RedoOutlined @click="handleQuery"/>
</ATooltip>
<!--尺寸-->
<ATooltip placement="top">
<template #title>
<span>{{ t('component.table.settingDens') }}</span>
</template>
<ADropdown :trigger="['click']"
:getPopupContainer="getPopupContainer"
placement="bottomCenter"
>
<ColumnHeightOutlined/>
<template #overlay>
<AMenu v-model:selectedKeys="state.selectedKeys" selectable>
<AMenuItem key="default">
<span>{{ t('component.table.settingDensDefault') }}</span>
</AMenuItem>
<AMenuItem key="middle">
<span>{{ t('component.table.settingDensMiddle') }}</span>
</AMenuItem>
<AMenuItem key="small">
<span>{{ t('component.table.settingDensSmall') }}</span>
</AMenuItem>
</AMenu>
</template>
</ADropdown>
</ATooltip>
<!--全屏-->
<ATooltip placement="top">
<template #title>
<span>{{ t('component.table.settingFullScreen') }}</span>
</template>
<FullscreenOutlined v-if="!isFullscreen" @click="toggle"/>
<FullscreenExitOutlined v-else @click="toggle"/>
</ATooltip>
</div>
</div>
</div>
</div>
</template>
</ATable>
</div>
</template>
<script lang="ts" setup>
/**
* 提供模板规范代码参考,请尽量保证编写代码风格跟模板规范代码一致
* 采用ant-design-vue表格表单组件编写,采用 setup 写法
* 当vben的BasicTable跟BasicForm组件不能满足一些特殊需求时,需要写原生ant-design-vue组件时,请严格参考此处代码
* 当前原生ant-design-vue表格表单组件模板,目前已经与系统项目配置高度集成,系统配置发生修改时组件也会产生对应的变化
* 目前是基于vben的BasicTable跟BasicForm组件重写出一套ant-design-vue原生表格表单组件模板
* 注意:不会强依赖vben的BasicTable跟BasicForm组件,只会依赖一些简单容易逻辑不复杂的功能,复杂的功能不会依赖,降低耦合,提升此模板的可扩展性
* Copyright © 2020-2022 <a href="http://www.entfrm.com/">entfrm</a> All rights reserved.
* author entfrm开发团队-王翔
*/
import { BasicTitle } from '/@/components/Basic';
import { RedoOutlined, ColumnHeightOutlined, FullscreenOutlined, FullscreenExitOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
import {ref, onMounted, watchEffect, ComputedRef, computed, watch} from 'vue';
import { Table, Form, Row, Col, Divider, Tooltip, Dropdown, Menu, Select, DatePicker } from 'ant-design-vue';
import {BasicTableProps, PaginationProps, SizeType, SorterResult} from '/@/components/Table';
import { listConfig, delConfig } from '/@/api/platform/system/controller/config';
import ConfigModal from './ConfigModal.vue';
import { columns } from './config.data';
import { useMessage } from '/@/hooks/web/useMessage';
import { reactive, toRaw, unref } from 'vue';
import { useModal } from "/@/components/Modal";
import { useDesign } from "/@/hooks/web/useDesign";
import { useI18n } from '/@/hooks/web/useI18n';
import { convertDateRange } from "/@/utils/dateUtil";
import { useFullscreen } from "@vueuse/core";
import { getPopupContainer, noop } from '/@/utils';
import { useTimeoutFn } from "/@/hooks/core/useTimeout";
import {useRowSelection} from "/@/components/Table/src/hooks/useRowSelection";
import {basicProps} from "/@/components/Table/src/props";
import {usePagination} from "/@/components/Table/src/hooks/usePagination";
import {PAGE_SIZE} from "/@/components/Table/src/const";
import {isFunction} from "/@/utils/is";
/** 类型规范统一声明定义区域 */
interface TableState {
loading: boolean;
single: boolean;
multiple: boolean;
tableHeight: number;
tableInstance: ComponentRef;
queryFormInstance: ComponentRef | any;
selectedKeys: SizeType[];
queryParams: {
name: string | undefined;
key: string | undefined;
isSys: string | undefined;
};
dataSource: any[];
dateRange: string[];
tableProps: Recordable;
}
/** 通用变量统一声明区域 */
const ATable = Table;
const AForm = Form;
const AMenu = Menu;
const AFormItem = Form.Item;
const AMenuItem = Menu.Item;
const ADivider = Divider;
const ATooltip = Tooltip;
const ADropdown = Dropdown;
const ARow = Row;
const ACol = Col;
const ASelect = Select;
const ASelectOption = Select.Option;
const ARangePicker = DatePicker.RangePicker;
const { t } = useI18n();
const { prefixCls } = useDesign('basic-table');
const { prefixCls: headerPrefixCls } = useDesign('basic-table-header');
const wrapRef = ref(null);
const tableElRef = ref(null);
const queryFormElRef = ref(null);
const { createConfirm } = useMessage();
const { createMessage } = useMessage();
const { toggle, isFullscreen } = useFullscreen(wrapRef);
const [registerModal, { openModal }] = useModal();
const state = reactive<TableState>({
// 遮罩层
loading: true,
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 手动设置表格高度
tableHeight: 588,
// a-table表格实例
tableInstance: null,
// a-form表单实例
queryFormInstance: null,
// 尺寸大小选择
selectedKeys: ['middle'],
// 查询参数
queryParams: {
name: undefined,
key: undefined,
isSys: undefined
},
// 数据列表
dataSource: [],
// 日期范围
dateRange: [],
// 表格api
tableProps: {
// 表格ID
rowKey: 'id',
// 表格行配置
rowSelection: { type: 'checkbox' }
}
});
// 基于vben-table扩展rowSelection,实现勾选数据自主可控
const basicTableProps = computed(() => {
return {
...basicProps,
...state.tableProps
} as unknown as BasicTableProps;
});
const {
getRowSelection,
getRowSelectionRef,
getSelectRows,
clearSelectedRowKeys,
getSelectRowKeys,
deleteSelectRowByKey,
setSelectedRowKeys
} = useRowSelection(basicTableProps, ref(state.dataSource), noop);
// 基于vben-table扩展分页
const {
getPaginationInfo,
getPagination,
setPagination,
setShowPagination,
getShowPagination
} = usePagination(basicTableProps);
/** 生命周期钩子回调处理区域 */
onMounted(() => {
state.tableInstance = unref(tableElRef);
state.queryFormInstance = unref(queryFormElRef);
useTimeoutFn(() => getList() , 16);
});
watchEffect(() => {
// 当数据不存在时清理表格高度
handleTableHeightSetting(state.dataSource.length > 0 ? false : true);
});
watch(getRowSelectionRef, ()=> {
handleSelectionChange(getSelectRowKeys());
},{
immediate: true,
deep: true
});
/** 处理表格高度设置 */
function handleTableHeightSetting(clean?: boolean) {
if (!state.tableInstance?.$el) return;
const bodyEl: HTMLElement | null = state.tableInstance.$el.querySelector('.ant-table-body');
bodyEl && (bodyEl.style.height = `${ clean ? 'unset' : state.tableHeight+'px' }`);
}
/** 查询列表数据 */
function getList() {
state.loading = true;
const { current = 1, pageSize = 10 } = getPagination() as PaginationProps;
listConfig(convertDateRange({ ...state.queryParams, current, size: pageSize }, state.dateRange)).then(response => {
state.dataSource = response.data;
setPagination({ total: response.total });
state.loading = false;
});
}
/** 搜索按钮操作 */
function handleQuery() {
setPagination({ current: 1 });
clearSelectedRowKeys();
getList();
}
/** 重置按钮操作 */
function resetQuery() {
state.dateRange = [];
state.queryFormInstance?.resetFields();
handleQuery();
}
/** 处理多选框选中数据 */
function handleSelectionChange(selectedRowKeys: string[]) {
state.single = selectedRowKeys.length != 1;
state.multiple = !selectedRowKeys.length;
}
/** 处理表格分页 */
function handleTablePaginationChange(pagination: PaginationProps) {
setPagination(pagination);
getList();
}
/** 新增按钮操作,行内新增与工具栏局域新增通用 */
function handleAdd() {
openModal(true,{isUpdate: false });
}
/** 编辑按钮操作,行内编辑 */
function handleEdit(record?: Recordable) {
record = record || { id: toRaw(state.ids) };
openModal(true, { isUpdate: true, record });
}
/** 删除按钮操作,行内删除 */
async function handleDel(record?: Recordable) {
const ids = record?.id || toRaw(state.ids);
createConfirm({
iconType: 'warning',
title: '警告',
content: `是否确认删除参数编号为${ids}参数吗?`,
onOk: async () => {
await remove({ids: ids});
createMessage.success('删除成功!');
handleSuccess();
}
});
}
</script>