fix: 修复插件分类查询并保留返回状态
- 统一按插件名称进行模糊查询并支持分类筛选 - 恢复插件列表与工具编辑的页码、分类和搜索条件
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package tech.easyflow.ai.service;
|
||||
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
import tech.easyflow.ai.entity.Plugin;
|
||||
import tech.easyflow.common.domain.Result;
|
||||
@@ -20,7 +21,16 @@ public interface PluginService extends IService<Plugin> {
|
||||
|
||||
List<Plugin> getList();
|
||||
|
||||
Result pageByCategory(Long pageNumber, Long pageSize, int category);
|
||||
/**
|
||||
* 按分类分页查询插件。
|
||||
*
|
||||
* @param pageNumber 页码
|
||||
* @param pageSize 每页数量
|
||||
* @param category 分类 ID
|
||||
* @param name 插件名称关键字
|
||||
* @return 插件分页结果
|
||||
*/
|
||||
Result<Page<Plugin>> pageByCategory(Long pageNumber, Long pageSize, int category, String name);
|
||||
|
||||
boolean updatePlugin(Plugin plugin);
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ public class PluginServiceImpl extends ServiceImpl<PluginMapper, Plugin> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Page<Plugin>> pageByCategory(Long pageNumber, Long pageSize, int category) {
|
||||
public Result<Page<Plugin>> pageByCategory(Long pageNumber, Long pageSize, int category, String name) {
|
||||
RoleCategoryAccessSnapshot access = categoryPermissionService.getCurrentAccess("PLUGIN");
|
||||
QueryWrapper queryWrapper = QueryWrapper.create().select(PluginCategoryMapping::getPluginId)
|
||||
.eq(PluginCategoryMapping::getCategoryId, category);
|
||||
@@ -158,7 +158,8 @@ public class PluginServiceImpl extends ServiceImpl<PluginMapper, Plugin> impleme
|
||||
return Result.ok(new Page<>(Collections.emptyList(), pageNumber, pageSize, 0L));
|
||||
}
|
||||
|
||||
List<Plugin> totalPlugins = preparePluginsForCurrentUser(queryPluginsByIds(visiblePluginIds), true, false);
|
||||
List<Plugin> totalPlugins = preparePluginsForCurrentUser(
|
||||
queryPluginsByIds(visiblePluginIds, name), true, false);
|
||||
int fromIndex = Math.max(0, Math.toIntExact((pageNumber - 1) * pageSize));
|
||||
if (fromIndex >= totalPlugins.size()) {
|
||||
return Result.ok(new Page<>(Collections.emptyList(), pageNumber, pageSize, totalPlugins.size()));
|
||||
@@ -251,11 +252,21 @@ public class PluginServiceImpl extends ServiceImpl<PluginMapper, Plugin> impleme
|
||||
return pluginMapper.selectListByQueryAs(creatorPluginWrapper, BigInteger.class);
|
||||
}
|
||||
|
||||
private List<Plugin> queryPluginsByIds(List<BigInteger> pluginIds) {
|
||||
/**
|
||||
* 按给定顺序查询插件,并按名称关键字过滤。
|
||||
*
|
||||
* @param pluginIds 插件 ID 列表
|
||||
* @param name 插件名称关键字
|
||||
* @return 保持输入 ID 顺序的插件列表
|
||||
*/
|
||||
private List<Plugin> queryPluginsByIds(List<BigInteger> pluginIds, String name) {
|
||||
if (CollectionUtil.isEmpty(pluginIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
QueryWrapper queryPluginWrapper = QueryWrapper.create().select().in(Plugin::getId, pluginIds);
|
||||
if (name != null && !name.isBlank()) {
|
||||
queryPluginWrapper.like(Plugin::getName, name.trim());
|
||||
}
|
||||
List<Plugin> plugins = pluginMapper.selectListWithRelationsByQuery(queryPluginWrapper);
|
||||
Map<BigInteger, Plugin> pluginMap = plugins.stream().collect(Collectors.toMap(
|
||||
Plugin::getId,
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package tech.easyflow.ai.service.impl;
|
||||
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import tech.easyflow.ai.entity.Plugin;
|
||||
import tech.easyflow.ai.mapper.PluginCategoryMappingMapper;
|
||||
import tech.easyflow.ai.mapper.PluginMapper;
|
||||
import tech.easyflow.system.entity.vo.RoleCategoryAccessSnapshot;
|
||||
import tech.easyflow.system.service.CategoryPermissionService;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* 插件分类分页查询测试。
|
||||
*/
|
||||
public class PluginServicePageQueryTest {
|
||||
|
||||
/**
|
||||
* 验证具体分类下仍会按插件名称过滤。
|
||||
*/
|
||||
@Test
|
||||
public void shouldFilterCategorizedPluginsByName() {
|
||||
PluginMapper pluginMapper = mock(PluginMapper.class);
|
||||
PluginCategoryMappingMapper mappingMapper = mock(PluginCategoryMappingMapper.class);
|
||||
CategoryPermissionService categoryPermissionService = mock(CategoryPermissionService.class);
|
||||
RoleCategoryAccessSnapshot access = mock(RoleCategoryAccessSnapshot.class);
|
||||
PluginServiceImpl service = new PluginServiceImpl();
|
||||
service.pluginMapper = pluginMapper;
|
||||
service.pluginCategoryMappingMapper = mappingMapper;
|
||||
setField(service, "categoryPermissionService", categoryPermissionService);
|
||||
|
||||
when(categoryPermissionService.getCurrentAccess("PLUGIN")).thenReturn(access);
|
||||
when(access.isRestricted()).thenReturn(false);
|
||||
when(mappingMapper.selectListByQueryAs(any(QueryWrapper.class), eq(BigInteger.class)))
|
||||
.thenReturn(List.of(BigInteger.ONE));
|
||||
when(pluginMapper.selectListWithRelationsByQuery(any(QueryWrapper.class)))
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
service.pageByCategory(1L, 12L, 7, " 1213 ");
|
||||
|
||||
ArgumentCaptor<QueryWrapper> queryCaptor = ArgumentCaptor.forClass(QueryWrapper.class);
|
||||
verify(pluginMapper).selectListWithRelationsByQuery(queryCaptor.capture());
|
||||
String sql = queryCaptor.getValue().toSQL().toLowerCase(Locale.ROOT);
|
||||
Assert.assertTrue(sql.contains("name"));
|
||||
Assert.assertTrue(sql.contains("like"));
|
||||
Assert.assertTrue(sql.contains("1213"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过反射设置私有依赖。
|
||||
*
|
||||
* @param target 目标对象
|
||||
* @param fieldName 字段名称
|
||||
* @param value 字段值
|
||||
*/
|
||||
private static void setField(Object target, String fieldName, Object value) {
|
||||
Class<?> current = target.getClass();
|
||||
while (current != null) {
|
||||
try {
|
||||
java.lang.reflect.Field field = current.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(target, value);
|
||||
return;
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
current = current.getSuperclass();
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException("设置测试字段失败: " + fieldName, e);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("未找到字段: " + fieldName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user