fix(项目任务): 1、任务完成后需要依然能够修改工作日志,但是只能修改工作内容和上传附件。2、任务完成后,协办人的工作日志不应该能删除、所有任务里的成员不能新增工作日志,前端不显示新增、删除按钮。3、团队成员的面板,在成员排序时,让有下属的成员提前。4、在任务弹出框有个快速用执行的信息填充的icon。
124 lines
3.3 KiB
TypeScript
124 lines
3.3 KiB
TypeScript
import dayjs from 'dayjs';
|
|
|
|
export type LogTabKey = 'login-log' | 'operate-log' | 'api-access-log' | 'api-error-log';
|
|
|
|
export interface LogTabOption {
|
|
name: LogTabKey;
|
|
label: string;
|
|
description: string;
|
|
queryPermission: string;
|
|
exportPermission: string;
|
|
}
|
|
|
|
export interface LogDetailField {
|
|
label: string;
|
|
key?: string;
|
|
span?: number;
|
|
type?: 'text' | 'datetime' | 'dict' | 'multiline';
|
|
dictCode?: string;
|
|
formatter?: (detail: Record<string, unknown>) => string;
|
|
}
|
|
|
|
export interface LogDetailSection {
|
|
title: string;
|
|
fields: LogDetailField[];
|
|
}
|
|
|
|
export const LogPermission = {
|
|
LoginQuery: 'system:login-log:query',
|
|
LoginExport: 'system:login-log:export',
|
|
OperateQuery: 'system:operate-log:query',
|
|
OperateExport: 'system:operate-log:export',
|
|
ApiAccessQuery: 'system:api-access-log:query',
|
|
ApiAccessExport: 'system:api-access-log:export',
|
|
ApiErrorQuery: 'system:api-error-log:query',
|
|
ApiErrorExport: 'system:api-error-log:export'
|
|
} as const;
|
|
|
|
export const LOG_TABS: LogTabOption[] = [
|
|
{
|
|
name: 'login-log',
|
|
label: '登录日志',
|
|
description: '查看系统登录行为、登录结果与登录时间。',
|
|
queryPermission: LogPermission.LoginQuery,
|
|
exportPermission: LogPermission.LoginExport
|
|
},
|
|
{
|
|
name: 'operate-log',
|
|
label: '操作日志',
|
|
description: '查看系统操作轨迹、请求地址与业务编号。',
|
|
queryPermission: LogPermission.OperateQuery,
|
|
exportPermission: LogPermission.OperateExport
|
|
},
|
|
{
|
|
name: 'api-access-log',
|
|
label: 'API访问日志',
|
|
description: '查看接口访问结果、执行时长与请求链路。',
|
|
queryPermission: LogPermission.ApiAccessQuery,
|
|
exportPermission: LogPermission.ApiAccessExport
|
|
},
|
|
{
|
|
name: 'api-error-log',
|
|
label: 'API错误日志',
|
|
description: '查看接口异常、处理状态与错误上下文。',
|
|
queryPermission: LogPermission.ApiErrorQuery,
|
|
exportPermission: LogPermission.ApiErrorExport
|
|
}
|
|
];
|
|
|
|
export function formatDateTime(value?: string | null) {
|
|
if (!value) return '--';
|
|
|
|
const target = dayjs(value);
|
|
return target.isValid() ? target.format('YYYY-MM-DD HH:mm:ss') : value;
|
|
}
|
|
|
|
export function formatText(value: unknown) {
|
|
if (value === null || value === undefined || value === '') return '--';
|
|
return String(value);
|
|
}
|
|
|
|
export function formatDuration(value: unknown) {
|
|
if (value === null || value === undefined || value === '') return '--';
|
|
|
|
const duration = Number(value);
|
|
return Number.isFinite(duration) ? `${duration} ms` : String(value);
|
|
}
|
|
|
|
export function formatMultilineText(value: unknown) {
|
|
if (value === null || value === undefined || value === '') return '--';
|
|
|
|
const text = String(value);
|
|
const normalized = text.trim();
|
|
|
|
if (!normalized) return '--';
|
|
|
|
if (
|
|
(normalized.startsWith('{') && normalized.endsWith('}')) ||
|
|
(normalized.startsWith('[') && normalized.endsWith(']'))
|
|
) {
|
|
try {
|
|
return JSON.stringify(JSON.parse(normalized), null, 2);
|
|
} catch {
|
|
return text;
|
|
}
|
|
}
|
|
|
|
return text;
|
|
}
|
|
|
|
export function downloadBlob(blob: Blob, fileName: string) {
|
|
const url = URL.createObjectURL(blob);
|
|
const link = document.createElement('a');
|
|
|
|
link.href = url;
|
|
link.download = fileName;
|
|
link.click();
|
|
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
|
|
export function getLogExportFileName(label: string) {
|
|
return `${label}_${dayjs().format('YYYY-MM-DD')}.xls`;
|
|
}
|