1818import org .lowcoder .api .usermanagement .OrgDevChecker ;
1919import org .lowcoder .domain .application .model .ApplicationStatus ;
2020import org .lowcoder .domain .application .model .ApplicationType ;
21- import org .lowcoder .domain .bundle .model .Bundle ;
22- import org .lowcoder .domain .bundle .model .BundleRequestType ;
23- import org .lowcoder .domain .bundle .model .BundleStatus ;
21+ import org .lowcoder .domain .application .service .ApplicationServiceImpl ;
22+ import org .lowcoder .domain .bundle .model .*;
2423import org .lowcoder .domain .bundle .service .BundleElementRelationService ;
2524import org .lowcoder .domain .bundle .service .BundleNode ;
2625import org .lowcoder .domain .bundle .service .BundleService ;
27- import org .lowcoder .domain .bundle .model .BundleElement ;
2826import org .lowcoder .domain .bundle .service .*;
2927import org .lowcoder .domain .group .service .GroupService ;
3028import org .lowcoder .domain .organization .model .OrgMember ;
3432import org .lowcoder .domain .permission .service .ResourcePermissionService ;
3533import org .lowcoder .domain .user .model .User ;
3634import org .lowcoder .domain .user .service .UserService ;
35+ import org .lowcoder .infra .birelation .BiRelation ;
36+ import org .lowcoder .infra .birelation .BiRelationBizType ;
37+ import org .lowcoder .infra .birelation .BiRelationServiceImpl ;
3738import org .lowcoder .sdk .exception .BizError ;
3839import org .lowcoder .sdk .exception .BizException ;
40+ import org .springframework .beans .factory .annotation .Autowired ;
3941import org .springframework .context .annotation .Lazy ;
4042import org .springframework .stereotype .Service ;
4143import reactor .core .publisher .Flux ;
4244import reactor .core .publisher .Mono ;
45+ import reactor .core .scheduler .Schedulers ;
4346
4447import java .util .*;
4548import java .util .function .Function ;
5558@ RequiredArgsConstructor
5659@ Service
5760public class BundleApiServiceImpl implements BundleApiService {
58-
59- private static final Comparator <Node <ApplicationInfoView , BundleInfoView >> DEFAULT_COMPARATOR =
60- // compare by last view time reversed.
61- Comparator .comparingLong ((ToLongFunction <Node <ApplicationInfoView , BundleInfoView >>) node -> {
62- if (node instanceof ElementNode <ApplicationInfoView , BundleInfoView > elementNode ) {
63- return elementNode .getSelf ().getBundlePosition ();
64- }
65- return ((BundleNode <ApplicationInfoView , BundleInfoView >) node ).getSelf ().getCreateTime ();
66- })
67- .reversed ()
68- // compare by name.
69- .thenComparing (node -> {
70- if (node instanceof ElementNode <ApplicationInfoView , BundleInfoView > elementNode ) {
71- return elementNode .getSelf ().getName ();
72- }
73- return ((BundleNode <ApplicationInfoView , BundleInfoView >) node ).getSelf ().getName ();
74- });
75-
61+ private final BiRelationServiceImpl biRelationService ;
7662 private final BundleService bundleService ;
7763 private final SessionUserService sessionUserService ;
7864 private final OrgDevChecker orgDevChecker ;
@@ -85,6 +71,7 @@ public class BundleApiServiceImpl implements BundleApiService {
8571 private final UserService userService ;
8672 private final OrganizationService organizationService ;
8773 private final FolderApiService folderApiService ;
74+ private final ApplicationServiceImpl applicationServiceImpl ;
8875
8976 @ Override
9077 public Mono <BundleInfoView > create (CreateBundleRequest createBundleRequest ) {
@@ -331,45 +318,15 @@ public Mono<Void> reorder(String bundleId, List<String> elementIds) {
331318 */
332319 @ Override
333320 public Flux <?> getElements (@ Nullable String bundleId , @ Nullable ApplicationType applicationType ) {
334- return buildApplicationInfoViewTree (applicationType )
335- .flatMap (tree -> {
336- BundleNode <ApplicationInfoView , BundleInfoView > bundleNode = tree .get (bundleId );
337- if (bundleNode == null ) {
338- return Mono .error (new BizException (BUNDLE_NOT_EXIST , "BUNDLE_NOT_EXIST" , bundleId ));
339- }
340- return Mono .just (bundleNode );
341- })
342- .zipWith (Mono .zip (sessionUserService .getVisitorOrgMemberCache (), orgDevChecker .isCurrentOrgDev ()))
343- .doOnNext (tuple -> {
344- BundleNode <ApplicationInfoView , BundleInfoView > node = tuple .getT1 ();
345- OrgMember orgMember = tuple .getT2 ().getT1 ();
346- boolean devOrAdmin = tuple .getT2 ().getT2 ();
347- // father bundle's visibility depends on child nodes
348- node .postOrderIterate (n -> {
349- if (n instanceof BundleNode <ApplicationInfoView , BundleInfoView > bundleNode ) {
350- BundleInfoView bundleInfoView = bundleNode .getSelf ();
351- if (bundleInfoView == null ) {
352- return ;
353- }
354- bundleInfoView .setManageable (orgMember .isAdmin () || orgMember .isSuperAdmin () || orgMember .getUserId ().equals (bundleInfoView .getCreateBy ()));
355- bundleInfoView .setSubApplications (bundleNode .getElementChildren ());
356- bundleInfoView .setVisible (devOrAdmin || isNotEmpty (bundleInfoView .getSubApplications ()));
357- }
358- });
359- })
360- .flatMapIterable (tuple -> tuple .getT1 ().getChildren ())
361- .map (node -> {
362- if (node instanceof ElementNode <ApplicationInfoView , BundleInfoView > elementNode ) {
363- return elementNode .getSelf ();
364- }
365- return ((BundleNode <ApplicationInfoView , BundleInfoView >) node ).getSelf ();
366- });
367- }
368-
369- private Mono <Tree <Object , Bundle >> buildBundleTree (String userId ) {
370- return bundleService .findByUserId (userId )
371- .collectList ()
372- .map (bundles -> new Tree <>(bundles , Bundle ::getId , __ -> null , Collections .emptyList (), null , null ));
321+ return biRelationService .getBySourceId (BiRelationBizType .BUNDLE_ELEMENT , bundleId )
322+ .sort ((o1 , o2 ) -> {
323+ var pos1 = Integer .parseInt (o1 .getExtParam1 ());
324+ var pos2 = Integer .parseInt (o2 .getExtParam1 ());
325+ return pos1 - pos2 ;
326+ }).map (bi -> applicationServiceImpl .findById (bi .getTargetId ()))
327+ .index ()
328+ .publishOn (Schedulers .boundedElastic ())
329+ .map (tuple -> new BundleApplication (tuple .getT2 ().block (), tuple .getT1 ()));
373330 }
374331
375332 @ Override
@@ -440,62 +397,6 @@ public Mono<ResourcePermission> checkBundlePermissionWithReadableErrorMsg(String
440397 });
441398 }
442399
443- private Mono <Tree <ApplicationInfoView , BundleInfoView >> buildApplicationInfoViewTree (@ Nullable ApplicationType applicationType ) {
444-
445- Mono <OrgMember > orgMemberMono = sessionUserService .getVisitorOrgMemberCache ()
446- .cache ();
447-
448- Flux <ApplicationInfoView > applicationInfoViewFlux =
449- userHomeApiService .getAllAuthorisedApplications4CurrentOrgMember (applicationType , ApplicationStatus .NORMAL , false )
450- .cache ();
451-
452- Mono <Map <String , String >> application2BundleMapMono = applicationInfoViewFlux
453- .map (ApplicationInfoView ::getApplicationId )
454- .collectList ()
455- .flatMapMany (applicationIds -> bundleElementRelationService .getByElementIds (applicationIds ))
456- .collectMap (BundleElement ::elementId , BundleElement ::bundleId );
457-
458- Flux <Bundle > bundleFlux = orgMemberMono .flatMapMany (orgMember -> bundleService .findByUserId (orgMember .getUserId ()))
459- .cache ();
460-
461- Mono <Map <String , User >> userMapMono = bundleFlux
462- .flatMap (bundle -> emptyIfNull (bundle .getCreatedBy ()))
463- .collectList ()
464- .flatMap (list -> userService .getByIds (list ))
465- .cache ();
466-
467- Flux <BundleInfoView > bundleInfoViewFlux = bundleFlux
468- .flatMap (bundle -> Mono .zip (orgMemberMono , userMapMono )
469- .map (tuple -> {
470- OrgMember orgMember = tuple .getT1 ();
471- Map <String , User > userMap = tuple .getT2 ();
472- User creator = userMap .get (bundle .getCreatedBy ());
473- return BundleInfoView .builder ()
474- .userId (orgMember .getUserId ())
475- .bundleId (bundle .getId ())
476- .name (bundle .getName ())
477- .createAt (bundle .getCreatedAt ().toEpochMilli ())
478- .createBy (creator == null ? null : creator .getName ())
479- .createTime (bundle .getCreatedAt ())
480- .build ();
481- }));
482-
483- return Mono .zip (applicationInfoViewFlux .collectList (),
484- application2BundleMapMono ,
485- bundleInfoViewFlux .collectList ())
486- .map (tuple -> {
487- List <ApplicationInfoView > applicationInfoViews = tuple .getT1 ();
488- Map <String , String > application2BundleMap = tuple .getT2 ();
489- List <BundleInfoView > bundleInfoViews = tuple .getT3 ();
490- return new Tree <>(bundleInfoViews ,
491- BundleInfoView ::getBundleId ,
492- __ -> null ,
493- applicationInfoViews ,
494- application -> application2BundleMap .get (application .getApplicationId ()),
495- DEFAULT_COMPARATOR );
496- });
497- }
498-
499400 /**
500401 * only bundle creator has manage permissions
501402 */
0 commit comments