master
parent
9d4b5956ad
commit
771c2dff8f
|
|
@ -1,5 +1,5 @@
|
||||||
import { TypeTag } from '@/common/utils/index.ts'
|
import { TypeTag } from '@/common/utils/index.ts'
|
||||||
import { isString } from '@/common/utils/types.ts'
|
import Types from '@/common/utils/types.ts'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查是否为普通对象
|
* 检查是否为普通对象
|
||||||
|
|
@ -36,7 +36,7 @@ export function isArrayLike(obj: any) {
|
||||||
* @param obj 待检查对象
|
* @param obj 待检查对象
|
||||||
*/
|
*/
|
||||||
export function isNumStr(obj: any) {
|
export function isNumStr(obj: any) {
|
||||||
return isString(obj) && !isNaN(Number(obj))
|
return Types.isString(obj) && !isNaN(Number(obj))
|
||||||
}
|
}
|
||||||
|
|
||||||
type tags = 'error' | 'info' | 'warning' | 'risk' | 'error' | 'fatal' | 'success' | undefined;
|
type tags = 'error' | 'info' | 'warning' | 'risk' | 'error' | 'fatal' | 'success' | undefined;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
import {
|
import Types from '@/common/utils/types'
|
||||||
isDate,
|
|
||||||
isNumber,
|
|
||||||
isString,
|
|
||||||
} from '@/common/utils/types'
|
|
||||||
import { isNumStr } from '@/common/utils/objects.ts'
|
import { isNumStr } from '@/common/utils/objects.ts'
|
||||||
import {
|
import {
|
||||||
type DateObjectUnits,
|
type DateObjectUnits,
|
||||||
|
|
@ -44,11 +40,11 @@ function now() {
|
||||||
* @return luxon 库的时间对象
|
* @return luxon 库的时间对象
|
||||||
*/
|
*/
|
||||||
function parse(date: Date | number | string | DateObjectUnits, fmt: string = FMT.date_time_sec) {
|
function parse(date: Date | number | string | DateObjectUnits, fmt: string = FMT.date_time_sec) {
|
||||||
if (isDate(date)) {
|
if (Types.isDate(date)) {
|
||||||
return DateTime.fromJSDate(date as Date)
|
return DateTime.fromJSDate(date as Date)
|
||||||
} else if (isNumber(date) || isNumStr(date)) {
|
} else if (Types.isNumber(date) || isNumStr(date)) {
|
||||||
return DateTime.fromMillis(Number(date))
|
return DateTime.fromMillis(Number(date))
|
||||||
} else if (isString(date)) {
|
} else if (Types.isString(date)) {
|
||||||
return DateTime.fromFormat(date as string, fmt)
|
return DateTime.fromFormat(date as string, fmt)
|
||||||
} else {
|
} else {
|
||||||
return DateTime.fromObject(date as DateObjectUnits)
|
return DateTime.fromObject(date as DateObjectUnits)
|
||||||
|
|
@ -63,7 +59,7 @@ function parse(date: Date | number | string | DateObjectUnits, fmt: string = FMT
|
||||||
*/
|
*/
|
||||||
function format(date?: DateTime<true | false> | Date, fmt: string = FMT.date_time_sec) {
|
function format(date?: DateTime<true | false> | Date, fmt: string = FMT.date_time_sec) {
|
||||||
if (date == null) return ''
|
if (date == null) return ''
|
||||||
if (isDate(date)) {
|
if (Types.isDate(date)) {
|
||||||
return DateTime.fromJSDate(date as Date).toFormat(fmt)
|
return DateTime.fromJSDate(date as Date).toFormat(fmt)
|
||||||
} else {
|
} else {
|
||||||
return (date as DateTime<true | false>).toFormat(fmt)
|
return (date as DateTime<true | false>).toFormat(fmt)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { TypeTag } from '@/common/utils/index.ts'
|
||||||
* 检查给定的值是否为字符串
|
* 检查给定的值是否为字符串
|
||||||
* @param obj 待检查的对象
|
* @param obj 待检查的对象
|
||||||
*/
|
*/
|
||||||
export function isString(obj: any) {
|
function isString(obj: any) {
|
||||||
return obj != null &&
|
return obj != null &&
|
||||||
(typeof obj === 'string' ||
|
(typeof obj === 'string' ||
|
||||||
(typeof obj === 'object' &&
|
(typeof obj === 'object' &&
|
||||||
|
|
@ -16,7 +16,7 @@ export function isString(obj: any) {
|
||||||
* 检查给定的值是否为 JS 日期(Date)
|
* 检查给定的值是否为 JS 日期(Date)
|
||||||
* @param obj 待检查的对象
|
* @param obj 待检查的对象
|
||||||
*/
|
*/
|
||||||
export function isDate(obj: any) {
|
function isDate(obj: any) {
|
||||||
return obj != null &&
|
return obj != null &&
|
||||||
(typeof obj === 'object' &&
|
(typeof obj === 'object' &&
|
||||||
Object.prototype.toString.call(obj) === TypeTag.DATE)
|
Object.prototype.toString.call(obj) === TypeTag.DATE)
|
||||||
|
|
@ -26,7 +26,7 @@ export function isDate(obj: any) {
|
||||||
* 检查给定的值是否为数字
|
* 检查给定的值是否为数字
|
||||||
* @param obj 待检查的对象
|
* @param obj 待检查的对象
|
||||||
*/
|
*/
|
||||||
export function isNumber(obj: any) {
|
function isNumber(obj: any) {
|
||||||
return obj != null &&
|
return obj != null &&
|
||||||
(typeof obj === 'number' ||
|
(typeof obj === 'number' ||
|
||||||
(typeof obj === 'object' &&
|
(typeof obj === 'object' &&
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,15 @@ import Strings from '@/common/utils/strings.ts'
|
||||||
import { saveFile } from '@/common/app'
|
import { saveFile } from '@/common/app'
|
||||||
import Colls from '@/common/utils/colls.ts'
|
import Colls from '@/common/utils/colls.ts'
|
||||||
import type { SetupContext } from '@vue/runtime-core'
|
import type { SetupContext } from '@vue/runtime-core'
|
||||||
|
import Types from '@/common/utils/types.ts'
|
||||||
|
|
||||||
|
type DeepPartial<T> = T extends Function
|
||||||
|
? T
|
||||||
|
: T extends Array<infer U>
|
||||||
|
? Array<DeepPartial<U>>
|
||||||
|
: T extends object
|
||||||
|
? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||||
|
: T;
|
||||||
|
|
||||||
interface ColumnScopeType<T> {
|
interface ColumnScopeType<T> {
|
||||||
row: T,
|
row: T,
|
||||||
|
|
@ -41,13 +50,12 @@ interface ColumnScopeType<T> {
|
||||||
$index: number
|
$index: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TableActionType<T> {
|
interface TableActionType<T> {
|
||||||
icon?: ElIconType
|
icon?: ElIconType
|
||||||
type?: 'text' | 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger'
|
type?: 'text' | 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger'
|
||||||
label?: string | ((data: ColumnScopeType<T>) => string)
|
label?: string | ((data: ColumnScopeType<T>) => string)
|
||||||
tooltip?: string | ((data: ColumnScopeType<T>) => string)
|
tooltip?: string | ((data: ColumnScopeType<T>) => string)
|
||||||
loading?: boolean
|
loading?: boolean
|
||||||
textBtn?: boolean
|
|
||||||
show?: (data: ColumnScopeType<T>) => boolean
|
show?: (data: ColumnScopeType<T>) => boolean
|
||||||
action: (data: ColumnScopeType<T>) => Promise<boolean> | void
|
action: (data: ColumnScopeType<T>) => Promise<boolean> | void
|
||||||
confirm?: {
|
confirm?: {
|
||||||
|
|
@ -58,57 +66,130 @@ export interface TableActionType<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ActionColumnType<T> {
|
interface ActionColumnType<T> {
|
||||||
width?: string
|
/**
|
||||||
|
* 列宽,默认:80px
|
||||||
|
*/
|
||||||
|
width: string
|
||||||
|
/**
|
||||||
|
* 按钮列表
|
||||||
|
*/
|
||||||
tableActions: TableActionType<T>[]
|
tableActions: TableActionType<T>[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ToolType {
|
interface ToolType {
|
||||||
icon?: ElIconType
|
icon?: ElIconType
|
||||||
type?: 'text' | 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger'
|
type?: 'text' | 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger'
|
||||||
label?: string
|
label?: string
|
||||||
action: () => void
|
action: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ToolBarType {
|
interface ToolBarType {
|
||||||
leftTools: ToolType[]
|
leftTools: ToolType[]
|
||||||
rightTools: Required<Omit<ToolType, 'type' | 'label'>>[]
|
rightTools: Required<Omit<ToolType, 'type' | 'label'>>[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TablePropsType<T extends DefaultRow, F extends object> = Omit<TableProps<T>, 'data' | 'headerRowClassName' | 'cellClassName' | 'context'> & {
|
interface TablePropsType<T extends DefaultRow, F extends object> extends Omit<TableProps<T>, 'data' | 'headerRowClassName' | 'cellClassName' | 'context'> {
|
||||||
treeLoad?: (param: F, row: T, expanded: any, resolve?: (data: T[]) => void) => void
|
treeLoad?: (param: F, row: T, expanded: any, resolve?: (data: T[]) => void) => void
|
||||||
|
/**
|
||||||
|
* 操作列配置
|
||||||
|
*/
|
||||||
actionColumn: ActionColumnType<T>
|
actionColumn: ActionColumnType<T>
|
||||||
}
|
}
|
||||||
export type FormPropsType<P, T> = {
|
|
||||||
paging?: (param: P) => Promise<R<G.PageResult<T>>>
|
interface FormPropsType<P, T> {
|
||||||
|
/**
|
||||||
|
* 分页函数
|
||||||
|
* @param param 查询条件
|
||||||
|
*/
|
||||||
|
paging: (param: P) => Promise<R<G.PageResult<T>>>
|
||||||
|
/**
|
||||||
|
* 导出函数
|
||||||
|
* @param param 查询条件
|
||||||
|
*/
|
||||||
export?: (param: P) => Promise<R<{ content: Blob, filename: string }>>
|
export?: (param: P) => Promise<R<{ content: Blob, filename: string }>>
|
||||||
|
/**
|
||||||
|
* 表单默认值
|
||||||
|
*/
|
||||||
defaultData: P
|
defaultData: P
|
||||||
highForm?: Partial<FormProps> & { colCount?: number, vgap?: string, hgap?: string }
|
/**
|
||||||
simpleForm?: Partial<FormProps>
|
* 高级查询表单配置
|
||||||
|
*/
|
||||||
|
highForm: Partial<Omit<FormProps, 'labelWidth'>> & {
|
||||||
|
/**
|
||||||
|
* 标签宽度,单位:px,默认:90px
|
||||||
|
*/
|
||||||
|
labelWidth: number,
|
||||||
|
/**
|
||||||
|
* 输入框宽度,单位:px,默认:190px
|
||||||
|
*/
|
||||||
|
contentWidth: number,
|
||||||
|
/**
|
||||||
|
* 行间隔,单位:px,默认:10px
|
||||||
|
*/
|
||||||
|
rgap: number,
|
||||||
|
/**
|
||||||
|
* 列间隔,单位:px,默认:10px
|
||||||
|
*/
|
||||||
|
cgap: number
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 简单查询表单配置
|
||||||
|
*/
|
||||||
|
simpleForm: Partial<FormProps>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页布局配置
|
||||||
|
*/
|
||||||
interface PageLayoutType {
|
interface PageLayoutType {
|
||||||
/* columns: string[]
|
/* columns: string[]
|
||||||
rows: string[] */
|
rows: string[] */
|
||||||
dataListHeight: string
|
/**
|
||||||
|
* 数据表格高度,传入数字时,单位:fr,传入字符串时不会而外添加单位,,默认:9fr
|
||||||
|
*/
|
||||||
|
dataListHeight: number | string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ATablePageType<P extends object, T extends DefaultRow> {
|
interface ATablePageType<P extends object, T extends DefaultRow> {
|
||||||
|
/**
|
||||||
|
* 页布局配置
|
||||||
|
*/
|
||||||
pageLayout: PageLayoutType
|
pageLayout: PageLayoutType
|
||||||
|
/**
|
||||||
|
* 查询表单配置
|
||||||
|
*/
|
||||||
searchForm: FormPropsType<P, T>
|
searchForm: FormPropsType<P, T>
|
||||||
|
/**
|
||||||
|
* 工具栏配置
|
||||||
|
*/
|
||||||
toolBar: ToolBarType
|
toolBar: ToolBarType
|
||||||
|
/**
|
||||||
|
* 表格配置
|
||||||
|
*/
|
||||||
table: TablePropsType<T, P>
|
table: TablePropsType<T, P>
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildSearchForm<P, T>(searchForm: Partial<FormPropsType<P, T>> = {}) {
|
function buildSearchForm<P, T>(searchForm: DeepPartial<FormPropsType<P, T>> = {}) {
|
||||||
if (searchForm.defaultData == null) {
|
if (searchForm.defaultData == null) {
|
||||||
searchForm.defaultData = {} as P
|
searchForm.defaultData = {} as DeepPartial<P>
|
||||||
}
|
}
|
||||||
|
if (searchForm.highForm == null) {
|
||||||
|
searchForm.highForm = {
|
||||||
|
labelWidth: 90,
|
||||||
|
contentWidth: 190,
|
||||||
|
rgap: 10,
|
||||||
|
cgap: 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (searchForm.highForm.labelWidth == null) searchForm.highForm.labelWidth = 90
|
||||||
|
if (searchForm.highForm.contentWidth == null) searchForm.highForm.contentWidth = 90
|
||||||
|
if (searchForm.highForm.rgap == null) searchForm.highForm.rgap = 10
|
||||||
|
if (searchForm.highForm.cgap == null) searchForm.highForm.cgap = 10
|
||||||
return searchForm
|
return searchForm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildPageLayout(pageLayout: DeepPartial<PageLayoutType> = {}) {
|
||||||
function buildPageLayout(pageLayout: Partial<PageLayoutType> = {}) {
|
|
||||||
/* if (pageLayout.columns == null) {
|
/* if (pageLayout.columns == null) {
|
||||||
pageLayout.columns = [ '1fr' ]
|
pageLayout.columns = [ '1fr' ]
|
||||||
}
|
}
|
||||||
|
|
@ -117,40 +198,55 @@ function buildPageLayout(pageLayout: Partial<PageLayoutType> = {}) {
|
||||||
pageLayout.rows = [ '1fr', '9fr' ]
|
pageLayout.rows = [ '1fr', '9fr' ]
|
||||||
} */
|
} */
|
||||||
if (pageLayout.dataListHeight == null) {
|
if (pageLayout.dataListHeight == null) {
|
||||||
pageLayout.dataListHeight = '9fr'
|
pageLayout.dataListHeight = 9
|
||||||
}
|
}
|
||||||
|
|
||||||
return pageLayout
|
return pageLayout
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildTable<P extends object, T extends DefaultRow>(table: Partial<TablePropsType<T, P>> = {}) {
|
function buildTable<P extends object, T extends DefaultRow>(table: DeepPartial<TablePropsType<T, P>> = {}) {
|
||||||
if (table.actionColumn == null) {
|
if (table.actionColumn == null) {
|
||||||
table.actionColumn = {
|
table.actionColumn = {
|
||||||
|
width: '80px',
|
||||||
tableActions: [],
|
tableActions: [],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (table.actionColumn.tableActions == null) {
|
if (table.actionColumn.tableActions == null) {
|
||||||
table.actionColumn.tableActions = []
|
table.actionColumn.tableActions = []
|
||||||
}
|
}
|
||||||
|
for (let tableAction of table.actionColumn.tableActions) {
|
||||||
|
if (tableAction.confirm != null) {
|
||||||
|
if (tableAction.confirm.cancelButtonText == null) tableAction.confirm.cancelButtonText = '否'
|
||||||
|
if (tableAction.confirm.confirmButtonText == null) tableAction.confirm.confirmButtonText = '是'
|
||||||
|
if (tableAction.confirm.width == null) tableAction.confirm.width = '180'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (table.actionColumn.width == null) {
|
||||||
|
table.actionColumn.width = '80px'
|
||||||
|
}
|
||||||
|
if (table.emptyText == null) {
|
||||||
|
table.emptyText = '暂无数据'
|
||||||
|
}
|
||||||
|
if (table.rowKey == null) {
|
||||||
|
table.emptyText = 'id'
|
||||||
|
}
|
||||||
|
|
||||||
return table
|
return table
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildToolBar(toolBar: Partial<ToolBarType> = {}) {
|
function buildToolBar(toolBar: DeepPartial<ToolBarType> = {}) {
|
||||||
if (toolBar.leftTools == null) toolBar.leftTools = []
|
if (toolBar.leftTools == null) toolBar.leftTools = []
|
||||||
|
for (let leftTool of toolBar.leftTools) {
|
||||||
|
if (leftTool.type == null) {
|
||||||
|
leftTool.type = 'primary'
|
||||||
|
}
|
||||||
|
}
|
||||||
if (toolBar.rightTools == null) toolBar.rightTools = []
|
if (toolBar.rightTools == null) toolBar.rightTools = []
|
||||||
|
|
||||||
return toolBar
|
return toolBar
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PropsTplType<P extends G.PageParam, T extends DefaultRow> {
|
export function buildProps<P extends G.PageParam, T extends DefaultRow>({pageLayout, searchForm, toolBar, table}: DeepPartial<ATablePageType<P, T>>) {
|
||||||
pageLayout?: Partial<PageLayoutType>
|
|
||||||
searchForm?: Partial<FormPropsType<P, T>>
|
|
||||||
toolBar?: Partial<ToolBarType>
|
|
||||||
table?: Partial<TablePropsType<T, P>>
|
|
||||||
}
|
|
||||||
|
|
||||||
export function buildProps<P extends G.PageParam, T extends DefaultRow>({pageLayout, searchForm, toolBar, table}: PropsTplType<P, T>) {
|
|
||||||
return reactive({
|
return reactive({
|
||||||
pageLayout: buildPageLayout(pageLayout),
|
pageLayout: buildPageLayout(pageLayout),
|
||||||
searchForm: buildSearchForm(searchForm),
|
searchForm: buildSearchForm(searchForm),
|
||||||
|
|
@ -159,10 +255,6 @@ export function buildProps<P extends G.PageParam, T extends DefaultRow>({pageLay
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Exposed extends Record<string, any> {
|
|
||||||
doSearch: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
const component = defineComponent(
|
const component = defineComponent(
|
||||||
<P extends G.PageParam, T extends DefaultRow>(props: ATablePageType<P, T>, {slots, expose}: SetupContext) => {
|
<P extends G.PageParam, T extends DefaultRow>(props: ATablePageType<P, T>, {slots, expose}: SetupContext) => {
|
||||||
const formData = Utils.resetAble(reactive<P>({
|
const formData = Utils.resetAble(reactive<P>({
|
||||||
|
|
@ -197,11 +289,11 @@ const component = defineComponent(
|
||||||
formData.$reset()
|
formData.$reset()
|
||||||
}
|
}
|
||||||
const doExport = () => {
|
const doExport = () => {
|
||||||
if (props?.searchForm?.export == null) {
|
if (props.searchForm.export == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
loading.value = true
|
loading.value = true
|
||||||
saveFile(props?.searchForm?.export(formData.$clone() as P))
|
saveFile(props.searchForm.export(formData.$clone() as P))
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
|
|
@ -232,16 +324,19 @@ const component = defineComponent(
|
||||||
}
|
}
|
||||||
|
|
||||||
const highFormCssParam = computed(() => {
|
const highFormCssParam = computed(() => {
|
||||||
|
const labelWidth = props.searchForm.highForm.labelWidth
|
||||||
|
const contentWidth = props.searchForm.highForm.contentWidth
|
||||||
return {
|
return {
|
||||||
'--col-count': props.searchForm.highForm?.colCount ?? 3,
|
'--item-min-width': (labelWidth + contentWidth) + 'px',
|
||||||
'--vgap': props.searchForm.highForm?.vgap ?? '0',
|
'--rgap': props.searchForm.highForm.rgap + 'px',
|
||||||
'--hgap': props.searchForm.highForm?.hgap ?? '0',
|
'--cgap': props.searchForm.highForm.cgap + 'px',
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const pageCssParam = computed(() => {
|
const pageCssParam = computed(() => {
|
||||||
|
const dataListHeight = props.pageLayout.dataListHeight
|
||||||
return {
|
return {
|
||||||
'--data-list-height': props.pageLayout.dataListHeight,
|
'--data-list-height': Types.isString(dataListHeight) ? dataListHeight : dataListHeight + 'fr',
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const actionColumnBtnRender = (scope: ColumnScopeType<T>, tableAction: TableActionType<T>) => {
|
const actionColumnBtnRender = (scope: ColumnScopeType<T>, tableAction: TableActionType<T>) => {
|
||||||
|
|
@ -249,7 +344,7 @@ const component = defineComponent(
|
||||||
icon={tableAction.icon == null ? undefined : elIcons[tableAction.icon]}
|
icon={tableAction.icon == null ? undefined : elIcons[tableAction.icon]}
|
||||||
loading={tableAction.loading}
|
loading={tableAction.loading}
|
||||||
type={tableAction.type}
|
type={tableAction.type}
|
||||||
class={tableAction.textBtn ? 'text-btn' : 'icon-btn'}
|
class={styles.iconBtn}
|
||||||
text>
|
text>
|
||||||
{tableAction.label}
|
{tableAction.label}
|
||||||
</ElButton>
|
</ElButton>
|
||||||
|
|
@ -264,20 +359,20 @@ const component = defineComponent(
|
||||||
return Btn
|
return Btn
|
||||||
}
|
}
|
||||||
const actionColumnRender = () => {
|
const actionColumnRender = () => {
|
||||||
const actionColumn = props.table?.actionColumn
|
const actionColumn = props.table.actionColumn
|
||||||
return Colls.isEmpty(actionColumn?.tableActions) ? <></>
|
return Colls.isEmpty(actionColumn.tableActions) ? <></>
|
||||||
: (<ElTableColumn width={actionColumn?.width ?? '180'} fixed="right" label="操作">
|
: (<ElTableColumn width={actionColumn.width} fixed="right" label="操作">
|
||||||
<div class="action-btn">
|
<div class="action-btn">
|
||||||
{{
|
{{
|
||||||
default: (scope: ColumnScopeType<T>) => (actionColumn?.tableActions!
|
default: (scope: ColumnScopeType<T>) => (actionColumn.tableActions
|
||||||
.filter(it => (it.show == null ? true : it.show(scope)))
|
.filter(it => (it.show == null ? true : it.show(scope)))
|
||||||
.map((tableAction, i) => (tableAction.confirm != null ?
|
.map((tableAction, i) => (tableAction.confirm != null ?
|
||||||
(<ElPopconfirm
|
(<ElPopconfirm
|
||||||
key={'action-btn-' + i}
|
key={'action-btn-' + i}
|
||||||
cancel-button-text={tableAction.confirm.cancelButtonText ?? '否'}
|
cancel-button-text={tableAction.confirm.cancelButtonText}
|
||||||
confirm-button-text={tableAction.confirm.confirmButtonText ?? '是'}
|
confirm-button-text={tableAction.confirm.confirmButtonText}
|
||||||
title={typeof tableAction.confirm.title === 'function' ? tableAction.confirm.title(scope) : tableAction.confirm.title}
|
title={typeof tableAction.confirm.title === 'function' ? tableAction.confirm.title(scope) : tableAction.confirm.title}
|
||||||
width={tableAction.confirm.width ?? '180'}
|
width={tableAction.confirm.width}
|
||||||
cancel-button-type="primary"
|
cancel-button-type="primary"
|
||||||
confirm-button-type="danger"
|
confirm-button-type="danger"
|
||||||
onConfirm={() => rowAction(scope, tableAction)}>
|
onConfirm={() => rowAction(scope, tableAction)}>
|
||||||
|
|
@ -292,11 +387,10 @@ const component = defineComponent(
|
||||||
}
|
}
|
||||||
onMounted(doSearch)
|
onMounted(doSearch)
|
||||||
return () => (<APage class={[ styles.tablePage, showHighForm.value ? '' : styles.folder ]} style={pageCssParam.value}>
|
return () => (<APage class={[ styles.tablePage, showHighForm.value ? '' : styles.folder ]} style={pageCssParam.value}>
|
||||||
{/*@ts-ignore*/}
|
|
||||||
<div class={styles.searchFormWrapper} style={highFormCssParam.value}>
|
<div class={styles.searchFormWrapper} style={highFormCssParam.value}>
|
||||||
<ElScrollbar>
|
<ElScrollbar>
|
||||||
{/*@ts-ignore*/}
|
{/*@ts-ignore*/}
|
||||||
<ElForm class={styles.searchForm} onSubmit={withModifiers(doSearch, [ 'prevent' ])} labelWidth={props.searchForm.highForm?.labelWidth ?? '90px'}>
|
<ElForm class={styles.searchForm} onSubmit={withModifiers(doSearch, [ 'prevent' ])} labelWidth={props.searchForm.highForm.labelWidth + 'px'}>
|
||||||
{
|
{
|
||||||
slots.highFormItem?.(formData)
|
slots.highFormItem?.(formData)
|
||||||
}
|
}
|
||||||
|
|
@ -308,10 +402,10 @@ const component = defineComponent(
|
||||||
<div class={styles.toolBar}>
|
<div class={styles.toolBar}>
|
||||||
<div class={styles.toolBarLeft}>
|
<div class={styles.toolBarLeft}>
|
||||||
{
|
{
|
||||||
props.toolBar?.leftTools?.map((tool, i) => (
|
props.toolBar.leftTools.map((tool, i) => (
|
||||||
<ElButton key={'tool-bar-left-' + i}
|
<ElButton key={'tool-bar-left-' + i}
|
||||||
icon={Strings.isBlank(tool.icon) ? undefined : elIcons[tool.icon!]}
|
icon={Strings.isBlank(tool.icon) ? undefined : elIcons[tool.icon!]}
|
||||||
type={tool.type ?? 'primary'}
|
type={tool.type}
|
||||||
onClick={tool.action}>
|
onClick={tool.action}>
|
||||||
{tool.label}
|
{tool.label}
|
||||||
</ElButton>
|
</ElButton>
|
||||||
|
|
@ -319,51 +413,57 @@ const component = defineComponent(
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class={styles.toolBarRight}>
|
<div class={styles.toolBarRight}>
|
||||||
{/*@ts-ignore*/}
|
<ElScrollbar>
|
||||||
<ElForm onSubmit={withModifiers(doSearch, [ 'prevent' ])}>
|
{/*@ts-ignore*/}
|
||||||
{
|
<ElForm onSubmit={withModifiers(doSearch, [ 'prevent' ])}>
|
||||||
slots.simpleFormItem?.(formData)
|
{
|
||||||
}
|
slots.simpleFormItem?.(formData)
|
||||||
<button style="display: none" type="submit"/>
|
|
||||||
</ElForm>
|
|
||||||
<ElTooltip content="搜索" placement="top">
|
|
||||||
<ElDropdown split-button onClick={doSearch} onCommand={(command: string) => {
|
|
||||||
if (command === 'reset') {
|
|
||||||
doReset()
|
|
||||||
}
|
}
|
||||||
}}>
|
<button style="display: none" type="submit"/>
|
||||||
{{
|
</ElForm>
|
||||||
default: () => (<ElButton icon={elIcons.Search} loading={loading.value} type="default"/>),
|
</ElScrollbar>
|
||||||
dropdown: () => (<ElDropdownMenu>
|
<div>
|
||||||
<ElDropdownItem icon={elIcons.Refresh} command="reset">重置并刷新</ElDropdownItem>
|
<ElTooltip content="搜索" placement="top">
|
||||||
</ElDropdownMenu>),
|
<ElDropdown split-button onClick={doSearch} onCommand={(command: string) => {
|
||||||
}}
|
if (command === 'reset') {
|
||||||
</ElDropdown>
|
doReset()
|
||||||
</ElTooltip>
|
}
|
||||||
{
|
}}>
|
||||||
props.toolBar?.rightTools?.map((tool, i) => (
|
{{
|
||||||
<ElButton key={'tool-bar-right-' + i}
|
default: () => (<ElButton icon={elIcons.Search} loading={loading.value} type="default"/>),
|
||||||
icon={elIcons[tool.icon]}
|
dropdown: () => (<ElDropdownMenu>
|
||||||
onClick={tool.action}/>
|
<ElDropdownItem icon={elIcons.Refresh} command="reset">重置并刷新</ElDropdownItem>
|
||||||
))
|
</ElDropdownMenu>),
|
||||||
}
|
}}
|
||||||
<ElTooltip content="导出" placement="top">
|
</ElDropdown>
|
||||||
<ElButton icon={elIcons.Download} loading={loading.value} type="default" onClick={doExport}/>
|
</ElTooltip>
|
||||||
</ElTooltip>
|
{
|
||||||
<ElTooltip content={showHighForm.value ? '关闭高级搜索' : '打开高级搜索'} placement="top">
|
props.toolBar.rightTools.map((tool, i) => (
|
||||||
<ElButton class={showHighForm.value ? styles.filterBtnActive : ''} icon={elIcons.Filter} type="default" onClick={showHighFormHandle}/>
|
<ElButton key={'tool-bar-right-' + i}
|
||||||
</ElTooltip>
|
icon={elIcons[tool.icon]}
|
||||||
|
onClick={tool.action}/>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
props.searchForm.export == null ? <></> : (<ElTooltip content="导出" placement="top">
|
||||||
|
<ElButton icon={elIcons.Download} loading={loading.value} type="default" onClick={doExport}/>
|
||||||
|
</ElTooltip>)
|
||||||
|
}
|
||||||
|
<ElTooltip content={showHighForm.value ? '关闭高级搜索' : '打开高级搜索'} placement="top">
|
||||||
|
<ElButton class={showHighForm.value ? styles.filterBtnActive : ''} icon={elIcons.Filter} type="default" onClick={showHighFormHandle}/>
|
||||||
|
</ElTooltip>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
withDirectives(<ElTable
|
withDirectives(<ElTable
|
||||||
data={tableData}
|
data={tableData}
|
||||||
empty-text={props.table?.emptyText ?? '暂无数据'}
|
empty-text={props.table.emptyText}
|
||||||
row-key={props.table?.rowKey ?? 'id'}
|
row-key={props.table.rowKey}
|
||||||
ref="dataTable"
|
ref="dataTable"
|
||||||
lazy={props.table?.treeLoad == null ? undefined : true}
|
lazy={props.table.treeLoad == null ? undefined : true}
|
||||||
load={props.table?.treeLoad ? ((row, expanded, resolve) => props.table?.treeLoad!(formData as P, row, expanded, resolve)) : undefined}
|
load={props.table.treeLoad ? ((row, expanded, resolve) => props.table.treeLoad!(formData as P, row, expanded, resolve)) : undefined}
|
||||||
onExpand-change={props.table?.treeLoad ? ((row: any, expandedRows: any) => props.table?.treeLoad!(formData as P, row, expandedRows, undefined)) : undefined}
|
onExpand-change={props.table.treeLoad ? ((row: any, expandedRows: any) => props.table.treeLoad!(formData as P, row, expandedRows, undefined)) : undefined}
|
||||||
cell-class-name="table-cell"
|
cell-class-name="table-cell"
|
||||||
header-row-class-name="table-header"
|
header-row-class-name="table-header"
|
||||||
>
|
>
|
||||||
|
|
@ -399,7 +499,8 @@ const component = defineComponent(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export interface ATablePageInstance extends InstanceType<typeof component>, Exposed {
|
export interface ATablePageInstance extends InstanceType<typeof component> {
|
||||||
|
doSearch: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default component
|
export default component
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
.table-page {
|
.table-page {
|
||||||
grid-template-columns 1fr
|
grid-template-columns 1fr
|
||||||
grid-template-rows: minmax(0, 1fr) minmax(0, var(--data-list-height));
|
grid-template-rows: minmax(74px, 1fr) minmax(277px, var(--data-list-height));
|
||||||
grid-auto-rows: minmax(0, auto);
|
grid-auto-rows: minmax(0, auto);
|
||||||
gap 10px
|
gap 10px
|
||||||
|
|
||||||
|
|
@ -35,9 +35,9 @@
|
||||||
|
|
||||||
.search-form {
|
.search-form {
|
||||||
display grid
|
display grid
|
||||||
grid-template-columns repeat(var(--col-count), 1fr)
|
grid-template-columns repeat(auto-fit, minmax(var(--item-min-width), 1fr))
|
||||||
row-gap var(--vgap);
|
row-gap var(--rgap);
|
||||||
column-gap var(--hgap);
|
column-gap var(--cgap);
|
||||||
|
|
||||||
:global(.el-form-item) {
|
:global(.el-form-item) {
|
||||||
margin 0
|
margin 0
|
||||||
|
|
@ -67,53 +67,59 @@
|
||||||
gap 20px
|
gap 20px
|
||||||
|
|
||||||
.tool-bar {
|
.tool-bar {
|
||||||
display flex
|
display: grid;
|
||||||
justify-content space-between
|
grid-template-columns: minmax(260px, 1fr) minmax(428px, 1fr);
|
||||||
|
grid-template-rows: 50px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
.tool-bar-left {
|
.tool-bar-left {
|
||||||
flex 1
|
//flex 1
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-bar-right {
|
.tool-bar-right {
|
||||||
flex 1
|
display grid
|
||||||
display flex
|
grid-template-columns: minmax(200px, 1fr) 150px;
|
||||||
|
grid-auto-rows: 32px;
|
||||||
gap 10px
|
gap 10px
|
||||||
justify-content end
|
|
||||||
|
|
||||||
:global(.el-form) {
|
& > div:first-child {
|
||||||
display flex
|
:global(.el-form) {
|
||||||
gap 10px
|
display: grid;
|
||||||
flex-shrink 0
|
grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
|
||||||
|
gap 10px
|
||||||
|
|
||||||
.el-form-item {
|
:global(.el-form-item) {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
flex 1
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.el-button--default) {
|
& > div:last-child {
|
||||||
width 32px
|
display: flex;
|
||||||
color #4D5875
|
justify-content: space-evenly;
|
||||||
background-color #F1F4F4
|
|
||||||
border-color #F1F4F4
|
|
||||||
margin 0
|
|
||||||
|
|
||||||
&:hover {
|
:global(.el-button--default) {
|
||||||
|
width 32px
|
||||||
|
color #4D5875
|
||||||
|
background-color #F1F4F4
|
||||||
|
border-color #F1F4F4
|
||||||
|
margin 0
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color var(--main-color)
|
||||||
|
background-color #E6EAEB;
|
||||||
|
border-color #E6EAEB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.el-dropdown) {
|
||||||
|
flex-shrink 0
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.el-button--default).filter-btn-active {
|
||||||
color var(--main-color)
|
color var(--main-color)
|
||||||
background-color #E6EAEB;
|
|
||||||
border-color #E6EAEB;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
:global(.el-dropdown) {
|
|
||||||
flex-shrink 0
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.el-button--default).filter-btn-active {
|
|
||||||
color var(--main-color)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@
|
||||||
<ElTableColumn label="出场时间" prop="outTime" width="140"/>
|
<ElTableColumn label="出场时间" prop="outTime" width="140"/>
|
||||||
<!-- <ElTableColumn label="完结时间" prop="finishTime"/> -->
|
<!-- <ElTableColumn label="完结时间" prop="finishTime"/> -->
|
||||||
<ElTableColumn fixed="right" label="支付状态" prop="paymentStatusTxt"/>
|
<ElTableColumn fixed="right" label="支付状态" prop="paymentStatusTxt"/>
|
||||||
|
y
|
||||||
<ElTableColumn fixed="right" label="订单状态" prop="transStatusTxt"/>
|
<ElTableColumn fixed="right" label="订单状态" prop="transStatusTxt"/>
|
||||||
<ElTableColumn fixed="right" label="勘料状态" prop="checkStatusTxt"/>
|
<ElTableColumn fixed="right" label="勘料状态" prop="checkStatusTxt"/>
|
||||||
|
|
||||||
|
|
@ -98,6 +99,9 @@ function research() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const tablePageProps = buildProps({
|
const tablePageProps = buildProps({
|
||||||
|
pageLayout: {
|
||||||
|
dataListHeight: 4,
|
||||||
|
},
|
||||||
table: {
|
table: {
|
||||||
actionColumn: {
|
actionColumn: {
|
||||||
tableActions: [
|
tableActions: [
|
||||||
|
|
@ -111,10 +115,13 @@ const tablePageProps = buildProps({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
searchForm: {
|
searchForm: {
|
||||||
|
highForm: {
|
||||||
|
contentWidth: 342,
|
||||||
|
},
|
||||||
paging(param: OrderTypes.SearchOrderParam) {
|
paging(param: OrderTypes.SearchOrderParam) {
|
||||||
return OrderApi.paging(param).then(res => {
|
return OrderApi.paging(param).then(res => {
|
||||||
res.data.records = []
|
res.data.records = []
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 20; i++) {
|
||||||
res.data.records.push({})
|
res.data.records.push({})
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
|
|
@ -122,6 +129,4 @@ const tablePageProps = buildProps({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue