From 1fdeff00f421b382ed9f601a5455520621fd17f8 Mon Sep 17 00:00:00 2001 From: Xc Date: Fri, 3 Jan 2025 16:12:57 +0800 Subject: [PATCH] =?UTF-8?q?update=E5=AF=B9ListNode=E7=BB=93=E6=9E=9C?= =?UTF-8?q?=E7=9A=84=E5=8F=98=E5=8C=96=E5=BD=B1=E5=93=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- es/features/runningTree.js | 46 +++++++++++++++++++++++++++++++- lib/features/runningTree.js | 44 +++++++++++++++++++++++++++++++ src/features/runningTree.ts | 52 ++++++++++++++++++++++++++++++++++++- 3 files changed, 140 insertions(+), 2 deletions(-) diff --git a/es/features/runningTree.js b/es/features/runningTree.js index 6526bc34..1a8e4940 100644 --- a/es/features/runningTree.js +++ b/es/features/runningTree.js @@ -1,5 +1,5 @@ import { assert } from 'oak-domain/lib/utils/assert'; -import { cloneDeep, unset, uniq } from "oak-domain/lib/utils/lodash"; +import { cloneDeep, difference, unset, uniq, intersection } from "oak-domain/lib/utils/lodash"; import { combineFilters, getRelevantIds } from "oak-domain/lib/store/filter"; import { createOperationsFromModies } from 'oak-domain/lib/store/modi'; import { judgeRelation } from "oak-domain/lib/store/relation"; @@ -507,6 +507,50 @@ class ListNode extends EntityNode { } case 'u': default: { + // 更新可能会引起本行不再满足条件 + const { e, d, f } = record; + if (e === this.entity) { + const { id } = f; + const ids = typeof id === 'string' ? [id] : id.$in; + const currentIds = Object.keys(this.sr); + const intersected = intersection(ids, currentIds); + const diffed = difference(ids, currentIds); + /** 检查原本就在的,现在还在不在, + * 以及原本不在的,现在是不是满足条件了 + * (后一种情况也可能原本就满足但不在当前的ids中,这时是判断不出来的,total+1可能不对,但是应该是较少的case)*/ + const filter = this.constructFilters(true, true, true); + if (intersected.length) { + const rows = this.cache.get(this.entity, { + data: { + id: 1, + }, + filter: combineFilters(this.entity, this.schema, [ + filter, + { + id: { + $in: intersected, + } + } + ]) + }); + const rowIds = rows.map(ele => ele.id); + const missed = difference(intersected, rowIds); + missed.forEach((id) => { + unset(this.sr, id); + if (this.pagination.total) { + this.pagination.total--; + } + }); + } + if (diffed.length) { + diffed.forEach((ele) => { + this.sr[ele] = {}; + if (this.pagination.total) { + this.pagination.total++; + } + }); + } + } // hasUpdated = true; break; } diff --git a/lib/features/runningTree.js b/lib/features/runningTree.js index a20f7b6e..34a1162e 100644 --- a/lib/features/runningTree.js +++ b/lib/features/runningTree.js @@ -510,6 +510,50 @@ class ListNode extends EntityNode { } case 'u': default: { + // 更新可能会引起本行不再满足条件 + const { e, d, f } = record; + if (e === this.entity) { + const { id } = f; + const ids = typeof id === 'string' ? [id] : id.$in; + const currentIds = Object.keys(this.sr); + const intersected = (0, lodash_1.intersection)(ids, currentIds); + const diffed = (0, lodash_1.difference)(ids, currentIds); + /** 检查原本就在的,现在还在不在, + * 以及原本不在的,现在是不是满足条件了 + * (后一种情况也可能原本就满足但不在当前的ids中,这时是判断不出来的,total+1可能不对,但是应该是较少的case)*/ + const filter = this.constructFilters(true, true, true); + if (intersected.length) { + const rows = this.cache.get(this.entity, { + data: { + id: 1, + }, + filter: (0, filter_1.combineFilters)(this.entity, this.schema, [ + filter, + { + id: { + $in: intersected, + } + } + ]) + }); + const rowIds = rows.map(ele => ele.id); + const missed = (0, lodash_1.difference)(intersected, rowIds); + missed.forEach((id) => { + (0, lodash_1.unset)(this.sr, id); + if (this.pagination.total) { + this.pagination.total--; + } + }); + } + if (diffed.length) { + diffed.forEach((ele) => { + this.sr[ele] = {}; + if (this.pagination.total) { + this.pagination.total++; + } + }); + } + } // hasUpdated = true; break; } diff --git a/src/features/runningTree.ts b/src/features/runningTree.ts index 32e964d1..ae241621 100644 --- a/src/features/runningTree.ts +++ b/src/features/runningTree.ts @@ -1,5 +1,5 @@ import { assert } from 'oak-domain/lib/utils/assert'; -import { cloneDeep, difference, unset, merge, uniq, omit } from "oak-domain/lib/utils/lodash"; +import { cloneDeep, difference, unset, merge, uniq, omit, intersection } from "oak-domain/lib/utils/lodash"; import { combineFilters, getRelevantIds } from "oak-domain/lib/store/filter"; import { createOperationsFromModies } from 'oak-domain/lib/store/modi'; import { judgeRelation } from "oak-domain/lib/store/relation"; @@ -628,6 +628,56 @@ class ListNode< } case 'u': default: { + // 更新可能会引起本行不再满足条件 + const { e, d, f } = record as UpdateOpResult; + if (e === this.entity) { + const { id } = f!; + const ids: string[] = typeof id === 'string' ? [id] : id.$in; + const currentIds = Object.keys(this.sr); + + const intersected = intersection(ids, currentIds); + const diffed = difference(ids, currentIds); + + /** 检查原本就在的,现在还在不在, + * 以及原本不在的,现在是不是满足条件了 + * (后一种情况也可能原本就满足但不在当前的ids中,这时是判断不出来的,total+1可能不对,但是应该是较少的case)*/ + const filter = this.constructFilters(true, true, true); + if (intersected.length) { + const rows = this.cache.get(this.entity, { + data: { + id: 1, + }, + filter: combineFilters(this.entity, this.schema, [ + filter, + { + id: { + $in: intersected, + } + } + ]) + }); + const rowIds = rows.map(ele => ele.id!); + const missed = difference(intersected, rowIds); + missed.forEach( + (id) => { + unset(this.sr, id); + if (this.pagination.total) { + this.pagination.total --; + } + } + ); + } + if (diffed.length) { + diffed.forEach( + (ele) => { + this.sr[ele] = {}; + if (this.pagination.total) { + this.pagination.total ++; + } + } + ); + } + } // hasUpdated = true; break; }