(feature)(webapp) use nativeQuery field to determine whether it is a selection (#222)

This commit is contained in:
williamhliu
2023-10-14 16:37:28 +08:00
committed by GitHub
parent d9efe8f137
commit fdf48d7bfd
16 changed files with 63 additions and 38 deletions

View File

@@ -2,7 +2,6 @@ import { Form, Input, Modal } from 'antd';
import { useEffect, useRef, useState } from 'react';
import { updateConversationName } from '../../service';
import type { ConversationDetailType } from '../../type';
import { CHAT_TITLE } from '../../constants';
const FormItem = Form.Item;
@@ -44,7 +43,7 @@ const ConversationModal: React.FC<Props> = ({ visible, editConversation, onClose
return (
<Modal
title={`修改${CHAT_TITLE}问答名称`}
title="修改问答名称"
open={visible}
onCancel={onClose}
onOk={onConfirm}
@@ -53,7 +52,7 @@ const ConversationModal: React.FC<Props> = ({ visible, editConversation, onClose
<Form {...layout} form={form}>
<FormItem name="conversationName" label="名称" rules={[{ required: true }]}>
<Input
placeholder={`请输入${CHAT_TITLE}问答名称`}
placeholder="请输入问答名称"
ref={conversationNameInputRef}
onPressEnter={onConfirm}
/>

View File

@@ -4,6 +4,7 @@ import classNames from 'classnames';
import LeftAvatar from './CopilotAvatar';
import Message from './Message';
import styles from './style.module.less';
import { userAvatarUrl } from '../../common/env';
type Props = {
position: 'left' | 'right';
@@ -15,6 +16,7 @@ const Text: React.FC<Props> = ({ position, data, quote }) => {
const textWrapperClass = classNames(styles.textWrapper, {
[styles.rightTextWrapper]: position === 'right',
});
const rightAvatarUrl = userAvatarUrl;
return (
<div className={textWrapperClass}>
{!isMobile && position === 'left' && <LeftAvatar />}
@@ -22,6 +24,9 @@ const Text: React.FC<Props> = ({ position, data, quote }) => {
{position === 'right' && quote && <div className={styles.quote}>{quote}</div>}
<div className={styles.text}>{data}</div>
</Message>
{!isMobile && position === 'right' && rightAvatarUrl && (
<Avatar shape="circle" size={40} src={rightAvatarUrl} className={styles.rightAvatar} />
)}
</div>
);
};

View File

@@ -43,16 +43,8 @@ export const AGENT_ICONS = [
export const HOLDER_TAG = '@_supersonic_@';
export const CHAT_TITLE = '';
export const DEFAULT_CONVERSATION_NAME = '新问答对话';
export const PAGE_TITLE = '问答对话';
export const WEB_TITLE = '问答对话';
export const MOBILE_TITLE = '问答对话';
export const PLACE_HOLDER = '请输入您的问题,或输入“/”切换助理';
export const SIMPLE_PLACE_HOLDER = '请输入您的问题';

View File

@@ -15,7 +15,6 @@ import { useThrottleFn } from 'ahooks';
import Conversation from './Conversation';
import ChatFooter from './ChatFooter';
import classNames from 'classnames';
import { CHAT_TITLE } from './constants';
import { cloneDeep } from 'lodash';
import AgentList from './AgentList';
import MobileAgents from './MobileAgents';
@@ -59,7 +58,7 @@ const Chat: ForwardRefRenderFunction<any, Props> = (
const [historyInited, setHistoryInited] = useState(false);
const [currentConversation, setCurrentConversation] = useState<
ConversationDetailType | undefined
>(isMobile ? { chatId: 0, chatName: `${CHAT_TITLE}问答` } : undefined);
>(isMobile ? { chatId: 0, chatName: '问答' } : undefined);
const [historyVisible, setHistoryVisible] = useState(false);
const [agentList, setAgentList] = useState<AgentType[]>([]);
const [currentAgent, setCurrentAgent] = useState<AgentType>();

View File

@@ -14,6 +14,7 @@ import { AgentType } from '../Chat/type';
import { setToken } from '../utils/utils';
import { SendMsgParamsType } from '../common/type';
import styles from './style.module.less';
import { copilotTitle } from '../common/env';
type Props = {
token?: string;
@@ -123,7 +124,7 @@ const Copilot: ForwardRefRenderFunction<any, Props> = (
/>
)}
</div>
<div className={styles.title}></div>
<div className={styles.title}>{copilotTitle}</div>
</div>
<div className={styles.chat}>
<Chat

View File

@@ -0,0 +1,7 @@
export const proxyTarget = 'http://localhost:9080';
export const userAvatarUrl = '';
export const webPageHost = '';
export const copilotTitle = 'Copilot';

View File

@@ -183,7 +183,7 @@ export enum SemanticTypeEnum {
};
export const SEMANTIC_TYPE_MAP = {
[SemanticTypeEnum.DOMAIN]: '数据来源',
[SemanticTypeEnum.DOMAIN]: '数据模型',
[SemanticTypeEnum.DIMENSION]: '维度',
[SemanticTypeEnum.METRIC]: '指标',
[SemanticTypeEnum.VALUE]: '维度值',

View File

@@ -150,7 +150,6 @@ const FilterItem: React.FC<Props> = ({
onChange={onChange}
mode={isArray(filter.value) ? 'multiple' : undefined}
showSearch
// allowClear
/>
) : entityAlias &&
['歌曲', '艺人'].includes(entityAlias) &&

View File

@@ -78,7 +78,6 @@ const ParseTip: React.FC<Props> = ({
queryMode,
properties,
entity,
// entityInfo,
elementMatches,
nativeQuery,
} = currentParseInfo || {};
@@ -198,7 +197,7 @@ const ParseTip: React.FC<Props> = ({
<div className={`${prefixCls}-tip-item-filter-content`}>
<div className={`${prefixCls}-tip-item-option`}>
<span className={`${prefixCls}-tip-item-filter-name`}></span>
{dimensions?.some(item => item.bizName?.includes('_id')) ? (
{nativeQuery ? (
<span className={itemValueClass}>
{startDate === endDate ? startDate : `${startDate} ~ ${endDate}`}
</span>

View File

@@ -61,6 +61,11 @@ const Table: React.FC<Props> = ({ data, size, onApplyAuth }) => {
return index % 2 !== 0 ? `${prefixCls}-even-row` : '';
};
const dateColumn = queryColumns.find(column => column.type === 'DATE');
const dataSource = dateColumn
? queryResults.sort((a, b) => moment(a[dateColumn.nameEn]).diff(moment(b[dateColumn.nameEn])))
: queryResults;
return (
<div className={prefixCls}>
<AntTable
@@ -68,8 +73,8 @@ const Table: React.FC<Props> = ({ data, size, onApplyAuth }) => {
queryResults.length <= 10 ? false : { defaultPageSize: 10, position: ['bottomCenter'] }
}
columns={tableColumns}
dataSource={queryResults}
style={{ width: '100%', overflowX: 'auto' }}
dataSource={dataSource}
style={{ width: '100%', overflowX: 'auto', overflowY: 'hidden' }}
rowClassName={getRowClassName}
size={size}
/>

View File

@@ -1,6 +1,7 @@
import { useCallback, useEffect, useState } from 'react';
import { MsgDataType } from '../../../common/type';
import { getToken, isProd } from '../../../utils/utils';
import { webPageHost } from '../../../common/env';
type Props = {
id: string | number;
@@ -88,6 +89,7 @@ const WebPage: React.FC<Props> = ({ id, data }) => {
'?',
`?token=${getToken()}&miniProgram=true&reportName=${name}&filterData=${filterData}&`
);
urlValue = `${webPageHost}${urlValue}`;
} else {
const params = Object.keys(valueParams || {}).map(key => `${key}=${valueParams[key]}`);
if (params.length > 0) {

View File

@@ -2,7 +2,7 @@ import { Input } from 'antd';
import styles from './style.module.less';
import { useEffect, useState } from 'react';
import ChatItem from '../components/ChatItem';
import { searchRecommend } from '../service';
import { MsgDataType } from '../common/type';
const { Search } = Input;
@@ -10,8 +10,9 @@ const Chat = () => {
const [data, setData] = useState<any>();
const [inputMsg, setInputMsg] = useState('');
const [msg, setMsg] = useState('');
const [followQuestions, setFollowQuestions] = useState<string[]>([]);
const [triggerResize, setTriggerResize] = useState(false);
const [executeItemNode, setExecuteItemNode] = useState<React.ReactNode>();
const [chatItemVisible, setChatItemVisible] = useState(false);
const onWindowResize = () => {
setTriggerResize(true);
@@ -34,14 +35,24 @@ const Chat = () => {
const onSearch = () => {
setMsg(inputMsg);
setChatItemVisible(false);
setTimeout(() => {
setChatItemVisible(true);
}, 200);
};
const onMsgDataLoaded = (msgData: any) => {
const onMsgDataLoaded = (msgData: MsgDataType) => {
setData(msgData);
setFollowQuestions(['测试1234测试', '测试1234测试', '测试1234测试']);
const { queryColumns, queryResults, queryMode } = msgData;
const songIds = queryColumns.some(column => column.nameEn === 'zyqk_song_id')
? (queryResults || []).map(result => result['zyqk_song_id'])
: [];
if (queryMode === 'DSL') {
setExecuteItemNode(<>test</>);
}
};
// 5: 查信息6: 智能圈选
//预发环境: 5: 查信息6: 智能圈选12问指标15歌曲库16艺人库
return (
<div className={styles.page}>
@@ -53,15 +64,19 @@ const Chat = () => {
onSearch={onSearch}
/>
</div>
{inputMsg && (
{msg && chatItemVisible && (
<div className={styles.chatItem}>
<ChatItem
msg={msg}
// msgData={data}
agentId={6}
agentId={5}
conversationId={112211121}
onMsgDataLoaded={onMsgDataLoaded}
isLastMessage
triggerResize={triggerResize}
integrateSystem="wiki"
executeItemNode={executeItemNode}
isDeveloper
/>
</div>
)}

View File

@@ -35,14 +35,7 @@ const CopilotDemo = () => {
</Button>
))}
</Space>
<Copilot
// token={localStorage.getItem('SUPERSONIC_TOKEN') || ''}
// agentIds={[8]}
isDeveloper
// integrateSystem="c2"
ref={copilotRef}
// noInput
/>
<Copilot isDeveloper ref={copilotRef} />
</div>
);
};

View File

@@ -5,7 +5,7 @@ import './styles/index.less';
// import ChatDemo from './demo/ChatDemo';
// import CopilotDemo from './demo/CopilotDemo';
// const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
// root.render(<ChatDemo />);
// root.render(<Chat />);
export { default as Chat } from './Chat';

View File

@@ -1,9 +1,10 @@
import axios from './axiosInstance';
import { ChatContextType, DrillDownDimensionType, EntityInfoType, HistoryType, MsgDataType, ParseDataType, SearchRecommendItem } from '../common/type';
import { isMobile } from '../utils/utils';
const DEFAULT_CHAT_ID = 0;
const prefix = '/api';
const prefix = isMobile ? '/openapi' : '/api';
export function searchRecommend(queryText: string, chatId?: number, modelId?: number, agentId?: number) {
return axios.post<SearchRecommendItem[]>(`${prefix}/chat/query/search`, {

View File

@@ -1,10 +1,18 @@
const { createProxyMiddleware } = require('http-proxy-middleware');
const { proxyTarget } = require('./common/env');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:9080',
target: proxyTarget,
changeOrigin: true,
})
);
app.use(
'/openapi',
createProxyMiddleware({
target: proxyTarget,
changeOrigin: true,
})
);