-
}
- type="primary"
- style={{ right: 24, top: 100 }}
- />
-
- {data.map((item: any) => {
- return (
-
- {
- handleEditKnowledge(item.id);
- }}
- >
-
-
-
{item.name}
-
- {
- e.stopPropagation();
- e.nativeEvent.stopImmediatePropagation();
- confirm(item.id);
- }}
- okText="Yes"
- cancelText="No"
- >
- {
- e.stopPropagation();
- e.nativeEvent.stopImmediatePropagation();
- }}
- />
-
-
-
-
-
-
- {item.doc_num}文档
-
-
-
- {item.chunk_num}个
-
-
-
- {item.token_num}千字符
-
-
- {formatDate(item.update_date)}
-
-
-
-
-
- );
- })}
-
+
+
+
+
Welcome back, Zing
+
+ Which database are we going to use today?
+
+
+
+ } className={styles.filterButton}>
+ Filters
+
+ }
+ onClick={handleAddKnowledge}
+ className={styles.topButton}
+ >
+ Create knowledge base
+
+
- >
+
+ {data.map((item: any) => {
+ return (
+
+
+
+ );
+ })}
+
+
);
};
diff --git a/web/src/pages/knowledge/knowledge-card/index.less b/web/src/pages/knowledge/knowledge-card/index.less
new file mode 100644
index 000000000..17b6bb642
--- /dev/null
+++ b/web/src/pages/knowledge/knowledge-card/index.less
@@ -0,0 +1,73 @@
+.container {
+ height: 251px;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+
+ .content {
+ display: flex;
+ justify-content: space-between;
+
+ .context {
+ flex: 1;
+ }
+ }
+
+ .footer {
+ // text-align: left;
+ }
+ .footerTop {
+ padding-bottom: 2px;
+ }
+}
+
+.card {
+ border-radius: 12px;
+ border: 1px solid rgba(234, 236, 240, 1);
+ box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.05);
+ padding: 24px;
+ min-width: 300px;
+ cursor: pointer;
+
+ .titleWrapper {
+ // flex: 1;
+ .title {
+ font-size: 24px;
+ line-height: 32px;
+ font-weight: 600;
+ color: rgba(0, 0, 0, 0.88);
+ }
+ .description {
+ font-size: 12px;
+ font-weight: 600;
+ line-height: 20px;
+ color: rgba(0, 0, 0, 0.45);
+ }
+ }
+
+ :global {
+ .ant-card-body {
+ padding: 0;
+ margin: 0;
+ }
+ }
+ .bottom {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+ .bottomLeft {
+ vertical-align: middle;
+ }
+ .leftIcon {
+ margin-right: 10px;
+ font-size: 18px;
+ vertical-align: middle;
+ }
+ .rightText {
+ font-size: 12px;
+ font-weight: 600;
+ color: rgba(0, 0, 0, 0.65);
+ vertical-align: middle;
+ }
+}
diff --git a/web/src/pages/knowledge/knowledge-card/index.tsx b/web/src/pages/knowledge/knowledge-card/index.tsx
new file mode 100644
index 000000000..2536641c0
--- /dev/null
+++ b/web/src/pages/knowledge/knowledge-card/index.tsx
@@ -0,0 +1,123 @@
+import { ReactComponent as MoreIcon } from '@/assets/svg/more.svg';
+import { formatDate } from '@/utils/date';
+import {
+ AntDesignOutlined,
+ CalendarOutlined,
+ DeleteOutlined,
+ FileTextOutlined,
+ UserOutlined,
+} from '@ant-design/icons';
+import { Avatar, Card, Dropdown, MenuProps, Space, Tooltip } from 'antd';
+import { MouseEvent } from 'react';
+import { useDispatch, useNavigate } from 'umi';
+
+import styles from './index.less';
+
+interface IProps {
+ item: any;
+}
+
+const KnowledgeCard = ({ item }: IProps) => {
+ const navigate = useNavigate();
+ const dispatch = useDispatch();
+
+ const handleDelete = (e: MouseEvent
) => {
+ e.stopPropagation();
+ };
+
+ const items: MenuProps['items'] = [
+ {
+ key: '1',
+ label: (
+
+ 删除
+
+
+ ),
+ },
+ ];
+
+ const confirm = (id: string) => {
+ dispatch({
+ type: 'knowledgeModel/rmKb',
+ payload: {
+ kb_id: id,
+ },
+ });
+ };
+
+ const handleCardClick = () => {
+ navigate(`add/setting?activeKey=file&id=${item.id}`);
+ };
+
+ const onConfirmDelete = (e?: MouseEvent) => {
+ e?.stopPropagation();
+ e?.nativeEvent.stopImmediatePropagation();
+ confirm(item.id);
+ };
+
+ return (
+
+
+
+
} />
+
+
+ {/*
+
+ */}
+
+
+
+
+
+
+
{item.name}
+
A comprehensive knowledge base for crafting effective resumes.
+
+
+
+
+
+
+ {item.doc_num}文档
+
+
+
+
+
+
+
+ {formatDate(item.update_date)}
+
+
+
+
+
+ K
+
+
+ }
+ />
+
+ }
+ />
+
+
+
+
+
+ );
+};
+
+export default KnowledgeCard;
diff --git a/web/src/pages/knowledge/model.ts b/web/src/pages/knowledge/model.ts
index 0621f763a..51ab284bc 100644
--- a/web/src/pages/knowledge/model.ts
+++ b/web/src/pages/knowledge/model.ts
@@ -19,7 +19,7 @@ const model: DvaModel = {
},
},
effects: {
- *rmKb({ payload = {}, callback }, { call, put }) {
+ *rmKb({ payload = {} }, { call, put }) {
const { data } = yield call(kbService.rmKb, payload);
const { retcode } = data;
if (retcode === 0) {
diff --git a/web/src/pages/login/index.tsx b/web/src/pages/login/index.tsx
index a0696b361..3493673b2 100644
--- a/web/src/pages/login/index.tsx
+++ b/web/src/pages/login/index.tsx
@@ -12,6 +12,8 @@ const Login = () => {
(state) => state.loading.effects,
);
+ // TODO: When the server address request is not accessible, the value of dva-loading always remains true.
+
const signLoading =
effectsLoading['loginModel/login'] || effectsLoading['loginModel/register'];
diff --git a/web/src/pages/login/model.ts b/web/src/pages/login/model.ts
index 257879f6d..0c2dd4abd 100644
--- a/web/src/pages/login/model.ts
+++ b/web/src/pages/login/model.ts
@@ -32,10 +32,8 @@ const model: DvaModel = {
},
effects: {
*login({ payload = {} }, { call, put }) {
- console.log(111, payload);
const { data, response } = yield call(userService.login, payload);
- const { retcode, data: res, retmsg } = data;
- console.log();
+ const { retcode, data: res } = data;
const authorization = response.headers.get(Authorization);
if (retcode === 0) {
message.success('登录成功!');
diff --git a/web/src/pages/setting/CPwModal.tsx b/web/src/pages/setting/CPwModal.tsx
index 031d611c7..c9713709d 100644
--- a/web/src/pages/setting/CPwModal.tsx
+++ b/web/src/pages/setting/CPwModal.tsx
@@ -1,92 +1,78 @@
-import { connect, Dispatch } from 'umi';
-import i18n from 'i18next';
-import { useTranslation, Trans } from 'react-i18next'
-import { Input, Modal, Form } from 'antd'
-import { rsaPsw } from '@/utils'
-import styles from './index.less';
-import { FC } from 'react';
+import { rsaPsw } from '@/utils';
+import { Form, Input, Modal } from 'antd';
+import { useTranslation } from 'react-i18next';
+import { useDispatch, useSelector } from 'umi';
type FieldType = {
- newPassword?: string;
- password?: string;
+ newPassword?: string;
+ password?: string;
};
-interface CPwModalProps {
- dispatch: Dispatch;
- settingModel: any
-}
-const Index: FC = ({ settingModel, dispatch }) => {
- const { isShowPSwModal } = settingModel
- const { t } = useTranslation()
- const handleCancel = () => {
- dispatch({
- type: 'settingModel/updateState',
- payload: {
- isShowPSwModal: false
- }
- });
- };
- const [form] = Form.useForm()
- const handleOk = async () => {
- try {
- const values = await form.validateFields();
- var password = rsaPsw(values.password)
- var new_password = rsaPsw(values.newPassword)
- dispatch({
- type: 'settingModel/setting',
- payload: {
- password,
- new_password
- },
- callback: () => {
- dispatch({
- type: 'settingModel/updateState',
- payload: {
- isShowPSwModal: false
- }
- });
- dispatch({
- type: 'settingModel/getUserInfo',
- payload: {
+const CpwModal = () => {
+ const dispatch = useDispatch();
+ const settingModel = useSelector((state: any) => state.settingModel);
+ const { isShowPSwModal } = settingModel;
+ const { t } = useTranslation();
+ const [form] = Form.useForm();
- }
- });
- }
- });
+ const handleCancel = () => {
+ dispatch({
+ type: 'settingModel/updateState',
+ payload: {
+ isShowPSwModal: false,
+ },
+ });
+ };
+ const handleOk = async () => {
+ try {
+ const values = await form.validateFields();
+ var password = rsaPsw(values.password);
+ var new_password = rsaPsw(values.newPassword);
- } catch (errorInfo) {
- console.log('Failed:', errorInfo);
- }
- };
+ dispatch({
+ type: 'settingModel/setting',
+ payload: {
+ password,
+ new_password,
+ },
+ });
+ } catch (errorInfo) {
+ console.log('Failed:', errorInfo);
+ }
+ };
- return (
-
-
- label="旧密码"
- name="password"
- rules={[{ required: true, message: 'Please input value' }]}
- >
-
-
-
- label="新密码"
- name="newPassword"
- rules={[{ required: true, message: 'Please input your newPassword!' }]}
- >
-
-
-
-
-
-
-
- );
-}
-export default connect(({ settingModel, loading }) => ({ settingModel, loading }))(Index);
+ return (
+
+
+ label="旧密码"
+ name="password"
+ rules={[{ required: true, message: 'Please input value' }]}
+ >
+
+
+
+ label="新密码"
+ name="newPassword"
+ rules={[
+ { required: true, message: 'Please input your newPassword!' },
+ ]}
+ >
+
+
+
+
+ );
+};
+export default CpwModal;
diff --git a/web/src/pages/setting/List.tsx b/web/src/pages/setting/List.tsx
index 86e0a3bf6..35c8191db 100644
--- a/web/src/pages/setting/List.tsx
+++ b/web/src/pages/setting/List.tsx
@@ -1,196 +1,146 @@
-import { connect, Dispatch } from 'umi';
-import i18n from 'i18next';
-import { useTranslation, Trans } from 'react-i18next'
+import { useTranslation } from 'react-i18next';
+import { useEffect, useState } from 'react';
import styles from './index.less';
-import type { ColumnsType } from 'antd/es/table';
-import { useEffect, useState, FC } from 'react';
import { RadarChartOutlined } from '@ant-design/icons';
import { ProCard } from '@ant-design/pro-components';
-import { Button, Tag, Row, Col, Card } from 'antd';
-
+import { Button, Card, Col, Row, Tag } from 'antd';
+import { useDispatch, useSelector } from 'umi';
interface DataType {
- key: React.Key;
- name: string;
- age: number;
- address: string;
- description: string;
+ key: React.Key;
+ name: string;
+ age: number;
+ address: string;
+ description: string;
}
-interface ListProps {
- dispatch: Dispatch;
- settingModel: any
-}
-const Index: FC = ({ settingModel, dispatch }) => {
- const { llmInfo = {}, factoriesList, myLlm = [] } = settingModel
- const { OpenAI = [], tongyi = [] } = llmInfo
- console.log(OpenAI)
- const [collapsed, setCollapsed] = useState(true);
- const { t } = useTranslation()
- const columns: ColumnsType = [
- { title: 'Name', dataIndex: 'name', key: 'name' },
- { title: 'Age', dataIndex: 'age', key: 'age' },
- {
- title: 'Action',
- dataIndex: '',
- key: 'x',
- render: () => Delete,
- },
- ];
- useEffect(() => {
- dispatch({
- type: 'settingModel/factories_list',
- payload: {
- },
- });
- dispatch({
- type: 'settingModel/llm_list',
- payload: {
- },
- });
- dispatch({
- type: 'settingModel/my_llm',
- payload: {
- },
- });
- }, [])
- const data: DataType[] = [
- {
- key: 1,
- name: 'John Brown',
- age: 32,
- address: 'New York No. 1 Lake Park',
- description: 'My name is John Brown, I am 32 years old, living in New York No. 1 Lake Park.',
- },
- {
- key: 2,
- name: 'Jim Green',
- age: 42,
- address: 'London No. 1 Lake Park',
- description: 'My name is Jim Green, I am 42 years old, living in London No. 1 Lake Park.',
- },
- {
- key: 3,
- name: 'Not Expandable',
- age: 29,
- address: 'Jiangsu No. 1 Lake Park',
- description: 'This not expandable',
- },
- {
- key: 4,
- name: 'Joe Black',
- age: 32,
- address: 'Sydney No. 1 Lake Park',
- description: 'My name is Joe Black, I am 32 years old, living in Sydney No. 1 Lake Park.',
- },
- ];
+const SettingList = () => {
+ const dispatch = useDispatch();
+ const settingModel = useSelector((state: any) => state.settingModel);
+ const { llmInfo = {}, factoriesList, myLlm = [] } = settingModel;
+ const { OpenAI = [], tongyi = [] } = llmInfo;
+ const [collapsed, setCollapsed] = useState(true);
+ const { t } = useTranslation();
- return (
- {
+ dispatch({
+ type: 'settingModel/factories_list',
+ payload: {},
+ });
+ dispatch({
+ type: 'settingModel/llm_list',
+ payload: {},
+ });
+ dispatch({
+ type: 'settingModel/my_llm',
+ payload: {},
+ });
+ }, []);
+
+ return (
+
+ {myLlm.map((item: any) => {
+ return (
+
可折叠-图标自定义}
+ collapsibleIconRender={({
+ collapsed: buildInCollapsed,
+ }: {
+ collapsed: boolean;
+ }) => {
+ return (
+
+
+
+ {item.llm_factory}
+
+
+ {item.tags.split(',').map((d: string) => {
+ return {d};
+ })}
+
+ {buildInCollapsed ? (
+
显示{OpenAI.length}个模型
+ ) : (
+
收起{OpenAI.length}个模型
+ )}
+
+ );
}}
- >
- {
- myLlm.map((item: any) => {
- return (
可折叠-图标自定义 }
- collapsibleIconRender={({
- collapsed: buildInCollapsed,
- }: {
- collapsed: boolean;
- }) => {
- return (
-
{item.llm_factory}
-
{item.tags.split(',').map((d: string) => {
- return {d}
- })}
- {
- buildInCollapsed ?
显示{OpenAI.length}个模型 :
收起{OpenAI.length}个模型
- }
-
)
- }}
- extra={
-
- }
- style={{ marginBlockStart: 16 }}
- headerBordered
- collapsible
- defaultCollapsed
- >
- {/*
- {OpenAI.map(item => {
- return -
- {item.llm_name}
-
-
-
- })}
-
*/}
- )
- })
+ extra={
+
}
+ style={{ marginBlockStart: 16 }}
+ headerBordered
+ collapsible
+ defaultCollapsed
+ >
+ );
+ })}
-
-
-
- {
- factoriesList.map((item: any) => {
- return (
- {
- e.stopPropagation();
- dispatch({
- type: 'settingModel/updateState',
- payload: {
- llm_factory: item.name,
- isShowSAKModal: true
- }
- });
- }}
- >
- 设置
-
- }>
-
-
- {
- item.tags.split(',').map((d: string) => {
- return {d}
- })
- }
-
-
- )
- })
+
+ {factoriesList.map((item: any) => {
+ return (
+
+ {
+ e.stopPropagation();
+ dispatch({
+ type: 'settingModel/updateState',
+ payload: {
+ llm_factory: item.name,
+ isShowSAKModal: true,
+ },
+ });
+ }}
+ >
+ 设置
+
}
-
-
- );
-}
-export default connect(({ settingModel, loading }) => ({ settingModel, loading }))(Index);
+ >
+
+ {item.tags.split(',').map((d: string) => {
+ return {d};
+ })}
+
+
+
+ );
+ })}
+
+
+ );
+};
+export default SettingList;
diff --git a/web/src/pages/setting/SAKModal.tsx b/web/src/pages/setting/SAKModal.tsx
index 94da17bb4..43744cb12 100644
--- a/web/src/pages/setting/SAKModal.tsx
+++ b/web/src/pages/setting/SAKModal.tsx
@@ -1,83 +1,66 @@
-import { connect, Dispatch } from 'umi';
-import i18n from 'i18next';
-import { FC } from 'react'
-import { useTranslation, Trans } from 'react-i18next'
-import { Input, Modal, Form } from 'antd'
-import styles from './index.less';
+import { Form, Input, Modal } from 'antd';
+import { useTranslation } from 'react-i18next';
+import { useDispatch, useSelector } from 'umi';
type FieldType = {
- api_key?: string;
+ api_key?: string;
};
-interface SAKModalProps {
- dispatch: Dispatch;
- settingModel: any
-}
-const Index: FC