mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-06-02 18:34:03 +08:00
### What problem does this PR solve? feat: Add GoogleScholar #918 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
43199c45c3
commit
0dba1743e3
9
web/src/assets/svg/google-scholar.svg
Normal file
9
web/src/assets/svg/google-scholar.svg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<svg t="1722910855180" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5111"
|
||||||
|
width="200" height="200">
|
||||||
|
<path d="M512 822.24L0 405.334 512 0z" fill="#4285F4" p-id="5112"></path>
|
||||||
|
<path d="M512 822.24l512-416.906L512 0z" fill="#356AC3" p-id="5113"></path>
|
||||||
|
<path d="M512 725.334m-298.666 0a298.666 298.666 0 1 0 597.332 0 298.666 298.666 0 1 0-597.332 0Z" fill="#A0C3FF"
|
||||||
|
p-id="5114"></path>
|
||||||
|
<path d="M242.074 597.334c47.936-100.906 150.784-170.668 269.926-170.668s221.99 69.762 269.926 170.668H242.074z"
|
||||||
|
fill="#76A7FA" p-id="5115"></path>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 621 B |
@ -6,3 +6,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.uploadLimit {
|
||||||
|
color: red;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
@ -53,6 +53,7 @@ const FileUpload = ({
|
|||||||
</p>
|
</p>
|
||||||
<p className="ant-upload-text">{t('uploadTitle')}</p>
|
<p className="ant-upload-text">{t('uploadTitle')}</p>
|
||||||
<p className="ant-upload-hint">{t('uploadDescription')}</p>
|
<p className="ant-upload-hint">{t('uploadDescription')}</p>
|
||||||
|
{false && <p className={styles.uploadLimit}>{t('uploadLimit')}</p>}
|
||||||
</Dragger>
|
</Dragger>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -562,6 +562,8 @@ The above is the content you need to summarize.`,
|
|||||||
s3: 'S3 uploads',
|
s3: 'S3 uploads',
|
||||||
preview: 'Preview',
|
preview: 'Preview',
|
||||||
fileError: 'File error',
|
fileError: 'File error',
|
||||||
|
uploadLimit:
|
||||||
|
'The file size cannot exceed 10M, and the total number of files cannot exceed 128',
|
||||||
},
|
},
|
||||||
flow: {
|
flow: {
|
||||||
cite: 'Cite',
|
cite: 'Cite',
|
||||||
@ -650,6 +652,13 @@ The above is the content you need to summarize.`,
|
|||||||
apiKey: 'Api Key',
|
apiKey: 'Api Key',
|
||||||
country: 'Country',
|
country: 'Country',
|
||||||
language: 'Language',
|
language: 'Language',
|
||||||
|
googleScholar: 'Google Scholar',
|
||||||
|
googleScholarDescription:
|
||||||
|
'This component is used to get search result from https://scholar.google.com/. Typically, it performs as a supplement to knowledgebases. Top N specifies the number of search results you need to adapt.',
|
||||||
|
yearLow: 'Year low',
|
||||||
|
yearHigh: 'Year high',
|
||||||
|
patents: 'Patents',
|
||||||
|
data: 'Data',
|
||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
profile: 'All rights reserved @ React',
|
profile: 'All rights reserved @ React',
|
||||||
|
@ -523,6 +523,7 @@ export default {
|
|||||||
s3: 'S3 上傳',
|
s3: 'S3 上傳',
|
||||||
preview: '預覽',
|
preview: '預覽',
|
||||||
fileError: '文件錯誤',
|
fileError: '文件錯誤',
|
||||||
|
uploadLimit: '文件大小不能超過10M,文件總數不超過128個',
|
||||||
},
|
},
|
||||||
flow: {
|
flow: {
|
||||||
cite: '引用',
|
cite: '引用',
|
||||||
@ -610,6 +611,12 @@ export default {
|
|||||||
apiKey: 'Api Key',
|
apiKey: 'Api Key',
|
||||||
country: '國家',
|
country: '國家',
|
||||||
language: '語言',
|
language: '語言',
|
||||||
|
googleScholar: '谷歌學術',
|
||||||
|
googleScholarDescription: `該元件用於從 https://scholar.google.com/ 取得搜尋結果。通常,它充當知識庫的補充。 Top N 指定您需要調整的搜尋結果的數量。`,
|
||||||
|
yearLow: '開始年份',
|
||||||
|
yearHigh: '結束年份',
|
||||||
|
patents: '專利',
|
||||||
|
data: '數據',
|
||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
profile: '“保留所有權利 @ react”',
|
profile: '“保留所有權利 @ react”',
|
||||||
|
@ -541,6 +541,7 @@ export default {
|
|||||||
s3: 'S3 上传',
|
s3: 'S3 上传',
|
||||||
preview: '预览',
|
preview: '预览',
|
||||||
fileError: '文件错误',
|
fileError: '文件错误',
|
||||||
|
uploadLimit: '文件大小不能超过10M,文件总数不超过128个',
|
||||||
},
|
},
|
||||||
flow: {
|
flow: {
|
||||||
flow: '工作流',
|
flow: '工作流',
|
||||||
@ -628,6 +629,12 @@ export default {
|
|||||||
apiKey: 'Api Key',
|
apiKey: 'Api Key',
|
||||||
country: '国家',
|
country: '国家',
|
||||||
language: '语言',
|
language: '语言',
|
||||||
|
googleScholar: '谷歌学术',
|
||||||
|
googleScholarDescription: `此组件用于从 https://scholar.google.com/ 获取搜索结果。通常,它作为知识库的补充。Top N 指定您需要调整的搜索结果数量。`,
|
||||||
|
yearLow: '开始年份',
|
||||||
|
yearHigh: '结束年份',
|
||||||
|
patents: '专利',
|
||||||
|
data: '数据',
|
||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
profile: 'All rights reserved @ React',
|
profile: 'All rights reserved @ React',
|
||||||
|
@ -2,6 +2,7 @@ import { ReactComponent as ArXivIcon } from '@/assets/svg/arxiv.svg';
|
|||||||
import { ReactComponent as BaiduIcon } from '@/assets/svg/baidu.svg';
|
import { ReactComponent as BaiduIcon } from '@/assets/svg/baidu.svg';
|
||||||
import { ReactComponent as BingIcon } from '@/assets/svg/bing.svg';
|
import { ReactComponent as BingIcon } from '@/assets/svg/bing.svg';
|
||||||
import { ReactComponent as DuckIcon } from '@/assets/svg/duck.svg';
|
import { ReactComponent as DuckIcon } from '@/assets/svg/duck.svg';
|
||||||
|
import { ReactComponent as GoogleScholarIcon } from '@/assets/svg/google-scholar.svg';
|
||||||
import { ReactComponent as GoogleIcon } from '@/assets/svg/google.svg';
|
import { ReactComponent as GoogleIcon } from '@/assets/svg/google.svg';
|
||||||
import { ReactComponent as KeywordIcon } from '@/assets/svg/keyword.svg';
|
import { ReactComponent as KeywordIcon } from '@/assets/svg/keyword.svg';
|
||||||
import { ReactComponent as PubMedIcon } from '@/assets/svg/pubmed.svg';
|
import { ReactComponent as PubMedIcon } from '@/assets/svg/pubmed.svg';
|
||||||
@ -44,6 +45,7 @@ export enum Operator {
|
|||||||
ArXiv = 'ArXiv',
|
ArXiv = 'ArXiv',
|
||||||
Google = 'Google',
|
Google = 'Google',
|
||||||
Bing = 'Bing',
|
Bing = 'Bing',
|
||||||
|
GoogleScholar = 'GoogleScholar',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const operatorIconMap = {
|
export const operatorIconMap = {
|
||||||
@ -63,6 +65,7 @@ export const operatorIconMap = {
|
|||||||
[Operator.ArXiv]: ArXivIcon,
|
[Operator.ArXiv]: ArXivIcon,
|
||||||
[Operator.Google]: GoogleIcon,
|
[Operator.Google]: GoogleIcon,
|
||||||
[Operator.Bing]: BingIcon,
|
[Operator.Bing]: BingIcon,
|
||||||
|
[Operator.GoogleScholar]: GoogleScholarIcon,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const operatorMap = {
|
export const operatorMap = {
|
||||||
@ -145,6 +148,7 @@ export const operatorMap = {
|
|||||||
backgroundColor: 'pink',
|
backgroundColor: 'pink',
|
||||||
},
|
},
|
||||||
[Operator.Bing]: {},
|
[Operator.Bing]: {},
|
||||||
|
[Operator.GoogleScholar]: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const componentMenuList = [
|
export const componentMenuList = [
|
||||||
@ -193,6 +197,9 @@ export const componentMenuList = [
|
|||||||
{
|
{
|
||||||
name: Operator.Bing,
|
name: Operator.Bing,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: Operator.GoogleScholar,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const initialRetrievalValues = {
|
export const initialRetrievalValues = {
|
||||||
@ -291,6 +298,12 @@ export const initialBingValues = {
|
|||||||
language: 'en',
|
language: 'en',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const initialGoogleScholarValues = {
|
||||||
|
top_n: 5,
|
||||||
|
sort_by: 'relevance',
|
||||||
|
patents: true,
|
||||||
|
};
|
||||||
|
|
||||||
export const CategorizeAnchorPointPositions = [
|
export const CategorizeAnchorPointPositions = [
|
||||||
{ top: 1, right: 34 },
|
{ top: 1, right: 34 },
|
||||||
{ top: 8, right: 18 },
|
{ top: 8, right: 18 },
|
||||||
@ -354,6 +367,7 @@ export const RestrictedUpstreamMap = {
|
|||||||
[Operator.ArXiv]: [Operator.Begin, Operator.Retrieval],
|
[Operator.ArXiv]: [Operator.Begin, Operator.Retrieval],
|
||||||
[Operator.Google]: [Operator.Begin, Operator.Retrieval],
|
[Operator.Google]: [Operator.Begin, Operator.Retrieval],
|
||||||
[Operator.Bing]: [Operator.Begin, Operator.Retrieval],
|
[Operator.Bing]: [Operator.Begin, Operator.Retrieval],
|
||||||
|
[Operator.GoogleScholar]: [Operator.Begin, Operator.Retrieval],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const NodeMap = {
|
export const NodeMap = {
|
||||||
@ -373,6 +387,7 @@ export const NodeMap = {
|
|||||||
[Operator.ArXiv]: 'ragNode',
|
[Operator.ArXiv]: 'ragNode',
|
||||||
[Operator.Google]: 'ragNode',
|
[Operator.Google]: 'ragNode',
|
||||||
[Operator.Bing]: 'ragNode',
|
[Operator.Bing]: 'ragNode',
|
||||||
|
[Operator.GoogleScholar]: 'ragNode',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LanguageOptions = [
|
export const LanguageOptions = [
|
||||||
|
@ -13,6 +13,7 @@ import { Operator } from '../constant';
|
|||||||
import DuckDuckGoForm from '../duckduckgo-form';
|
import DuckDuckGoForm from '../duckduckgo-form';
|
||||||
import GenerateForm from '../generate-form';
|
import GenerateForm from '../generate-form';
|
||||||
import GoogleForm from '../google-form';
|
import GoogleForm from '../google-form';
|
||||||
|
import GoogleScholarForm from '../google-scholar-form';
|
||||||
import { useHandleFormValuesChange, useHandleNodeNameChange } from '../hooks';
|
import { useHandleFormValuesChange, useHandleNodeNameChange } from '../hooks';
|
||||||
import KeywordExtractForm from '../keyword-extract-form';
|
import KeywordExtractForm from '../keyword-extract-form';
|
||||||
import MessageForm from '../message-form';
|
import MessageForm from '../message-form';
|
||||||
@ -46,6 +47,7 @@ const FormMap = {
|
|||||||
[Operator.ArXiv]: ArXivForm,
|
[Operator.ArXiv]: ArXivForm,
|
||||||
[Operator.Google]: GoogleForm,
|
[Operator.Google]: GoogleForm,
|
||||||
[Operator.Bing]: BingForm,
|
[Operator.Bing]: BingForm,
|
||||||
|
[Operator.GoogleScholar]: GoogleScholarForm,
|
||||||
};
|
};
|
||||||
|
|
||||||
const EmptyContent = () => <div>empty</div>;
|
const EmptyContent = () => <div>empty</div>;
|
||||||
|
78
web/src/pages/flow/google-scholar-form/index.tsx
Normal file
78
web/src/pages/flow/google-scholar-form/index.tsx
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import TopNItem from '@/components/top-n-item';
|
||||||
|
import { useTranslate } from '@/hooks/common-hooks';
|
||||||
|
import { DatePicker, DatePickerProps, Form, Select, Switch } from 'antd';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { useCallback, useMemo } from 'react';
|
||||||
|
import { IOperatorForm } from '../interface';
|
||||||
|
|
||||||
|
const YearPicker = ({
|
||||||
|
onChange,
|
||||||
|
value,
|
||||||
|
}: {
|
||||||
|
onChange?: (val: number | undefined) => void;
|
||||||
|
value?: number | undefined;
|
||||||
|
}) => {
|
||||||
|
const handleChange: DatePickerProps['onChange'] = useCallback(
|
||||||
|
(val: any) => {
|
||||||
|
const nextVal = val?.format('YYYY');
|
||||||
|
onChange?.(nextVal ? Number(nextVal) : undefined);
|
||||||
|
},
|
||||||
|
[onChange],
|
||||||
|
);
|
||||||
|
// The year needs to be converted into a number and saved to the backend
|
||||||
|
const nextValue = useMemo(() => {
|
||||||
|
if (value) {
|
||||||
|
return dayjs(value.toString());
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
|
return <DatePicker picker="year" onChange={handleChange} value={nextValue} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const GoogleScholarForm = ({ onValuesChange, form }: IOperatorForm) => {
|
||||||
|
const { t } = useTranslate('flow');
|
||||||
|
|
||||||
|
const options = useMemo(() => {
|
||||||
|
return ['data', 'relevance'].map((x) => ({
|
||||||
|
value: x,
|
||||||
|
label: t(x),
|
||||||
|
}));
|
||||||
|
}, [t]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form
|
||||||
|
name="basic"
|
||||||
|
labelCol={{ span: 6 }}
|
||||||
|
wrapperCol={{ span: 18 }}
|
||||||
|
autoComplete="off"
|
||||||
|
form={form}
|
||||||
|
onValuesChange={onValuesChange}
|
||||||
|
>
|
||||||
|
<TopNItem initialValue={5}></TopNItem>
|
||||||
|
<Form.Item
|
||||||
|
label={t('sortBy')}
|
||||||
|
name={'sort_by'}
|
||||||
|
initialValue={'relevance'}
|
||||||
|
>
|
||||||
|
<Select options={options}></Select>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t('yearLow')} name={'year_low'}>
|
||||||
|
<YearPicker />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t('yearHigh')} name={'year_high'}>
|
||||||
|
<YearPicker />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t('patents')}
|
||||||
|
name={'patents'}
|
||||||
|
valuePropName="checked"
|
||||||
|
initialValue={true}
|
||||||
|
>
|
||||||
|
<Switch></Switch>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GoogleScholarForm;
|
@ -37,6 +37,7 @@ import {
|
|||||||
initialCategorizeValues,
|
initialCategorizeValues,
|
||||||
initialDuckValues,
|
initialDuckValues,
|
||||||
initialGenerateValues,
|
initialGenerateValues,
|
||||||
|
initialGoogleScholarValues,
|
||||||
initialGoogleValues,
|
initialGoogleValues,
|
||||||
initialKeywordExtractValues,
|
initialKeywordExtractValues,
|
||||||
initialMessageValues,
|
initialMessageValues,
|
||||||
@ -97,6 +98,7 @@ export const useInitializeOperatorParams = () => {
|
|||||||
[Operator.ArXiv]: initialArXivValues,
|
[Operator.ArXiv]: initialArXivValues,
|
||||||
[Operator.Google]: initialGoogleValues,
|
[Operator.Google]: initialGoogleValues,
|
||||||
[Operator.Bing]: initialBingValues,
|
[Operator.Bing]: initialBingValues,
|
||||||
|
[Operator.GoogleScholar]: initialGoogleScholarValues,
|
||||||
};
|
};
|
||||||
}, [llmId]);
|
}, [llmId]);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user