| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 | 
							- 'use client'
 
- import React, { useEffect, useState } from 'react'
 
- import { RiCloseLine } from '@remixicon/react'
 
- import Modal from '@/app/components/base/modal'
 
- import Button from '@/app/components/base/button'
 
- import {
 
-   addIntent, addIntentKeyword, delBatchIntentKeyword, editIntent, editIntentKeyword, fetchIntentKeyword,
 
-   fetchIntentType, getIntent,
 
- } from '@/service/common'
 
- import 'react-multi-email/dist/style.css'
 
- import Input from '@/app/components/base/input'
 
- import { SimpleSelect } from '@/app/components/base/select'
 
- import useSWR from 'swr'
 
- import Checkbox from '@/app/components/base/checkbox'
 
- import cn from '@/utils/classnames'
 
- import { useContext } from 'use-context-selector'
 
- import { ToastContext } from '@/app/components/base/toast'
 
- import Confirm from '@/app/components/base/confirm'
 
- import { Textarea } from '@/app/components/base/textarea'
 
- const DetailModal = ({
 
-   transfer,
 
-   onCancel,
 
-   onSend,
 
-   onRefresh,
 
- }: any) => {
 
-   const { notify } = useContext(ToastContext)
 
-   const [intentName, setIntentName] = useState<string>(transfer.row?.intentName || '')
 
-   const [intentType, setIntentType] = useState<string>(transfer.row?.intentType || '')
 
-   const [corpusList, setCorpusList] = useState<any>([])
 
-   const [corpusFilter, setCorpusFilter] = useState<string>('')
 
-   const [keywordsList, setKeywordsList] = useState<any>([])
 
-   const { data: dataOptionsIntentType }: any = useSWR(
 
-     {
 
-       url: '/intentions/types',
 
-       params: {
 
-         page: 1,
 
-         limit: 99999,
 
-       },
 
-     },
 
-     fetchIntentType,
 
-   )
 
-   const optionsIntentType: any = dataOptionsIntentType?.data.map((v: any) => ({ name: v.name, value: v.id })) || []
 
-   useEffect(() => {
 
-     if (transfer.row?.id) {
 
-       getIntent({ url: `/intentions/${transfer.row.id}` }).then((res: any) => {
 
-         setIntentType(res.type.id)
 
-         setIntentName(res.name)
 
-         setCorpusList(res.corpus)
 
-         setKeywordsList(res.keywords)
 
-       })
 
-     }
 
-   }, [])
 
-   const [keyword, setKeyword] = useState<string>('')
 
-   const [keywordFilter, setKeywordFilter] = useState<string>('')
 
-   const refreshKeywords = async () => {
 
-     const res = await fetchIntentKeyword({
 
-       url: `/intentions/${transfer.row.id}/keywords`,
 
-       params: {
 
-         page: 1,
 
-         limit: 99999,
 
-       },
 
-     })
 
-     setKeywordsList(res)
 
-   }
 
-   const handleAddKeyword = async () => {
 
-     if (!keyword)
 
-       return
 
-     if (keywordsList.some((v: any) => v.name === keyword)) {
 
-       notify({ type: 'warning', message: '请勿新增重复数据!' })
 
-       return
 
-     }
 
-     const { id }: any = await addIntentKeyword({
 
-       url: `/intentions/${transfer.row.id}/keywords`,
 
-       body: {
 
-         name: keyword,
 
-       },
 
-     })
 
-     if (id) {
 
-       await refreshKeywords()
 
-       setKeyword('')
 
-     }
 
-   }
 
-   const [keywordSelectMap, setKeywordsSelectMap] = useState<any>(new Map())
 
-   const addKeywordsSelectMap = (key: any, value: any) => {
 
-     setKeywordsSelectMap((prevMap: any) => {
 
-       const newMap = new Map(prevMap)
 
-       newMap.set(key, value)
 
-       return newMap
 
-     })
 
-   }
 
-   const delKeywordsSelectMap = (key: any) => {
 
-     setKeywordsSelectMap((prevMap: any) => {
 
-       const newMap = new Map(prevMap)
 
-       newMap.delete(key)
 
-       return newMap
 
-     })
 
-   }
 
-   const [keywordRow, setKeywordRow] = useState<any>({})
 
-   const [showKeywordEdit, setShowKeywordEdit] = useState(false)
 
-   const [editKeyword, setEditKeyword] = useState<string>('')
 
-   const handleSaveKeyword = async () => {
 
-     if (keywordsList.some((v: any) => v.name === editKeyword)) {
 
-       notify({ type: 'warning', message: '请勿新增重复数据!' })
 
-       return
 
-     }
 
-     const { id }: any = await editIntentKeyword({
 
-       url: `/intentions/keywords/${keywordRow.id}`,
 
-       body: {
 
-         name: editKeyword,
 
-         intention_id: keywordRow.intention_id,
 
-       },
 
-     })
 
-     if (id) {
 
-       await refreshKeywords()
 
-       setShowKeywordEdit(false)
 
-     }
 
-   }
 
-   const [showConfirmDelete, setShowConfirmDelete] = useState(false)
 
-   const [delBatch, setDelBatch] = useState(false)
 
-   const handleDelKeyword = async () => {
 
-     try {
 
-       await delBatchIntentKeyword({
 
-         url: '/intentions/keywords/batch',
 
-         body: {
 
-           method: 'delete',
 
-           delete_data: delBatch ? Array.from(keywordSelectMap.keys()) : [keywordRow.id],
 
-         },
 
-       })
 
-       setShowConfirmDelete(false)
 
-       setKeywordsSelectMap(new Map())
 
-       refreshKeywords()
 
-     }
 
-     catch (e) { }
 
-   }
 
-   const handleSave = async () => {
 
-     try {
 
-       let res
 
-       if (transfer.mode === 'add') {
 
-         res = await addIntent({
 
-           url: '/intentions',
 
-           body: { type_id: intentType, name: intentName },
 
-         })
 
-       }
 
-       else {
 
-         res = await editIntent({
 
-           url: `/intentions/${transfer.row.id}`,
 
-           body: { type_id: intentType, name: intentName },
 
-         })
 
-       }
 
-       const { id }: any = res
 
-       if (id) {
 
-         if (transfer.mode === 'add')
 
-           onRefresh(id)
 
-         else
 
-           onSend()
 
-       }
 
-     }
 
-     catch (e) { }
 
-   }
 
-   const [similarityRow, setSimilarityRow] = useState<any>({})
 
-   const [showSimilarityCorpus, setShowSimilarityCorpus] = useState(false)
 
-   return (
 
-     <div>
 
-       <Modal overflowVisible isShow onClose={() => { }} className="p-[24px 32px] w-[800px] max-w-[800px]">
 
-         <div className='mb-2 flex justify-between'>
 
-           <div className='text-xl font-semibold text-text-primary'>{transfer.mode === 'add' ? '新增' : '编辑'}意图</div>
 
-           <RiCloseLine className='h-4 w-4 cursor-pointer text-text-tertiary' onClick={onCancel} />
 
-         </div>
 
-         <div className="shrink-0 text-gray-500">
 
-           <div className="flex flex-col gap-2">
 
-             <div className="flex w-full items-center">
 
-               <div className="w-[80px]">意图类型</div>
 
-               <div className="flex flex-1">
 
-                 <SimpleSelect
 
-                   className="h-[32px] w-[200px]"
 
-                   defaultValue={intentType}
 
-                   onSelect={(i: any) => {
 
-                     setIntentType(i.value)
 
-                   }}
 
-                   items={optionsIntentType}
 
-                   allowSearch={false}
 
-                   placeholder="请选择意图类型"
 
-                 />
 
-               </div>
 
-             </div>
 
-             <div className="flex w-full items-center">
 
-               <div className="w-[80px]">意图名称</div>
 
-               <div className="flex-1">
 
-                 <Input
 
-                   showClearIcon
 
-                   value={intentName}
 
-                   onChange={e => setIntentName(e.target.value)}
 
-                   onClear={() => setIntentName('')}
 
-                 />
 
-               </div>
 
-             </div>
 
-             {
 
-               transfer.mode === 'edit' && (
 
-                 <div className="flex w-full items-center">
 
-                   <div className="w-[80px]">关键词</div>
 
-                   <div className="flex-1">
 
-                     <Input
 
-                       showClearIcon
 
-                       value={keyword}
 
-                       onChange={e => setKeyword(e.target.value)}
 
-                       onClear={() => setKeyword('')}
 
-                       placeholder='输入后Enter以添加'
 
-                       onEnter={handleAddKeyword}
 
-                     />
 
-                   </div>
 
-                 </div>
 
-               )
 
-             }
 
-           </div>
 
-           {
 
-             transfer.mode === 'edit' && (
 
-               <div className="mt-3 flex flex-col">
 
-                 <div className="flex h-10 w-full items-center gap-2 border-2 border-[#F6F8FC] bg-[#F6F8FC] px-2">
 
-                   <div className='flex items-center' onClick={e => e.stopPropagation()}>
 
-                     <Checkbox
 
-                       className='mr-2 shrink-0'
 
-                       checked={keywordsList.every((v: any) => keywordSelectMap.has(v.id))}
 
-                       onCheck={() => {
 
-                         keywordsList.every((v: any) => keywordSelectMap.has(v.id))
 
-                           ? setKeywordsSelectMap(new Map())
 
-                           : keywordsList.forEach((v: any) => addKeywordsSelectMap(v.id, v))
 
-                       }}
 
-                       disabled={keywordsList.length === 0}
 
-                     />
 
-                     全选
 
-                   </div>
 
-                   <div className="ml-auto w-[200px]">
 
-                     <Input
 
-                       showClearIcon
 
-                       value={keywordFilter}
 
-                       onChange={e => setKeywordFilter(e.target.value)}
 
-                       onClear={() => setKeywordFilter('')}
 
-                       placeholder='请输入关键词名称进行过滤'
 
-                     />
 
-                   </div>
 
-                   <Button variant='primary' className={cn('shrink-0')} onClick={() => {
 
-                     setDelBatch(true)
 
-                     setShowConfirmDelete(true)
 
-                   }}>
 
-                     批量删除
 
-                   </Button>
 
-                 </div>
 
-                 <div className="flex h-[150px] flex-col gap-2 overflow-y-auto border-2 border-solid border-[#F6F8FC] p-2">
 
-                   {
 
-                     keywordsList.filter((v: any) => !keywordFilter || v.name.includes(keywordFilter)).map((item: any) => (
 
-                       <div key={item.id} className="flex items-center">
 
-                         <Checkbox
 
-                           className='mr-2 shrink-0'
 
-                           checked={keywordSelectMap.has(item.id)}
 
-                           onCheck={() => {
 
-                             keywordSelectMap.has(item.id)
 
-                               ? delKeywordsSelectMap(item.id)
 
-                               : addKeywordsSelectMap(item.id, item)
 
-                           }}
 
-                           disabled={keywordsList.length === 0}
 
-                         />
 
-                         <div className="flex-1">
 
-                           {item.name}
 
-                         </div>
 
-                         <Button variant='ghost-accent' size='small' className={cn('shrink-0')}
 
-                           onClick={() => {
 
-                             setKeywordRow(item)
 
-                             setEditKeyword(item.name)
 
-                             setShowKeywordEdit(true)
 
-                           }}>
 
-                           编辑
 
-                         </Button>
 
-                         <Button variant='ghost' size='small' className={cn('shrink-0 text-red-600')}
 
-                           onClick={() => {
 
-                             setKeywordRow(item)
 
-                             setShowConfirmDelete(true)
 
-                           }}>
 
-                           刪除
 
-                         </Button>
 
-                       </div>
 
-                     ))
 
-                   }
 
-                 </div>
 
-                 <div className="flex border-2 border-t-0 border-solid border-[#F6F8FC] p-2 text-xs">
 
-                   <div>共{keywordsList.length}条</div>
 
-                   <div className="ml-4">已选择{keywordSelectMap.size}条</div>
 
-                 </div>
 
-               </div>
 
-             )
 
-           }
 
-           {
 
-             transfer.mode === 'edit' && (
 
-               <div className="mt-3 flex flex-col">
 
-                 <div className="flex h-10 w-full items-center gap-2 border-2 border-[#F6F8FC] bg-[#F6F8FC] px-2">
 
-                   <div>语料列表</div>
 
-                   <div className="ml-auto w-[200px]">
 
-                     <Input
 
-                       showClearIcon
 
-                       value={corpusFilter}
 
-                       onChange={e => setCorpusFilter(e.target.value)}
 
-                       onClear={() => setCorpusFilter('')}
 
-                       placeholder='请输入语料名称进行过滤'
 
-                     />
 
-                   </div>
 
-                 </div>
 
-                 <div className="flex h-[150px] flex-col gap-2 overflow-y-auto border-2 border-solid border-[#F6F8FC] p-2">
 
-                   {
 
-                     corpusList.filter((v: any) => !corpusFilter || v.question.includes(corpusFilter)).map((item: any) => (
 
-                       <div key={item.id} className="flex items-center">
 
-                         <div className="flex-1">
 
-                           {item.question}
 
-                         </div>
 
-                         <Button variant='ghost-accent' size='small' className={cn('shrink-0')} onClick={() => {
 
-                           setSimilarityRow(item)
 
-                           setShowSimilarityCorpus(true)
 
-                         }}>
 
-                           语料配置
 
-                         </Button>
 
-                       </div>
 
-                     ))
 
-                   }
 
-                 </div>
 
-                 <div className="flex border-2 border-t-0 border-solid border-[#F6F8FC] p-2 text-xs">
 
-                   <div>共{corpusList.length}条</div>
 
-                 </div>
 
-               </div>
 
-             )
 
-           }
 
-           <Button
 
-             tabIndex={0}
 
-             className='mt-2 w-full'
 
-             onClick={handleSave}
 
-             disabled={!intentType.length || !intentName.length}
 
-             variant='primary'
 
-           >
 
-             保存
 
-           </Button>
 
-         </div>
 
-       </Modal>
 
-       {
 
-         showKeywordEdit && (
 
-           <Modal overflowVisible isShow onClose={() => { }} className="p-[24px 32px] w-[400px]">
 
-             <div className='mb-2 flex justify-between'>
 
-               <div className='text-xl font-semibold text-text-primary'>编辑关键词</div>
 
-               <RiCloseLine className='h-4 w-4 cursor-pointer text-text-tertiary' onClick={() => setShowKeywordEdit(false)} />
 
-             </div>
 
-             <div>
 
-               <div className={cn('flex flex-wrap items-center justify-between py-4')}>
 
-                 <div className='shrink-0 py-2 text-sm font-medium leading-[20px] text-text-primary'>
 
-                   关键词
 
-                 </div>
 
-                 <Input
 
-                   value={editKeyword}
 
-                   onChange={e => setEditKeyword(e.target.value)}
 
-                   className='h-9'
 
-                   placeholder='请输入关键词'
 
-                 />
 
-               </div>
 
-               <Button
 
-                 tabIndex={0}
 
-                 className='w-full'
 
-                 onClick={handleSaveKeyword}
 
-                 disabled={!editKeyword.length}
 
-                 variant='primary'
 
-               >
 
-                 保存
 
-               </Button>
 
-             </div>
 
-           </Modal>
 
-         )
 
-       }
 
-       {showConfirmDelete && (
 
-         <Confirm
 
-           title="删除确认"
 
-           content={`请确认是否删除${delBatch ? `${keywordSelectMap.size}条关键词` : keywordRow.name}?`}
 
-           isShow={showConfirmDelete}
 
-           onConfirm={handleDelKeyword}
 
-           onCancel={() => setShowConfirmDelete(false)}
 
-         />
 
-       )}
 
-       {
 
-         showSimilarityCorpus && (
 
-           <Modal overflowVisible isShow onClose={() => { }} className="p-[24px 32px]  max-w-[800px]">
 
-             <div className='mb-2 flex justify-between'>
 
-               <div className='text-xl font-semibold text-text-primary'>训练语料配置</div>
 
-               <RiCloseLine className='h-4 w-4 cursor-pointer text-text-tertiary' onClick={() => setShowSimilarityCorpus(false)} />
 
-             </div>
 
-             <div>
 
-               <div className={cn('flex flex-wrap items-center justify-between py-4')}>
 
-                 <div className='shrink-0 py-2 text-sm font-medium leading-[20px] text-text-primary'>
 
-                   当前标注问题:{similarityRow.question}
 
-                 </div>
 
-                 <Textarea
 
-                   value={similarityRow.question_config || ''}
 
-                   className='resize-none'
 
-                   rows={30}
 
-                   disabled={true}
 
-                 />
 
-               </div>
 
-             </div>
 
-           </Modal>
 
-         )
 
-       }
 
-     </div>
 
-   )
 
- }
 
- export default DetailModal
 
 
  |