diff --git a/packages/ui-vue/components/data-view/components/column-format/boolean.component.tsx b/packages/ui-vue/components/data-view/components/column-format/boolean.component.tsx index 3407179cd9dcbb4b9c82ab63d00a421b0ceb938a..c1be5edca51a854d5576074ecfe4d13013958dbf 100644 --- a/packages/ui-vue/components/data-view/components/column-format/boolean.component.tsx +++ b/packages/ui-vue/components/data-view/components/column-format/boolean.component.tsx @@ -1,31 +1,20 @@ -import { resolveField } from '@farris/ui-vue/components/common'; -import { ColumnFormatterDataType, DataColumn, VisualData } from '../../composition/types'; +import { InnerFormatter } from '../../composition/types'; export default function () { // format image - function renderImage(value: any, column: DataColumn) { + function renderImage(value: any, options: InnerFormatter) { if (value) { - return ; + return ; } - return ; + return ; } // format text - function renderText(value: any, column: DataColumn) { + function renderText(value: any, options: InnerFormatter) { if (value) { - return column.formatter?.trueText; + return options?.trueText; } - return column.formatter?.falseText; + return options?.falseText; } - - function renderBooleanColumn(column: DataColumn, visualDataRow: VisualData) { - const { formatter } = column; - const value = resolveField(visualDataRow.raw, column.field); - if (formatter.type === ColumnFormatterDataType.TEXT) { - return renderText(value, column); - } else if (formatter.type === ColumnFormatterDataType.IMAGE) { - return renderImage(value, column); - } - } - return { renderBooleanColumn }; + return { renderText, renderImage }; } diff --git a/packages/ui-vue/components/data-view/components/column-format/column-format.component.tsx b/packages/ui-vue/components/data-view/components/column-format/column-format.component.tsx index 679930b3b514002f66a5997398c7bb271ee74f84..8a71d79a8c534a52c250000e4165a4fcc4071cea 100644 --- a/packages/ui-vue/components/data-view/components/column-format/column-format.component.tsx +++ b/packages/ui-vue/components/data-view/components/column-format/column-format.component.tsx @@ -1,19 +1,22 @@ +import { resolveField } from '@farris/ui-vue/components/common'; import { - ColumnFormatterDataType, DataColumn, DataColumnCommand, - VisualData, VisualDataCell, VisualDataStatus + DataColumn, + InnerFormatter, + VisualData } from '../../composition/types'; import getEnumColumn from './enum.component'; import getBooleanColumn from './boolean.component'; import getDateColumn from './date.component'; import getNumberColumn from './number.component'; -import { resolveField } from '@farris/ui-vue/components/common'; +import getLookupFormatColumn from './column-lookup-format.component'; export default function () { - const { renderBooleanColumn } = getBooleanColumn(); + const { renderText, renderImage } = getBooleanColumn(); const { renderEnumColumn } = getEnumColumn(); const { renderNumberColumn } = getNumberColumn(); const { renderDateColumn } = getDateColumn(); + const { renderLookupFormatColumn } = getLookupFormatColumn(); // format none function renderNone(value: any) { @@ -21,37 +24,51 @@ export default function () { } // format custom - function renderCustom(value: any, column: DataColumn) { - const { formatter } = column; - return formatter.customFormat ? - new Function(`return ${formatter.customFormat}`)() : + function renderCustom(value: any, options: InnerFormatter) { + return options.customFormat ? + new Function(`return ${options.customFormat}`)() : renderNone(value); } - function renderFormatColumn(dataType: string, column: DataColumn, visualDataRow: VisualData) { - - const value = resolveField(visualDataRow.raw, [column.field]); - const { formatter } = column; - // no formatter - if (formatter.type === 'none') { + function renderInnerFormatColumn( + column: DataColumn, + visualDataRow: VisualData, + formatter: InnerFormatter) { + const value = resolveField(visualDataRow.raw, column.field); + // no formatter + if (formatter.type === 'none') { + return renderNone(value); + } + // custom formatter + if (formatter.type === 'custom') { + return renderCustom(value, formatter); + } + // formatter + if (formatter.type === 'enum') { + return renderEnumColumn(value, formatter); + } else if (formatter.type === 'number') { + return renderNumberColumn(value, formatter); + } else if (formatter.type === 'boolean') { + return renderText(value, formatter); + } else if (formatter.type === 'boolean2') { + return renderImage(value, formatter); + } else if (formatter.type === 'date') { + return renderDateColumn(value, formatter); + } + // default no formmater return renderNone(value); + } + + function renderFormatColumn( + column: DataColumn, + visualDataRow: VisualData, + formatter: InnerFormatter + ) { + if (formatter.options) { + // 帮助列formatter属性有options,帮助列表格式化 + return renderLookupFormatColumn(column, visualDataRow, formatter); } - // custom formatter - if (formatter.type === 'custom') { - return renderCustom(value, column); - } - // formatter - if (formatter.type === 'enum') { - return renderEnumColumn(column, visualDataRow); - } else if (formatter.type === 'number') { - return renderNumberColumn(column, visualDataRow); - } else if (formatter.type === 'boolean') { - return renderBooleanColumn(column, visualDataRow); - } else if (formatter.type === 'date') { - return renderDateColumn(column, visualDataRow); - } - // default no formmater - return renderNone(value); + return renderInnerFormatColumn(column, visualDataRow, formatter); } return { renderFormatColumn }; } diff --git a/packages/ui-vue/components/data-view/components/column-format/column-lookup-format.component.tsx b/packages/ui-vue/components/data-view/components/column-format/column-lookup-format.component.tsx new file mode 100644 index 0000000000000000000000000000000000000000..cd3fc25c8403fc6e0fb0ae2bedc98823140d9147 --- /dev/null +++ b/packages/ui-vue/components/data-view/components/column-format/column-lookup-format.component.tsx @@ -0,0 +1,119 @@ +import { resolveField, useDateFormat } from '@farris/ui-vue/components/common'; +import { + BooleanFormatOptions, + DataColumn, + DateTimeFormatOptions, + EnumFormatOptions, + ImageFormatOptions, + InnerFormatter, + NumberFormatOptions, + VisualData, +} from '../../composition/types'; +import getNumberColumn from './number.component'; + +export default function () { + const { formatTo } = useDateFormat(); + const { renderNumberColumn } = getNumberColumn(); + function formatDateTimeColumn(value: any, options: DateTimeFormatOptions) { + if (value) { + let dateFormat = 'yyyy-MM-dd'; + if (typeof (options) === 'string') { + dateFormat = options; + } else if (typeof (options) === 'object') { + dateFormat = options.format || 'yyyy-MM-dd'; + } + dateFormat = dateFormat.replace('YYYY', 'yyyy').replace('-DD', '-dd'); + if (typeof (options) === 'object' && options.dateRange) { + const splitStr = options.dateRangeDatesDelimiter || '~'; + let [beginDate, endDate] = value.split(splitStr); + beginDate = formatTo(beginDate, dateFormat); + endDate = formatTo(endDate, dateFormat); + return beginDate + splitStr + endDate; + } + return formatTo(value, dateFormat); + } + return value; + } + + function formatNumberColumn(value: any, options: NumberFormatOptions) { + return renderNumberColumn(value, options); + } + + function formatEnumColumn(value: any, options?: EnumFormatOptions) { + if (value === undefined || value === null) { + value = ''; + } + if (options?.data?.length) { + const valueString = value.toString(); + let valueList = [valueString]; + if (valueString.indexOf(',') > -1) { // 多选 + valueList = valueString.split(','); + } + const str = [] as any[]; + valueList.forEach((valueListItem: any) => { + const optionData = options.data?.find(item => item[options.valueField] === valueListItem); + if (optionData) { + str.push(optionData[options.textField]); + } + }); + if (str.length) { + return str.join(','); + } + return value; + } + return value; + } + + function formatImageColumn(value, options?: ImageFormatOptions) { + if (value) { + if (options) { + const imgList = [`'); + return imgList.join(''); + } + return ``; + } + return value; + } + + function formatBooleanColumn(value, options?: BooleanFormatOptions) { + if (value !== undefined) { + if (options) { + const realValue = value ? options.trueText : options.falseText; + if (realValue === null || realValue === undefined) { + return value; + } + return realValue; + } + return value; + } + return ''; + } + function renderLookupFormatColumn( + column: DataColumn, + visualDataRow: VisualData, + formatter: InnerFormatter) { + const value = resolveField(visualDataRow.raw, column.field); + if (formatter.type === 'datetime') { + return formatDateTimeColumn(value, formatter.options as DateTimeFormatOptions); + } else if (formatter.type === 'number') { + return formatNumberColumn(value, formatter.options as NumberFormatOptions); + } else if (formatter.type === 'boolean' || formatter.type === 'boolean2') { + return formatBooleanColumn(value, formatter.options as BooleanFormatOptions); + } else if (formatter.type === 'enum') { + return formatEnumColumn(value, formatter.options as EnumFormatOptions); + } else if (formatter.type === 'image') { + return formatImageColumn(value, formatter.options as ImageFormatOptions); + } + + return value; + } + + return { renderLookupFormatColumn }; +} diff --git a/packages/ui-vue/components/data-view/components/column-format/date.component.tsx b/packages/ui-vue/components/data-view/components/column-format/date.component.tsx index e046e656fe0982989043f9931c6d07be717dd725..7ab413bf23be981765d76f31ed9537861fb7f944 100644 --- a/packages/ui-vue/components/data-view/components/column-format/date.component.tsx +++ b/packages/ui-vue/components/data-view/components/column-format/date.component.tsx @@ -1,16 +1,12 @@ import { resolveField, useDateFormat } from '@farris/ui-vue/components/common'; -import { DataColumn, VisualData } from '../../composition/types'; +import { DataColumn, DateTimeFormatOptions, InnerFormatter, LookupFormatOptions, VisualData } from '../../composition/types'; export default function () { const { formatTo } = useDateFormat(); // format date - function renderDate(value: any, column: DataColumn) { - return formatTo(value, column.formatter.dateFormat); - } - - function renderDateColumn(column: DataColumn, visualDataRow: VisualData) { - const value = resolveField(visualDataRow.raw, column.field); - return renderDate(value, column); + function renderDateColumn(value: any, options: InnerFormatter | DateTimeFormatOptions) { + const dateFormat = ((options as InnerFormatter).dateFormat) || 'yyyy-MM-dd'; + return formatTo(value, dateFormat); } return { renderDateColumn }; } diff --git a/packages/ui-vue/components/data-view/components/column-format/enum.component.tsx b/packages/ui-vue/components/data-view/components/column-format/enum.component.tsx index a6a193806c450467b330b7bc64e360979fd5fbc7..d9fa79bad70527c0d900da45a3bf1d87d9bded3d 100644 --- a/packages/ui-vue/components/data-view/components/column-format/enum.component.tsx +++ b/packages/ui-vue/components/data-view/components/column-format/enum.component.tsx @@ -1,21 +1,18 @@ import { resolveField } from '@farris/ui-vue/components/common'; -import { DataColumn, VisualData } from '../../composition/types'; +import { DataColumn, InnerFormatter, VisualData } from '../../composition/types'; export default function () { - - function renderEnumColumn(column: DataColumn, visualDataRow: VisualData) { - const { formatter } = column; - const value = resolveField(visualDataRow.raw, column.field); + function renderEnumColumn(value: any, options: InnerFormatter) { if (value?.includes(',')) { const valueList = value.split(','); - const dataMap = formatter.data.reduce((total: any, next: { value: number, name: number }) => { + const dataMap = options.data?.reduce((total: any, next: { value: number, name: number }) => { total[next.value] = next; return total; }, {}); const nameList = valueList.map((value: string) => dataMap[value].name); return nameList.join(','); } - const selectedDataItem = formatter.data.find((item: { value: number, name: number }) => item.value === value); + const selectedDataItem = options.data?.find((item: { value: number, name: number }) => item.value === value); return selectedDataItem?.name || ''; } diff --git a/packages/ui-vue/components/data-view/components/column-format/number.component.tsx b/packages/ui-vue/components/data-view/components/column-format/number.component.tsx index 501e55c268826a549c92b5d314ce85c4d3418df1..d0ee7f1c9473331708697a51141f8bc8651a9e19 100644 --- a/packages/ui-vue/components/data-view/components/column-format/number.component.tsx +++ b/packages/ui-vue/components/data-view/components/column-format/number.component.tsx @@ -1,24 +1,18 @@ import { useNumberFormat, resolveField } from '@farris/ui-vue/components/common'; -import { DataColumn, VisualData } from '../../composition/types'; +import { DataColumn, InnerFormatter, LookupFormatOptions, NumberFormatOptions, VisualData } from '../../composition/types'; export default function () { const { formatTo } = useNumberFormat(); - // format number - function renderNumber(value: any, column: DataColumn) { - const { formatter } = column; + + function renderNumberColumn(value: any, options: InnerFormatter | NumberFormatOptions) { const numberOptions = { - precision: formatter.precision, - prefix: formatter.prefix || '', - suffix: formatter.suffix || '', - decimalSeparator: formatter.decimal || '.', - groupSeparator: formatter.thousand || '', + precision: options.precision, + prefix: options.prefix || '', + suffix: options.suffix || '', + decimalSeparator: options.decimal || '.', + groupSeparator: options.thousand || '', }; return formatTo(value, numberOptions); } - - function renderNumberColumn(column: DataColumn, visualDataRow: VisualData) { - const value = resolveField(visualDataRow.raw, column.field); - return renderNumber(value, column); - } return { renderNumberColumn }; } diff --git a/packages/ui-vue/components/data-view/composition/types.ts b/packages/ui-vue/components/data-view/composition/types.ts index d81b8a0248d24b7cacd650224fb88fa1a9775a5b..853123567071fc54ba27679989a6ad201abfef9e 100644 --- a/packages/ui-vue/components/data-view/composition/types.ts +++ b/packages/ui-vue/components/data-view/composition/types.ts @@ -1132,3 +1132,66 @@ export interface HierarchyItem { expanded?: boolean; selectable?: boolean; } + + +export interface NumberFormatOptions { + /** 货币符号 */ + prefix?: string; + /** 后缀符号 */ + suffix?: string; + /** 输出格式: %s = 货币符号, %v = 值 */ + format?: string; + /** 小数点分隔符 */ + decimal?: string; + /** 千分位分隔符 */ + thousand?: string; + /** 保留小数位数 */ + precision?: number; + /** 去掉小数末尾的0 */ + stripZeros?: boolean; +} + +export interface DateTimeFormatOptions { + format?: string; + dateRangeDatesDelimiter?: string; + dateRange: any; + +} + +export interface BooleanFormatOptions { + trueText?: string; + falseText?: string; +} + +export interface EnumFormatOptions { + valueField: string; + textField: string; + data?: any[]; +} + +export interface ImageFormatOptions { + width?: string; + height?: string; +} + +export type LookupFormatOptions = NumberFormatOptions | +DateTimeFormatOptions | +BooleanFormatOptions | +EnumFormatOptions | +ImageFormatOptions; + +export interface InnerFormatter { + data?: any; + customFormat?: any; + precision?: number; + prefix?: string; + suffix?: string; + decimal?: string; + thousand?: string; + trueText?: string; + falseText?: string; + dateFormat?: string; + type?: 'date' | 'datetime' | 'number' | 'enum' + | 'image' | 'boolean' | 'boolean2' | 'timeago' | 'none' | 'custom'; + options?: LookupFormatOptions; +} diff --git a/packages/ui-vue/components/data-view/composition/visualization/use-visual-data-cell.ts b/packages/ui-vue/components/data-view/composition/visualization/use-visual-data-cell.ts index e9e168aed94c991245fe7d40384babf167bf72ca..111a45901f1f7e1ecee06cf802ebfd16ce946028 100644 --- a/packages/ui-vue/components/data-view/composition/visualization/use-visual-data-cell.ts +++ b/packages/ui-vue/components/data-view/composition/visualization/use-visual-data-cell.ts @@ -73,7 +73,7 @@ export function useVisualDataCell( targetCell.formatter = (cell: VisualDataCell, visualDataRow: VisualData) => { return typeof column.formatter === 'function' ? column.formatter(cell, visualDataRow) : - renderFormatColumn(column.dataType, column, visualDataRow); + renderFormatColumn(column, visualDataRow, column.formatter); }; } }