2022-03-10 09:47:29 +08:00
|
|
|
|
import { reactive, ref, Ref } from 'vue'
|
|
|
|
|
import { merge } from 'lodash-es'
|
|
|
|
|
import { DynamicProps } from '/#/utils'
|
|
|
|
|
import { BasicTableProps, TableActionType, useTable } from '/@/components/Table'
|
|
|
|
|
import { ColEx } from '/@/components/Form/src/types'
|
|
|
|
|
import { FormActionType } from '/@/components/Form'
|
|
|
|
|
import { useMessage } from '/@/hooks/web/useMessage'
|
|
|
|
|
import { useMethods } from '/@/hooks/system/useMethods'
|
|
|
|
|
import { useDesign } from '/@/hooks/web/useDesign'
|
|
|
|
|
import { filterObj } from '/@/utils/common/compUtils'
|
|
|
|
|
const { handleExportXls, handleImportXls } = useMethods()
|
|
|
|
|
|
|
|
|
|
// 定义 useListPage 方法所需参数
|
|
|
|
|
interface ListPageOptions {
|
|
|
|
|
// 样式作用域范围
|
|
|
|
|
designScope?: string,
|
|
|
|
|
// 【必填】表格参数配置
|
|
|
|
|
tableProps: TableProps,
|
|
|
|
|
// 分页
|
|
|
|
|
pagination?: boolean,
|
|
|
|
|
// 导出配置
|
|
|
|
|
exportConfig?: {
|
|
|
|
|
url: string,
|
|
|
|
|
// 导出文件名
|
|
|
|
|
name?: string | (() => string),
|
2022-04-27 19:19:39 +08:00
|
|
|
|
//导出参数
|
|
|
|
|
params?: object,
|
2022-03-10 09:47:29 +08:00
|
|
|
|
}
|
|
|
|
|
// 导入配置
|
|
|
|
|
importConfig?: {
|
|
|
|
|
url: string,
|
|
|
|
|
// 导出成功后的回调
|
|
|
|
|
success?: (fileInfo?: any) => void
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface IDoRequestOptions {
|
|
|
|
|
// 是否显示确认对话框,默认 true
|
|
|
|
|
confirm?: boolean,
|
|
|
|
|
// 是否自动刷新表格,默认 true
|
|
|
|
|
reload?: boolean,
|
|
|
|
|
// 是否自动清空选择,默认 true
|
|
|
|
|
clearSelection?: boolean,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* listPage页面公共方法
|
|
|
|
|
*
|
|
|
|
|
* @param options
|
|
|
|
|
*/
|
|
|
|
|
export function useListPage(options: ListPageOptions) {
|
|
|
|
|
const $message = useMessage()
|
|
|
|
|
let $design = {} as ReturnType<typeof useDesign>
|
|
|
|
|
if (options.designScope) {
|
|
|
|
|
$design = useDesign(options.designScope)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const tableContext = useListTable(options.tableProps)
|
|
|
|
|
|
|
|
|
|
const [, { getForm, reload, setLoading }, { selectedRowKeys }] = tableContext
|
|
|
|
|
|
|
|
|
|
// 导出 excel
|
|
|
|
|
async function onExportXls() {
|
2022-04-27 19:19:39 +08:00
|
|
|
|
//update-begin---author:wangshuai ---date:20220411 for:导出新增自定义参数------------
|
|
|
|
|
let { url, name,params } = options?.exportConfig ?? {}
|
2022-03-10 09:47:29 +08:00
|
|
|
|
if (url) {
|
|
|
|
|
let title = typeof name === 'function' ? name() : name
|
2022-04-27 19:19:39 +08:00
|
|
|
|
let paramsForm = await getForm().validate()
|
|
|
|
|
//如果参数不为空,则整合到一起
|
|
|
|
|
if(params){
|
|
|
|
|
paramsForm = Object.assign({},paramsForm,params);
|
|
|
|
|
}
|
2022-03-10 09:47:29 +08:00
|
|
|
|
if(selectedRowKeys.value && selectedRowKeys.value.length>0){
|
2022-04-27 19:19:39 +08:00
|
|
|
|
paramsForm['selections'] = selectedRowKeys.value.join(",")
|
2022-03-10 09:47:29 +08:00
|
|
|
|
}
|
2022-04-27 19:19:39 +08:00
|
|
|
|
return handleExportXls(title as string, url,filterObj(paramsForm))
|
|
|
|
|
//update-end---author:wangshuai ---date:20220411 for:导出新增自定义参数--------------
|
2022-03-10 09:47:29 +08:00
|
|
|
|
} else {
|
|
|
|
|
$message.createMessage.warn('没有传递 exportConfig.url 参数')
|
|
|
|
|
return Promise.reject()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 导入 excel
|
|
|
|
|
function onImportXls(file) {
|
|
|
|
|
let { url,success } = options?.importConfig ?? {}
|
|
|
|
|
if (url) {
|
|
|
|
|
return handleImportXls(file, url, success||reload)
|
|
|
|
|
} else {
|
|
|
|
|
$message.createMessage.warn('没有传递 importConfig.url 参数')
|
|
|
|
|
return Promise.reject()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 通用请求处理方法,可自动刷新表格,自动清空选择
|
|
|
|
|
* @param api 请求api
|
|
|
|
|
* @param options 是否显示确认框
|
|
|
|
|
*/
|
|
|
|
|
function doRequest(api: () => Promise<any>, options?: IDoRequestOptions) {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
const execute = async () => {
|
|
|
|
|
try {
|
|
|
|
|
setLoading(true)
|
|
|
|
|
const res = await api()
|
|
|
|
|
if (options?.reload ?? true) {
|
|
|
|
|
reload()
|
|
|
|
|
}
|
|
|
|
|
if (options?.clearSelection ?? true) {
|
|
|
|
|
selectedRowKeys.value = []
|
|
|
|
|
}
|
|
|
|
|
resolve(res)
|
|
|
|
|
} catch (e) {
|
|
|
|
|
reject(e)
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (options?.confirm ?? true) {
|
|
|
|
|
$message.createConfirm({
|
|
|
|
|
iconType: 'warning',
|
|
|
|
|
title: '删除',
|
|
|
|
|
content: '确定要删除吗?',
|
|
|
|
|
onOk: () => execute(),
|
|
|
|
|
onCancel: () => reject(),
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
execute()
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 执行单个删除操作 */
|
|
|
|
|
function doDeleteRecord(api: () => Promise<any>) {
|
|
|
|
|
return doRequest(api, { confirm: false, clearSelection: false })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
...$design,
|
|
|
|
|
...$message,
|
|
|
|
|
onExportXls,
|
|
|
|
|
onImportXls,
|
|
|
|
|
doRequest,
|
|
|
|
|
doDeleteRecord,
|
|
|
|
|
tableContext,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 定义表格所需参数
|
|
|
|
|
type TableProps = Partial<DynamicProps<BasicTableProps>>;
|
|
|
|
|
type UseTableMethod = TableActionType & {
|
|
|
|
|
getForm: () => FormActionType;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* useListTable 列表页面标准表格参数
|
|
|
|
|
*
|
|
|
|
|
* @param tableProps 表格参数
|
|
|
|
|
*/
|
|
|
|
|
export function useListTable(tableProps: TableProps): [
|
|
|
|
|
(instance: TableActionType, formInstance: UseTableMethod) => void,
|
|
|
|
|
TableActionType & {
|
|
|
|
|
getForm: () => FormActionType;
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
rowSelection: any,
|
|
|
|
|
selectedRows: Ref<Recordable[]>
|
|
|
|
|
selectedRowKeys: Ref<any[]>
|
|
|
|
|
}
|
|
|
|
|
] {
|
|
|
|
|
// 自适应列配置
|
|
|
|
|
const adaptiveColProps: Partial<ColEx> = {
|
|
|
|
|
xs: 24, // <576px
|
|
|
|
|
sm: 12, // ≥576px
|
|
|
|
|
md: 12, // ≥768px
|
|
|
|
|
lg: 8, // ≥992px
|
|
|
|
|
xl: 8, // ≥1200px
|
|
|
|
|
xxl: 6, // ≥1600px
|
|
|
|
|
}
|
|
|
|
|
const defaultTableProps: TableProps = {
|
|
|
|
|
rowKey: 'id',
|
|
|
|
|
// 使用查询条件区域
|
|
|
|
|
useSearchForm: true,
|
|
|
|
|
// 查询条件区域配置
|
|
|
|
|
formConfig: {
|
|
|
|
|
// 紧凑模式
|
|
|
|
|
compact: true,
|
|
|
|
|
// label默认宽度
|
|
|
|
|
labelWidth: 120,
|
|
|
|
|
// 按下回车后自动提交
|
|
|
|
|
autoSubmitOnEnter: true,
|
|
|
|
|
// 默认 row 配置
|
|
|
|
|
rowProps: { gutter: 8 },
|
|
|
|
|
// 默认 col 配置
|
|
|
|
|
baseColProps: {
|
|
|
|
|
...adaptiveColProps,
|
|
|
|
|
},
|
|
|
|
|
labelCol: {
|
|
|
|
|
xs: 24,
|
|
|
|
|
sm: 8,
|
|
|
|
|
md: 6,
|
|
|
|
|
lg: 8,
|
|
|
|
|
xl: 6,
|
|
|
|
|
xxl: 6,
|
|
|
|
|
},
|
|
|
|
|
wrapperCol: {},
|
|
|
|
|
// 是否显示 展开/收起 按钮
|
|
|
|
|
showAdvancedButton: true,
|
|
|
|
|
// 超过指定列数默认折叠
|
|
|
|
|
autoAdvancedCol: 3,
|
|
|
|
|
// 操作按钮配置
|
|
|
|
|
actionColOptions: {
|
|
|
|
|
...adaptiveColProps,
|
|
|
|
|
style: { textAlign: 'left' },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
// 斑马纹
|
|
|
|
|
striped: true,
|
|
|
|
|
// 是否可以自适应高度
|
|
|
|
|
canResize: true,
|
|
|
|
|
// 表格最小高度
|
|
|
|
|
minHeight: 500,
|
|
|
|
|
// 点击行选中
|
|
|
|
|
clickToRowSelect: false,
|
|
|
|
|
// 是否显示边框
|
|
|
|
|
bordered: true,
|
|
|
|
|
// 是否显示序号列
|
|
|
|
|
showIndexColumn: false,
|
|
|
|
|
// 显示表格设置
|
|
|
|
|
showTableSetting: true,
|
|
|
|
|
// 表格设置
|
|
|
|
|
tableSetting: {
|
|
|
|
|
fullScreen: true,
|
|
|
|
|
},
|
|
|
|
|
// 是否显示操作列
|
|
|
|
|
showActionColumn: true,
|
|
|
|
|
// 操作列
|
|
|
|
|
actionColumn: {
|
|
|
|
|
width: 120,
|
|
|
|
|
title: '操作',
|
|
|
|
|
//是否锁定操作列取值 right ,left,false
|
|
|
|
|
fixed: false,
|
|
|
|
|
dataIndex: 'action',
|
|
|
|
|
slots: { customRender: 'action' },
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
// 合并用户个性化配置
|
|
|
|
|
if (tableProps) {
|
|
|
|
|
// merge 方法可深度合并对象
|
|
|
|
|
merge(defaultTableProps, tableProps)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发送请求之前调用的方法
|
|
|
|
|
function beforeFetch(params) {
|
|
|
|
|
// 默认以 createTime 降序排序
|
|
|
|
|
return Object.assign({ column: 'createTime', order: 'desc' }, params)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 合并方法
|
|
|
|
|
Object.assign(defaultTableProps, { beforeFetch })
|
|
|
|
|
if (typeof tableProps.beforeFetch === 'function') {
|
|
|
|
|
defaultTableProps.beforeFetch = function (params) {
|
|
|
|
|
params = beforeFetch(params)
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
tableProps.beforeFetch(params)
|
|
|
|
|
return params
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 当前选择的行
|
|
|
|
|
const selectedRowKeys = ref<any[]>([])
|
|
|
|
|
// 选择的行记录
|
|
|
|
|
const selectedRows = ref<Recordable[]>([])
|
|
|
|
|
|
|
|
|
|
// 表格选择列配置
|
|
|
|
|
const rowSelection: any = tableProps?.rowSelection ?? {}
|
|
|
|
|
const defaultRowSelection = reactive({
|
|
|
|
|
...rowSelection,
|
|
|
|
|
type: rowSelection.type ?? 'checkbox',
|
|
|
|
|
// 选择列宽度,默认 50
|
|
|
|
|
columnWidth: rowSelection.columnWidth ?? 50,
|
|
|
|
|
selectedRows: selectedRows,
|
|
|
|
|
selectedRowKeys: selectedRowKeys,
|
|
|
|
|
onChange(...args) {
|
|
|
|
|
selectedRowKeys.value = args[0]
|
|
|
|
|
selectedRows.value = args[1]
|
|
|
|
|
if (typeof rowSelection.onChange === 'function') {
|
|
|
|
|
rowSelection.onChange(...args)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
delete defaultTableProps.rowSelection
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
...useTable(defaultTableProps),
|
|
|
|
|
{
|
|
|
|
|
selectedRows,
|
|
|
|
|
selectedRowKeys,
|
|
|
|
|
rowSelection: defaultRowSelection,
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
}
|