3
3
This commit is contained in:
101
src/App.tsx
101
src/App.tsx
@ -60,6 +60,40 @@ export default function App() {
|
||||
return out;
|
||||
};
|
||||
|
||||
const deriveGroupOrderDraftByProcessOrder = (nodes: any[]): ProcessGroupInstance[] => {
|
||||
const arr = Array.isArray(nodes) ? nodes : [];
|
||||
const groupToMinOrder = new Map<string, number>();
|
||||
const groupToFirstIndex = new Map<string, number>();
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const r: any = arr[i];
|
||||
const g = (typeof r?.processGroup === 'string' ? r.processGroup : extractText(r?.processGroup)).trim();
|
||||
if (!g) continue;
|
||||
if (!groupToFirstIndex.has(g)) groupToFirstIndex.set(g, i);
|
||||
const n = Number(r?.processOrder);
|
||||
if (Number.isFinite(n)) {
|
||||
const prev = groupToMinOrder.get(g);
|
||||
if (typeof prev === 'undefined' || n < prev) groupToMinOrder.set(g, n);
|
||||
}
|
||||
}
|
||||
const groups = Array.from(groupToFirstIndex.keys());
|
||||
groups.sort((a, b) => {
|
||||
const ao = groupToMinOrder.get(a);
|
||||
const bo = groupToMinOrder.get(b);
|
||||
const aHas = typeof ao !== 'undefined';
|
||||
const bHas = typeof bo !== 'undefined';
|
||||
if (aHas && bHas) {
|
||||
if (ao !== bo) return ao - bo;
|
||||
} else if (aHas !== bHas) {
|
||||
return aHas ? -1 : 1;
|
||||
}
|
||||
const ai = groupToFirstIndex.get(a) || 0;
|
||||
const bi = groupToFirstIndex.get(b) || 0;
|
||||
if (ai !== bi) return ai - bi;
|
||||
return a.localeCompare(b, 'zh-Hans-CN');
|
||||
});
|
||||
return groups.map(g => createProcessGroupInstance(g));
|
||||
};
|
||||
|
||||
const applyGroupOrderConfigToTimelineResults = (results: any[], config: ProcessGroupInstance[]) => {
|
||||
const base = Array.isArray(results) ? results : [];
|
||||
const order = Array.isArray(config) ? config : [];
|
||||
@ -368,16 +402,46 @@ export default function App() {
|
||||
const BATCH_TABLE_ID = 'tblXO7iSxBYxrqtY';
|
||||
const BATCH_ROW_NUMBER_FIELD_ID = 'fldiqlTVsU';
|
||||
|
||||
const activateTableForPaging = async (table: any) => {
|
||||
try {
|
||||
if (typeof (table as any)?.getRecordIdListByPage === 'function') {
|
||||
await (table as any).getRecordIdListByPage({ pageSize: 1 });
|
||||
return;
|
||||
}
|
||||
} catch {}
|
||||
try {
|
||||
if (typeof (table as any)?.getRecordIdList === 'function') {
|
||||
await (table as any).getRecordIdList();
|
||||
}
|
||||
} catch {}
|
||||
};
|
||||
|
||||
const safeGetRecordsByPage = async (table: any, req: any) => {
|
||||
const cleaned: any = { ...(req || {}) };
|
||||
if (!cleaned.viewId) delete cleaned.viewId;
|
||||
if (!cleaned.pageToken) delete cleaned.pageToken;
|
||||
if (!cleaned.pageSize || Number(cleaned.pageSize) <= 0) cleaned.pageSize = 200;
|
||||
if (Number(cleaned.pageSize) > 200) cleaned.pageSize = 200;
|
||||
|
||||
try {
|
||||
return await table.getRecordsByPage(cleaned);
|
||||
} catch (e: any) {
|
||||
if (e?.code === 12) {
|
||||
await activateTableForPaging(table);
|
||||
return await table.getRecordsByPage(cleaned);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
const fetchAllRecordsByPage = async (table: any, params?: any) => {
|
||||
let token: any = undefined;
|
||||
let all: any[] = [];
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
const requestedPageSize = Math.min(200, (params && params.pageSize) ? params.pageSize : 200);
|
||||
const req: any = { pageSize: requestedPageSize, ...(params || {}) };
|
||||
if (!req.viewId) delete req.viewId;
|
||||
if (token) req.pageToken = token;
|
||||
else delete req.pageToken;
|
||||
const res: any = await table.getRecordsByPage(req);
|
||||
const res: any = await safeGetRecordsByPage(table, req);
|
||||
const recs: any[] = Array.isArray(res?.records) ? res.records : [];
|
||||
all = all.concat(recs);
|
||||
const nextToken = res?.pageToken || res?.nextPageToken;
|
||||
@ -419,7 +483,7 @@ export default function App() {
|
||||
const total = await getRecordTotalByPage(batchTable);
|
||||
let totalByRowNumber = 0;
|
||||
try {
|
||||
const rows = await fetchAllRecordsByPage(batchTable);
|
||||
const rows = await fetchAllRecordsByPage(batchTable, undefined);
|
||||
for (const r of rows) {
|
||||
const no = parseBatchRowNumber((r?.fields || {})[BATCH_ROW_NUMBER_FIELD_ID]);
|
||||
if (no !== null) totalByRowNumber = Math.max(totalByRowNumber, no);
|
||||
@ -2334,7 +2398,7 @@ export default function App() {
|
||||
.filter((option: any) => option && typeof option.name === 'string')
|
||||
.map((option: any) => ({ label: option.name, value: option.name }));
|
||||
}
|
||||
const records = await fetchAllRecordsByPage(table);
|
||||
const records = await fetchAllRecordsByPage(table, undefined);
|
||||
const values = new Set<string>();
|
||||
for (const r of records) {
|
||||
const raw = (r?.fields || {})[fieldId];
|
||||
@ -2554,12 +2618,9 @@ export default function App() {
|
||||
try {
|
||||
let token: any = undefined;
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
const res: any = await deliveryTable.getRecordsByPage({
|
||||
pageSize: 200,
|
||||
pageToken: token,
|
||||
filter: planFilter,
|
||||
sort,
|
||||
});
|
||||
const req: any = { pageSize: 200, filter: planFilter, sort };
|
||||
if (token) req.pageToken = token;
|
||||
const res: any = await safeGetRecordsByPage(deliveryTable, req);
|
||||
const recs: any[] = Array.isArray(res?.records) ? res.records : [];
|
||||
|
||||
for (const r of recs) {
|
||||
@ -2620,11 +2681,9 @@ export default function App() {
|
||||
try {
|
||||
let token: any = undefined;
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
const res: any = await deliveryTable.getRecordsByPage({
|
||||
pageSize: 200,
|
||||
pageToken: token,
|
||||
sort,
|
||||
});
|
||||
const req: any = { pageSize: 200, sort };
|
||||
if (token) req.pageToken = token;
|
||||
const res: any = await safeGetRecordsByPage(deliveryTable, req);
|
||||
const recs: any[] = Array.isArray(res?.records) ? res.records : [];
|
||||
|
||||
for (const r of recs) {
|
||||
@ -2863,7 +2922,7 @@ export default function App() {
|
||||
|
||||
// 1. 先获取匹配的流程节点(复用预览功能的逻辑)
|
||||
const processTable = await bitable.base.getTable(PROCESS_CONFIG_TABLE_ID);
|
||||
const processRecords = await fetchAllRecordsByPage(processTable);
|
||||
const processRecords = await fetchAllRecordsByPage(processTable, undefined);
|
||||
const matchedProcessNodes: any[] = [];
|
||||
|
||||
// 匹配流程配置节点
|
||||
@ -3049,7 +3108,7 @@ export default function App() {
|
||||
);
|
||||
|
||||
if (allGroups.length > 1 && groupOrderConfig.length === 0 && showUI) {
|
||||
const initial = allGroups.map(g => createProcessGroupInstance(g));
|
||||
const initial = deriveGroupOrderDraftByProcessOrder(matchedProcessNodes);
|
||||
setGroupOrderDraft(initial);
|
||||
setGroupConfigVisible(true);
|
||||
setTimelineLoading(false);
|
||||
@ -3117,7 +3176,7 @@ export default function App() {
|
||||
console.log('按顺序排列的流程节点:', orderedProcessNodes);
|
||||
|
||||
// 2. 优化:预先获取所有时效数据并建立索引
|
||||
const timelineRecords = await fetchAllRecordsByPage(timelineTable);
|
||||
const timelineRecords = await fetchAllRecordsByPage(timelineTable, undefined);
|
||||
|
||||
// 优化2:预处理时效数据,建立节点名称到记录的映射
|
||||
const timelineIndexByNode = new Map<string, any[]>();
|
||||
@ -5334,7 +5393,7 @@ export default function App() {
|
||||
nameToId.set(nm, id);
|
||||
}
|
||||
}
|
||||
const rows = await fetchAllRecordsByPage(batchTable);
|
||||
const rows = await fetchAllRecordsByPage(batchTable, undefined);
|
||||
|
||||
const rowsWithNo = rows.map((row: any, idx: number) => {
|
||||
const f = row?.fields || {};
|
||||
@ -6378,7 +6437,7 @@ export default function App() {
|
||||
const existing = Array.isArray(groupOrderConfig)
|
||||
? groupOrderConfig.filter(inst => groupSet.has((inst?.groupName || '').trim()))
|
||||
: [];
|
||||
const draft = existing.length > 0 ? existing : deriveGroupOrderDraftFromTimelineResults(base);
|
||||
const draft = existing.length > 0 ? existing : deriveGroupOrderDraftByProcessOrder(base);
|
||||
setGroupOrderDraft(draft);
|
||||
pendingGroupConfigCalcRef.current = null;
|
||||
setGroupConfigVisible(true);
|
||||
|
||||
Reference in New Issue
Block a user