日志填写下来选择项目,没有过滤过期项目
parent
8821ea4d4b
commit
d7ea5d64be
|
|
@ -62,10 +62,16 @@ interface ProjectRow {
|
||||||
projectName?: string;
|
projectName?: string;
|
||||||
startDate?: string;
|
startDate?: string;
|
||||||
endDate?: string;
|
endDate?: string;
|
||||||
|
startTime?: string;
|
||||||
|
endTime?: string;
|
||||||
beginDate?: string;
|
beginDate?: string;
|
||||||
finishDate?: string;
|
finishDate?: string;
|
||||||
planStartDate?: string;
|
planStartDate?: string;
|
||||||
planEndDate?: string;
|
planEndDate?: string;
|
||||||
|
projectStartDate?: string;
|
||||||
|
projectEndDate?: string;
|
||||||
|
projectBeginDate?: string;
|
||||||
|
projectFinishDate?: string;
|
||||||
workTime?: number;
|
workTime?: number;
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|
@ -138,7 +144,11 @@ const pickProjectBoundaryDate = (row: ProjectRow, keys: Array<keyof ProjectRow>)
|
||||||
if (!raw) {
|
if (!raw) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const parsed = dayjs(String(raw));
|
const normalizedRaw =
|
||||||
|
typeof raw === 'number' || (typeof raw === 'string' && /^\d{10,13}$/.test(raw.trim()))
|
||||||
|
? Number(raw)
|
||||||
|
: String(raw);
|
||||||
|
const parsed = dayjs(normalizedRaw);
|
||||||
if (parsed.isValid()) {
|
if (parsed.isValid()) {
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
|
|
@ -169,6 +179,51 @@ const normalizeProjectRows = (value: unknown): ProjectRow[] =>
|
||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
|
const PROJECT_BOUNDARY_KEYS: Array<keyof ProjectRow> = [
|
||||||
|
'startDate',
|
||||||
|
'startTime',
|
||||||
|
'beginDate',
|
||||||
|
'planStartDate',
|
||||||
|
'projectStartDate',
|
||||||
|
'projectBeginDate',
|
||||||
|
'endDate',
|
||||||
|
'endTime',
|
||||||
|
'finishDate',
|
||||||
|
'planEndDate',
|
||||||
|
'projectEndDate',
|
||||||
|
'projectFinishDate',
|
||||||
|
];
|
||||||
|
|
||||||
|
const hasProjectBoundaryInfo = (row: ProjectRow) =>
|
||||||
|
PROJECT_BOUNDARY_KEYS.some((key) => {
|
||||||
|
const value = row[key];
|
||||||
|
return value !== undefined && value !== null && String(value).trim() !== '';
|
||||||
|
});
|
||||||
|
|
||||||
|
const mergeProjectRowsWithDetails = (rows: ProjectRow[], detailRows: ProjectRow[]) => {
|
||||||
|
if (rows.length === 0 || detailRows.length === 0) {
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
const detailMap = new Map(
|
||||||
|
detailRows.map((item) => [String(item.projectId ?? ''), item] as const),
|
||||||
|
);
|
||||||
|
|
||||||
|
return rows.map((row) => {
|
||||||
|
const detail = detailMap.get(String(row.projectId ?? ''));
|
||||||
|
if (!detail) {
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...detail,
|
||||||
|
...row,
|
||||||
|
projectName: String(row.projectName ?? detail.projectName ?? detail.name ?? ''),
|
||||||
|
name: String(row.name ?? detail.name ?? detail.projectName ?? ''),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const toNullableNumber = (value: unknown) => {
|
const toNullableNumber = (value: unknown) => {
|
||||||
if (value === undefined || value === null || value === '') {
|
if (value === undefined || value === null || value === '') {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
@ -436,7 +491,28 @@ const WorkLogPage = () => {
|
||||||
}
|
}
|
||||||
const payload = normalizeResponseData(response);
|
const payload = normalizeResponseData(response);
|
||||||
const rows = isObject(payload) && Array.isArray(payload.rows) ? payload.rows : Array.isArray(payload) ? payload : [];
|
const rows = isObject(payload) && Array.isArray(payload.rows) ? payload.rows : Array.isArray(payload) ? payload : [];
|
||||||
setProjectList(normalizeProjectRows(rows));
|
const normalizedRows = normalizeProjectRows(rows);
|
||||||
|
|
||||||
|
if (!normalizedRows.some(hasProjectBoundaryInfo)) {
|
||||||
|
try {
|
||||||
|
const detailResponse = await fetchFallbackProjectListRequest();
|
||||||
|
if (requestId !== projectListRequestIdRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const detailPayload = normalizeResponseData(detailResponse);
|
||||||
|
const detailRows = isObject(detailPayload) && Array.isArray(detailPayload.rows)
|
||||||
|
? detailPayload.rows
|
||||||
|
: Array.isArray(detailPayload)
|
||||||
|
? detailPayload
|
||||||
|
: [];
|
||||||
|
setProjectList(mergeProjectRowsWithDetails(normalizedRows, normalizeProjectRows(detailRows)));
|
||||||
|
return;
|
||||||
|
} catch (detailError) {
|
||||||
|
console.warn('Failed to enrich user project list with project boundaries:', detailError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setProjectList(normalizedRows);
|
||||||
return;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Failed to fetch user project list, fallback to full project list:', error);
|
console.warn('Failed to fetch user project list, fallback to full project list:', error);
|
||||||
|
|
@ -623,8 +699,22 @@ const WorkLogPage = () => {
|
||||||
|
|
||||||
const projectListFilter = useMemo(() => {
|
const projectListFilter = useMemo(() => {
|
||||||
return projectList.filter((item) => {
|
return projectList.filter((item) => {
|
||||||
const start = pickProjectBoundaryDate(item, ['startDate', 'beginDate', 'planStartDate']);
|
const start = pickProjectBoundaryDate(item, [
|
||||||
const end = pickProjectBoundaryDate(item, ['endDate', 'finishDate', 'planEndDate']);
|
'startDate',
|
||||||
|
'startTime',
|
||||||
|
'beginDate',
|
||||||
|
'planStartDate',
|
||||||
|
'projectStartDate',
|
||||||
|
'projectBeginDate',
|
||||||
|
]);
|
||||||
|
const end = pickProjectBoundaryDate(item, [
|
||||||
|
'endDate',
|
||||||
|
'endTime',
|
||||||
|
'finishDate',
|
||||||
|
'planEndDate',
|
||||||
|
'projectEndDate',
|
||||||
|
'projectFinishDate',
|
||||||
|
]);
|
||||||
if (!start && !end) {
|
if (!start && !end) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue