244 lines
6.6 KiB
TypeScript
244 lines
6.6 KiB
TypeScript
import { dateUtil } from '/nerv-lib/util/date-util';
|
||
import { NsModal } from '/nerv-lib/component/modal';
|
||
import { HttpRequestConfig, useApi } from '/nerv-lib/use/use-api';
|
||
import { useParams } from '/nerv-lib/use/use-params';
|
||
import { isFunction, isNumber, isString, toLower } from 'lodash-es';
|
||
import { Loading3QuartersOutlined, QuestionCircleOutlined } from '@ant-design/icons-vue';
|
||
|
||
import './table-columns.less';
|
||
|
||
interface RenderTransform {
|
||
api?: string | Recordable | Function;
|
||
messageField?: string | Function;
|
||
params?: string | Array<string> | Recordable;
|
||
pipe: string;
|
||
statusField?: string | Function;
|
||
textField?: string | Function;
|
||
isShowQuIcon?: Function; //是否展示错误时的 ?icon,用法同上,需要返回boolean,传了,就代表你要控制icon的展示,不传就代表只在错误时展示
|
||
}
|
||
|
||
type RenderTransformProps = Omit<RenderTransform, 'pipe'>;
|
||
|
||
interface ColumnData {
|
||
index: number;
|
||
record: Recordable;
|
||
text: any;
|
||
}
|
||
|
||
//格式化列数据
|
||
export function transformColumns(columns: Array<any>) {
|
||
return columns.map((item) => {
|
||
if (item.transform) {
|
||
item.customRender = getRender(item.transform);
|
||
// delete item.transform; //排序中有字段比较,对象属性影响结果
|
||
if (item.transform?.pipe === 'CNY') {
|
||
item.align = 'right';
|
||
}
|
||
}
|
||
|
||
if (item.textNumber || isNumber(item.customType)) {
|
||
const textNumber = item.textNumber || item.customType;
|
||
item.width = 12 * 2 + 16 * textNumber;
|
||
}
|
||
return item;
|
||
});
|
||
}
|
||
|
||
function formatMoney(s: string) {
|
||
const n = 2;
|
||
s = parseFloat((s + '').replace(/[^\d\.-]/g, '')).toFixed(n) + '';
|
||
const l = s.split('.')[0].split('').reverse(),
|
||
r = s.split('.')[1];
|
||
let t = '';
|
||
for (let index = 0; index < l.length; index++) {
|
||
t += l[index] + ((index + 1) % 3 == 0 && index + 1 != l.length ? ',' : '');
|
||
}
|
||
return '¥' + t.split('').reverse().join('') + '.' + r;
|
||
}
|
||
|
||
//根据transform生成customRender
|
||
function getRender(transform: RenderTransform) {
|
||
const { pipe, ...ext } = transform;
|
||
return (data: any) => {
|
||
return pipes[pipe](data, {
|
||
params: {},
|
||
...ext,
|
||
});
|
||
};
|
||
}
|
||
const { httpRequest } = useApi();
|
||
const { getParams } = useParams();
|
||
|
||
//约定处理函数
|
||
const pipes: Record<
|
||
string,
|
||
(columnData: ColumnData, { params, api, messageField, statusField }: RenderTransformProps) => any
|
||
> = {
|
||
date: ({ text }, { params }) => {
|
||
const { format = 'YYYY-MM-DD HH:mm' } = params as Recordable;
|
||
return dateUtil(text).format(format);
|
||
},
|
||
CNY: ({ text }) => {
|
||
const money = text || 0;
|
||
return <span style="color: #D07C35;"> {formatMoney(money)}</span>;
|
||
},
|
||
state: (
|
||
{ text, record },
|
||
{ params, api, messageField, statusField = 'showStatus', textField, isShowQuIcon },
|
||
) => {
|
||
let statusFieldValue = '';
|
||
if (isFunction(statusField)) {
|
||
statusFieldValue = statusField(record);
|
||
} else if (isString(statusField)) {
|
||
statusFieldValue = record[statusField];
|
||
}
|
||
|
||
// 优先使用textField 取值 没有则使用text
|
||
let textFieldValue: string = text;
|
||
if (isFunction(textField)) {
|
||
textFieldValue = textField(record);
|
||
} else if (isString(textField)) {
|
||
textFieldValue = record[textField];
|
||
}
|
||
|
||
// 点击提示框参数
|
||
const props = {
|
||
onClick: () => {
|
||
if (messageField) {
|
||
if (isFunction(messageField)) {
|
||
messageField = messageField(record);
|
||
}
|
||
NsModal.error({
|
||
title: '警告',
|
||
content: record[messageField as string],
|
||
});
|
||
} else if (api) {
|
||
const requestConfig: HttpRequestConfig = { method: 'get' };
|
||
|
||
const requestParams = getParams(record, params);
|
||
|
||
httpRequest({ api, params: requestParams, pathParams: record, requestConfig }).then(
|
||
(res: any) => {
|
||
NsModal.error({
|
||
title: '警告',
|
||
content: res.message,
|
||
});
|
||
},
|
||
);
|
||
}
|
||
},
|
||
style: {
|
||
cursor: 'pointer',
|
||
},
|
||
};
|
||
// 问号图标
|
||
const quIconNode = () => {
|
||
return (
|
||
isShowQuIcon &&
|
||
isShowQuIcon(record) && (
|
||
<QuestionCircleOutlined
|
||
{...props}
|
||
style={{
|
||
fontSize: '14px',
|
||
marginLeft: '4px',
|
||
color: '#666',
|
||
}}
|
||
/>
|
||
)
|
||
);
|
||
};
|
||
|
||
// 成功
|
||
if (
|
||
statusFieldValue.endsWith('success') ||
|
||
statusFieldValue.endsWith('available') ||
|
||
toLower(statusFieldValue).endsWith('active') ||
|
||
statusFieldValue.endsWith('enabled')
|
||
) {
|
||
return (
|
||
<div class="status-field status-success">
|
||
<span>{textFieldValue}</span>
|
||
{quIconNode()}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// 错误
|
||
if (
|
||
statusFieldValue.endsWith('fail') ||
|
||
statusFieldValue.endsWith('error') ||
|
||
statusFieldValue.endsWith('failed') ||
|
||
toLower(statusFieldValue).endsWith('disabled')
|
||
) {
|
||
if (isFunction(messageField)) {
|
||
messageField = messageField(record);
|
||
}
|
||
return (
|
||
<div class="status-field status-fail">
|
||
<span> {textFieldValue} </span>
|
||
{(!isShowQuIcon || isShowQuIcon(record)) && record[messageField as string] && (
|
||
<QuestionCircleOutlined
|
||
{...props}
|
||
style={{
|
||
fontSize: '14px',
|
||
marginLeft: '4px',
|
||
color: '#666',
|
||
}}
|
||
/>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// 提醒状态
|
||
if (statusFieldValue.endsWith('warning')) {
|
||
return (
|
||
<div class="status-field status-warning">
|
||
<span>{textFieldValue}</span>
|
||
{quIconNode()}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// 执行中
|
||
if (statusFieldValue.endsWith('ing')) {
|
||
return (
|
||
<div
|
||
style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
}}>
|
||
<a-spin
|
||
indicator={
|
||
<Loading3QuartersOutlined
|
||
style={{
|
||
fontSize: '11px',
|
||
margin: '6px',
|
||
}}
|
||
spin={true}></Loading3QuartersOutlined>
|
||
}
|
||
/>
|
||
<a-typography-text>{textFieldValue}</a-typography-text>
|
||
</div>
|
||
);
|
||
}
|
||
// 提醒状态
|
||
if (statusFieldValue.endsWith('unknown')) {
|
||
return (
|
||
<div class="status-field status-normal">
|
||
<span>{textFieldValue}</span>
|
||
{quIconNode()}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
return (
|
||
// <div class="status-field status-normal">
|
||
<div>
|
||
<span>{textFieldValue ? textFieldValue : '-'}</span>
|
||
{quIconNode()}
|
||
</div>
|
||
);
|
||
},
|
||
};
|