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.
244 lines
6.6 KiB
244 lines
6.6 KiB
7 months ago
|
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>
|
||
|
);
|
||
|
},
|
||
|
};
|