Skip to content

feat: Service extends IService #242

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 17, 2025
Merged

feat: Service extends IService #242

merged 5 commits into from
Jun 17, 2025

Conversation

lu-yg
Copy link
Collaborator

@lu-yg lu-yg commented Jun 16, 2025

English | 简体中文

PR

PR Checklist

Please check if your PR fulfills the following requirements:

  • The commit message follows our Commit Message Guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)
  • Built its own designer, fully self-validated

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

Background and solution

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Summary by CodeRabbit

  • Refactor

    • Migrated backend services and configurations from Spring MVC to Spring WebFlux for improved reactive support.
    • Streamlined service interfaces and implementations by integrating MyBatis-Plus generic service capabilities and simplifying method signatures.
    • Updated dependencies to use WebFlux-compatible libraries.
  • Chores

    • Enhanced test reliability by explicitly injecting mocks into internal service fields using reflection.
  • Style

    • Simplified method signatures across service interfaces and implementations by removing unnecessary annotations.

Copy link

coderabbitai bot commented Jun 16, 2025

Walkthrough

This update migrates the project from Spring MVC to Spring WebFlux, replacing relevant dependencies and configuration interfaces. All service interfaces now extend MyBatis-Plus's IService, and their implementations inherit from ServiceImpl, utilizing the provided baseMapper instead of explicit mapper injections. Method parameter annotations like @Param are removed for simplicity. Corresponding test classes are updated to inject mocks into the new baseMapper field using reflection.

Changes

