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