| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 | 'use client'// Librariesimport { useEffect, useMemo, useRef, useState } from 'react'import { useRouter } from 'next/navigation'import { useTranslation } from 'react-i18next'import { useBoolean, useDebounceFn } from 'ahooks'import { useQuery } from '@tanstack/react-query'// Componentsimport ExternalAPIPanel from '../../components/datasets/external-api/external-api-panel'import Datasets from './Datasets'import DatasetFooter from './DatasetFooter'import ApiServer from './ApiServer'import Doc from './Doc'import TabSliderNew from '@/app/components/base/tab-slider-new'import TagManagementModal from '@/app/components/base/tag-management'import TagFilter from '@/app/components/base/tag-management/filter'import Input from '@/app/components/base/input'// Servicesimport { fetchDatasetApiBaseUrl } from '@/service/datasets'// Hooksimport { useTabSearchParams } from '@/hooks/use-tab-searchparams'import { useStore as useTagStore } from '@/app/components/base/tag-management/store'import { useAppContext } from '@/context/app-context'import { useExternalApiPanel } from '@/context/external-api-panel-context'import { SimpleSelect } from '@/app/components/base/select'import { fetchDepts, fetchTypes } from '@/service/common'import Statistic from '@/app/(commonLayout)/datasets/Statistic'import { TreeSelect as AntdTreeSelect } from 'antd'const Container = () => {  const { t } = useTranslation()  const router = useRouter()  const { currentWorkspace, isCurrentWorkspaceOwner } = useAppContext()  const showTagManagementModal = useTagStore(s => s.showTagManagementModal)  const { showExternalApiPanel, setShowExternalApiPanel } = useExternalApiPanel()  const [includeAll, { toggle: toggleIncludeAll }] = useBoolean(false)  const options = useMemo(() => {    return [      { value: 'dataset', text: t('dataset.datasets') },      ...(currentWorkspace.role === 'dataset_operator' ? [] : [{ value: 'api', text: t('dataset.datasetsApi') }]),      { value: 'statistic', text: '知识总览' },    ]  }, [currentWorkspace.role, t])  const [activeTab, setActiveTab] = useTabSearchParams({    defaultTab: 'dataset',  })  const containerRef = useRef<HTMLDivElement>(null)  const { data } = useQuery(    {      queryKey: ['datasetApiBaseInfo'],      queryFn: () => fetchDatasetApiBaseUrl('/datasets/api-base-info'),      enabled: activeTab !== 'dataset',    },  )  const [keywords, setKeywords] = useState('')  const [searchKeywords, setSearchKeywords] = useState('')  const { run: handleSearch } = useDebounceFn(() => {    setSearchKeywords(keywords)  }, { wait: 500 })  const handleKeywordsChange = (value: string) => {    setKeywords(value)    handleSearch()  }  const [creator, setCreator] = useState('')  const [searchCreator, setSearchCreator] = useState('')  const { run: handleSearchCreator } = useDebounceFn(() => {    setSearchCreator(creator)  }, { wait: 500 })  const handleCreatorChange = (value: string) => {    setCreator(value)    handleSearchCreator()  }  const [tagFilterValue, setTagFilterValue] = useState<string[]>([])  const [tagIDs, setTagIDs] = useState<string[]>([])  const { run: handleTagsUpdate } = useDebounceFn(() => {    setTagIDs(tagFilterValue)  }, { wait: 500 })  const handleTagsChange = (value: string[]) => {    setTagFilterValue(value)    handleTagsUpdate()  }  // useEffect(() => {  //   if (currentWorkspace.role === 'normal')  //     return router.replace('/apps')  // }, [currentWorkspace, router])  const [type, setType] = useState<any>()  const [searchType, setSearchType] = useState('')  const { run: handleTypeUpdate } = useDebounceFn(() => {    setSearchType(type)  }, { wait: 500 })  const [optionsType, setOptionsType] = useState<any>([])  useEffect(() => {    fetchTypes({      url: '/tags/page',      params: {        page: 1,        limit: 99999,        tag_type: 'knowledge_category',      },    }).then((res: any) => {      setOptionsType(res.data.map((v: any) => ({ name: v.name, value: v.id })) || [])    })  }, [])  const [dept, setDept] = useState<any>()  const [optionsDept, setOptionsDept] = useState<any>([])  useEffect(() => {    fetchDepts({      url: '/depts',    }).then((res: any) => {      setOptionsDept(res.data || [])    })  }, [])  const [authType, setAuthType] = useState<any>('')  const optionsAuthType = [    { name: '创建', value: '1' },    { name: '编辑', value: '2' },    { name: '授权编辑', value: '3' },    { name: '授权可见', value: '4' },  ]  return (    <div ref={containerRef} className='scroll-container relative flex grow flex-col overflow-y-auto bg-background-body'>      <div className='sticky top-0 z-10 flex flex-wrap justify-between gap-y-2 bg-background-body px-12 pb-2 pt-4 leading-[56px]'>        <TabSliderNew          value={activeTab}          onChange={newActiveTab => setActiveTab(newActiveTab)}          options={options}        />        {activeTab === 'dataset' && (          <div className='flex items-center justify-center gap-2'>            <Input              showLeftIcon              showClearIcon              wrapperClassName='w-[200px]'              value={creator}              onChange={e => handleCreatorChange(e.target.value)}              onClear={() => handleCreatorChange('')}              placeholder="请输入创建人"            />            <SimpleSelect              wrapperClassName="h-[32px] w-[200px]"              defaultValue={authType}              onSelect={(i) => {                setAuthType(i.value)              }}              items={optionsAuthType}              allowSearch={false}              placeholder="请选择权限类型"            />            <AntdTreeSelect              showSearch              style={{ width: '200px' }}              value={dept}              dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}              placeholder="请选择部门"              allowClear              treeDefaultExpandAll              onChange={v => setDept(v || '')}              treeData={optionsDept}              fieldNames={{ label: 'dept_name', value: 'dept_id' }}            />            <SimpleSelect              wrapperClassName="h-[32px] w-[200px]"              defaultValue={type}              onSelect={(i) => {                setType(i.value)                handleTypeUpdate()              }}              items={optionsType}              allowSearch={false}              placeholder="请选择类型"            />            {/* {isCurrentWorkspaceOwner && <CheckboxWithLabel */}            {/*  isChecked={includeAll} */}            {/*  onChange={toggleIncludeAll} */}            {/*  label={t('dataset.allKnowledge')} */}            {/*  labelClassName='system-md-regular text-text-secondary' */}            {/*  className='mr-2' */}            {/*  tooltip={t('dataset.allKnowledgeDescription') as string} */}            {/* />} */}            <TagFilter type='knowledge' value={tagFilterValue} onChange={handleTagsChange} />            <Input              showLeftIcon              showClearIcon              wrapperClassName='w-[200px]'              value={keywords}              onChange={e => handleKeywordsChange(e.target.value)}              onClear={() => handleKeywordsChange('')}            />            {/* <div className="h-4 w-[1px] bg-divider-regular" /> */}            {/* <Button */}            {/*  className='shadows-shadow-xs gap-0.5' */}            {/*  onClick={() => setShowExternalApiPanel(true)} */}            {/* > */}            {/*  <ApiConnectionMod className='h-4 w-4 text-components-button-secondary-text' /> */}            {/*  <div className='system-sm-medium flex items-center justify-center gap-1 px-0.5 text-components-button-secondary-text'>{t('dataset.externalAPIPanelTitle')}</div> */}            {/* </Button> */}          </div>        )}        {activeTab === 'api' && data && <ApiServer apiBaseUrl={data.api_base_url || ''} />}      </div>      {activeTab === 'dataset' && (        <>          <Datasets containerRef={containerRef} tags={tagIDs} keywords={searchKeywords} includeAll={includeAll} type={searchType} dept={dept} authType={authType} creator={searchCreator} />          <DatasetFooter />          {showTagManagementModal && (            <TagManagementModal type='knowledge' show={showTagManagementModal} />          )}        </>      )}      {activeTab === 'api' && data && <Doc apiBaseUrl={data.api_base_url || ''} />}      {activeTab === 'statistic' && data && <Statistic/>}      {showExternalApiPanel && <ExternalAPIPanel onClose={() => setShowExternalApiPanel(false)} />}    </div>  )}export default Containerexport const GetDatasetAuth = (row: any) => {  const { currentWorkspace, userProfile } = useAppContext()  let isCreate = false  let isEdit = false  let isOperation = false  if (row) {    isCreate = currentWorkspace.role === 'owner' || row.created_by === userProfile.id    isEdit = isCreate || currentWorkspace.role === 'admin' || (row.edit_auth === 2 && currentWorkspace.role === 'leader' && row.dept_id === userProfile.dept_id)    isOperation = isEdit || row.has_edit_permission || (row.edit_auth === 2 && row.dept_id === userProfile.dept_id)  }  return {    isCreate,    isEdit,    isOperation,  }}
 |