File(s) Change Summary
pom.xml, app/src/main/java/com/tinyengine/it/config/filter/WebConfig.java Migrated from Spring MVC to Spring WebFlux; updated OpenAPI dependency and configuration interface.
base/src/main/java/com/tinyengine/it/service/.../*.java (service interfaces) All service interfaces now extend IService<T>. Removed @Param annotations from method parameters.
base/src/main/java/com/tinyengine/it/service/.../impl/*.java (service implementations) All implementations now extend ServiceImpl<Mapper, Entity>. Replaced injected mappers with baseMapper. Removed @Param annotations. No business logic changes.
base/src/test/java/com/tinyengine/it/service/.../impl/*.java Test classes updated to inject mock mappers into the baseMapper field using reflection (ReflectUtil.setFieldValue). Removed unused mocks.
base/src/test/java/com/tinyengine/it/service/app/impl/PageServiceImplTest.java Enhanced mocking for additional dependencies in one test method.
All other files Minor code and import cleanups to support these structural changes.

Sequence Diagram(s)

sequenceDiagram
    participant Controller
    participant Service (extends ServiceImpl)
    participant baseMapper (MyBatis-Plus)
    participant Database

    Controller->>Service: Call serviceMethod(id)
    Service->>baseMapper: baseMapper.method(id)
    baseMapper->>Database: Execute SQL
    Database-->>baseMapper: Return result
    baseMapper-->>Service: Return entity/result
    Service-->>Controller: Return response
Loading

Poem

A hop from MVC to WebFlux land,
With MyBatis-Plus now lending a hand.
No more mappers scattered wide—
Just baseMapper by our side.
Reflection magic in every test,
Our code is lighter, feeling blessed!
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6e5331 and 159897a.

📒 Files selected for processing (1)
  • app/src/main/java/com/tinyengine/it/config/filter/WebConfig.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/main/java/com/tinyengine/it/config/filter/WebConfig.java
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Commit Unit Tests in branch feat/develop
  • Post Copyable Unit Tests in Comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🔭 Outside diff range comments (13)
base/src/main/java/com/tinyengine/it/service/platform/impl/PlatformHistoryServiceImpl.java (2)

80-84: 🛠️ Refactor suggestion

Return value check can silently swallow DB errors

deleteResult != 1CM008; ==1 → success.
If the record did not exist (0 affected rows) the caller gets generic “success” (line 78) which hides the fact that nothing was deleted. Consider distinguishing:

-if (deleteResult != 1) { ... }
+if (deleteResult == 0) {
+    return Result.failed(ExceptionEnum.DATA_NOT_FOUND);
+}

This yields clearer feedback to API consumers.


98-104: 🛠️ Refactor suggestion

Same silent-failure pattern on update

A 0-row update currently maps to CM008 (generic SQL fail).
Return a “not found” / “concurrent update” code instead so clients can react properly.

base/src/main/java/com/tinyengine/it/service/platform/impl/PlatformServiceImpl.java (1)

75-85: 🛠️ Refactor suggestion

Mark write operations @Transactional to ensure atomicity
deletePlatformById, updatePlatformById, and createPlatform each perform a read-then-write (or write-then-read) sequence.
Without @Transactional, a failure or concurrent update between the two statements can leave the service returning stale or inconsistent data.
Annotating the methods (or the whole class) with @Transactional(rollbackFor = Exception.class) will guarantee the read/write pair participates in one DB transaction.

 @Override
-public Result<Platform> deletePlatformById(Integer id) {
+@Transactional(rollbackFor = Exception.class)
+public Result<Platform> deletePlatformById(Integer id) {
   ...
 }

 @Override
-public Result<Platform> updatePlatformById(Platform platform) {
+@Transactional(rollbackFor = Exception.class)
+public Result<Platform> updatePlatformById(Platform platform) {
   ...
 }

 @Override
-public Result<Platform> createPlatform(Platform platform) {
+@Transactional(rollbackFor = Exception.class)
+public Result<Platform> createPlatform(Platform platform) {
   ...
 }

Also applies to: 94-104, 112-124

base/src/main/java/com/tinyengine/it/service/app/I18nEntryService.java (1)

35-97: 🛠️ Refactor suggestion

Large interface surface after extending IService

This interface now mixes:

  1. Generic CRUD (already covered by IService<I18nEntry>).
  2. High-level domain operations (batch upload, file parsing, formatting).

Consider splitting into two interfaces:

  • I18nEntryCrudService extends IService<I18nEntry>
  • I18nEntryDomainService with the higher-level methods

This adheres to the Interface Segregation Principle, eases testing, and clarifies responsibilities.

base/src/main/java/com/tinyengine/it/service/app/impl/UserServiceImpl.java (1)

84-97: 🛠️ Refactor suggestion

Add transaction boundaries for write operations.

updateUserById and createUser mutate state but are not annotated with @Transactional, so partial updates could escape rollback on exception.

@@
 @Override
-public Integer updateUserById(User user) {
-    return baseMapper.updateUserById(user);
+@Transactional(rollbackFor = Exception.class)
+public Integer updateUserById(User user) {
+    return baseMapper.updateUserById(user);
 }
@@
 @Override
-public Integer createUser(User user) {
-    return baseMapper.createUser(user);
+@Transactional(rollbackFor = Exception.class)
+public Integer createUser(User user) {
+    return baseMapper.createUser(user);
 }
base/src/main/java/com/tinyengine/it/service/material/impl/BlockServiceImpl.java (3)

330-336: ⚠️ Potential issue

Possible SQL-injection through manual OR-clause concatenation

labelsCondition is built via raw string interpolation:

String labelsCondition = block.stream()
    .map(name -> "label = '" + name + "'")
    .collect(Collectors.joining(" OR "));
wrapper.apply(labelsCondition);

Any illegal character in name (e.g. ' OR 1=1 --) will be injected verbatim.

Fix by using the fluent API instead of apply:

- String labelsCondition = block.stream()
-     .map(name -> "label = '" + name + "'")
-     .collect(Collectors.joining(" OR "));
- queryWrapper.and(w -> w.apply(labelsCondition));
+ queryWrapper.in("label", block);

590-598: 🛠️ Refactor suggestion

Redundant full fetch before paging – switch to selectCount

selectList(queryWrapper) is executed solely to obtain the record count, immediately followed by selectPage.
That doubles the query cost for large tables.

- List<Block> blocksList = baseMapper.selectList(queryWrapper);
- Page<Block> page = new Page<>(1, blocksList.size());
- return baseMapper.selectPage(page, queryWrapper);
+ long total = baseMapper.selectCount(queryWrapper);
+ Page<Block> page = new Page<>(1, total);
+ return baseMapper.selectPage(page, queryWrapper);

702-709: ⚠️ Potential issue

Null-pointer risk when blockDto.getGroups() is absent

blockDto.getGroups().stream() will throw if getGroups() returns null
(e.g. when a client omits the field).

Guard the call:

- List<Integer> groups = blockDto.getGroups().stream()
-     .map(BlockGroup::getId).collect(Collectors.toList());
+ List<Integer> groups = Optional.ofNullable(blockDto.getGroups())
+     .orElse(Collections.emptyList())
+     .stream()
+     .map(BlockGroup::getId)
+     .collect(Collectors.toList());
base/src/main/java/com/tinyengine/it/service/material/impl/MaterialServiceImpl.java (1)

76-82: ⚠️ Potential issue

Deleted record is fetched after deletion – returned payload will always be null

queryMaterialById is executed after the row has been removed, so the API will return data=null, while the caller probably expects the deleted object (your MaterialHistoryServiceImpl does it the right way).

-        int deleteResult = baseMapper.deleteMaterialById(id);
-        if (deleteResult != 1) {
-            return Result.failed(ExceptionEnum.CM008);
-        }
-        return this.queryMaterialById(id);
+        // fetch first so we can echo the deleted entity
+        Material material = baseMapper.queryMaterialById(id);
+        int deleteResult = baseMapper.deleteMaterialById(id);
+        if (deleteResult != 1) {
+            return Result.failed(ExceptionEnum.CM008);
+        }
+        return Result.success(material);
base/src/main/java/com/tinyengine/it/service/app/impl/PageServiceImpl.java (1)

177-185: ⚠️ Potential issue

Null-pointer risk when page / app is not found

pageInfo or the App returned by appMapper can be null. Calling methods on them without a guard (getApp(), getFramework()) will throw NullPointerException, turning a “not found” case into HTTP 500.

-        Page pageInfo = baseMapper.queryPageById(id);
+        Page pageInfo = baseMapper.queryPageById(id);
+        if (pageInfo == null) {
+            throw new ServiceException(ExceptionEnum.CM005.getResultCode(), "Page not found");
+        }
         String framework = appMapper.queryAppById(pageInfo.getApp()).getFramework();
-        if (framework.isEmpty()) {
+        if (framework == null || framework.isEmpty()) {
             throw new ServiceException(ExceptionEnum.CM312.getResultCode(), ExceptionEnum.CM312.getResultMsg());
         }
base/src/main/java/com/tinyengine/it/service/app/impl/AppExtensionServiceImpl.java (2)

82-88: ⚠️ Potential issue

Potential time-of-check / time-of-use race in delete flow.

Between queryAppExtensionById(id) and deleteAppExtensionById(id) another request could delete or modify the row, leading to a misleading success response (Result.success(appExtension)) even though the DELETE affected 0 rows.

Mitigate by:

  1. Deleting first and checking rowsAffected; if 0 → CM009.
  2. Executing both statements inside one transaction (see previous comment).

116-124: 🛠️ Refactor suggestion

Duplicate-check and insert should be atomic.

queryAppExtensionByCondition followed by createAppExtension is vulnerable to race conditions. Use a DB unique constraint and rely on exception handling, or enclose both operations in a transaction with a SELECT … FOR UPDATE.

base/src/main/java/com/tinyengine/it/service/material/impl/BlockGroupServiceImpl.java (1)

191-208: 🛠️ Refactor suggestion

N+1 query pattern – fetch groups in bulk instead of per-ID loop.

Looping over ids and invoking queryBlockGroupAndBlockById one-by-one incurs a DB round-trip per element. Replace with a single mapper method that accepts a collection:

-        for (int blockgroupId : ids) {
-            blockGroup = baseMapper.queryBlockGroupAndBlockById(blockgroupId, blockCreatedBy, groupCreatedBy);
-            blockGroupsListResult.add(blockGroup);
-        }
+        blockGroupsListResult =
+            baseMapper.queryBlockGroupAndBlockByIds(ids, blockCreatedBy, groupCreatedBy);

This will significantly improve latency when ids.size() is large.

♻️ Duplicate comments (6)
base/src/main/java/com/tinyengine/it/service/material/MaterialService.java (2)

26-26: Same note as TaskRecordService: duplicated CRUD after IService

IService<Material> already offers generic CRUD methods.


40-41: @Param removal can break mapper XML – verify build flags

See earlier comment in TaskRecordService.

Also applies to: 56-57

base/src/main/java/com/tinyengine/it/service/app/PageService.java (2)

28-28: Duplicated CRUD after IService

The interface now exposes both getById (via IService) and custom queryPageById. Harmonise or remove duplicates to avoid API confusion.


43-44: Potential MyBatis parameter-name mismatch

Dropping @Param("id") bears the same runtime risk described earlier.

Also applies to: 59-60

base/src/main/java/com/tinyengine/it/service/material/MaterialHistoryService.java (2)

26-26: Redundant custom CRUD after adopting IService

Same rationale as previous service interfaces.


40-41: Verify MyBatis XML after @Param removal

Same concern as noted for the other services.

Also applies to: 56-57

🧹 Nitpick comments (40)
base/src/main/java/com/tinyengine/it/service/platform/TenantService.java (1)

25-55: Extending IService but still redefining CRUD-like APIs – consider consolidation

Now that the interface inherits MyBatis-Plus IService<Tenant>, common methods such as getById, removeById, updateById, save, and list are already available.
Keeping custom equivalents (findTenantById, deleteTenantById, etc.) can confuse clients and inflate maintenance cost.

If no domain-specific behaviour is added, consider:

-public interface TenantService extends IService<Tenant> {
-    ...
-    Tenant findTenantById(Integer id);
-    ...
-    Integer deleteTenantById(Integer id);
-    ...
-}
+public interface TenantService extends IService<Tenant> {
+    // Add only domain-specific queries that are NOT covered by IService
+}

Otherwise, document clearly why both variants coexist.

base/src/main/java/com/tinyengine/it/service/platform/PlatformService.java (1)

26-56: Duplicate CRUD surface after inheriting IService<Platform>

Same observation as in TenantService: queryPlatformById, deletePlatformById, etc., overlap with IService defaults, with extra wrapping into Result<T>.
Decide either to:

  1. Fully rely on IService and drop custom methods, or
  2. Keep the richer Result<T> contract but remove/alias the redundant reads (queryPlatformById vs getById) to avoid two ways of doing the same thing.

Aligning method names will ease onboarding and reduce cognitive load.

base/src/main/java/com/tinyengine/it/service/platform/PlatformHistoryService.java (1)

26-56: Interface inherits IService but still exposes CRUD methods

As with the other services, decide whether these custom methods add value over IService defaults; otherwise trim for clarity or rename to emphasise domain semantics (e.g., archiveHistory(...) vs create).

base/src/main/java/com/tinyengine/it/service/platform/impl/TenantServiceImpl.java (2)

52-54: baseMapper.queryTenantById duplicates getById

Since ServiceImpl already offers getById(id), consider delegating to it or removing the wrapper unless extra logic is injected.

-return baseMapper.queryTenantById(id);
+return this.getById(id);

85-98: Consider leveraging saveOrUpdate from ServiceImpl

Manual baseMapper.updateTenantById / createTenant pairs can be replaced with the framework’s saveOrUpdate(tenant), reducing boilerplate and centralising optimistic-lock handling (if enabled).

base/src/main/java/com/tinyengine/it/service/platform/impl/PlatformServiceImpl.java (2)

43-66: Prefer the built-in CRUD helpers to cut duplication
queryAllPlatform, queryPlatformById, and queryPlatformByCondition still delegate straight to baseMapper.
If these methods merely wrap standard list(), getById(id) or a simple lambda query, you can delete them altogether and expose the inherited list/getById from ServiceImpl.
This keeps the service layer thinner and avoids maintaining duplicate SQL in PlatformMapper.

-@Override
-public List<Platform> queryAllPlatform() {
-    return baseMapper.queryAllPlatform();
-}
+// Callers can now just use platformService.list();

115-119: Stricter name validation
platform.getName().isEmpty() treats strings containing only whitespace as valid.
Switching to StringUtils.hasText(platform.getName()) (Spring) or StringUtils.isNotBlank (Apache Commons) closes that gap.

-if (platform.getName() == null || platform.getName().isEmpty()) {
+if (!StringUtils.hasText(platform.getName())) {
     return Result.failed(ExceptionEnum.CM002);
 }
app/src/main/java/com/tinyengine/it/config/filter/WebConfig.java (1)

33-49: Nit: typo in variable name

crosDomainListcorsDomainList to keep naming consistent with the CORS acronym.

base/src/main/java/com/tinyengine/it/service/material/ComponentLibraryService.java (1)

26-72: Redundant CRUD methods after adopting IService

By extending IService<ComponentLibrary> you already inherit a full CRUD API (getById, removeById, updateById, save, list, etc.).
Keeping additional methods (queryComponentLibraryById, deleteComponentLibraryById, updateComponentLibraryById, createComponentLibrary) that merely wrap the same semantics introduces duplication and cognitive overhead.

If the intent is to add domain-specific behaviour (e.g. wrapping the result in Result<>), consider:

  1. Renaming the wrapper methods to clarify the added value (e.g. getWithValidation).
  2. Or drop them and let callers use the inherited MyBatis-Plus methods directly.

Cleaning this up will shrink the service interface surface and make the codebase more consistent with other modules that rely solely on IService.

base/src/main/java/com/tinyengine/it/service/app/UserService.java (2)

25-56: Consolidate CRUD to the inherited IService API

Same observation as for ComponentLibraryService: queryUserById, deleteUserById, etc. overlap with getById, removeById, list() provided by IService<User>.

Unless these methods deliver extra behaviour (e.g. audit, validation, Result<> wrapping), consider deleting them and relying on the default API to avoid bloat and maintenance friction.


31-39: Naming consistency: plural vs singular

Method queryAllUser() mixes plural semantics with a singular noun.
Recommend renaming to queryAllUsers() (or simply listUsers() if retained).

base/src/main/java/com/tinyengine/it/service/material/ComponentService.java (2)

32-70: Consider eliminating duplicated find*/delete* methods

