From 86b93876c7c29be85bd032893da47c496a7be920 Mon Sep 17 00:00:00 2001 From: williamhliu Date: Tue, 15 Aug 2023 20:04:04 +0800 Subject: [PATCH] [feature](webapp) add copilot and modify domain to model --- .../config/webpackDevServer.config.js | 4 +- webapp/packages/chat-sdk/src/common/type.ts | 20 ++- .../src/components/ChatItem/ParseTip.tsx | 18 +- .../src/components/ChatItem/index.tsx | 58 ++++-- .../components/ChatMsg/ApplyAuth/index.tsx | 8 +- .../src/components/ChatMsg/Bar/index.tsx | 10 +- .../src/components/ChatMsg/Message/index.tsx | 4 +- .../src/components/ChatMsg/Message/style.less | 2 +- .../components/ChatMsg/MetricCard/index.tsx | 8 +- .../components/ChatMsg/MetricCard/style.less | 4 +- .../ChatMsg/MetricTrend/MetricTrendChart.tsx | 8 +- .../components/ChatMsg/MetricTrend/index.tsx | 16 +- .../ChatMsg/NoPermissionChart/index.tsx | 8 +- .../src/components/ChatMsg/Table/index.tsx | 8 +- .../src/components/ChatMsg/Table/style.less | 2 +- .../chat-sdk/src/components/ChatMsg/index.tsx | 9 +- .../components/DrillDownDimensions/index.tsx | 6 +- .../src/components/RecommendOptions/index.tsx | 18 +- .../chat-sdk/src/components/Tools/index.tsx | 23 +-- webapp/packages/chat-sdk/src/demo/Chat.tsx | 1 - webapp/packages/chat-sdk/src/index.tsx | 2 +- webapp/packages/chat-sdk/src/service/index.ts | 28 +-- webapp/packages/supersonic-fe/src/app.tsx | 8 +- .../src/pages/Chat/ChatFooter/index.tsx | 95 +++++----- .../src/pages/Chat/ChatFooter/style.less | 10 +- .../src/pages/Chat/Conversation.tsx | 18 +- .../src/pages/Chat/MessageContainer.tsx | 37 ++-- .../src/pages/Chat/components/Message.tsx | 33 +--- .../pages/Chat/components/Plugin/index.tsx | 10 +- .../src/pages/Chat/components/style.less | 2 +- .../supersonic-fe/src/pages/Chat/constants.ts | 4 +- .../supersonic-fe/src/pages/Chat/index.tsx | 165 ++++++++++-------- .../supersonic-fe/src/pages/Chat/service.ts | 18 +- .../supersonic-fe/src/pages/Chat/style.less | 6 +- .../supersonic-fe/src/pages/Chat/type.ts | 14 +- .../src/pages/ChatPlugin/DetailModal.tsx | 148 ++++++++-------- .../src/pages/ChatPlugin/index.tsx | 48 ++--- .../src/pages/ChatPlugin/service.ts | 10 +- .../src/pages/ChatPlugin/style.less | 2 +- .../src/pages/ChatPlugin/type.ts | 4 +- .../supersonic-fe/src/pages/Copilot/index.tsx | 160 +++++++++++++++++ .../src/pages/Copilot/style.less | 110 ++++++++++++ webapp/packages/supersonic-fe/tsconfig.json | 2 +- 43 files changed, 738 insertions(+), 431 deletions(-) create mode 100644 webapp/packages/supersonic-fe/src/pages/Copilot/index.tsx create mode 100644 webapp/packages/supersonic-fe/src/pages/Copilot/style.less diff --git a/webapp/packages/chat-sdk/config/webpackDevServer.config.js b/webapp/packages/chat-sdk/config/webpackDevServer.config.js index 52f4edf36..4e7e94de5 100644 --- a/webapp/packages/chat-sdk/config/webpackDevServer.config.js +++ b/webapp/packages/chat-sdk/config/webpackDevServer.config.js @@ -22,7 +22,7 @@ module.exports = function (proxy, allowedHost) { // https://github.com/webpack/webpack-dev-server/issues/887 // https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a // However, it made several existing use cases such as development in cloud - // environment or subdomains in development significantly more complicated: + // environment or submodels in development significantly more complicated: // https://github.com/facebook/create-react-app/issues/2271 // https://github.com/facebook/create-react-app/issues/2233 // While we're investigating better solutions, for now we will take a @@ -33,7 +33,7 @@ module.exports = function (proxy, allowedHost) { // So we will disable the host check normally, but enable it if you have // specified the `proxy` setting. Finally, we let you override it if you // really know what you're doing with a special environment variable. - // Note: ["localhost", ".localhost"] will support subdomains - but we might + // Note: ["localhost", ".localhost"] will support submodels - but we might // want to allow setting the allowedHosts manually for more complex setups allowedHosts: disableFirewall ? 'all' : [allowedHost], headers: { diff --git a/webapp/packages/chat-sdk/src/common/type.ts b/webapp/packages/chat-sdk/src/common/type.ts index e4142e2b0..8b92a5f9c 100644 --- a/webapp/packages/chat-sdk/src/common/type.ts +++ b/webapp/packages/chat-sdk/src/common/type.ts @@ -1,7 +1,7 @@ export type SearchRecommendItem = { complete: boolean; - domainId: number; - domainName: string; + modelId: number; + modelName: string; recommend: string; subRecommend: string; schemaElementType: string; @@ -12,12 +12,12 @@ export type FieldType = { id: number; name: string; status: number; - domain: number; + model: number; type: string; value: string; }; -export type DomainInfoType = { +export type ModelInfoType = { bizName: string; itemId: number; name: string; @@ -27,7 +27,7 @@ export type DomainInfoType = { }; export type EntityInfoType = { - domainInfo: DomainInfoType; + modelInfo: ModelInfoType; dimensions: FieldType[]; metrics: FieldType[]; entityId: number; @@ -53,8 +53,8 @@ export type FilterItemType = { export type ChatContextType = { aggType: string; - domainId: number; - domainName: string; + modelId: number; + modelName: string; dateInfo: DateInfoType; dimensions: FieldType[]; metrics: FieldType[]; @@ -104,6 +104,7 @@ export type MsgDataType = { queryMode: string; queryState: string; response: PluginResonseType; + parseOptions?: ChatContextType[]; }; export enum ParseStateEnum { @@ -121,6 +122,7 @@ export type ParseDataType = { } export type QueryDataType = { + aggregateInfo: AggregateInfoType; queryColumns: ColumnType[]; queryResults: any[]; }; @@ -153,7 +155,7 @@ export const SEMANTIC_TYPE_MAP = { }; export type SuggestionItemType = { - domain: number; + model: number; name: string; bizName: string }; @@ -187,7 +189,7 @@ export type HistoryType = { export type DrillDownDimensionType = { id: number; - domain: number; + model: number; name: string; bizName: string; } \ No newline at end of file diff --git a/webapp/packages/chat-sdk/src/components/ChatItem/ParseTip.tsx b/webapp/packages/chat-sdk/src/components/ChatItem/ParseTip.tsx index 4760f2cc5..8012cde63 100644 --- a/webapp/packages/chat-sdk/src/components/ChatItem/ParseTip.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatItem/ParseTip.tsx @@ -10,6 +10,7 @@ type Props = { parseInfoOptions: ChatContextType[]; parseTip: string; currentParseInfo?: ChatContextType; + optionMode?: boolean; onSelectParseInfo: (parseInfo: ChatContextType) => void; }; @@ -20,6 +21,7 @@ const ParseTip: React.FC = ({ parseInfoOptions, parseTip, currentParseInfo, + optionMode, onSelectParseInfo, }) => { const prefixCls = `${PREFIX_CLS}-item`; @@ -38,7 +40,7 @@ const ParseTip: React.FC = ({ const getTipNode = (parseInfo: ChatContextType, isOptions?: boolean, index?: number) => { const { - domainName, + modelName, dateInfo, dimensionFilters, dimensions, @@ -70,6 +72,7 @@ const ParseTip: React.FC = ({ [`${prefixCls}-tip-item-option`]: isOptions, }); + const entityId = dimensionFilters?.length > 0 ? dimensionFilters[0].value : undefined; const entityAlias = entity?.alias?.[0]?.split('.')?.[0]; const entityName = elementMatches?.find(item => item.element?.type === 'ID')?.element.name; @@ -106,7 +109,10 @@ const ParseTip: React.FC = ({ ) : ( <> - {queryMode === 'METRIC_ENTITY' || queryMode === 'ENTITY_DETAIL' ? ( + {queryMode.includes('ENTITY') && + typeof entityId === 'string' && + !!entityAlias && + !!entityName ? (
{entityAlias}:
{entityName}
@@ -114,7 +120,7 @@ const ParseTip: React.FC = ({ ) : (
主题域:
-
{domainName}
+
{modelName}
)} {modeName === '算指标' && metric && ( @@ -180,10 +186,12 @@ const ParseTip: React.FC = ({ let tipNode: ReactNode; - if (parseInfoOptions.length > 1) { + if (parseInfoOptions.length > 1 || optionMode) { tipNode = (
-
您的问题解析为以下几项,请您点击确认
+
+ 还有以下的相关问题,请您点击提交 +
{parseInfoOptions.map((item, index) => getTipNode(item, true, index))}
diff --git a/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx b/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx index acebd42dc..5dedfc9fe 100644 --- a/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx @@ -9,12 +9,13 @@ import ExecuteItem from './ExecuteItem'; type Props = { msg: string; conversationId?: number; - domainId?: number; + modelId?: number; filter?: any[]; isLastMessage?: boolean; msgData?: MsgDataType; isMobileMode?: boolean; triggerResize?: boolean; + parseOptions?: ChatContextType[]; onMsgDataLoaded?: (data: MsgDataType, valid: boolean) => void; onUpdateMessageScroll?: () => void; }; @@ -22,19 +23,20 @@ type Props = { const ChatItem: React.FC = ({ msg, conversationId, - domainId, + modelId, filter, isLastMessage, isMobileMode, triggerResize, msgData, + parseOptions, onMsgDataLoaded, onUpdateMessageScroll, }) => { const [data, setData] = useState(); const [parseLoading, setParseLoading] = useState(false); const [parseInfo, setParseInfo] = useState(); - const [parseInfoOptions, setParseInfoOptions] = useState([]); + const [parseInfoOptions, setParseInfoOptions] = useState(parseOptions || []); const [parseTip, setParseTip] = useState(''); const [executeLoading, setExecuteLoading] = useState(false); const [executeTip, setExecuteTip] = useState(''); @@ -68,20 +70,43 @@ const ChatItem: React.FC = ({ return true; }; - const onExecute = async (parseInfoValue: ChatContextType, isSwitch?: boolean) => { + const onExecute = async ( + parseInfoValue: ChatContextType, + parseInfoOptions?: ChatContextType[] + ) => { setExecuteMode(true); setExecuteLoading(true); const { data } = await chatExecute(msg, conversationId!, parseInfoValue); setExecuteLoading(false); const valid = updateData(data); - if (onMsgDataLoaded && !isSwitch) { - onMsgDataLoaded({ ...data.data, chatContext: parseInfoValue }, valid); + if (onMsgDataLoaded) { + let parseOptions: ChatContextType[] = parseInfoOptions || []; + if ( + parseInfoOptions && + parseInfoOptions.length > 1 && + (parseInfoOptions[0].queryMode.includes('METRIC') || + parseInfoOptions[0].queryMode.includes('ENTITY')) + ) { + parseOptions = parseInfoOptions.filter( + (item, index) => + index === 0 || + (!item.queryMode.includes('METRIC') && !item.queryMode.includes('ENTITY')) + ); + } + onMsgDataLoaded( + { + ...data.data, + chatContext: parseInfoValue, + parseOptions: parseOptions.length > 1 ? parseOptions.slice(1) : undefined, + }, + valid + ); } }; const onSendMsg = async () => { setParseLoading(true); - const { data: parseData } = await chatParse(msg, conversationId, domainId, filter); + const { data: parseData } = await chatParse(msg, conversationId, modelId, filter); setParseLoading(false); const { code, data } = parseData || {}; const { state, selectedParses } = data || {}; @@ -91,7 +116,7 @@ const ChatItem: React.FC = ({ selectedParses == null || selectedParses.length === 0 || (selectedParses.length === 1 && - !selectedParses[0]?.domainName && + !selectedParses[0]?.modelName && !selectedParses[0]?.properties?.CONTEXT?.plugin?.name && selectedParses[0]?.queryMode !== 'WEB_PAGE') ) { @@ -102,15 +127,13 @@ const ChatItem: React.FC = ({ onUpdateMessageScroll(); } setParseInfoOptions(selectedParses || []); - if (selectedParses.length === 1) { - const parseInfoValue = selectedParses[0]; - setParseInfo(parseInfoValue); - onExecute(parseInfoValue); - } + const parseInfoValue = selectedParses[0]; + setParseInfo(parseInfoValue); + onExecute(parseInfoValue, selectedParses); }; useEffect(() => { - if (data !== undefined) { + if (data !== undefined || parseOptions !== undefined || executeTip !== '') { return; } if (msgData) { @@ -124,7 +147,7 @@ const ChatItem: React.FC = ({ const onSwitchEntity = async (entityId: string) => { setEntitySwitching(true); - const res = await switchEntity(entityId, data?.chatContext?.domainId, conversationId || 0); + const res = await switchEntity(entityId, data?.chatContext?.modelId, conversationId || 0); setEntitySwitching(false); setData(res.data.data); }; @@ -135,7 +158,7 @@ const ChatItem: React.FC = ({ const onSelectParseInfo = async (parseInfoValue: ChatContextType) => { setParseInfo(parseInfoValue); - onExecute(parseInfoValue, parseInfo !== undefined); + onExecute(parseInfoValue); if (onUpdateMessageScroll) { onUpdateMessageScroll(); } @@ -148,9 +171,10 @@ const ChatItem: React.FC = ({
diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/ApplyAuth/index.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/ApplyAuth/index.tsx index 34f06383a..f17a95053 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/ApplyAuth/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/ApplyAuth/index.tsx @@ -1,11 +1,11 @@ import { PREFIX_CLS } from '../../../common/constants'; type Props = { - domain: string; - onApplyAuth?: (domain: string) => void; + model: string; + onApplyAuth?: (model: string) => void; }; -const ApplyAuth: React.FC = ({ domain, onApplyAuth }) => { +const ApplyAuth: React.FC = ({ model, onApplyAuth }) => { const prefixCls = `${PREFIX_CLS}-apply-auth`; return ( @@ -15,7 +15,7 @@ const ApplyAuth: React.FC = ({ domain, onApplyAuth }) => { { - onApplyAuth(domain); + onApplyAuth(model); }} > 点击申请 diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/Bar/index.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/Bar/index.tsx index d807127ef..c858acf2f 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/Bar/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/Bar/index.tsx @@ -15,7 +15,7 @@ type Props = { drillDownDimension?: DrillDownDimensionType; loading: boolean; onSelectDimension: (dimension?: DrillDownDimensionType) => void; - onApplyAuth?: (domain: string) => void; + onApplyAuth?: (model: string) => void; }; const BarChart: React.FC = ({ @@ -152,7 +152,7 @@ const BarChart: React.FC = ({ if (metricColumn && !metricColumn?.authorized) { return ( @@ -193,11 +193,9 @@ const BarChart: React.FC = ({
- {(queryMode === 'METRIC_DOMAIN' || - queryMode === 'METRIC_FILTER' || - queryMode === 'METRIC_GROUPBY') && ( + {queryMode.includes('METRIC') && ( = ({ }) => { const prefixCls = `${PREFIX_CLS}-message`; - const { domainName, dateInfo, dimensionFilters } = chatContext || {}; + const { modelName, dateInfo, dimensionFilters } = chatContext || {}; const { startDate, endDate } = dateInfo || {}; const entityInfoList = @@ -67,7 +67,7 @@ const Message: React.FC = ({
主题域:
-
{domainName}
+
{modelName}
时间:
diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/Message/style.less b/webapp/packages/chat-sdk/src/components/ChatMsg/Message/style.less index 5c3f737f9..1db81f131 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/Message/style.less +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/Message/style.less @@ -10,7 +10,7 @@ margin-bottom: 6px; } - &-domain-name { + &-model-name { color: var(--text-color); margin-left: 4px; font-weight: 500; diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricCard/index.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricCard/index.tsx index 3b6b48fe5..428e1f752 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricCard/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricCard/index.tsx @@ -13,7 +13,7 @@ type Props = { drillDownDimension?: DrillDownDimensionType; loading: boolean; onSelectDimension: (dimension?: DrillDownDimensionType) => void; - onApplyAuth?: (domain: string) => void; + onApplyAuth?: (model: string) => void; }; const MetricCard: React.FC = ({ @@ -64,7 +64,7 @@ const MetricCard: React.FC = ({
{startDate}
{indicatorColumn && !indicatorColumn?.authorized ? ( - + ) : (
{formatMetric(queryResults?.[0]?.[indicatorColumnName]) || '-'} @@ -79,10 +79,10 @@ const MetricCard: React.FC = ({ )}
- {(queryMode === 'METRIC_DOMAIN' || queryMode === 'METRIC_FILTER') && ( + {queryMode.includes('METRIC') && (
void; + onApplyAuth?: (model: string) => void; }; const MetricTrendChart: React.FC = ({ - domain, + model, dateColumnName, categoryColumnName, metricField, @@ -204,7 +204,7 @@ const MetricTrendChart: React.FC = ({ return (
{!metricField.authorized ? ( - + ) : (
)} diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/index.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/index.tsx index e32d1abc1..e3b5275a3 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/index.tsx @@ -15,7 +15,7 @@ type Props = { data: MsgDataType; chartIndex: number; triggerResize?: boolean; - onApplyAuth?: (domain: string) => void; + onApplyAuth?: (model: string) => void; }; const MetricTrend: React.FC = ({ data, chartIndex, triggerResize, onApplyAuth }) => { @@ -36,6 +36,7 @@ const MetricTrend: React.FC = ({ data, chartIndex, triggerResize, onApply const [currentDateOption, setCurrentDateOption] = useState(initialDateOption); const [dimensions, setDimensions] = useState(chatContext?.dimensions); const [drillDownDimension, setDrillDownDimension] = useState(); + const [aggregateInfoValue, setAggregateInfoValue] = useState(aggregateInfo); const [dateModeValue, setDateModeValue] = useState(dateMode); const [loading, setLoading] = useState(false); @@ -72,6 +73,7 @@ const MetricTrend: React.FC = ({ data, chartIndex, triggerResize, onApply if (data.code === 200) { setColumns(data.data?.queryColumns || []); setDataSource(data.data?.queryResults || []); + setAggregateInfoValue(data.data?.aggregateInfo); } }; @@ -172,7 +174,9 @@ const MetricTrend: React.FC = ({ data, chartIndex, triggerResize, onApply
)}
- {aggregateInfo?.metricInfos?.length > 0 && } + {aggregateInfoValue?.metricInfos?.length > 0 && ( + + )}
{dateOptions.map((dateOption: { label: string; value: number }, index: number) => { const dateOptionClass = classNames(`${prefixCls}-date-option`, { @@ -205,7 +209,7 @@ const MetricTrend: React.FC = ({ data, chartIndex, triggerResize, onApply ) : ( = ({ data, chartIndex, triggerResize, onApply /> )} - {(queryMode === 'METRIC_DOMAIN' || - queryMode === 'METRIC_FILTER' || - queryMode === 'METRIC_GROUPBY') && ( + {queryMode.includes('METRIC') && ( void; + onApplyAuth?: (model: string) => void; }; -const NoPermissionChart: React.FC = ({ domain, chartType, onApplyAuth }) => { +const NoPermissionChart: React.FC = ({ model, chartType, onApplyAuth }) => { const prefixCls = `${CLS_PREFIX}-no-permission-chart`; const chartHolderClass = classNames(`${prefixCls}-holder`, { @@ -19,7 +19,7 @@ const NoPermissionChart: React.FC = ({ domain, chartType, onApplyAuth })
- +
); diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/Table/index.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/Table/index.tsx index fb30fd42c..dee0a0f7e 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/Table/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/Table/index.tsx @@ -8,7 +8,7 @@ import { SizeType } from 'antd/es/config-provider/SizeContext'; type Props = { data: MsgDataType; size?: SizeType; - onApplyAuth?: (domain: string) => void; + onApplyAuth?: (model: string) => void; }; const Table: React.FC = ({ data, size, onApplyAuth }) => { @@ -24,9 +24,7 @@ const Table: React.FC = ({ data, size, onApplyAuth }) => { title: name || nameEn, render: (value: string | number) => { if (!authorized) { - return ( - - ); + return ; } if (dataFormatType === 'percent') { return ( @@ -71,7 +69,7 @@ const Table: React.FC = ({ data, size, onApplyAuth }) => { columns={tableColumns} dataSource={queryResults} style={{ width: '100%' }} - scroll={{ x: 'max-content' }} + // scroll={{ x: 'max-content' }} rowClassName={getRowClassName} size={size} /> diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/Table/style.less b/webapp/packages/chat-sdk/src/components/ChatMsg/Table/style.less index 06fd26c4d..9c0707ee4 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/Table/style.less +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/Table/style.less @@ -3,7 +3,7 @@ @table-prefix-cls: ~'@{supersonic-chat-prefix}-table'; .@{table-prefix-cls} { - margin-top: 20px; + margin-top: 16px; margin-bottom: 20px; &-photo { diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/index.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/index.tsx index 1496c3abe..b701f75c8 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/index.tsx @@ -35,10 +35,15 @@ const ChatMsg: React.FC = ({ question, data, chartIndex, isMobileMode, tr const metricFields = columns.filter(item => item.showType === 'NUMBER'); const isMetricCard = - (queryMode === 'METRIC_DOMAIN' || queryMode === 'METRIC_FILTER') && + queryMode.includes('METRIC') && (singleData || chatContext?.dateInfo?.startDate === chatContext?.dateInfo?.endDate); - const isText = columns.length === 1 && columns[0].showType === 'CATEGORY' && singleData; + const isText = + columns.length === 1 && + columns[0].showType === 'CATEGORY' && + !queryMode.includes('METRIC') && + !queryMode.includes('ENTITY') && + singleData; const onLoadData = async (value: any) => { setLoading(true); diff --git a/webapp/packages/chat-sdk/src/components/DrillDownDimensions/index.tsx b/webapp/packages/chat-sdk/src/components/DrillDownDimensions/index.tsx index 186d9a61d..a126f15f8 100644 --- a/webapp/packages/chat-sdk/src/components/DrillDownDimensions/index.tsx +++ b/webapp/packages/chat-sdk/src/components/DrillDownDimensions/index.tsx @@ -7,7 +7,7 @@ import { DownOutlined } from '@ant-design/icons'; import classNames from 'classnames'; type Props = { - domainId: number; + modelId: number; drillDownDimension?: DrillDownDimensionType; isMetricCard?: boolean; dimensionFilters?: FilterItemType[]; @@ -17,7 +17,7 @@ type Props = { const MAX_DIMENSION_COUNT = 20; const DrillDownDimensions: React.FC = ({ - domainId, + modelId, drillDownDimension, isMetricCard, dimensionFilters, @@ -30,7 +30,7 @@ const DrillDownDimensions: React.FC = ({ const prefixCls = `${CLS_PREFIX}-drill-down-dimensions`; const initData = async () => { - const res = await queryDrillDownDimensions(domainId); + const res = await queryDrillDownDimensions(modelId); setDimensions( res.data.data.dimensions .filter(dimension => !dimensionFilters?.some(filter => filter.name === dimension.name)) diff --git a/webapp/packages/chat-sdk/src/components/RecommendOptions/index.tsx b/webapp/packages/chat-sdk/src/components/RecommendOptions/index.tsx index 0ef2c2a34..bd4a25585 100644 --- a/webapp/packages/chat-sdk/src/components/RecommendOptions/index.tsx +++ b/webapp/packages/chat-sdk/src/components/RecommendOptions/index.tsx @@ -10,16 +10,16 @@ import classNames from 'classnames'; type Props = { entityId: string | number; - domainId: number; - domainName: string; + modelId: number; + modelName: string; isMobileMode?: boolean; onSelect: (option: string) => void; }; const RecommendOptions: React.FC = ({ entityId, - domainId, - domainName, + modelId, + modelName, isMobileMode, onSelect, }) => { @@ -30,7 +30,7 @@ const RecommendOptions: React.FC = ({ const initData = async () => { setLoading(true); - const res = await queryEntities(entityId, domainId); + const res = await queryEntities(entityId, modelId); setLoading(false); setData(res.data.data); }; @@ -51,7 +51,7 @@ const RecommendOptions: React.FC = ({
} + icon={} src={record.url} />
@@ -64,7 +64,7 @@ const RecommendOptions: React.FC = ({ }, }; - const playCntColumnIdex = domainName.includes('歌曲') + const playCntColumnIdex = modelName.includes('歌曲') ? 'tme3platAvgLogYyPlayCnt' : 'tme3platJsPlayCnt'; @@ -72,7 +72,7 @@ const RecommendOptions: React.FC = ({ ? [basicColumn] : [ basicColumn, - domainName.includes('艺人') + modelName.includes('艺人') ? { dataIndex: 'onlineSongCnt', key: 'onlineSongCnt', @@ -95,7 +95,7 @@ const RecommendOptions: React.FC = ({ dataIndex: playCntColumnIdex, key: playCntColumnIdex, align: 'center', - title: domainName.includes('歌曲') ? '近7天日均运营播放量' : '昨日结算播放量', + title: modelName.includes('歌曲') ? '近7天日均运营播放量' : '昨日结算播放量', render: (value: string) => { return value ? getFormattedValue(+value) : '-'; }, diff --git a/webapp/packages/chat-sdk/src/components/Tools/index.tsx b/webapp/packages/chat-sdk/src/components/Tools/index.tsx index 66d1d02c6..0ca36a895 100644 --- a/webapp/packages/chat-sdk/src/components/Tools/index.tsx +++ b/webapp/packages/chat-sdk/src/components/Tools/index.tsx @@ -26,21 +26,22 @@ const Tools: React.FC = ({ onChangeChart, }) => { const [recommendOptionsOpen, setRecommendOptionsOpen] = useState(false); - const { queryColumns, queryResults, queryId, chatContext, queryMode } = data || {}; + const { queryColumns, queryResults, queryId, chatContext, queryMode, entityInfo } = data || {}; const [score, setScore] = useState(scoreValue || 0); const prefixCls = `${CLS_PREFIX}-tools`; + const singleData = queryResults.length === 1; + const isMetricCard = + queryMode.includes('METRIC') && + (singleData || chatContext?.dateInfo?.startDate === chatContext?.dateInfo?.endDate); + const noDashboard = (queryColumns?.length === 1 && queryColumns[0].showType === 'CATEGORY' && queryResults?.length === 1) || - (!queryMode.includes('METRIC') && !queryMode.includes('ENTITY')); - - console.log( - 'chatContext?.properties?.CONTEXT?.plugin?.name', - chatContext?.properties?.CONTEXT?.plugin?.name - ); + (!queryMode.includes('METRIC') && !queryMode.includes('ENTITY')) || + isMetricCard; const changeChart = () => { onChangeChart(); @@ -74,13 +75,13 @@ const Tools: React.FC = ({ return (
- {/* {isLastMessage && chatContext?.domainId && entityInfo?.entityId && ( + {/* {isLastMessage && chatContext?.modelId && entityInfo?.entityId && ( @@ -105,7 +106,7 @@ const Tools: React.FC = ({ 加入看板 )} - {isLastMessage && ( + {isLastMessage && !isMetricCard && (
这个回答正确吗?
diff --git a/webapp/packages/chat-sdk/src/demo/Chat.tsx b/webapp/packages/chat-sdk/src/demo/Chat.tsx index eb33112cd..1f5caada4 100644 --- a/webapp/packages/chat-sdk/src/demo/Chat.tsx +++ b/webapp/packages/chat-sdk/src/demo/Chat.tsx @@ -56,7 +56,6 @@ const Chat = () => { msg={msg} // msgData={data} onMsgDataLoaded={onMsgDataLoaded} - domainId={37} isLastMessage isMobileMode triggerResize={triggerResize} diff --git a/webapp/packages/chat-sdk/src/index.tsx b/webapp/packages/chat-sdk/src/index.tsx index 4847e67ed..428529e52 100644 --- a/webapp/packages/chat-sdk/src/index.tsx +++ b/webapp/packages/chat-sdk/src/index.tsx @@ -19,7 +19,7 @@ export { default as ChatItem } from './components/ChatItem'; export type { SearchRecommendItem, FieldType, - DomainInfoType, + ModelInfoType, EntityInfoType, DateInfoType, ChatContextType, diff --git a/webapp/packages/chat-sdk/src/service/index.ts b/webapp/packages/chat-sdk/src/service/index.ts index 4a4fe6b8a..36b0c8188 100644 --- a/webapp/packages/chat-sdk/src/service/index.ts +++ b/webapp/packages/chat-sdk/src/service/index.ts @@ -6,30 +6,30 @@ const DEFAULT_CHAT_ID = 0; const prefix = '/api'; -export function searchRecommend(queryText: string, chatId?: number, domainId?: number) { +export function searchRecommend(queryText: string, chatId?: number, modelId?: number) { return axios.post>(`${prefix}/chat/query/search`, { queryText, chatId: chatId || DEFAULT_CHAT_ID, - domainId, + modelId, }); } -export function chatQuery(queryText: string, chatId?: number, domainId?: number, filters?: any[]) { +export function chatQuery(queryText: string, chatId?: number, modelId?: number, filters?: any[]) { return axios.post>(`${prefix}/chat/query/query`, { queryText, chatId: chatId || DEFAULT_CHAT_ID, - domainId, + modelId, queryFilters: filters ? { filters } : undefined, }); } -export function chatParse(queryText: string, chatId?: number, domainId?: number, filters?: any[]) { +export function chatParse(queryText: string, chatId?: number, modelId?: number, filters?: any[]) { return axios.post>(`${prefix}/chat/query/parse`, { queryText, chatId: chatId || DEFAULT_CHAT_ID, - domainId, + modelId, queryFilters: filters ? { filters } : undefined, @@ -44,10 +44,10 @@ export function chatExecute(queryText: string, chatId: number, parseInfo: ChatC }); } -export function switchEntity(entityId: string, domainId?: number, chatId?: number) { +export function switchEntity(entityId: string, modelId?: number, chatId?: number) { return axios.post>(`${prefix}/chat/query/switchQuery`, { queryText: entityId, - domainId, + modelId, chatId: chatId || DEFAULT_CHAT_ID, }); } @@ -63,8 +63,8 @@ export function queryContext(queryText: string, chatId?: number) { }); } -export function querySuggestionInfo(domainId: number) { - return axios.get>(`${prefix}/chat/recommend/${domainId}`); +export function querySuggestionInfo(modelId: number) { + return axios.get>(`${prefix}/chat/recommend/${modelId}`); } export function getHistoryMsg(current: number, chatId: number = DEFAULT_CHAT_ID, pageSize: number = 10) { @@ -98,10 +98,10 @@ export function getAllConversations() { return axios.get>(`${prefix}/chat/manage/getAll`); } -export function queryEntities(entityId: string | number, domainId: number) { +export function queryEntities(entityId: string | number, modelId: number) { return axios.post>(`${prefix}/chat/query/choice`, { entityId, - domainId, + modelId, }); } @@ -109,6 +109,6 @@ export function updateQAFeedback(questionId: number, score: number) { return axios.post>(`${prefix}/chat/manage/updateQAFeedback?id=${questionId}&score=${score}&feedback=`); } -export function queryDrillDownDimensions(domainId: number) { - return axios.get>(`${prefix}/chat/recommend/metric/${domainId}`); +export function queryDrillDownDimensions(modelId: number) { + return axios.get>(`${prefix}/chat/recommend/metric/${modelId}`); } diff --git a/webapp/packages/supersonic-fe/src/app.tsx b/webapp/packages/supersonic-fe/src/app.tsx index aede97b80..2829bf995 100644 --- a/webapp/packages/supersonic-fe/src/app.tsx +++ b/webapp/packages/supersonic-fe/src/app.tsx @@ -13,6 +13,7 @@ import { queryToken } from './services/login'; import { queryCurrentUser } from './services/user'; import { traverseRoutes, deleteUrlQuery } from './utils/utils'; import { publicPath } from '../config/defaultSettings'; +import Copilot from './pages/Copilot'; export { request } from './services/request'; const TOKEN_KEY = AUTH_TOKEN_KEY; @@ -148,7 +149,12 @@ export const layout: RunTimeLayoutConfig = (params) => { disableContentMargin: true, menuHeaderRender: undefined, childrenRender: (dom) => { - return dom; + return ( + <> + {dom} + {history.location.pathname !== '/chat' && } + + ); }, openKeys: false, ...initialState?.settings, diff --git a/webapp/packages/supersonic-fe/src/pages/Chat/ChatFooter/index.tsx b/webapp/packages/supersonic-fe/src/pages/Chat/ChatFooter/index.tsx index 628faf327..4acdd9fc4 100644 --- a/webapp/packages/supersonic-fe/src/pages/Chat/ChatFooter/index.tsx +++ b/webapp/packages/supersonic-fe/src/pages/Chat/ChatFooter/index.tsx @@ -9,21 +9,21 @@ import { searchRecommend } from 'supersonic-chat-sdk'; import { SemanticTypeEnum, SEMANTIC_TYPE_MAP } from '../constants'; import styles from './style.less'; import { PLACE_HOLDER } from '../constants'; -import { DefaultEntityType, DomainType } from '../type'; +import { DefaultEntityType, ModelType } from '../type'; import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'; type Props = { inputMsg: string; chatId?: number; - currentDomain?: DomainType; + currentModel?: ModelType; defaultEntity?: DefaultEntityType; isCopilotMode?: boolean; copilotFullscreen?: boolean; - domains: DomainType[]; + models: ModelType[]; collapsed: boolean; onToggleCollapseBtn: () => void; onInputMsgChange: (value: string) => void; - onSendMsg: (msg: string, domainId?: number) => void; + onSendMsg: (msg: string, modelId?: number) => void; onAddConversation: () => void; onCancelDefaultFilter: () => void; }; @@ -44,9 +44,9 @@ const ChatFooter: ForwardRefRenderFunction = ( { inputMsg, chatId, - currentDomain, + currentModel, defaultEntity, - domains, + models, collapsed, isCopilotMode, copilotFullscreen, @@ -58,7 +58,7 @@ const ChatFooter: ForwardRefRenderFunction = ( }, ref, ) => { - const [domainOptions, setDomainOptions] = useState([]); + const [modelOptions, setModelOptions] = useState([]); const [stepOptions, setStepOptions] = useState>({}); const [open, setOpen] = useState(false); const [focused, setFocused] = useState(false); @@ -100,7 +100,7 @@ const ChatFooter: ForwardRefRenderFunction = ( }, []); const getStepOptions = (recommends: any[]) => { - const data = groupByColumn(recommends, 'domainName'); + const data = groupByColumn(recommends, 'modelName'); return isMobile && recommends.length > 6 ? Object.keys(data) .slice(0, 4) @@ -114,23 +114,23 @@ const ChatFooter: ForwardRefRenderFunction = ( : data; }; - const processMsg = (msg: string, domains: DomainType[]) => { + const processMsg = (msg: string, models: ModelType[]) => { let msgValue = msg; - let domainId: number | undefined; + let modelId: number | undefined; if (msg?.[0] === '@') { - const domain = domains.find((item) => msg.includes(`@${item.name}`)); - msgValue = domain ? msg.replace(`@${domain.name}`, '') : msg; - domainId = domain?.id; + const model = models.find((item) => msg.includes(`@${item.name}`)); + msgValue = model ? msg.replace(`@${model.name}`, '') : msg; + modelId = model?.id; } - return { msgValue, domainId }; + return { msgValue, modelId }; }; const debounceGetWordsFunc = useCallback(() => { const getAssociateWords = async ( msg: string, - domains: DomainType[], + models: ModelType[], chatId?: number, - domain?: DomainType, + model?: ModelType, ) => { if (isPinyin) { return; @@ -140,9 +140,9 @@ const ChatFooter: ForwardRefRenderFunction = ( } fetchRef.current += 1; const fetchId = fetchRef.current; - const { msgValue, domainId } = processMsg(msg, domains); - const domainIdValue = domainId || domain?.id; - const res = await searchRecommend(msgValue.trim(), chatId, domainIdValue); + const { msgValue, modelId } = processMsg(msg, models); + const modelIdValue = modelId || model?.id; + const res = await searchRecommend(msgValue.trim(), chatId, modelIdValue); if (fetchId !== fetchRef.current) { return; } @@ -165,19 +165,19 @@ const ChatFooter: ForwardRefRenderFunction = ( useEffect(() => { if (inputMsg.length === 1 && inputMsg[0] === '@') { setOpen(true); - setDomainOptions(domains); + setModelOptions(models); setStepOptions({}); return; } else { setOpen(false); - if (domainOptions.length > 0) { + if (modelOptions.length > 0) { setTimeout(() => { - setDomainOptions([]); + setModelOptions([]); }, 500); } } if (!isSelect) { - debounceGetWords(inputMsg, domains, chatId, currentDomain); + debounceGetWords(inputMsg, models, chatId, currentModel); } else { isSelect = false; } @@ -219,10 +219,10 @@ const ChatFooter: ForwardRefRenderFunction = ( .find((item) => Object.keys(stepOptions).length === 1 ? item.recommend === value - : `${item.domainName || ''}${item.recommend}` === value, + : `${item.modelName || ''}${item.recommend}` === value, ); if (option && isSelect) { - onSendMsg(option.recommend, option.domainId); + onSendMsg(option.recommend, option.modelId); } else { onSendMsg(value.trim()); } @@ -230,12 +230,12 @@ const ChatFooter: ForwardRefRenderFunction = ( const autoCompleteDropdownClass = classNames(styles.autoCompleteDropdown, { [styles.mobile]: isMobile, - [styles.domainOptions]: domainOptions.length > 0, + [styles.modelOptions]: modelOptions.length > 0, }); const onSelect = (value: string) => { isSelect = true; - if (domainOptions.length === 0) { + if (modelOptions.length === 0) { sendMsg(value); } setOpen(false); @@ -263,19 +263,16 @@ const ChatFooter: ForwardRefRenderFunction = ( />
- {currentDomain && ( -
-
+ {currentModel && ( +
+
输入联想与问题回复将限定于:“ - 主题域【{currentDomain.name}】 + 主题域【{currentModel.name}】 {defaultEntity && ( <> - {`${currentDomain.name.slice( - 0, - currentDomain.name.length - 1, - )}【`} + {`${currentModel.name.slice(0, currentModel.name.length - 1)}【`} {defaultEntity.entityName} @@ -285,7 +282,7 @@ const ChatFooter: ForwardRefRenderFunction = (
-
+
取消限定
@@ -293,8 +290,8 @@ const ChatFooter: ForwardRefRenderFunction = ( = ( open={open} getPopupContainer={(triggerNode) => triggerNode.parentNode} > - {domainOptions.length > 0 - ? domainOptions.map((domain) => { + {modelOptions.length > 0 + ? modelOptions.map((model) => { return ( ); }) @@ -342,17 +339,15 @@ const ChatFooter: ForwardRefRenderFunction = ( let optionValue = Object.keys(stepOptions).length === 1 ? option.recommend - : `${option.domainName || ''}${option.recommend}`; + : `${option.modelName || ''}${option.recommend}`; if (inputMsg[0] === '@') { - const domain = domains.find((item) => inputMsg.includes(item.name)); - optionValue = domain - ? `@${domain.name} ${option.recommend}` - : optionValue; + const model = models.find((item) => inputMsg.includes(item.name)); + optionValue = model ? `@${model.name} ${option.recommend}` : optionValue; } return (