123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- import { apiInterceptors, cancelFeedback, feedbackAdd, getFeedbackReasons, stopTopic } from '@/client/api';
- import { IChatDialogueMessageSchema } from '@/types/chat';
- import { CopyOutlined, DislikeOutlined, LikeOutlined } from '@ant-design/icons';
- import { useRequest } from 'ahooks';
- import { App, Button, Divider } from 'antd';
- import classNames from 'classnames';
- import copy from 'copy-to-clipboard';
- import React, { useContext, useState } from 'react';
- import { MobileChatContext } from '..';
- import DislikeDrawer from './DislikeDrawer';
- interface Tags {
- reason: string;
- reason_type: string;
- }
- const Feedback: React.FC<{
- content: IChatDialogueMessageSchema;
- index: number;
- chatDialogRef: React.RefObject<HTMLDivElement>;
- }> = ({ content, index, chatDialogRef }) => {
- const { conv_uid, history, scene } = useContext(MobileChatContext);
- const { message } = App.useApp();
- const [feedbackOpen, setFeedbackOpen] = useState<boolean>(false);
- const [status, setStatus] = useState<'like' | 'unlike' | 'none'>(content?.feedback?.feedback_type);
- const [list, setList] = useState<Tags[]>([]);
- // 复制回答
- const onCopyContext = async (context: any) => {
- const pureStr = context?.replace(/\trelations:.*/g, '');
- const result = copy(chatDialogRef.current?.textContent || pureStr);
- if (result) {
- if (pureStr) {
- message.success('复制成功');
- } else {
- message.warning('内容复制为空');
- }
- } else {
- message.error('复制失败');
- }
- };
- // 点赞 or 踩
- const { run: feedback, loading } = useRequest(
- async (params: { feedback_type: string; reason_types?: string[]; remark?: string }) =>
- await apiInterceptors(
- feedbackAdd({
- conv_uid: conv_uid,
- message_id: content.order + '',
- feedback_type: params.feedback_type,
- reason_types: params.reason_types,
- remark: params.remark,
- }),
- ),
- {
- manual: true,
- onSuccess: data => {
- const [, res] = data;
- setStatus(res?.feedback_type);
- message.success('反馈成功');
- setFeedbackOpen(false);
- },
- },
- );
- // 取消反馈
- const { run: cancel } = useRequest(
- async () => await apiInterceptors(cancelFeedback({ conv_uid: conv_uid, message_id: content?.order + '' })),
- {
- manual: true,
- onSuccess: data => {
- const [, res] = data;
- if (res) {
- setStatus('none');
- message.success('操作成功');
- }
- },
- },
- );
- // 反馈原因类型
- const { run: getReasonList } = useRequest(async () => await apiInterceptors(getFeedbackReasons()), {
- manual: true,
- onSuccess: data => {
- const [, res] = data;
- setList(res || []);
- if (res) {
- setFeedbackOpen(true);
- }
- },
- });
- // 终止话题
- const { run: stopTopicRun, loading: stopTopicLoading } = useRequest(
- async () => await apiInterceptors(stopTopic({ conv_id: conv_uid, round_index: 0 })),
- {
- manual: true,
- onSuccess: () => {
- message.success('操作成功');
- },
- },
- );
- return (
- <div className='flex items-center text-sm'>
- <div className='flex gap-3'>
- <LikeOutlined
- className={classNames('cursor-pointer', {
- 'text-[#0C75FC]': status === 'like',
- })}
- onClick={async () => {
- if (status === 'like') {
- await cancel();
- return;
- }
- await feedback({ feedback_type: 'like' });
- }}
- />
- <DislikeOutlined
- className={classNames('cursor-pointer', {
- 'text-[#0C75FC]': status === 'unlike',
- })}
- onClick={async () => {
- if (status === 'unlike') {
- await cancel();
- return;
- }
- await getReasonList();
- }}
- />
- <DislikeDrawer
- open={feedbackOpen}
- setFeedbackOpen={setFeedbackOpen}
- list={list}
- feedback={feedback}
- loading={loading}
- />
- </div>
- <Divider type='vertical' />
- <div className='flex items-center gap-3'>
- <CopyOutlined className='cursor-pointer' onClick={() => onCopyContext(content.context)} />
- {history.length - 1 === index && scene === 'chat_agent' && (
- <Button
- loading={stopTopicLoading}
- size='small'
- onClick={async () => {
- await stopTopicRun();
- }}
- className='text-xs'
- >
- 终止话题
- </Button>
- )}
- </div>
- </div>
- );
- };
- export default Feedback;
|