After extending IService<Component> the interface already exposes:

  • getById(id)findComponentById
  • removeById(id)deleteComponentById
  • list()findAllComponent
  • updateById(entity)updateComponentById
  • save(entity)createComponent

Unless you need the custom return types (Result<>) or additional processing, drop the duplicates to keep the contract minimal.


62-63: Return type semantics

deleteComponentById returns Integer, presumably the affected row count.
MyBatis-Plus’s removeById returns boolean, which is clearer for consumers.
If you keep the custom method, consider switching to boolean to express intent unambiguously.

base/src/main/java/com/tinyengine/it/service/material/TaskRecordService.java (1)

28-36: queryTaskRecordById duplicates getById

Given the new IService<TaskRecord> parent, getById(id) is available out-of-the-box.
Please remove or repurpose queryTaskRecordById to avoid two ways of doing the same thing.

base/src/main/java/com/tinyengine/it/service/app/I18nEntryService.java (1)

35-50: Camel-case inconsistency & typo

Method readFilesAndbulkCreate has a lowercase “b” in “bulk”.
Recommend renaming to readFilesAndBulkCreate for standard camel-case formatting.

base/src/main/java/com/tinyengine/it/service/app/I18nLangService.java (1)

15-26: Redundant CRUD declarations now that IService is inherited.

