bugfix: 清洗/算子支持名称/描述搜索 (#116)

* bugfix: milvus适配etcd deploy部署

* bugfix: 可以在知识库界面跳转到创建模型
This commit is contained in:
hhhhsc701
2025-11-29 18:15:43 +08:00
committed by GitHub
parent 5c178d5274
commit bb3345268e
22 changed files with 88 additions and 56 deletions

View File

@@ -24,9 +24,14 @@ public class CleaningTaskRepositoryImpl extends CrudRepository<CleaningTaskMappe
public List<CleaningTaskDto> findTasks(String status, String keywords, Integer page, Integer size) {
LambdaQueryWrapper<CleaningTask> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.eq(StringUtils.isNotBlank(status), CleaningTask::getStatus, status)
.like(StringUtils.isNotBlank(keywords), CleaningTask::getName, keywords)
.orderByDesc(CleaningTask::getCreatedAt);
lambdaWrapper.eq(StringUtils.isNotBlank(status), CleaningTask::getStatus, status);
if (StringUtils.isNotBlank(keywords)) {
lambdaWrapper.and(w ->
w.like(CleaningTask::getName, keywords)
.or()
.like(CleaningTask::getDescription, keywords));
}
lambdaWrapper.orderByDesc(CleaningTask::getCreatedAt);
if (size != null && page != null) {
Page<CleaningTask> queryPage = new Page<>(page + 1, size);
IPage<CleaningTask> resultPage = mapper.selectPage(queryPage, lambdaWrapper);

View File

@@ -25,8 +25,12 @@ public class CleaningTemplateRepositoryImpl extends CrudRepository<CleaningTempl
@Override
public List<TemplateWithInstance> findAllTemplates(String keywords) {
QueryWrapper<TemplateWithInstance> queryWrapper = new QueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(keywords), "name", keywords)
.orderByDesc("created_at");
if (StringUtils.isNotBlank(keywords)) {
queryWrapper.like("name", keywords)
.or()
.like("description", keywords);
}
queryWrapper.orderByDesc("created_at");
return mapper.findAllTemplates(queryWrapper);
}

View File

@@ -20,9 +20,9 @@ public class CleaningTaskController {
public PagedResponse<CleaningTaskDto> cleaningTasksGet(
@RequestParam("page") Integer page,
@RequestParam("size") Integer size, @RequestParam(value = "status", required = false) String status,
@RequestParam(value = "keywords", required = false) String keywords) {
List<CleaningTaskDto> tasks = cleaningTaskService.getTasks(status, keywords, page, size);
int count = cleaningTaskService.countTasks(status, keywords);
@RequestParam(value = "keyword", required = false) String keyword) {
List<CleaningTaskDto> tasks = cleaningTaskService.getTasks(status, keyword, page, size);
int count = cleaningTaskService.countTasks(status, keyword);
int totalPages = (count + size + 1) / size;
return PagedResponse.of(tasks, page, count, totalPages);
}

View File

@@ -30,7 +30,7 @@ public class CleaningTemplateController {
public PagedResponse<CleaningTemplateDto> cleaningTemplatesGet(
@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size,
@RequestParam(value = "keywords", required = false) String keyword) {
@RequestParam(value = "keyword", required = false) String keyword) {
List<CleaningTemplateDto> templates = cleaningTemplateService.getTemplates(keyword);
if (page == null || size == null) {
return PagedResponse.of(templates.stream()

View File

@@ -49,12 +49,12 @@ public class OperatorService {
private String operatorBasePath;
public List<OperatorDto> getOperators(Integer page, Integer size, List<String> categories,
String operatorName, Boolean isStar) {
return operatorViewRepo.findOperatorsByCriteria(page, size, operatorName, categories, isStar);
String keyword, Boolean isStar) {
return operatorViewRepo.findOperatorsByCriteria(page, size, keyword, categories, isStar);
}
public int getOperatorsCount(List<String> categories, String operatorName, Boolean isStar) {
return operatorViewRepo.countOperatorsByCriteria(operatorName, categories, isStar);
public int getOperatorsCount(List<String> categories, String keyword, Boolean isStar) {
return operatorViewRepo.countOperatorsByCriteria(keyword, categories, isStar);
}
public OperatorDto getOperatorById(String id) {

View File

@@ -7,10 +7,10 @@ import com.datamate.operator.interfaces.dto.OperatorDto;
import java.util.List;
public interface OperatorViewRepository extends IRepository<OperatorView> {
List<OperatorDto> findOperatorsByCriteria(Integer page, Integer size, String operatorName,
List<OperatorDto> findOperatorsByCriteria(Integer page, Integer size, String keyword,
List<String> categories, Boolean isStar);
Integer countOperatorsByCriteria(String operatorName, List<String> categories, Boolean isStar);
Integer countOperatorsByCriteria(String keyword, List<String> categories, Boolean isStar);
OperatorView findOperatorById(String id);
}

View File

@@ -23,13 +23,18 @@ public class OperatorViewRepositoryImpl extends CrudRepository<OperatorViewMappe
private final OperatorViewMapper mapper;
@Override
public List<OperatorDto> findOperatorsByCriteria(Integer page, Integer size, String operatorName,
public List<OperatorDto> findOperatorsByCriteria(Integer page, Integer size, String keyword,
List<String> categories, Boolean isStar) {
QueryWrapper<OperatorView> queryWrapper = Wrappers.query();
queryWrapper.in(CollectionUtils.isNotEmpty(categories), "category_id", categories)
.like(StringUtils.isNotBlank(operatorName), "operator_name", operatorName)
.eq(isStar != null, "is_star", isStar)
.groupBy("operator_id")
.eq(isStar != null, "is_star", isStar);
if (StringUtils.isNotEmpty(keyword)) {
queryWrapper.and(w ->
w.like("operator_name", keyword)
.or()
.like("description", keyword));
}
queryWrapper.groupBy("operator_id")
.orderByDesc("created_at");
Page<OperatorView> queryPage;
if (size != null && page != null) {
@@ -43,11 +48,16 @@ public class OperatorViewRepositoryImpl extends CrudRepository<OperatorViewMappe
}
@Override
public Integer countOperatorsByCriteria(String operatorName, List<String> categories, Boolean isStar) {
public Integer countOperatorsByCriteria(String keyword, List<String> categories, Boolean isStar) {
QueryWrapper<OperatorView> queryWrapper = Wrappers.query();
queryWrapper.in(CollectionUtils.isNotEmpty(categories),"category_id", categories)
.like(StringUtils.isNotBlank(operatorName), "operator_name", operatorName)
.eq(isStar != null, "is_star", isStar);
if (StringUtils.isNotEmpty(keyword)) {
queryWrapper.and(w ->
w.like("operator_name", keyword)
.or()
.like("description", keyword));
}
return mapper.countOperatorsByCriteria(queryWrapper);
}

View File

@@ -17,7 +17,7 @@ import lombok.Setter;
public class OperatorsListPostRequest extends PagingQuery {
private List<String> categories = new ArrayList<>();
private String operatorName;
private String keyword;
private String labelName;

View File

@@ -29,8 +29,8 @@ public class OperatorController {
categories.remove(OperatorConstant.CATEGORY_STAR_ID);
}
List<OperatorDto> responses = operatorService.getOperators(request.getPage(), request.getSize(),
categories, request.getOperatorName(), isStar);
int count = operatorService.getOperatorsCount(categories, request.getOperatorName(), isStar);
categories, request.getKeyword(), isStar);
int count = operatorService.getOperatorsCount(categories, request.getKeyword(), isStar);
int totalPages = (count + request.getSize() + 1) / request.getSize();
return PagedResponse.of(responses, request.getPage(), count, totalPages);
}

View File

@@ -172,11 +172,11 @@ spec:
# 警告:以下 Env Vars 依赖 StatefulSet 命名 (headless service 和 ordered names)
# 在 Deployment 中如果不修改副本数为 1,这些配置会导致集群发现失败。
- name: ETCD_ADVERTISE_CLIENT_URLS
value: "{{ $etcdClientProtocol }}://$(MY_POD_NAME).{{ $etcdHeadlessServiceName }}.{{ .Release.Namespace }}.svc.{{ $clusterDomain }}:{{ .Values.containerPorts.client }},{{ $etcdClientProtocol }}://{{ $etcdFullname }}.{{ .Release.Namespace }}.svc.{{ $clusterDomain }}:{{ coalesce .Values.service.ports.client .Values.service.port }}"
value: "{{ $etcdClientProtocol }}://{{ $etcdHeadlessServiceName }}.{{ .Release.Namespace }}.svc.{{ $clusterDomain }}:{{ .Values.containerPorts.client }},{{ $etcdClientProtocol }}://{{ $etcdFullname }}.{{ .Release.Namespace }}.svc.{{ $clusterDomain }}:{{ coalesce .Values.service.ports.client .Values.service.port }}"
- name: ETCD_LISTEN_CLIENT_URLS
value: "{{ $etcdClientProtocol }}://0.0.0.0:{{ .Values.containerPorts.client }}"
- name: ETCD_INITIAL_ADVERTISE_PEER_URLS
value: "{{ $etcdPeerProtocol }}://$(MY_POD_NAME).{{ $etcdHeadlessServiceName }}.{{ .Release.Namespace }}.svc.{{ $clusterDomain }}:{{ .Values.containerPorts.peer }}"
value: "{{ $etcdPeerProtocol }}://{{ $etcdHeadlessServiceName }}.{{ .Release.Namespace }}.svc.{{ $clusterDomain }}:{{ .Values.containerPorts.peer }}"
- name: ETCD_LISTEN_PEER_URLS
value: "{{ $etcdPeerProtocol }}://0.0.0.0:{{ .Values.containerPorts.peer }}"
{{- if .Values.autoCompactionMode }}

View File

@@ -28,6 +28,9 @@ etcd:
{{- range .Values.externalEtcd.endpoints }}
- {{ . }}
{{- end }}
{{- else if eq (.Values.etcd.workload | lower) "deployment" }}
endpoints:
- {{ $etcdReleaseName }}-headless.{{ $namespace }}.svc.{{ $.Values.etcd.clusterDomain }}:{{ $etcdPort }}
{{- else }}
endpoints:
{{- range $i := until ( .Values.etcd.replicaCount | int ) }}

View File

@@ -71,6 +71,14 @@ export default function useFetchData<T>(
});
};
const handleKeywordChange = (keyword: string) => {
setSearchParams({
...searchParams,
current: 1,
keyword: keyword,
});
};
function getFirstOfArray(arr: string[]) {
if (!arr || arr.length === 0 || !Array.isArray(arr)) return undefined;
if (arr[0] === "all") return undefined;
@@ -217,6 +225,7 @@ export default function useFetchData<T>(
setSearchParams,
setPagination,
handleFiltersChange,
handleKeywordChange,
fetchData,
isPolling,
startPolling,

View File

@@ -32,9 +32,9 @@ export default function DataAnnotation() {
tableData,
pagination,
searchParams,
setSearchParams,
fetchData,
handleFiltersChange,
handleKeywordChange,
} = useFetchData(queryAnnotationTasksUsingGet, mapAnnotationTask, 30000, true, [], 0);
const [labelStudioBase, setLabelStudioBase] = useState<string | null>(null);
@@ -313,9 +313,7 @@ export default function DataAnnotation() {
<div className="flex items-center gap-2">
<SearchControls
searchTerm={searchParams.keyword}
onSearchChange={(keyword) =>
setSearchParams({ ...searchParams, keyword })
}
onSearchChange={handleKeywordChange}
searchPlaceholder="搜索任务名称、描述"
onFiltersChange={handleFiltersChange}
viewMode={viewMode}

View File

@@ -41,6 +41,7 @@ export default function TaskList() {
setSearchParams,
fetchData,
handleFiltersChange,
handleKeywordChange,
} = useFetchData(queryCleaningTasksUsingGet, mapTask);
const pauseTask = async (item: CleansingTask) => {
@@ -270,9 +271,7 @@ export default function TaskList() {
{/* Search and Filters */}
<SearchControls
searchTerm={searchParams.keyword}
onSearchChange={(keyword) =>
setSearchParams({ ...searchParams, keyword })
}
onSearchChange={handleKeywordChange}
searchPlaceholder="搜索任务名称、描述"
filters={filterOptions}
onFiltersChange={handleFiltersChange}

View File

@@ -24,6 +24,7 @@ export default function TemplateList() {
setSearchParams,
fetchData,
handleFiltersChange,
handleKeywordChange,
} = useFetchData(queryCleaningTemplatesUsingGet, mapTemplate);
const templateOperations = () => {
@@ -120,9 +121,7 @@ export default function TemplateList() {
{/* Search and Filters */}
<SearchControls
searchTerm={searchParams.keyword}
onSearchChange={(keyword) =>
setSearchParams({ ...searchParams, keyword })
}
onSearchChange={handleKeywordChange}
searchPlaceholder="搜索模板名称、描述"
onFiltersChange={handleFiltersChange}
viewMode={viewMode}

View File

@@ -37,6 +37,7 @@ export default function ExecutionLog() {
searchParams,
setSearchParams,
handleFiltersChange,
handleKeywordChange,
} = useFetchData(queryExecutionLogUsingPost);
const columns: ColumnsType<CollectionLog> = [
@@ -113,12 +114,7 @@ export default function ExecutionLog() {
<div className="flex items-center justify-between gap-4">
<SearchControls
searchTerm={searchParams.keyword}
onSearchChange={(keyword: string) =>
setSearchParams({
...searchParams,
keyword,
})
}
onSearchChange={handleKeywordChange}
filters={filterOptions}
onFiltersChange={handleFiltersChange}
showViewToggle={false}

View File

@@ -120,6 +120,7 @@ export default function DatasetManagementPage() {
fetchData,
setSearchParams,
handleFiltersChange,
handleKeywordChange,
} = useFetchData<Dataset>(
queryDatasetsUsingGet,
mapDataset,
@@ -370,9 +371,7 @@ export default function DatasetManagementPage() {
</div>
<SearchControls
searchTerm={searchParams.keyword}
onSearchChange={(keyword) =>
setSearchParams({ ...searchParams, keyword })
}
onSearchChange={handleKeywordChange}
searchPlaceholder="搜索数据集名称、描述或标签..."
filters={filterOptions}
onFiltersChange={handleFiltersChange}

View File

@@ -69,6 +69,7 @@ const KnowledgeBaseDetailPage: React.FC = () => {
fetchData: fetchFiles,
setSearchParams,
handleFiltersChange,
handleKeywordChange,
} = useFetchData<KBFile>(
(params) => id ? queryKnowledgeBaseFilesUsingGet(id, params) : Promise.resolve({ data: [] }),
mapFileData
@@ -265,7 +266,7 @@ const KnowledgeBaseDetailPage: React.FC = () => {
<div className="flex-1">
<SearchControls
searchTerm={searchParams.keyword}
onSearchChange={(keyword) => setSearchParams({ ...searchParams, keyword })}
onSearchChange={handleKeywordChange}
searchPlaceholder="搜索文件名..."
filters={[]}
onFiltersChange={handleFiltersChange}

View File

@@ -26,6 +26,7 @@ export default function KnowledgeBasePage() {
fetchData,
setSearchParams,
handleFiltersChange,
handleKeywordChange,
} = useFetchData<KnowledgeBaseItem>(
queryKnowledgeBasesUsingPost,
(kb) => mapKnowledgeBase(kb, false) // 在首页不显示索引模型和文本理解模型字段
@@ -146,9 +147,7 @@ export default function KnowledgeBasePage() {
<SearchControls
searchTerm={searchParams.keyword}
onSearchChange={(keyword) =>
setSearchParams({ ...searchParams, keyword })
}
onSearchChange={handleKeywordChange}
searchPlaceholder="搜索知识库..."
filters={[]}
onFiltersChange={handleFiltersChange}

View File

@@ -156,6 +156,19 @@ export default function CreateKnowledgeBase({
<Select
placeholder="请选择文本理解模型"
options={chatModelOptions}
popupRender={(menu) => (
<>
{menu}
<Button
block
type="link"
icon={<PlusOutlined />}
onClick={() => dispatch(showSettings())}
>
</Button>
</>
)}
/>
</Form.Item>
</Form>

View File

@@ -49,9 +49,9 @@ export default function OperatorMarketPage() {
tableData,
pagination,
searchParams,
setSearchParams,
fetchData,
handleFiltersChange,
handleKeywordChange,
} = useFetchData(queryOperatorsUsingPost, mapOperator);
const handleUploadOperator = () => {
@@ -157,9 +157,7 @@ export default function OperatorMarketPage() {
<div className="flex-1 mb-4">
<SearchControls
searchTerm={searchParams.keyword}
onSearchChange={(keyword) =>
setSearchParams({ ...searchParams, keyword })
}
onSearchChange={handleKeywordChange}
searchPlaceholder="搜索算子名称、描述..."
filters={[]}
onFiltersChange={handleFiltersChange}

View File

@@ -26,6 +26,7 @@ export default function RatioTasksPage() {
setSearchParams,
handleFiltersChange,
fetchData,
handleKeywordChange,
} = useFetchData<RatioTaskItem>(
queryRatioTasksUsingGet,
mapRatioTask,
@@ -186,9 +187,7 @@ export default function RatioTasksPage() {
{/* 搜索、筛选和视图控制 */}
<SearchControls
searchTerm={searchParams.keyword}
onSearchChange={(keyword) =>
setSearchParams({ ...searchParams, keyword })
}
onSearchChange={handleKeywordChange}
searchPlaceholder="搜索任务名称..."
filters={filters}
onFiltersChange={handleFiltersChange}