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) { public List<CleaningTaskDto> findTasks(String status, String keywords, Integer page, Integer size) {
LambdaQueryWrapper<CleaningTask> lambdaWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<CleaningTask> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.eq(StringUtils.isNotBlank(status), CleaningTask::getStatus, status) lambdaWrapper.eq(StringUtils.isNotBlank(status), CleaningTask::getStatus, status);
.like(StringUtils.isNotBlank(keywords), CleaningTask::getName, keywords) if (StringUtils.isNotBlank(keywords)) {
.orderByDesc(CleaningTask::getCreatedAt); lambdaWrapper.and(w ->
w.like(CleaningTask::getName, keywords)
.or()
.like(CleaningTask::getDescription, keywords));
}
lambdaWrapper.orderByDesc(CleaningTask::getCreatedAt);
if (size != null && page != null) { if (size != null && page != null) {
Page<CleaningTask> queryPage = new Page<>(page + 1, size); Page<CleaningTask> queryPage = new Page<>(page + 1, size);
IPage<CleaningTask> resultPage = mapper.selectPage(queryPage, lambdaWrapper); IPage<CleaningTask> resultPage = mapper.selectPage(queryPage, lambdaWrapper);

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,10 +7,10 @@ import com.datamate.operator.interfaces.dto.OperatorDto;
import java.util.List; import java.util.List;
public interface OperatorViewRepository extends IRepository<OperatorView> { 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); 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); OperatorView findOperatorById(String id);
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -28,6 +28,9 @@ etcd:
{{- range .Values.externalEtcd.endpoints }} {{- range .Values.externalEtcd.endpoints }}
- {{ . }} - {{ . }}
{{- end }} {{- end }}
{{- else if eq (.Values.etcd.workload | lower) "deployment" }}
endpoints:
- {{ $etcdReleaseName }}-headless.{{ $namespace }}.svc.{{ $.Values.etcd.clusterDomain }}:{{ $etcdPort }}
{{- else }} {{- else }}
endpoints: endpoints:
{{- range $i := until ( .Values.etcd.replicaCount | int ) }} {{- 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[]) { function getFirstOfArray(arr: string[]) {
if (!arr || arr.length === 0 || !Array.isArray(arr)) return undefined; if (!arr || arr.length === 0 || !Array.isArray(arr)) return undefined;
if (arr[0] === "all") return undefined; if (arr[0] === "all") return undefined;
@@ -217,6 +225,7 @@ export default function useFetchData<T>(
setSearchParams, setSearchParams,
setPagination, setPagination,
handleFiltersChange, handleFiltersChange,
handleKeywordChange,
fetchData, fetchData,
isPolling, isPolling,
startPolling, startPolling,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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