123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- 'use client'
- import React, { useCallback, useState } from 'react'
- import { RiCloseLine } from '@remixicon/react'
- import Modal from '@/app/components/base/modal'
- import Button from '@/app/components/base/button'
- import { delCorpusQuestion, fetchIntent, fetchIntentType } 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 { v4 as uuid4 } from 'uuid'
- 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'
- const DetailModal = ({
- transfer,
- onCancel,
- onSend,
- }: any) => {
- const { notify } = useContext(ToastContext)
- const [questionRelation, setQuestionRelation] = useState<string>('')
- const [questionFilter, setQuestionFilter] = useState<string>('') // the input value
- const [question, setQuestion] = useState<string>(transfer.row?.question || '') // the input value
- const [intentType, setIntentType] = useState<string>(transfer.row?.intentType || '') // the input value
- const { data: dataOptionsIntentType }: any = useSWR(
- {
- url: '/xxx',
- params: {
- page: 1,
- limit: 1000,
- },
- },
- fetchIntentType,
- )
- const optionsIntentType: any = dataOptionsIntentType?.data.map((v: any) => ({ name: v.name, value: v.id })) || []
- const [intentName, setIntentName] = useState<string>(transfer.row?.intentName || '') // the input value
- const { data: dataOptionsIntentName }: any = useSWR(
- {
- url: '/xxx',
- params: {
- page: 1,
- limit: 1000,
- intentType,
- },
- },
- fetchIntent,
- )
- const optionsIntentName: any = dataOptionsIntentName?.data.map((v: any) => ({ name: v.name, value: v.id })) || []
- const [questionList, setQuestionList] = useState<any>([{ id: uuid4(), name: '啊啊啊啊啊啊啊啊啊啊' }, { id: uuid4(), name: '啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊' }])
- const handleAddQuestion = () => {
- if (!questionRelation)
- return
- if (questionList.some((v: any) => v.name === questionRelation)) {
- notify({ type: 'warning', message: '请勿新增重复数据!' })
- return
- }
- setQuestionList([...questionList, { id: uuid4(), name: questionRelation }])
- setQuestionRelation('')
- }
- const [questionSelectMap, setQuestionSelectMap] = useState<any>(new Map())
- const addQuestionSelectMap = (key: any, value: any) => {
- setQuestionSelectMap((prevMap: any) => {
- const newMap = new Map(prevMap)
- newMap.set(key, value)
- return newMap
- })
- }
- const delQuestionSelectMap = (key: any) => {
- setQuestionSelectMap((prevMap: any) => {
- const newMap = new Map(prevMap)
- newMap.delete(key)
- return newMap
- })
- }
- const [showConfirmDelete, setShowConfirmDelete] = useState(false)
- const [row, setRow] = useState<any>({})
- const handleDelQuestion = async () => {
- try {
- await delCorpusQuestion({
- url: `/xxx/${row.id}`,
- body: {},
- })
- setShowConfirmDelete(false)
- // mutate()
- }
- catch (e) { }
- }
- const [showQuestionEdit, setShowQuestionEdit] = useState(false)
- const [editQuestion, setEditQuestion] = useState<string>('')
- const [corpusRow, setCorpusRow] = useState<any>({})
- const [corpusRowConfig, setCorpusRowConfig] = useState<string>('')
- const handleSave = useCallback(async () => {
- // try {
- // let res
- // if (transfer.mode === 'add') {
- // res = await addCorpus({
- // url: '/xxx',
- // body: { name, type: 'knowledge_category' },
- // })
- // }
- // else {
- // res = await editCorpus({
- // url: '/xxx',
- // body: { name },
- // })
- // }
- // const { id }: any = res
- // if (id) {
- // onCancel()
- // onSend()
- // }
- // }
- // catch (e) { }
- }, [name, onCancel, onSend, transfer])
- const handleSaveQuestion = useCallback(async () => {
- // try {
- // let res
- // if (transfer.mode === 'add') {
- // res = await addCorpus({
- // url: '/xxx',
- // body: { name, type: 'knowledge_category' },
- // })
- // }
- // else {
- // res = await editCorpus({
- // url: '/xxx',
- // body: { name },
- // })
- // }
- // const { id }: any = res
- // if (id) {
- // onCancel()
- // onSend()
- // }
- // }
- // catch (e) { }
- }, [name, onCancel, onSend, transfer])
- 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)
- setIntentName('')
- }}
- 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={question}
- onChange={e => setQuestion(e.target.value)}
- onClear={() => setQuestion('')}
- />
- </div>
- </div>
- {
- transfer.mode === 'edit' && (
- <div className="flex w-full items-center">
- <div className="w-[80px]">关键词</div>
- <div className="flex-1">
- <Input
- showClearIcon
- value={questionRelation}
- onChange={e => setQuestionRelation(e.target.value)}
- onClear={() => setQuestionRelation('')}
- placeholder='输入后Enter以添加'
- onEnter={handleAddQuestion}
- />
- </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={questionList.every((v: any) => questionSelectMap.has(v.id))}
- onCheck={() => {
- questionList.every((v: any) => questionSelectMap.has(v.id))
- ? setQuestionSelectMap(new Map())
- : questionList.forEach((v: any) => addQuestionSelectMap(v.id, v))
- }}
- disabled={questionList.length === 0}
- />
- 全选
- </div>
- <div className="ml-auto w-[200px]">
- <Input
- showClearIcon
- value={questionFilter}
- onChange={e => setQuestionFilter(e.target.value)}
- onClear={() => setQuestionFilter('')}
- placeholder='请输入相似问题名称进行过滤'
- />
- </div>
- <Button variant='primary' className={cn('shrink-0')}>
- 批量删除
- </Button>
- </div>
- <div className="flex h-[150px] flex-col gap-2 overflow-y-auto border-2 border-solid border-[#F6F8FC] p-2">
- {
- questionList.filter((v: any) => !questionFilter || v.name.includes(questionFilter)).map((item: any) => (
- <div key={item.id} className="flex items-center">
- <Checkbox
- className='mr-2 shrink-0'
- checked={questionSelectMap.has(item.id)}
- onCheck={() => {
- questionSelectMap.has(item.id)
- ? delQuestionSelectMap(item.id)
- : addQuestionSelectMap(item.id, item)
- }}
- disabled={questionList.length === 0}
- />
- <div className="flex-1">
- {item.name}
- </div>
- <Button variant='ghost-accent' size='small' className={cn('shrink-0')}
- onClick={() => {
- setRow(item)
- setEditQuestion(item.name)
- setShowQuestionEdit(true)
- }}>
- 编辑
- </Button>
- <Button variant='ghost' size='small' className={cn('shrink-0 text-red-600')}
- onClick={() => {
- setRow(item)
- setShowConfirmDelete(true)
- }}>
- 刪除
- </Button>
- </div>
- ))
- }
- </div>
- <div className="flex border-2 border-t-0 border-solid border-[#F6F8FC] p-2 text-xs">
- <div>共{questionList.length}条</div>
- <div className="ml-4">已选择{questionSelectMap.size}条</div>
- </div>
- </div>
- )
- }
- <Button
- tabIndex={0}
- className='w-full'
- onClick={handleSave}
- disabled={!question.length || !intentType.length || !intentName.length}
- variant='primary'
- >
- 保存
- </Button>
- </div>
- </Modal>
- {
- showQuestionEdit && (
- <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={() => setShowQuestionEdit(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={editQuestion}
- onChange={e => setEditQuestion(e.target.value)}
- className='h-9'
- placeholder='请输入关键词'
- />
- </div>
- <Button
- tabIndex={0}
- className='w-full'
- onClick={handleSaveQuestion}
- disabled={!editQuestion.length}
- variant='primary'
- >
- 保存
- </Button>
- </div>
- </Modal>
- )
- }
- {showConfirmDelete && (
- <Confirm
- title="删除确认"
- content={`请确认是否删除${row.name}?`}
- isShow={showConfirmDelete}
- onConfirm={handleDelQuestion}
- onCancel={() => setShowConfirmDelete(false)}
- />
- )}
- </div>
- )
- }
- export default DetailModal
|