IService<I18nLang> already exposes list(), getById(), removeById(), save(), updateById()
Keeping custom aliases (queryAllI18nLang, deleteI18nLangById …) creates two parallel APIs for the same thing and inflates the surface area.

Consider:

  1. Drop the duplicated methods and rely on the generic ones; or
  2. Keep the methods but mark them @Deprecated and delegate to generic calls.

This will reduce maintenance cost and confusion for future contributors.

base/src/main/java/com/tinyengine/it/service/app/AppExtensionService.java (1)

15-27: Same duplication concern as above – streamline against IService.

The interface now inherits full CRUD; reevaluate whether findAppExtensionById, deleteAppExtensionById, etc. need to stay. If they provide extra behaviour (e.g. wrapping Result<>), document the difference clearly to avoid accidental misuse.

base/src/main/java/com/tinyengine/it/service/app/AppService.java (1)

29-29: Avoid redundant CRUD wrappers after inheriting IService

IService<App> already offers generic CRUD operations (list(), getById(), removeById(), etc.).
Keeping bespoke equivalents (queryAllApp, queryAppById, deleteAppById, …) inflates the API surface and sends mixed signals to callers.

Consider either

-interface AppService extends IService<App> {
+interface AppService extends IService<App> {
+    // keep only domain-specific methods …

or drop the IService inheritance if you need fully customized semantics.

base/src/main/java/com/tinyengine/it/service/material/BlockService.java (1)

34-34: Duplicate CRUD contracts

Extending IService<Block> while still declaring queryBlockById, deleteBlockById, etc., repeats functionality and may confuse clients (which one to call?).

If domain-specific wrapping is required, rename the methods (e.g. fetchDtoById) to communicate the added value, otherwise rely on IService alone.

base/src/main/java/com/tinyengine/it/service/app/DatasourceService.java (1)

26-26: Consistency vs. verbosity

Same observation: inheriting IService<Datasource> plus hand-rolled CRUD style methods increases maintenance overhead. Evaluate whether the custom wrappers are still justified.

base/src/main/java/com/tinyengine/it/service/app/PageTemplateService.java (1)

26-26: Potential overlap with IService<PageTemplate>

IService already exposes getById, removeByIds, etc. Reconsider keeping queryPageTemplateById, deletePageTemplateByIds, … to avoid redundancy.

base/src/main/java/com/tinyengine/it/service/material/BusinessCategoryService.java (1)

25-25: Redundant CRUD methods

Same duplication concern: IService<BusinessCategory> already supplies CRUD; extra wrappers should have clear added value or be removed.

base/src/main/java/com/tinyengine/it/service/app/TaskRecordService.java (1)

25-25: Consider pruning duplicate CRUD declarations after extending IService

By inheriting from IService<TaskRecord> you already get getById, removeById, save, etc.
Keeping home-grown equivalents (queryTaskRecordById, deleteTaskRecordById, …) bloats the API surface and may confuse callers about which variant to use.

base/src/main/java/com/tinyengine/it/service/app/impl/AppServiceImpl.java (1)

94-100: Custom queryAppById duplicates ServiceImpl#getById

The bespoke method adds minimal value over the built-in getById. Consider delegating to or removing this wrapper to keep the interface lean.

base/src/main/java/com/tinyengine/it/service/material/BlockHistoryService.java (1)

15-26: Duplicate CRUD surface after introducing IService

Now that the interface extends IService<BlockHistory>, generic CRUD helpers (getById, list, removeById, save …) come for free. Keeping bespoke counterparts (findBlockHistoryById, deleteBlockHistoryById, etc.) bloats the API surface and invites inconsistent use.

Consider dropping the hand-rolled methods (or delegating them to the inherited ones) to keep the service lean and consistent.

base/src/main/java/com/tinyengine/it/service/material/impl/ComponentServiceImpl.java (2)

55-56: ServiceImpl adopted — leverage its built-ins

Extending ServiceImpl<ComponentMapper, Component> already provides getById, list, saveBatch, saveOrUpdateBatch, etc. Most of the wrapper methods below re-expose mapper calls 1-for-1, defeating the purpose and adding maintenance overhead.

If no extra domain logic is injected, prefer the out-of-the-box methods or add thin adapters that simply call super helpers rather than raw baseMapper calls.


69-83: Missed opportunity to replace bespoke queries with MP wrappers

queryAllComponent, queryComponentById and queryComponentByCondition look like straight-through SQL pores.
Unless they rely on custom joins/filters, they could be replaced with:

return list();                // all
return getById(id);           // single
return lambdaQuery()
         .setEntity(component) // or build conditions explicitly
         .list();              // conditional

This reduces mapper code and aligns with the new MyBatis-Plus direction.

base/src/main/java/com/tinyengine/it/service/app/impl/PageHistoryServiceImpl.java (2)

48-60: Redundant wrappers around simple CRUD

With ServiceImpl<PageHistoryMapper, PageHistory> you already have list(), getById(), etc.
findAllPageHistory and findPageHistoryById presently just proxy to the mapper. Unless they encapsulate complex SQL, consider deleting them or delegating to inherited helpers to avoid duplicating the API.


81-82: Custom delete mirrors removeById

return baseMapper.deletePageHistoryById(id);

If this is a plain PK delete, boolean removeById(id) from ServiceImpl does the job and returns success status. Swapping would simplify code and testing.

base/src/main/java/com/tinyengine/it/service/app/impl/DatasourceServiceImpl.java (2)

35-45: ServiceImpl migration not fully utilised

Most service methods still fall back to mapper calls (queryDatasourceById, createDatasource, …). Evaluate replacing straightforward CRUD with the generic helpers provided by ServiceImpl to minimise boilerplate and mapper surface.


100-101: Prefer save() over custom createDatasource if no special SQL is needed

If createDatasource performs a simple insert, the built-in save(datasource) (or saveOrUpdate) would remove the need for a mapper method entirely and benefit from MP features such as automatic field filling.

base/src/main/java/com/tinyengine/it/service/app/impl/I18nLangServiceImpl.java (1)

33-42: Prefer MyBatis-Plus default CRUD over 1-to-1 passthrough methods

Now that the class extends ServiceImpl, the framework already provides

list()
getById(id)
save(entity)
updateById(entity)
removeById(id)

and other helpers.
queryAllI18nLang, queryI18nLangById, etc. are simple passthroughs to custom mapper methods that replicate this behaviour and add maintenance surface.

If no extra SQL is really needed, consider deleting the custom mapper methods and, in the service, delegating to the built-ins instead.
This will:

  • reduce boilerplate
  • keep the codebase consistent with MyBatis-Plus idioms
  • ease unit-testing / mocking
base/src/main/java/com/tinyengine/it/service/material/impl/BlockHistoryServiceImpl.java (1)

33-42: Same CRUD duplication issue as above

findAllBlockHistory() is functionally identical to list() that you already inherit from ServiceImpl.
Re-evaluate whether the custom queryAllBlockHistory mapper method is still justified.

base/src/main/java/com/tinyengine/it/service/material/impl/ComponentLibraryServiceImpl.java (1)

35-44: Reuse inherited CRUD where possible

queryAllComponentLibrary() is equivalent to list().
Unless custom SQL is essential, migrate to the built-in API and delete the extra mapper method to keep the service lean.

base/src/main/java/com/tinyengine/it/service/app/impl/PageTemplateServiceImpl.java (1)

52-57: Potential elimination of duplicated mapper calls

Within the name == null || name.isEmpty() branch you already fetch all
page templates once.
Right after the branch you perform a second fetch based on name.
Consider restructuring the method to make exactly one mapper call:

List<PageTemplate> pageTemplates = StringUtils.isBlank(name)
        ? baseMapper.queryAllPageTemplate(type)
        : baseMapper.queryPageTemplateByName(name, type);
return Result.success(pageTemplates);

Minor, but saves an allocation and keeps the method concise.

base/src/main/java/com/tinyengine/it/service/material/impl/MaterialServiceImpl.java (1)

108-112: Minor: use forEach for side-effects instead of map

The stream pipeline here is only used for its side-effects; using map is semantically misleading and allocates an unused List<Integer>. Replace with forEach to express intent.

-i18nEntriesList.stream().map(entry -> baseMapper.createMaterial(entry)).collect(Collectors.toList());
+i18nEntriesList.forEach(entry -> baseMapper.createMaterial(entry));
base/src/main/java/com/tinyengine/it/service/app/impl/I18nEntryServiceImpl.java (1)

153-156: Replace stream().map(..).collect(..) used only for side-effects

Using map here hides the intent and creates an unnecessary intermediate list. A simple forEach is clearer and avoids the extra allocation.

-i18nEntriesList.stream().map(entry -> baseMapper.createI18nEntry(entry)).collect(Collectors.toList());
+i18nEntriesList.forEach(baseMapper::createI18nEntry);

Apply the same change in the bulkCreate path below.

Also applies to: 199-201

base/src/main/java/com/tinyengine/it/service/app/impl/TaskRecordServiceImpl.java (1)

41-41: Leverage built-in MyBatis-Plus helpers instead of hand-rolled mapper calls.

ServiceImpl already exposes list() which returns all rows.
Keeping both queryAllTaskRecord() and list() creates API duplication.

Example replacement:

-    public List<TaskRecord> queryAllTaskRecord() {
-        return baseMapper.queryAllTaskRecord();
-    }
+    public List<TaskRecord> queryAllTaskRecord() {
+        return list();
+    }
base/src/main/java/com/tinyengine/it/service/material/impl/BlockGroupServiceImpl.java (2)

63-64: queryAllBlockGroup() duplicates list() from ServiceImpl.

Unless you require custom SQL, prefer list() to reduce mapper code and improve maintainability.


211-211: Avoid full-table scan when no filter supplied.

Calling queryAllBlockGroupAndBlock with no ids and no appId can explode in large installations.
Require at least one filtering parameter or enforce pagination to protect the database.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 929a971 and bbd19f2.

📒 Files selected for processing (46)
  • app/src/main/java/com/tinyengine/it/config/filter/WebConfig.java (1 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/AppExtensionService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/AppService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/DatasourceService.java (2 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/I18nEntryService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/I18nLangService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/PageHistoryService.java (2 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/PageService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/PageTemplateService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/TaskRecordService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/UserService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/impl/AppExtensionServiceImpl.java (8 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/impl/AppServiceImpl.java (8 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/impl/DatasourceServiceImpl.java (6 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/impl/I18nEntryServiceImpl.java (13 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/impl/I18nLangServiceImpl.java (7 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/impl/PageHistoryServiceImpl.java (9 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/impl/PageServiceImpl.java (18 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/impl/PageTemplateServiceImpl.java (8 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/impl/TaskRecordServiceImpl.java (7 hunks)
  • base/src/main/java/com/tinyengine/it/service/app/impl/UserServiceImpl.java (7 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/BlockGroupService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/BlockHistoryService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/BlockService.java (4 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/BusinessCategoryService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/ComponentLibraryService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/ComponentService.java (4 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/MaterialHistoryService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/MaterialService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/TaskRecordService.java (2 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/impl/BlockGroupServiceImpl.java (10 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/impl/BlockHistoryServiceImpl.java (7 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/impl/BlockServiceImpl.java (18 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/impl/BusinessCategoryServiceImpl.java (7 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/impl/ComponentLibraryServiceImpl.java (7 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/impl/ComponentServiceImpl.java (9 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/impl/MaterialHistoryServiceImpl.java (7 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/impl/MaterialServiceImpl.java (7 hunks)
  • base/src/main/java/com/tinyengine/it/service/material/impl/TaskRecordMaterialServiceImpl.java (4 hunks)
  • base/src/main/java/com/tinyengine/it/service/platform/PlatformHistoryService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/platform/PlatformService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/platform/TenantService.java (3 hunks)
  • base/src/main/java/com/tinyengine/it/service/platform/impl/PlatformHistoryServiceImpl.java (7 hunks)
  • base/src/main/java/com/tinyengine/it/service/platform/impl/PlatformServiceImpl.java (7 hunks)
  • base/src/main/java/com/tinyengine/it/service/platform/impl/TenantServiceImpl.java (7 hunks)
  • pom.xml (2 hunks)
🔇 Additional comments (14)
base/src/main/java/com/tinyengine/it/service/platform/impl/PlatformServiceImpl.java (1)

15-15: Smooth migration to ServiceImpl acknowledged
Extending ServiceImpl<PlatformMapper, Platform> cleanly removes the manual mapper wiring and brings the class in-line with MyBatis-Plus idioms.

Also applies to: 35-35

pom.xml (2)

33-33: Verify Springdoc 2.5.0 compatibility with Boot 3.1.9

Springdoc 2.5.0 is the first GA release on the new starter coordinates, but its BOM is aligned with Spring-Boot 3.2.x. Running it on Boot 3.1.9 may introduce subtle version mismatches (e.g., spring-webflux transitive dependencies).
Please double-check the full dependency tree or pin an explicit springdoc BOM compatible with Boot 3.1.x before merging.


103-107: Confirm legacy springdoc-openapi-ui artefact is fully removed

The project now depends on the WebFlux starter (springdoc-openapi-starter-webflux-ui). Make sure no residual <dependency> or plugin still pulls in the MVC-oriented springdoc-openapi-ui, otherwise duplicate OpenAPI auto-configurations will be registered at runtime.

base/src/main/java/com/tinyengine/it/service/app/impl/UserServiceImpl.java (1)

15-16: Solid move to MyBatis-Plus ServiceImpl.

Extending ServiceImpl<UserMapper, User> removes boiler-plate mapper wiring and keeps the class lean. Type parameters are correct (UserMapper, User) so baseMapper will resolve as expected.

Also applies to: 33-33

base/src/main/java/com/tinyengine/it/service/material/BlockGroupService.java (1)

41-49: DTO ↔︎ Entity inconsistency may leak persistence objects to callers.

findBlockGroupById returns BlockGroup (entity) while findBlockGroupByCondition returns BlockGroupDto. Mixing the two can confuse clients and break serialization rules (e.g. JPA lazy fields).

Verify which type the REST/API layer expects; align both methods (prefer DTO).
If keeping the entity, annotate it with @JsonIgnore on internal fields or move mapping to a converter.

base/src/main/java/com/tinyengine/it/service/app/AppService.java (1)

43-43: Mapper XML must be reviewed after dropping @Param

@Param provided stable names for parameters used inside XML mappers (#{id} etc.).
Without it, MyBatis resorts to positional names like param1, unless mybatis-plus.configuration.use-actual-param-name=true and the byte-code retains parameter names (compiled with -parameters).
Please verify all XML / annotation queries referencing id still resolve.

Also applies to: 59-59

base/src/main/java/com/tinyengine/it/service/material/BlockService.java (1)

48-48: Re-check mapper statements for removed @Param annotations

As with other services, ensure XML statements that previously used #{id} do not break after annotation removal.

Also applies to: 64-64

base/src/main/java/com/tinyengine/it/service/app/DatasourceService.java (1)

33-33: Confirm parameter bindings post-@Param removal

Validate that mapper XML or annotations no longer rely on named parameters.

Also applies to: 49-49

base/src/main/java/com/tinyengine/it/service/app/PageTemplateService.java (1)

42-42: Parameter naming after annotation cleanup

Double-check the underlying mapper (PageTemplateMapper.xml) for usages of #{id} / #{ids}.

Also applies to: 58-58

base/src/main/java/com/tinyengine/it/service/material/BusinessCategoryService.java (1)

39-39: Verify mapper compatibility after @Param deletion

Ensure SQL mappings still bind the id parameter correctly.

Also applies to: 55-55

base/src/main/java/com/tinyengine/it/service/app/impl/AppServiceImpl.java (1)

51-51: Good move to ServiceImpl

Leveraging ServiceImpl<AppMapper, App> eliminates boiler-plate mapper injection and aligns with MyBatis-Plus idioms.

base/src/main/java/com/tinyengine/it/service/material/impl/BusinessCategoryServiceImpl.java (1)

34-43: No functional issues detected – implementation looks solid

The refactor correctly leverages ServiceImpl and replaces the handwritten mapper field with baseMapper. The delegated calls compile and behave identically.

base/src/main/java/com/tinyengine/it/service/material/impl/MaterialHistoryServiceImpl.java (1)

36-45: LGTM – straightforward delegation

The switch to ServiceImpl is clean and mirrors the pattern used elsewhere.

base/src/main/java/com/tinyengine/it/service/app/impl/TaskRecordServiceImpl.java (1)

51-53: Method name duplicates getById and can be removed.

ServiceImpl offers getById(id) out-of-the-box; maintaining queryTaskRecordById adds surface area without extra value.

Do any callers outside this module still rely on the custom name? If not, consider deleting the wrapper.

@lu-yg lu-yg merged commit 7b41498 into opentiny:develop Jun 17, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants