feat: Add component TuShare #1739 (#2745)

### What problem does this PR solve?

feat: Add component  TuShare  #1739

### Type of change

- [ ] Bug Fix (non-breaking change which fixes an issue)
- [x] New Feature (non-breaking change which adds functionality)
- [ ] Documentation Update
- [ ] Refactoring
- [ ] Performance Improvement
- [ ] Other (please describe):
This commit is contained in:
balibabu 2024-10-08 15:35:30 +08:00 committed by GitHub
parent b3b54680e7
commit 5845b2b137
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 172 additions and 1 deletions

View File

@ -30,7 +30,7 @@ export default defineConfig({
copy: ['src/conf.json'], copy: ['src/conf.json'],
proxy: { proxy: {
'/v1': { '/v1': {
target: 'http://127.0.0.1:9380/', target: 'http://127.0.0.1:9456/',
changeOrigin: true, changeOrigin: true,
ws: true, ws: true,
logger: console, logger: console,

View File

@ -0,0 +1,10 @@
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="24" height="32">
<title>tushare</title>
<defs>
<image width="20" height="32" id="img1"
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAdCAMAAACdWLz3AAAAAXNSR0IB2cksfwAAAnZQTFRF///////9z/msyvil/f/38Pzl/f/8xfGhf+Euf+Evs+2C+P33/v/9y/WiqO5gvPKEnulgjOREjuVGnuldtOmhb9VMe9hb6Pji8fzlpu5erO9oqu5lk+ZMj+VJk+ZLd9pCWM4xXtA3UMwlnOKD+/73uPF9p+5fr/BtmOhTkeZJgt9GYNA8Y9I+ZNI+Us0os+mh7/zhsO9uqO5foetcjuVEbtc9YNE9YdE7U80oi91u+v758v/zw/idsPFwo+tfcddFVs4wYtNAneiR+v////br/+fO/+nQ/+nR/+bO/+PL9vfh+f7y6/nl0fLG6fDR/+TM//fv/9Ke/4kF/5IW/5IX/4wL/5cg/9ap//v6//r4/86Y/5EV/44O/4kH/9mv/9Og/4wJ/5Qb/5Qc/5gk/+zW/+G//5MY/9qw/9Oh/40L/5Ud/44N/9an/8aF/40M/40N/9qx/5oo//jw//Lj/50t//jx//r0/9Ge/82V/9Gc/8uR/5Ye/5Qa/+3a/5wr/5Uc/+C+//36//ny/9Gd/6ZC/7Ja/7Nd/+rT/7pu/65R/6tL/6ZA/+TF/5ws/5AR/6pJ/9mu/4wK/5gl//Xp//bt/7lq/7Ne/7lp/6I5/5AS/+TG//Tp/61R/6M6/5Ue/9Oi/8+Z/+bK/48R/9y0/7Zj/8qP/48Q/+3Z/5sq/6hF/48S//Hh//38/6Q8/8+a/9y1/48P/6lI///+/82U/5IY/5Yg/+bL/4oH/9eq//z5/6pK/4sI/5MZ/61Q/69V/5EU/4oF/7Jb//Xq/6dE/65T//v3/8aG/54x/58y//79//v2/+fM/8+Y/8iJ/8eI/8iL/9Sj/+XHh/PjeAAAANJ0Uk5TAAD//wCgAP////8AAP/////////////QoP//////////////AP//////////////4P///////////wAA/////////wBA///////gAKD///8A/////////wAA////////////////////////////////AMD/AAD/////////////AAD/////////////////////YCD///////9g////////////////////4AD//////wD///////8A//////////9Q//8A////AAD/////////BLUGZwAAAZpJREFUeJxNkV0og2EUx89f87U3lreGiRIrN4oLJc0FkSQUoVZqboiLKZFys3zcKCVld5QkoaYpUfKZfJR244KaWhEbttWo+WrTPM/7sTk3z3N+73PO/z3nD1ICLKLqXT6SOcOngHAcpqQiHq8qzE0weFRo/Aev4z3LE/AiIWRS2aEkVA/I/yPrJ8UoJqCNQSlfJzKz4zumBSzs8pOGRblNb0iMhEX0Sy/t6mBWRNkgDEYFzKpw+D4zU4L+QsywfJQ1ConwyVD05k/xR8KTQfNYEJDLKTlrnJdOgN6yghEF+su52hj/MO1ThEj84CsZYWxSuMxWoBFDivgc3KTAaCmsRHY+134OhxYtSJ+HPqIFvBiO6lwcLl2xhZToeqTqZXgCHK64ImxLVd0SXA26SV9yjLUbbzr5O+5sHG7ghMSiDDgQZA4EzO2MOTeLA9TA5Gh7qdlFTdhaoN19v46oBY2gPeDRVbEzADg6D0LUhfdWJn2K39hK2let5rbooQaaI5tk3DkzwflcTXRWX+YxVqpuXmF+UDIqbOLpH/bLcsV/98goAAAAAElFTkSuQmCC" />
</defs>
<style>
</style>
<use id="Background" href="#img1" x="6" y="1" />
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -968,6 +968,23 @@ The above is the content you need to summarize.`,
concentrator: 'Concentrator', concentrator: 'Concentrator',
concentratorDescription: concentratorDescription:
'A component that receives the output from the upstream component and passes it on as input to the downstream components.', 'A component that receives the output from the upstream component and passes it on as input to the downstream components.',
tuShare: 'TuShare',
tuShareDescription:
'This component can be used to obtain financial news briefs from mainstream financial websites, aiding industry and quantitative research.',
tuShareSrcOptions: {
sina: 'Sina',
wallstreetcn: 'wallstreetcn',
'10jqka': 'Straight flush',
eastmoney: 'Eastmoney',
yuncaijing: 'YUNCAIJING',
fenghuang: 'FENGHUANG',
jinrongjie: 'JRJ',
},
token: 'Token',
src: 'Source',
startDate: 'Start date',
endDate: 'End date',
keyword: 'Keyword',
}, },
footer: { footer: {
profile: 'All rights reserved @ React', profile: 'All rights reserved @ React',

View File

@ -920,6 +920,23 @@ export default {
concentrator: '集線器', concentrator: '集線器',
concentratorDescription: concentratorDescription:
'此組件可用於連接多個下游組件。它接收來自上游組件的輸入並將其傳遞給每個下游組件。 ', '此組件可用於連接多個下游組件。它接收來自上游組件的輸入並將其傳遞給每個下游組件。 ',
tuShare: 'TuShare',
tuShareDescription:
'該組件可用於從主流金融網站獲取金融新聞簡報,輔助行業和量化研究。 ',
tuShareSrcOptions: {
sina: '新浪財經',
wallstreetcn: '華爾街見聞',
'10jqka': '同花順',
eastmoney: '東方財富',
yuncaijing: '雲財經',
fenghuang: '鳳凰新聞',
jinrongjie: '金融界',
},
token: 'Token',
src: '來源',
startDate: '開始日期',
endDate: '結束日期',
keyword: '關鍵字',
}, },
footer: { footer: {
profile: '“保留所有權利 @ react”', profile: '“保留所有權利 @ react”',

View File

@ -938,6 +938,23 @@ export default {
concentrator: '集线器', concentrator: '集线器',
concentratorDescription: concentratorDescription:
'该组件可用于连接多个下游组件。它接收来自上游组件的输入并将其传递给每个下游组件。', '该组件可用于连接多个下游组件。它接收来自上游组件的输入并将其传递给每个下游组件。',
tuShare: 'TuShare',
tuShareDescription:
'该组件可用于从主流金融网站获取金融新闻简报,辅助行业和量化研究。',
tuShareSrcOptions: {
sina: '新浪财经',
wallstreetcn: '华尔街见闻',
'10jqka': '同花顺',
eastmoney: '东方财富',
yuncaijing: '云财经',
fenghuang: '凤凰新闻',
jinrongjie: '金融界',
},
token: 'Token',
src: '源',
startDate: '开始日期',
endDate: '结束日期',
keyword: '关键字',
}, },
footer: { footer: {
profile: 'All rights reserved @ React', profile: 'All rights reserved @ React',

View File

@ -15,6 +15,7 @@ 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';
import { ReactComponent as QWeatherIcon } from '@/assets/svg/qweather.svg'; import { ReactComponent as QWeatherIcon } from '@/assets/svg/qweather.svg';
import { ReactComponent as SwitchIcon } from '@/assets/svg/switch.svg'; import { ReactComponent as SwitchIcon } from '@/assets/svg/switch.svg';
import { ReactComponent as TuShareIcon } from '@/assets/svg/tushare.svg';
import { ReactComponent as WenCaiIcon } from '@/assets/svg/wencai.svg'; import { ReactComponent as WenCaiIcon } from '@/assets/svg/wencai.svg';
import { ReactComponent as WikipediaIcon } from '@/assets/svg/wikipedia.svg'; import { ReactComponent as WikipediaIcon } from '@/assets/svg/wikipedia.svg';
import { ReactComponent as YahooFinanceIcon } from '@/assets/svg/yahoo-finance.svg'; import { ReactComponent as YahooFinanceIcon } from '@/assets/svg/yahoo-finance.svg';
@ -69,6 +70,7 @@ export enum Operator {
YahooFinance = 'YahooFinance', YahooFinance = 'YahooFinance',
Jin10 = 'Jin10', Jin10 = 'Jin10',
Concentrator = 'Concentrator', Concentrator = 'Concentrator',
TuShare = 'TuShare',
} }
export const operatorIconMap = { export const operatorIconMap = {
@ -100,6 +102,7 @@ export const operatorIconMap = {
[Operator.YahooFinance]: YahooFinanceIcon, [Operator.YahooFinance]: YahooFinanceIcon,
[Operator.Jin10]: Jin10Icon, [Operator.Jin10]: Jin10Icon,
[Operator.Concentrator]: ConcentratorIcon, [Operator.Concentrator]: ConcentratorIcon,
[Operator.TuShare]: TuShareIcon,
}; };
export const operatorMap: Record< export const operatorMap: Record<
@ -221,6 +224,7 @@ export const operatorMap: Record<
fontSize: 10, fontSize: 10,
iconFontSize: 16, iconFontSize: 16,
}, },
[Operator.TuShare]: { backgroundColor: '#f8cfa0' },
}; };
export const componentMenuList = [ export const componentMenuList = [
@ -305,6 +309,9 @@ export const componentMenuList = [
{ {
name: Operator.Jin10, name: Operator.Jin10,
}, },
{
name: Operator.TuShare,
},
]; ];
export const initialRetrievalValues = { export const initialRetrievalValues = {
@ -467,6 +474,12 @@ export const initialJin10Values = {
export const initialConcentratorValues = {}; export const initialConcentratorValues = {};
export const initialTuShareValues = {
token: 'xxx',
src: 'eastmoney',
start_date: '2024-01-01 09:00:00',
};
export const CategorizeAnchorPointPositions = [ export const CategorizeAnchorPointPositions = [
{ top: 1, right: 34 }, { top: 1, right: 34 },
{ top: 8, right: 18 }, { top: 8, right: 18 },
@ -542,6 +555,7 @@ export const RestrictedUpstreamMap = {
[Operator.YahooFinance]: [Operator.Begin], [Operator.YahooFinance]: [Operator.Begin],
[Operator.Jin10]: [Operator.Begin], [Operator.Jin10]: [Operator.Begin],
[Operator.Concentrator]: [Operator.Begin], [Operator.Concentrator]: [Operator.Begin],
[Operator.TuShare]: [Operator.Begin],
}; };
export const NodeMap = { export const NodeMap = {
@ -573,6 +587,7 @@ export const NodeMap = {
[Operator.AkShare]: 'ragNode', [Operator.AkShare]: 'ragNode',
[Operator.YahooFinance]: 'ragNode', [Operator.YahooFinance]: 'ragNode',
[Operator.Jin10]: 'ragNode', [Operator.Jin10]: 'ragNode',
[Operator.TuShare]: 'ragNode',
}; };
export const LanguageOptions = [ export const LanguageOptions = [
@ -2750,3 +2765,12 @@ export const Jin10CalendarTypeOptions = ['cj', 'qh', 'hk', 'us'];
export const Jin10CalendarDatashapeOptions = ['data', 'event', 'holiday']; export const Jin10CalendarDatashapeOptions = ['data', 'event', 'holiday'];
export const Jin10SymbolsTypeOptions = ['GOODS', 'FOREX', 'FUTURE', 'CRYPTO']; export const Jin10SymbolsTypeOptions = ['GOODS', 'FOREX', 'FUTURE', 'CRYPTO'];
export const Jin10SymbolsDatatypeOptions = ['symbols', 'quotes']; export const Jin10SymbolsDatatypeOptions = ['symbols', 'quotes'];
export const TuShareSrcOptions = [
'sina',
'wallstreetcn',
'10jqka',
'eastmoney',
'yuncaijing',
'fenghuang',
'jinrongjie',
];

View File

@ -29,6 +29,7 @@ import RelevantForm from '../relevant-form';
import RetrievalForm from '../retrieval-form'; import RetrievalForm from '../retrieval-form';
import RewriteQuestionForm from '../rewrite-question-form'; import RewriteQuestionForm from '../rewrite-question-form';
import SwitchForm from '../switch-form'; import SwitchForm from '../switch-form';
import TuShareForm from '../tushare-form';
import WenCaiForm from '../wencai-form'; import WenCaiForm from '../wencai-form';
import WikipediaForm from '../wikipedia-form'; import WikipediaForm from '../wikipedia-form';
@ -68,6 +69,7 @@ const FormMap = {
[Operator.AkShare]: AkShareForm, [Operator.AkShare]: AkShareForm,
[Operator.YahooFinance]: YahooFinanceForm, [Operator.YahooFinance]: YahooFinanceForm,
[Operator.Jin10]: Jin10Form, [Operator.Jin10]: Jin10Form,
[Operator.TuShare]: TuShareForm,
}; };
const EmptyContent = () => <div>empty</div>; const EmptyContent = () => <div>empty</div>;

View File

@ -55,6 +55,7 @@ import {
initialRetrievalValues, initialRetrievalValues,
initialRewriteQuestionValues, initialRewriteQuestionValues,
initialSwitchValues, initialSwitchValues,
initialTuShareValues,
initialWenCaiValues, initialWenCaiValues,
initialWikipediaValues, initialWikipediaValues,
initialYahooFinanceValues, initialYahooFinanceValues,
@ -123,6 +124,7 @@ export const useInitializeOperatorParams = () => {
[Operator.YahooFinance]: initialYahooFinanceValues, [Operator.YahooFinance]: initialYahooFinanceValues,
[Operator.Jin10]: initialJin10Values, [Operator.Jin10]: initialJin10Values,
[Operator.Concentrator]: initialConcentratorValues, [Operator.Concentrator]: initialConcentratorValues,
[Operator.TuShare]: initialTuShareValues,
}; };
}, [llmId]); }, [llmId]);

View File

@ -0,0 +1,82 @@
import { useTranslate } from '@/hooks/common-hooks';
import { DatePicker, DatePickerProps, Form, Input, Select } from 'antd';
import dayjs from 'dayjs';
import { useCallback, useMemo } from 'react';
import { TuShareSrcOptions } from '../constant';
import { IOperatorForm } from '../interface';
const DateTimePicker = ({
onChange,
value,
}: {
onChange?: (val: number | undefined) => void;
value?: number | undefined;
}) => {
const handleChange: DatePickerProps['onChange'] = useCallback(
(val: any) => {
const nextVal = val?.format('YYYY-MM-DD HH:mm:ss');
onChange?.(nextVal ? nextVal : undefined);
},
[onChange],
);
// The value needs to be converted into a string and saved to the backend
const nextValue = useMemo(() => {
if (value) {
return dayjs(value);
}
return undefined;
}, [value]);
return (
<DatePicker
showTime
format="YYYY-MM-DD HH:mm:ss"
onChange={handleChange}
value={nextValue}
/>
);
};
const TuShareForm = ({ onValuesChange, form }: IOperatorForm) => {
const { t } = useTranslate('flow');
const tuShareSrcOptions = useMemo(() => {
return TuShareSrcOptions.map((x) => ({
value: x,
label: t(`tuShareSrcOptions.${x}`),
}));
}, [t]);
return (
<Form
name="basic"
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
autoComplete="off"
form={form}
onValuesChange={onValuesChange}
>
<Form.Item
label={t('token')}
name={'token'}
tooltip={'Get from https://tushare.pro/'}
>
<Input></Input>
</Form.Item>
<Form.Item label={t('src')} name={'src'}>
<Select options={tuShareSrcOptions}></Select>
</Form.Item>
<Form.Item label={t('startDate')} name={'start_date'}>
<DateTimePicker />
</Form.Item>
<Form.Item label={t('endDate')} name={'end_date'}>
<DateTimePicker />
</Form.Item>
<Form.Item label={t('keyword')} name={'keyword'}>
<Input></Input>
</Form.Item>
</Form>
);
};
export default TuShareForm;