Fix get datasets owner retrieve the whole dataset (#17370)

This commit is contained in:
Wang Qi
2026-07-27 10:24:13 +08:00
committed by GitHub
parent f53518c110
commit 53afc32349
12 changed files with 137 additions and 4 deletions

View File

@@ -363,6 +363,20 @@ def list_datasets(tenant_id):
items:
type: object
"""
if request.args.get("type") == "filter":
try:
success, result = dataset_api_service.list_dataset_filters(tenant_id)
if success:
return get_result(data=result)
else:
return get_error_data_result(message=result)
except OperationalError as e:
logging.exception(e)
return get_error_data_result(message="Database operation failed")
except Exception as e:
logging.exception(e)
return get_error_data_result(message="Internal server error")
args, err = validate_and_parse_request_args(request, ListDatasetReq)
if err is not None:
return get_error_argument_result(err)

View File

@@ -458,6 +458,13 @@ def list_datasets(tenant_id: str, args: dict):
return True, {"data": response_data_list, "total": total}
def list_dataset_filters(tenant_id: str):
tenants = TenantService.get_joined_tenants_by_user_id(tenant_id)
tenant_ids = [m["tenant_id"] for m in tenants]
owners = KnowledgebaseService.get_owner_filter(tenant_ids, tenant_id)
return True, {"filter": {"owner": owners}, "total": sum(owner["count"] for owner in owners)}
async def get_knowledge_graph(dataset_id: str, tenant_id: str):
"""
Get knowledge graph for a dataset.

View File

@@ -501,6 +501,21 @@ class KnowledgebaseService(CommonService):
return list(kbs.dicts()), total
@classmethod
@DB.connection_context()
def get_owner_filter(cls, joined_tenant_ids, user_id):
owners = (
cls.model.select(
cls.model.tenant_id.alias("id"),
User.nickname.alias("label"),
fn.COUNT(cls.model.id).alias("count"),
)
.join(User, on=(cls.model.tenant_id == User.id))
.where(cls._visibility_and_status_filter(joined_tenant_ids, user_id))
.group_by(cls.model.tenant_id, User.nickname)
)
return list(owners.dicts())
@classmethod
@DB.connection_context()
def accessible(cls, kb_id, user_id):

View File

@@ -227,6 +227,21 @@ func (dao *KnowledgebaseDAO) GetByTenantIDs(ctx context.Context, db *gorm.DB, te
return kbs, total, nil
}
// GetOwnerFilter returns owner counts for datasets visible to a user.
func (dao *KnowledgebaseDAO) GetOwnerFilter(tenantIDs []string, userID string) ([]*entity.DatasetOwnerFilter, error) {
owners := make([]*entity.DatasetOwnerFilter, 0)
err := DB.Model(&entity.Knowledgebase{}).
Select("knowledgebase.tenant_id as id, user.nickname as label, COUNT(knowledgebase.id) as count").
Joins("LEFT JOIN user ON knowledgebase.tenant_id = user.id").
Where("((knowledgebase.tenant_id IN ? AND knowledgebase.permission = ?) OR knowledgebase.tenant_id = ?) AND knowledgebase.status = ?",
tenantIDs, string(entity.TenantPermissionTeam), userID, string(entity.StatusValid)).
Group("knowledgebase.tenant_id, user.nickname").
Scan(&owners).Error
return owners, err
}
// GetAllByTenantIDs retrieves all permitted knowledge bases by tenant IDs
// This matches the Python get_all_kb_by_tenant_ids method
func (dao *KnowledgebaseDAO) GetAllByTenantIDs(ctx context.Context, db *gorm.DB, tenantIDs []string, userID string) ([]*entity.Knowledgebase, error) {

View File

@@ -239,3 +239,10 @@ type KnowledgebaseListItem struct {
TenantAvatar *string `json:"tenant_avatar,omitempty"`
UpdateTime *int64 `json:"update_time,omitempty"`
}
// DatasetOwnerFilter represents an owner option in dataset filter responses.
type DatasetOwnerFilter struct {
ID string `json:"id"`
Label string `json:"label"`
Count int64 `json:"count"`
}

View File

@@ -77,6 +77,16 @@ func (h *DatasetsHandler) ListDatasets(c *gin.Context) {
return
}
if c.Query("type") == "filter" {
data, code, err := h.datasetsService.ListDatasetFilters(user.ID)
if err != nil {
common.ErrorWithCode(c, code, err.Error())
return
}
common.SuccessNoMessage(c, data)
return
}
page := 1
if pageStr := c.Query("page"); pageStr != "" {
if p, err := strconv.Atoi(pageStr); err == nil && p > 0 {

View File

@@ -393,6 +393,40 @@ func (d *DatasetService) ListDatasets(ctx context.Context, id, name string, page
return data, total, common.CodeSuccess, nil
}
func (d *DatasetService) ListDatasetFilters(userID string) (map[string]interface{}, common.ErrorCode, error) {
joinedTenants, err := d.tenantDAO.GetJoinedTenantsByUserID(userID)
if err != nil {
return nil, common.CodeServerError, errors.New("database operation failed")
}
tenantIDs := make([]string, 0, len(joinedTenants))
for _, joinedTenant := range joinedTenants {
if joinedTenant == nil || joinedTenant.TenantID == "" {
continue
}
tenantIDs = append(tenantIDs, joinedTenant.TenantID)
}
owners, err := d.kbDAO.GetOwnerFilter(tenantIDs, userID)
if err != nil {
return nil, common.CodeServerError, errors.New("database operation failed")
}
var total int64
for _, owner := range owners {
if owner != nil {
total += owner.Count
}
}
return map[string]interface{}{
"filter": map[string]interface{}{
"owner": owners,
},
"total": total,
}, common.CodeSuccess, nil
}
// ptrStringValue safely dereferences a *string.
func ptrStringValue(s *string) string {
if s == nil {

View File

@@ -8,6 +8,7 @@ import {
IArtifactPage,
IArtifactTopic,
IDataset,
IDatasetFilter,
IDatasetListResult,
IKnowledgeGraph,
INextTestingResult,
@@ -33,6 +34,7 @@ import kbService, {
getWikiCommit,
listArtifactTopics,
listArtifacts,
datasetFilter,
listDataset,
listTag,
listWikiCommits,
@@ -65,6 +67,7 @@ import { useSetPaginationParams } from './route-hook';
export const enum KnowledgeApiAction {
FetchKnowledgeListByPage = 'fetchKnowledgeListByPage',
FetchDatasetFilter = 'fetchDatasetFilter',
CreateKnowledge = 'createKnowledge',
DeleteKnowledge = 'deleteKnowledge',
SaveKnowledge = 'saveKnowledge',
@@ -209,6 +212,24 @@ export const useFetchNextKnowledgeListByPage = () => {
};
};
export const useGetDatasetFilter = (): { filter: IDatasetFilter } => {
const { data } = useQuery({
queryKey: [KnowledgeApiAction.FetchDatasetFilter],
queryFn: async () => {
const { data } = await datasetFilter();
if (data.code === 0) {
return data.data;
}
},
});
return {
filter: data?.filter || {
owner: [],
},
};
};
export const useCreateKnowledge = () => {
const queryClient = useQueryClient();
const {

View File

@@ -50,6 +50,14 @@ export interface IDataset {
connectors: IConnector[];
}
export type IDatasetFilter = {
owner: Array<{
id: string;
label: string;
count: number;
}>;
};
interface Parserconfig {
auto_keywords: number;
auto_questions: number;

View File

@@ -1,14 +1,13 @@
import { FilterCollection } from '@/components/list-filter-bar/interface';
import { useFetchAllKnowledgeList } from '@/hooks/use-knowledge-request';
import { buildOwnersFilter } from '@/utils/list-filter-util';
import { useGetDatasetFilter } from '@/hooks/use-knowledge-request';
import { useTranslation } from 'react-i18next';
export function useSelectOwners() {
const { list } = useFetchAllKnowledgeList();
const { filter } = useGetDatasetFilter();
const { t } = useTranslation();
const filters: FilterCollection[] = [
buildOwnersFilter(list, undefined, t('common.owner')),
{ field: 'owner', list: filter.owner, label: t('common.owner') },
];
return filters;

View File

@@ -267,6 +267,8 @@ export function deleteKnowledgeGraph(knowledgeId: string) {
export const listDataset = (params?: IFetchKnowledgeListRequestParams) =>
request.get(api.kbList, { params });
export const datasetFilter = () => request.get(api.datasetFilter);
export const updateKb = (datasetId: string, data: Record<string, any>) =>
request.put(api.updateKb(datasetId), { data });

View File

@@ -143,6 +143,7 @@ export default {
checkEmbedding: (datasetId: string) =>
`${restAPIv1}/datasets/${datasetId}/embedding/check`,
kbList: `${restAPIv1}/datasets`,
datasetFilter: `${restAPIv1}/datasets?type=filter`,
createKb: `${restAPIv1}/datasets`,
updateKb: (datasetId: string) => `${restAPIv1}/datasets/${datasetId}`,
rmKb: `${restAPIv1}/datasets`,