* feat: Fixed the issue where the greeting would disappear when clicking on a new dialog * feat: replace favicon with logo.svg * feat: if the backend returns 401, it will jump to the login page. * feat: unavailable llm models appear disabled * feat: display chunk token number when category of knowledge as generaltags/v0.1.0
| esbuildMinifyIIFE: true, | esbuildMinifyIIFE: true, | ||||
| icons: {}, | icons: {}, | ||||
| hash: true, | hash: true, | ||||
| favicons: ['/logo.svg'], | |||||
| history: { | history: { | ||||
| type: 'browser', | type: 'browser', | ||||
| }, | }, |
| <svg width="32" height="34" viewBox="0 0 32 34" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" clip-rule="evenodd" | |||||
| d="M3.43265 20.7677C4.15835 21.5062 4.15834 22.7035 3.43262 23.4419L3.39546 23.4797C2.66974 24.2182 1.49312 24.2182 0.767417 23.4797C0.0417107 22.7412 0.0417219 21.544 0.767442 20.8055L0.804608 20.7677C1.53033 20.0292 2.70694 20.0293 3.43265 20.7677Z" | |||||
| fill="#B2DDFF" /> | |||||
| <path fill-rule="evenodd" clip-rule="evenodd" | |||||
| d="M12.1689 21.3375C12.8933 22.0773 12.8912 23.2746 12.1641 24.0117L7.01662 29.2307C6.2896 29.9678 5.11299 29.9657 4.38859 29.2259C3.66419 28.4861 3.66632 27.2888 4.39334 26.5517L9.54085 21.3327C10.2679 20.5956 11.4445 20.5977 12.1689 21.3375Z" | |||||
| fill="#53B1FD" /> | |||||
| <path fill-rule="evenodd" clip-rule="evenodd" | |||||
| d="M19.1551 30.3217C19.7244 29.4528 20.8781 29.218 21.7321 29.7973L21.8436 29.8729C22.6975 30.4522 22.9283 31.6262 22.359 32.4952C21.7897 33.3641 20.6359 33.5989 19.782 33.0196L19.6705 32.944C18.8165 32.3647 18.5858 31.1907 19.1551 30.3217Z" | |||||
| fill="#B2DDFF" /> | |||||
| <path fill-rule="evenodd" clip-rule="evenodd" | |||||
| d="M31.4184 20.6544C32.1441 21.3929 32.1441 22.5902 31.4184 23.3286L28.8911 25.9003C28.1654 26.6388 26.9887 26.6388 26.263 25.9003C25.5373 25.1619 25.5373 23.9646 26.263 23.2261L28.7903 20.6544C29.516 19.916 30.6927 19.916 31.4184 20.6544Z" | |||||
| fill="#53B1FD" /> | |||||
| <path fill-rule="evenodd" clip-rule="evenodd" | |||||
| d="M31.4557 11.1427C32.1814 11.8812 32.1814 13.0785 31.4557 13.8169L12.7797 32.8209C12.054 33.5594 10.8774 33.5594 10.1517 32.8209C9.42599 32.0825 9.42599 30.8852 10.1517 30.1467L28.8277 11.1427C29.5534 10.4043 30.73 10.4043 31.4557 11.1427Z" | |||||
| fill="#1570EF" /> | |||||
| <path fill-rule="evenodd" clip-rule="evenodd" | |||||
| d="M27.925 5.29994C28.6508 6.0384 28.6508 7.23568 27.925 7.97414L17.184 18.9038C16.4583 19.6423 15.2817 19.6423 14.556 18.9038C13.8303 18.1653 13.8303 16.9681 14.556 16.2296L25.297 5.29994C26.0227 4.56148 27.1993 4.56148 27.925 5.29994Z" | |||||
| fill="#1570EF" /> | |||||
| <path fill-rule="evenodd" clip-rule="evenodd" | |||||
| d="M22.256 1.59299C22.9822 2.33095 22.983 3.52823 22.2578 4.26718L8.45055 18.3358C7.72533 19.0748 6.54871 19.0756 5.82251 18.3376C5.09631 17.5996 5.09552 16.4024 5.82075 15.6634L19.6279 1.59478C20.3532 0.855827 21.5298 0.855022 22.256 1.59299Z" | |||||
| fill="#1570EF" /> | |||||
| <path fill-rule="evenodd" clip-rule="evenodd" | |||||
| d="M8.58225 6.09619C9.30671 6.83592 9.30469 8.0332 8.57772 8.77038L3.17006 14.2541C2.4431 14.9913 1.26649 14.9893 0.542025 14.2495C-0.182438 13.5098 -0.180413 12.3125 0.546548 11.5753L5.95421 6.09159C6.68117 5.3544 7.85778 5.35646 8.58225 6.09619Z" | |||||
| fill="#53B1FD" /> | |||||
| <path fill-rule="evenodd" clip-rule="evenodd" | |||||
| d="M11.893 0.624023C12.9193 0.624023 13.7513 1.47063 13.7513 2.51497V2.70406C13.7513 3.7484 12.9193 4.59501 11.893 4.59501C10.8667 4.59501 10.0347 3.7484 10.0347 2.70406V2.51497C10.0347 1.47063 10.8667 0.624023 11.893 0.624023Z" | |||||
| fill="#B2DDFF" /> | |||||
| </svg> |
| options: value.map((x) => ({ | options: value.map((x) => ({ | ||||
| label: x.llm_name, | label: x.llm_name, | ||||
| value: x.llm_name, | value: x.llm_name, | ||||
| disabled: !x.available, | |||||
| })), | })), | ||||
| }; | }; | ||||
| }); | }); |
| import { | import { | ||||
| Button, | Button, | ||||
| Divider, | Divider, | ||||
| Flex, | |||||
| Form, | Form, | ||||
| Input, | Input, | ||||
| InputNumber, | |||||
| Radio, | Radio, | ||||
| Select, | Select, | ||||
| Slider, | |||||
| Space, | Space, | ||||
| Typography, | Typography, | ||||
| Upload, | Upload, | ||||
| 'permission', | 'permission', | ||||
| 'embd_id', | 'embd_id', | ||||
| 'parser_id', | 'parser_id', | ||||
| 'parser_config.chunk_token_num', | |||||
| ]), | ]), | ||||
| avatar: fileList, | avatar: fileList, | ||||
| }); | }); | ||||
| name="embd_id" | name="embd_id" | ||||
| label="Embedding Model" | label="Embedding Model" | ||||
| rules={[{ required: true }]} | rules={[{ required: true }]} | ||||
| tooltip="xx" | |||||
| > | > | ||||
| <Select | <Select | ||||
| placeholder="Please select a country" | placeholder="Please select a country" | ||||
| <Form.Item | <Form.Item | ||||
| name="parser_id" | name="parser_id" | ||||
| label="Knowledge base category" | label="Knowledge base category" | ||||
| tooltip="xx" | |||||
| rules={[{ required: true }]} | rules={[{ required: true }]} | ||||
| > | > | ||||
| <Select placeholder="Please select a country"> | <Select placeholder="Please select a country"> | ||||
| ))} | ))} | ||||
| </Select> | </Select> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item noStyle dependencies={['parser_id']}> | |||||
| {({ getFieldValue }) => { | |||||
| const parserId = getFieldValue('parser_id'); | |||||
| if (parserId === 'general') { | |||||
| return ( | |||||
| <Form.Item label="Chunk token number" tooltip="xxx"> | |||||
| <Flex gap={20} align="center"> | |||||
| <Flex flex={1}> | |||||
| <Form.Item | |||||
| name={['parser_config', 'chunk_token_num']} | |||||
| noStyle | |||||
| initialValue={128} | |||||
| rules={[ | |||||
| { required: true, message: 'Province is required' }, | |||||
| ]} | |||||
| > | |||||
| <Slider className={styles.variableSlider} max={2048} /> | |||||
| </Form.Item> | |||||
| </Flex> | |||||
| <Form.Item | |||||
| name={['parser_config', 'chunk_token_num']} | |||||
| noStyle | |||||
| initialValue={128} | |||||
| rules={[ | |||||
| { required: true, message: 'Street is required' }, | |||||
| ]} | |||||
| > | |||||
| <InputNumber | |||||
| className={styles.sliderInputNumber} | |||||
| max={2048} | |||||
| min={0} | |||||
| /> | |||||
| </Form.Item> | |||||
| </Flex> | |||||
| </Form.Item> | |||||
| ); | |||||
| } | |||||
| return null; | |||||
| }} | |||||
| </Form.Item> | |||||
| <Form.Item> | <Form.Item> | ||||
| <div className={styles.buttonWrapper}> | <div className={styles.buttonWrapper}> | ||||
| <Space> | <Space> |
| .buttonWrapper { | .buttonWrapper { | ||||
| text-align: right; | text-align: right; | ||||
| } | } | ||||
| .variableSlider { | |||||
| width: 100%; | |||||
| } | |||||
| } | } |
| import { ReactComponent as ChatConfigurationAtom } from '@/assets/svg/chat-configuration-atom.svg'; | import { ReactComponent as ChatConfigurationAtom } from '@/assets/svg/chat-configuration-atom.svg'; | ||||
| import { IModalManagerChildrenProps } from '@/components/modal-manager'; | import { IModalManagerChildrenProps } from '@/components/modal-manager'; | ||||
| import { IDialog } from '@/interfaces/database/chat'; | |||||
| import { Divider, Flex, Form, Modal, Segmented, UploadFile } from 'antd'; | import { Divider, Flex, Form, Modal, Segmented, UploadFile } from 'antd'; | ||||
| import { SegmentedValue } from 'antd/es/segmented'; | import { SegmentedValue } from 'antd/es/segmented'; | ||||
| import omit from 'lodash/omit'; | import omit from 'lodash/omit'; | ||||
| import { useEffect, useRef, useState } from 'react'; | import { useEffect, useRef, useState } from 'react'; | ||||
| import AssistantSetting from './assistant-setting'; | |||||
| import ModelSetting from './model-setting'; | |||||
| import PromptEngine from './prompt-engine'; | |||||
| import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks'; | |||||
| import { variableEnabledFieldMap } from '../constants'; | import { variableEnabledFieldMap } from '../constants'; | ||||
| import { useFetchDialog, useResetCurrentDialog, useSetDialog } from '../hooks'; | |||||
| import { IPromptConfigParameters } from '../interface'; | import { IPromptConfigParameters } from '../interface'; | ||||
| import { excludeUnEnabledVariables } from '../utils'; | import { excludeUnEnabledVariables } from '../utils'; | ||||
| import AssistantSetting from './assistant-setting'; | |||||
| import { useFetchModelId } from './hooks'; | import { useFetchModelId } from './hooks'; | ||||
| import ModelSetting from './model-setting'; | |||||
| import PromptEngine from './prompt-engine'; | |||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| enum ConfigurationSegmented { | enum ConfigurationSegmented { | ||||
| }; | }; | ||||
| interface IProps extends IModalManagerChildrenProps { | interface IProps extends IModalManagerChildrenProps { | ||||
| id: string; | |||||
| initialDialog: IDialog; | |||||
| loading: boolean; | |||||
| onOk: (dialog: IDialog) => void; | |||||
| clearDialog: () => void; | |||||
| } | } | ||||
| const ChatConfigurationModal = ({ visible, hideModal, id }: IProps) => { | |||||
| const ChatConfigurationModal = ({ | |||||
| visible, | |||||
| hideModal, | |||||
| initialDialog, | |||||
| loading, | |||||
| onOk, | |||||
| clearDialog, | |||||
| }: IProps) => { | |||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const [value, setValue] = useState<ConfigurationSegmented>( | const [value, setValue] = useState<ConfigurationSegmented>( | ||||
| ConfigurationSegmented.AssistantSetting, | ConfigurationSegmented.AssistantSetting, | ||||
| ); | ); | ||||
| const promptEngineRef = useRef<Array<IPromptConfigParameters>>([]); | const promptEngineRef = useRef<Array<IPromptConfigParameters>>([]); | ||||
| const loading = useOneNamespaceEffectsLoading('chatModel', ['setDialog']); | |||||
| const modelId = useFetchModelId(visible); | const modelId = useFetchModelId(visible); | ||||
| const setDialog = useSetDialog(); | |||||
| const currentDialog = useFetchDialog(id, visible); | |||||
| const { resetCurrentDialog } = useResetCurrentDialog(); | |||||
| const handleOk = async () => { | const handleOk = async () => { | ||||
| const values = await form.validateFields(); | const values = await form.validateFields(); | ||||
| const nextValues: any = omit(values, [ | const nextValues: any = omit(values, [ | ||||
| } | } | ||||
| const finalValues = { | const finalValues = { | ||||
| dialog_id: id, | |||||
| dialog_id: initialDialog.id, | |||||
| ...nextValues, | ...nextValues, | ||||
| prompt_config: { | prompt_config: { | ||||
| ...nextValues.prompt_config, | ...nextValues.prompt_config, | ||||
| }, | }, | ||||
| icon, | icon, | ||||
| }; | }; | ||||
| console.info(promptEngineRef.current); | |||||
| console.info(nextValues); | |||||
| console.info(finalValues); | |||||
| const retcode: number = await setDialog(finalValues); | |||||
| if (retcode === 0) { | |||||
| hideModal(); | |||||
| } | |||||
| onOk(finalValues); | |||||
| }; | }; | ||||
| const handleCancel = () => { | const handleCancel = () => { | ||||
| }; | }; | ||||
| const handleModalAfterClose = () => { | const handleModalAfterClose = () => { | ||||
| resetCurrentDialog(); | |||||
| clearDialog(); | |||||
| form.resetFields(); | form.resetFields(); | ||||
| }; | }; | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (visible) { | if (visible) { | ||||
| const icon = currentDialog.icon; | |||||
| const icon = initialDialog.icon; | |||||
| let fileList: UploadFile[] = []; | let fileList: UploadFile[] = []; | ||||
| if (icon) { | if (icon) { | ||||
| fileList = [{ uid: '1', name: 'file', thumbUrl: icon, status: 'done' }]; | fileList = [{ uid: '1', name: 'file', thumbUrl: icon, status: 'done' }]; | ||||
| } | } | ||||
| form.setFieldsValue({ | form.setFieldsValue({ | ||||
| ...currentDialog, | |||||
| ...initialDialog, | |||||
| icon: fileList, | icon: fileList, | ||||
| llm_id: currentDialog.llm_id ?? modelId, | |||||
| llm_id: initialDialog.llm_id ?? modelId, | |||||
| }); | }); | ||||
| } | } | ||||
| }, [currentDialog, form, visible, modelId]); | |||||
| }, [initialDialog, form, visible, modelId]); | |||||
| return ( | return ( | ||||
| <Modal | <Modal |
| name="llm_id" | name="llm_id" | ||||
| rules={[{ required: true, message: 'Please select!' }]} | rules={[{ required: true, message: 'Please select!' }]} | ||||
| > | > | ||||
| <Select options={modelOptions} /> | |||||
| <Select options={modelOptions} showSearch /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <Divider></Divider> | <Divider></Divider> | ||||
| <Form.Item | <Form.Item |
| return setDialog; | return setDialog; | ||||
| }; | }; | ||||
| export const useFetchDialog = (dialogId: string, visible: boolean): IDialog => { | |||||
| const dispatch = useDispatch(); | |||||
| export const useSelectCurrentDialog = () => { | |||||
| const currentDialog: IDialog = useSelector( | const currentDialog: IDialog = useSelector( | ||||
| (state: any) => state.chatModel.currentDialog, | (state: any) => state.chatModel.currentDialog, | ||||
| ); | ); | ||||
| const fetchDialog = useCallback(() => { | |||||
| if (dialogId) { | |||||
| dispatch({ | |||||
| type: 'chatModel/getDialog', | |||||
| payload: { dialog_id: dialogId }, | |||||
| }); | |||||
| } | |||||
| }, [dispatch, dialogId]); | |||||
| return currentDialog; | |||||
| }; | |||||
| export const useFetchDialog = () => { | |||||
| const dispatch = useDispatch(); | |||||
| const fetchDialog = useCallback( | |||||
| (dialogId: string, needToBeSaved = true) => { | |||||
| if (dialogId) { | |||||
| return dispatch<any>({ | |||||
| type: 'chatModel/getDialog', | |||||
| payload: { dialog_id: dialogId, needToBeSaved }, | |||||
| }); | |||||
| } | |||||
| }, | |||||
| [dispatch], | |||||
| ); | |||||
| return fetchDialog; | |||||
| }; | |||||
| export const useFetchDialogOnMount = ( | |||||
| dialogId: string, | |||||
| visible: boolean, | |||||
| ): IDialog => { | |||||
| const currentDialog: IDialog = useSelectCurrentDialog(); | |||||
| const fetchDialog = useFetchDialog(); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if (dialogId && visible) { | if (dialogId && visible) { | ||||
| fetchDialog(); | |||||
| fetchDialog(dialogId); | |||||
| } | } | ||||
| }, [dialogId, fetchDialog, visible]); | }, [dialogId, fetchDialog, visible]); | ||||
| return finalParameters; | return finalParameters; | ||||
| }; | }; | ||||
| export const useSelectCurrentDialog = () => { | |||||
| const currentDialog: IDialog = useSelector( | |||||
| (state: any) => state.chatModel.currentDialog, | |||||
| ); | |||||
| return currentDialog; | |||||
| }; | |||||
| export const useRemoveDialog = () => { | export const useRemoveDialog = () => { | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| }; | }; | ||||
| }; | }; | ||||
| export const useEditDialog = () => { | |||||
| const [dialog, setDialog] = useState<IDialog>({} as IDialog); | |||||
| const fetchDialog = useFetchDialog(); | |||||
| const submitDialog = useSetDialog(); | |||||
| const loading = useOneNamespaceEffectsLoading('chatModel', ['setDialog']); | |||||
| const { | |||||
| visible: dialogEditVisible, | |||||
| hideModal: hideDialogEditModal, | |||||
| showModal: showDialogEditModal, | |||||
| } = useSetModalState(); | |||||
| const onDialogEditOk = useCallback( | |||||
| async (dialog: IDialog) => { | |||||
| const ret = await submitDialog(dialog); | |||||
| if (ret === 0) { | |||||
| hideDialogEditModal(); | |||||
| } | |||||
| }, | |||||
| [submitDialog, hideDialogEditModal], | |||||
| ); | |||||
| const handleShowDialogEditModal = useCallback( | |||||
| async (dialogId?: string) => { | |||||
| if (dialogId) { | |||||
| const ret = await fetchDialog(dialogId, false); | |||||
| if (ret.retcode === 0) { | |||||
| setDialog(ret.data); | |||||
| } | |||||
| } | |||||
| showDialogEditModal(); | |||||
| }, | |||||
| [showDialogEditModal, fetchDialog], | |||||
| ); | |||||
| const clearDialog = useCallback(() => { | |||||
| setDialog({} as IDialog); | |||||
| }, []); | |||||
| return { | |||||
| dialogSettingLoading: loading, | |||||
| initialDialog: dialog, | |||||
| onDialogEditOk, | |||||
| dialogEditVisible, | |||||
| hideDialogEditModal, | |||||
| showDialogEditModal: handleShowDialogEditModal, | |||||
| clearDialog, | |||||
| }; | |||||
| }; | |||||
| //#region conversation | //#region conversation | ||||
| export const useFetchConversationList = () => { | export const useFetchConversationList = () => { |
| import { | import { | ||||
| useClickConversationCard, | useClickConversationCard, | ||||
| useClickDialogCard, | useClickDialogCard, | ||||
| useEditDialog, | |||||
| useFetchConversationList, | useFetchConversationList, | ||||
| useFetchDialog, | |||||
| useFetchDialogOnMount, | |||||
| useGetChatSearchParams, | useGetChatSearchParams, | ||||
| useHandleItemHover, | useHandleItemHover, | ||||
| useRemoveConversation, | useRemoveConversation, | ||||
| hideConversationRenameModal, | hideConversationRenameModal, | ||||
| showConversationRenameModal, | showConversationRenameModal, | ||||
| } = useRenameConversation(); | } = useRenameConversation(); | ||||
| const { | |||||
| dialogSettingLoading, | |||||
| initialDialog, | |||||
| onDialogEditOk, | |||||
| dialogEditVisible, | |||||
| clearDialog, | |||||
| hideDialogEditModal, | |||||
| showDialogEditModal, | |||||
| } = useEditDialog(); | |||||
| useFetchDialog(dialogId, true); | |||||
| useFetchDialogOnMount(dialogId, true); | |||||
| const handleAppCardEnter = (id: string) => () => { | const handleAppCardEnter = (id: string) => () => { | ||||
| handleItemEnter(id); | handleItemEnter(id); | ||||
| (info: any) => { | (info: any) => { | ||||
| info?.domEvent?.preventDefault(); | info?.domEvent?.preventDefault(); | ||||
| info?.domEvent?.stopPropagation(); | info?.domEvent?.stopPropagation(); | ||||
| // if (dialogId) { | |||||
| setCurrentDialog(dialogId ?? ''); | |||||
| // } | |||||
| showModal(); | |||||
| showDialogEditModal(dialogId); | |||||
| }; | }; | ||||
| const handleRemoveDialog = | const handleRemoveDialog = | ||||
| <Divider type={'vertical'} className={styles.divider}></Divider> | <Divider type={'vertical'} className={styles.divider}></Divider> | ||||
| <ChatContainer></ChatContainer> | <ChatContainer></ChatContainer> | ||||
| <ChatConfigurationModal | <ChatConfigurationModal | ||||
| visible={visible} | |||||
| showModal={showModal} | |||||
| hideModal={hideModal} | |||||
| id={currentDialog.id} | |||||
| visible={dialogEditVisible} | |||||
| initialDialog={initialDialog} | |||||
| showModal={showDialogEditModal} | |||||
| hideModal={hideDialogEditModal} | |||||
| loading={dialogSettingLoading} | |||||
| onOk={onDialogEditOk} | |||||
| clearDialog={clearDialog} | |||||
| ></ChatConfigurationModal> | ></ChatConfigurationModal> | ||||
| <RenameModal | <RenameModal | ||||
| visible={conversationRenameVisible} | visible={conversationRenameVisible} |
| effects: { | effects: { | ||||
| *getDialog({ payload }, { call, put }) { | *getDialog({ payload }, { call, put }) { | ||||
| const { data } = yield call(chatService.getDialog, payload); | |||||
| if (data.retcode === 0) { | |||||
| const needToBeSaved = | |||||
| payload.needToBeSaved === undefined ? true : payload.needToBeSaved; | |||||
| const { data } = yield call(chatService.getDialog, { | |||||
| dialog_id: payload.dialog_id, | |||||
| }); | |||||
| if (data.retcode === 0 && needToBeSaved) { | |||||
| yield put({ type: 'setCurrentDialog', payload: data.data }); | yield put({ type: 'setCurrentDialog', payload: data.data }); | ||||
| } | } | ||||
| return data; | |||||
| }, | }, | ||||
| *setDialog({ payload }, { call, put }) { | *setDialog({ payload }, { call, put }) { | ||||
| const { data } = yield call(chatService.setDialog, payload); | const { data } = yield call(chatService.setDialog, payload); | ||||
| if (data.retcode === 0) { | if (data.retcode === 0) { | ||||
| yield put({ type: 'listDialog' }); | yield put({ type: 'listDialog' }); | ||||
| message.success('Created successfully !'); | |||||
| message.success(payload.dialog_id ? 'Modified!' : 'Created!'); | |||||
| } | } | ||||
| return data.retcode; | return data.retcode; | ||||
| }, | }, |
| import { createBrowserHistory } from 'history'; | |||||
| export const history = createBrowserHistory(); |
| import { message, notification } from 'antd'; | |||||
| import { RequestMethod, extend } from 'umi-request'; | |||||
| import { Authorization } from '@/constants/authorization'; | import { Authorization } from '@/constants/authorization'; | ||||
| import api from '@/utils/api'; | |||||
| import authorizationUtil from '@/utils/authorizationUtil'; | import authorizationUtil from '@/utils/authorizationUtil'; | ||||
| const { login } = api; | |||||
| import { message, notification } from 'antd'; | |||||
| import { history } from 'umi'; | |||||
| import { RequestMethod, extend } from 'umi-request'; | |||||
| const ABORT_REQUEST_ERR_MESSAGE = 'The user aborted a request.'; // 手动中断请求。errorHandler 抛出的error message | const ABORT_REQUEST_ERR_MESSAGE = 'The user aborted a request.'; // 手动中断请求。errorHandler 抛出的error message | ||||
| duration: 3, | duration: 3, | ||||
| }); | }); | ||||
| authorizationUtil.removeAll(); | authorizationUtil.removeAll(); | ||||
| // history.push('/login'); // Will not jump to the login page | |||||
| history.push('/login'); // Will not jump to the login page | |||||
| } else if (data.retcode !== 0) { | } else if (data.retcode !== 0) { | ||||
| if (data.retcode === 100) { | if (data.retcode === 100) { | ||||
| message.error(data.retmsg); | message.error(data.retmsg); |