Commit 4b431dc7 authored by littleforest's avatar littleforest
parents ce56df68 06cce791
import logoSvg from '../../assets/logo.svg'; import logoSvg from '../../assets/logo.svg';
import copySvg from '../../assets/copy.svg'; import copySvg from '../../assets/copy.svg';
import { Button, Grid } from 'antd'; import { Button, Col, Grid, Row } from 'antd';
import styles from './index.less'; import styles from './index.less';
import classNames from 'classnames';
interface IAnswerProps { interface IAnswerProps {
answerValue: string; answerValue: string;
...@@ -17,60 +18,50 @@ const Answer = (props: IAnswerProps) => { ...@@ -17,60 +18,50 @@ const Answer = (props: IAnswerProps) => {
const isMobile = screens.xs; const isMobile = screens.xs;
return ( return (
<div> <Col span={24}>
<p className={styles.question} style={{ marginTop: isMobile ? '20px' : '40px' }}> <Row>
<img src={logoSvg} alt="" className={styles.question_img } /> <Col span={24}>
<span <p className={styles.question} style={{ marginTop: isMobile ? '20px' : '40px' }}>
className={styles.question_span} <img src={logoSvg} alt="" className={styles.question_img} />
style={{ <span
marginLeft: isMobile ? '8px' : '16px', className={classNames(isMobile && styles.mobile_question_span, styles.question_span)}
fontSize: isMobile ? '18px': '20px', style={{ marginLeft: isMobile ? '8px' : '16px' }}
}}> >
回答如下: 回答如下:
</span> </span>
</p> </p>
<div className={styles.chat}> </Col>
<div <Col span={24} className={styles.chat}>
className={styles.answer} <div className={classNames(styles.answer, isMobile && styles.mobile_answer)}>
style={{ <div className={styles.answer}>
width: isMobile ? '316px' : '900px', {!answerValue ? (
fontSize: isMobile ? '16px': '18px', <p style={{ color: '#666666' }}>请耐心等待3-5秒~</p>
lineHeight: isMobile ? '28px': '32px', ) : (
}} <p dangerouslySetInnerHTML={{ __html: answerValue }}></p>
> )}
{ </div>
!isMobile && {!isMobile && answerValue && (
<p <p className={styles.copyAnswer} onClick={() => {}}>
className={styles.copyAnswer}
onClick={() => {
}}
>
<img src={copySvg} alt="" /> <img src={copySvg} alt="" />
<span>复制回答</span> <span>复制回答</span>
</p> </p>
} )}
{!answerValue ? ( </div>
<p className={styles.answerValue}>请耐心等待3-5秒~</p> {isShowRetry && !isMobile && <Button className={styles.chat_retry}>重试</Button>}
) : ( </Col>
<p className={styles.answerValue} dangerouslySetInnerHTML={{ __html: answerValue }}></p> <Col>
{isMobile && answerValue && (
<Row justify={'center'} className={styles.mobile_button}>
<Button className={styles.mobile_copyAnswer}>
<img src={copySvg} alt="" />
<span>复制回答</span>
</Button>
<Button className={styles.mobile_chat_retry}>重试</Button>
</Row>
)} )}
</div> </Col>
{ </Row>
isShowRetry && !isMobile && <Button className={styles.chat_retry}>重试</Button> </Col>
}
</div>
{
isMobile &&
<div className={styles.mobile_button}>
<Button className={styles.mobile_copyAnswer}>
<img src={copySvg} alt="" />
<span>复制回答</span>
</Button>
<Button className={styles.mobile_chat_retry}>重试</Button>
</div>
}
</div>
); );
}; };
......
@import (reference) '~antd/es/style/themes/index'; @import (reference) '~antd/es/style/themes/index';
.mobile_newSession {
width: 100% !important;
margin-top: 24px !important;
padding: 48px 16px 16px;
}
.mobile_question_span {
font-size: 18px !important;
}
.mobile_answer {
// width: 316px !important;
font-size: 16px !important;
line-height: 28px !important;
}
.newSession { .newSession {
width: 1000px; margin-top: 0px;
margin-top: 40px;
.question { .question {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
...@@ -20,25 +35,28 @@ ...@@ -20,25 +35,28 @@
.chat { .chat {
display: flex; display: flex;
width: 100vw;
padding-left: 28px;
// justify-content: center;
.answer { .answer {
position: relative; width: 100%;
width: 900px; padding: 4px 8px;
min-height: 268px;
margin-left: 28px;
color: rgba(0, 0, 0, 0.85); color: rgba(0, 0, 0, 0.85);
font-size: 18px; font-size: 16px;
line-height: 32px; line-height: 32px;
white-space: pre-wrap;
word-wrap: break-word;
background: #f0f3f6; background: #f0f3f6;
border-radius: 4px; border-radius: 4px;
.copyAnswer { .copyAnswer {
position: absolute;
right: 16px;
bottom: 0;
z-index: 2; z-index: 2;
padding-right: 16px;
text-align: right;
cursor: pointer; cursor: pointer;
img { img {
width: 24px; width: 24px;
height: 24px; height: 24px;
padding-left: 2px;
} }
span { span {
height: 24px; height: 24px;
...@@ -55,7 +73,7 @@ ...@@ -55,7 +73,7 @@
.chat_retry { .chat_retry {
width: 90px; width: 90px;
height: 48px; height: 48px;
margin-left: 10px; // margin-left: 10px;
background: #ffffff; background: #ffffff;
border: 1px solid #009b95; border: 1px solid #009b95;
border-radius: 6px; border-radius: 6px;
...@@ -74,7 +92,7 @@ ...@@ -74,7 +92,7 @@
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
margin-top: 16px; margin-top: 16px;
margin-left: 24px; margin-left: 28px;
.mobile_copyAnswer { .mobile_copyAnswer {
width: 151px; width: 151px;
height: 40px; height: 40px;
...@@ -94,6 +112,7 @@ ...@@ -94,6 +112,7 @@
.mobile_chat_retry { .mobile_chat_retry {
width: 151px; width: 151px;
height: 40px; height: 40px;
margin-left: 12px;
color: #009b95; color: #009b95;
background: #ffffff; background: #ffffff;
border: 1px solid #009b95; border: 1px solid #009b95;
......
import styles from './index.less'; import styles from './index.less';
import Issue from './issue.component'; import Issue from './issue.component';
import Answer from './answer.component'; import Answer from './answer.component';
import { Grid } from 'antd'; import { Grid, Row } from 'antd';
import classNames from 'classnames';
interface INewSessionProps { interface INewSessionProps {
questionValue: string; questionValue: string;
...@@ -17,13 +18,16 @@ const NewSession = (props: INewSessionProps) => { ...@@ -17,13 +18,16 @@ const NewSession = (props: INewSessionProps) => {
const isMobile = screens.xs; const isMobile = screens.xs;
return ( return (
<div className={styles.newSession} style={{ <Row
padding: isMobile ? '4px 16px 16px' : '0', style={{
width: isMobile ? '100%' : '1000px' padding: isMobile ? '' : '0 0 0 72px !important',
}}> width: isMobile ? '100vw' : 'calc(100vw - 240px - 144px)',
}}
className={classNames(isMobile && styles.mobile_newSession, styles.newSession)}
>
<Issue questionValue={questionValue} /> <Issue questionValue={questionValue} />
<Answer answerValue={answerValue} /> <Answer answerValue={answerValue} />
</div> </Row>
); );
}; };
......
import classNames from 'classnames'; import classNames from 'classnames';
import userSvg from '../../assets/user.svg'; import userSvg from '../../assets/user.svg';
import styles from './index.less'; import styles from './index.less';
import { Grid } from 'antd'; import { Col, Grid } from 'antd';
interface IIssueProps { interface IIssueProps {
questionValue: string; questionValue: string;
...@@ -10,7 +10,6 @@ interface IIssueProps { ...@@ -10,7 +10,6 @@ interface IIssueProps {
const { useBreakpoint } = Grid; const { useBreakpoint } = Grid;
const Issue = (props: IIssueProps) => { const Issue = (props: IIssueProps) => {
const { questionValue } = props; const { questionValue } = props;
const screens = useBreakpoint(); const screens = useBreakpoint();
...@@ -19,19 +18,16 @@ const Issue = (props: IIssueProps) => { ...@@ -19,19 +18,16 @@ const Issue = (props: IIssueProps) => {
console.log('isMobile', isMobile); console.log('isMobile', isMobile);
return ( return (
<div className={styles.question} style={{ marginTop: isMobile ? '20px' : '40px' }}> <Col span={24} className={styles.question} style={{ marginTop: isMobile ? '0px' : '40px' }}>
<img src={userSvg} alt="" className={styles.question_img } /> <img src={userSvg} alt="" className={styles.question_img} />
<span <span
className={styles.question_span} className={classNames(isMobile && styles.mobile_question_span, styles.question_span)}
style={{ style={{ marginLeft: isMobile ? '8px' : '16px' }}
marginLeft: isMobile ? '8px' : '16px',
fontSize: isMobile ? '18px': '20px',
}}
> >
{questionValue} {questionValue}
</span> </span>
</div> </Col>
); );
} };
export default Issue; export default Issue;
\ No newline at end of file
...@@ -12,6 +12,11 @@ body, ...@@ -12,6 +12,11 @@ body,
height: 100%; height: 100%;
} }
body {
margin: 0;
padding: 0;
}
.colorWeak { .colorWeak {
filter: invert(80%); filter: invert(80%);
} }
......
...@@ -2,8 +2,5 @@ ...@@ -2,8 +2,5 @@
padding: 8px; padding: 8px;
} }
.CardContent { .CardContent {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-bottom: 150px; margin-bottom: 150px;
} }
import { Row, Col, Grid } from 'antd'; import { Row, Col, Grid } from 'antd';
import type { FC } from 'react'; import type { FC } from 'react';
import styles from './content.less'; import styles from './content.less';
import ProductionCard from './productionCard'; import ProductionCard from './productionCard';
import { IPromptWord } from '@/services/chatGLM/api';
const { useBreakpoint } = Grid;
const { useBreakpoint } = Grid;
interface ChatFirstContentProps {
onChange?: (text: string) => void; interface ChatFirstContentProps {
} list: IPromptWord[];
onChange?: (text: string) => void;
const ChatFirstContent: FC<ChatFirstContentProps> = (props) => { }
const { onChange } = props;
const screen = useBreakpoint(); const ChatFirstContent: FC<ChatFirstContentProps> = (props) => {
const isMobile = screen.xs; const { onChange, list } = props;
const cardList = [
{ return (
title: '市场营销', <div className={styles.CardContent}>
content: <Row>
'请为我编写一个杨过大战钢铁侠的额电影脚本,要足够精彩,细节丰富,好像好莱坞大片,有场景有对话,叨叨剧本要求', {list.map((item, index) => {
onclick: (text: string) => { return (
onChange && onChange(text); <Col
}, lg={12}
}, md={12}
{ span={8}
title: '技术文档', xs={24}
content: '请为我们的新款智能手表撰写一份产品说明书,包括功能,使用方法和注意事项', sm={12}
onclick: (text: string) => { xl={8}
onChange && onChange(text); xxl={8}
}, key={`${item.title}-card-${index}`}
}, >
{ <Row justify={'start'} style={{ marginBottom: 16, minWidth: 306 }}>
title: '灵感提示', <ProductionCard
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项', index={index}
onclick: (text: string) => { title={item.title}
onChange && onChange(text); content={item.content}
}, onChange={() => {
}, onChange && onChange(item.content);
{ }}
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项', />
onclick: (text: string) => { </Row>
onChange && onChange(text); </Col>
}, );
}, })}
{ </Row>
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项', </div>
onclick: (text: string) => { );
onChange && onChange(text); };
},
}, export default ChatFirstContent;
{
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项',
onclick: (text: string) => {
onChange && onChange(text);
},
},
{
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项',
onclick: (text: string) => {
onChange && onChange(text);
},
},
{
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项',
onclick: (text: string) => {
onChange && onChange(text);
},
},
{
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项',
onclick: (text: string) => {
onChange && onChange(text);
},
},
];
return (
<div className={styles.CardContent}>
<Row gutter={1}>
{cardList.map((item, index) => {
return (
<Col lg={8} md={12} span={8} xs={24} sm={16} key={`${item.title}-card-${index}`}>
<Row justify={isMobile && 'center'} className={styles.cardPadding}>
<ProductionCard title={item.title} content={item.content} onChange={item.onclick} />
</Row>
</Col>
);
})}
</Row>
</div>
);
};
export default ChatFirstContent;
.CardWrapper { .CardWrapper {
width: 306px; width: 100%;
cursor: pointer; padding: 0 16px;
&:hover .CardContent { cursor: pointer;
background-color: #0a7a73; &:hover .CardContent {
&:hover .content { background-color: #0a7a73;
color: white; &:hover .content {
} color: white;
&:hover .button { }
color: #0a7a73; &:hover .button {
background-color: white; color: #0a7a73;
border: solid 1px white; background-color: white;
} border: solid 1px white;
} }
.title { }
padding: 5px; .title {
color: #333333; padding-bottom: 10px;
font-weight: 600; color: #333333;
font-size: 22px; font-weight: 600;
line-height: 26px; font-size: 20px;
text-align: center; text-align: center;
} }
.CardContent { .CardContent {
padding: 16px 24px; padding: 16px 16px;
background-color: #f8f9fb; background-color: #f8f9fb;
border-radius: 5px; border-radius: 5px;
transition: all 0.25s; transition: all 0.25s;
.content { .content {
height: 204px; display: -webkit-box;
padding: 12px 8px; height: 202px;
color: #666666; overflow: hidden;
font-weight: 400; color: #666666;
font-size: 14px; font-weight: 400;
line-height: 28px; font-size: 18px;
} line-height: 28px;
.button { white-space: normal;
width: 180px; text-overflow: ellipsis;
margin: 0 auto; -webkit-box-orient: vertical;
padding: 6px 24px; -webkit-line-clamp: 7;
color: #0a7a73; }
font-size: 16px; .button {
text-align: center; width: 180px;
border: solid 1px #0a7a73; margin: 0 auto;
border-radius: 5px; padding: 6px 24px;
} color: #0a7a73;
} font-weight: 500;
} font-size: 16px;
text-align: center;
border: solid 1px #0a7a73;
border-radius: 5px;
}
}
}
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import styles from './productionCard.less'; import styles from './productionCard.less';
import classnames from 'classnames'; import classnames from 'classnames';
interface ProductionCardProps { interface ProductionCardProps {
title?: string; index: number;
content: ReactNode; title?: string;
onChange: (content: string) => void; content: ReactNode;
} onChange: (content: string) => void;
}
const ProductionCard = (props: ProductionCardProps) => {
const { title, content, onChange } = props; const ProductionCard = (props: ProductionCardProps) => {
const { index, title, content, onChange } = props;
const handleClick = () => {
onChange && onChange(content); const handleClick = () => {
}; onChange && onChange(content);
};
return (
<div className={classnames(styles.CardWrapper)}> return (
<div className={styles.title}>{title}</div> <div className={classnames(styles.CardWrapper)}>
<div className={styles.CardContent}> <div className={styles.title}>{title}</div>
<div className={styles.content}>{content}</div> <div className={styles.CardContent}>
<div className={styles.button} onClick={handleClick}> <div className={styles.content}>{content}</div>
试一下看看 <div className={styles.button} onClick={handleClick}>
</div> 试一下看看
</div> </div>
</div> </div>
); </div>
}; );
};
export default ProductionCard;
export default ProductionCard;
...@@ -3,16 +3,15 @@ ...@@ -3,16 +3,15 @@
.chatContent { .chatContent {
background: white !important; background: white !important;
} }
.siderWrapper { .siderWrapper {
background: white; background: white;
.sider { .sider {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
z-index: 100;
width: 240px; width: 240px;
min-height: 100vh; min-height: 100vh;
padding: 30px 20px;
background-color: #001529; background-color: #001529;
.siderChatContent { .siderChatContent {
height: 70%; height: 70%;
...@@ -26,12 +25,13 @@ ...@@ -26,12 +25,13 @@
} }
} }
.header { .header {
margin-top: 68px; margin-top: 80px;
margin-bottom: 40px;
color: #333; color: #333;
font-size: 32px; font-size: 32px;
line-height: 45px;
text-align: center; text-align: center;
.subTitle { .subTitle {
margin-bottom: 0;
color: #999999; color: #999999;
font-weight: 400; font-weight: 400;
} }
...@@ -68,11 +68,28 @@ ...@@ -68,11 +68,28 @@
} }
} }
.chatFooter {
position: fixed;
bottom: 0;
left: 0;
width: 240px;
width: 100%;
margin-bottom: 52px;
}
.chatFooterItem {
margin-left: 64px;
padding: 19px 0px;
color: #ffffff;
font-size: 18px;
line-height: 25px;
}
.footer { .footer {
position: fixed; position: fixed;
bottom: 0; bottom: 0;
left: 0; left: 0;
z-index: 10; z-index: 12;
width: 100%; width: 100%;
height: 150px; height: 150px;
padding: 16px; padding: 16px;
...@@ -80,7 +97,7 @@ ...@@ -80,7 +97,7 @@
background-color: white; background-color: white;
box-shadow: 0 2px 8px #f0f1f2; box-shadow: 0 2px 8px #f0f1f2;
.chatWrapper { .chatWrapper {
padding: 0 16px 0 50px; border-radius: 4px;
:global { :global {
.ant-input:focus, .ant-input:focus,
.ant-input:hover, .ant-input:hover,
...@@ -94,10 +111,10 @@ ...@@ -94,10 +111,10 @@
} }
} }
.outputButtonWrapper { .outputButtonWrapper {
width: 120px;
:global(.ant-btn-primary) { :global(.ant-btn-primary) {
background: #009b95; background: #009b95;
border: solid 1px #009b95; border: solid 1px #009b95;
border-radius: 6px !important;
} }
} }
} }
......
This diff is collapsed.
...@@ -10,10 +10,10 @@ const request = extend({}); ...@@ -10,10 +10,10 @@ const request = extend({});
request.interceptors.request.use((url, options) => { request.interceptors.request.use((url, options) => {
const token = JSON.parse(localStorage.getItem('user') || '{}')?.token; const token = JSON.parse(localStorage.getItem('user') || '{}')?.token;
const authHeader = { const authHeader = {
Authorization: `Bearer ${token || ''}`, Authorization: `Bearer ${token || ''}`,
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'__tenant': '3a0a90fe-9a0d-70f4-200d-a80a41fb6195' __tenant: '3a0a90fe-9a0d-70f4-200d-a80a41fb6195',
}; };
return { return {
url: url, url: url,
...@@ -21,19 +21,18 @@ request.interceptors.request.use((url, options) => { ...@@ -21,19 +21,18 @@ request.interceptors.request.use((url, options) => {
}; };
}); });
request.interceptors.response.use(async (response): Promise<any> => { request.interceptors.response.use(async (response): Promise<any> => {
console.log('response', response); console.log('response', response);
if(response.status === 401) { if (response.status === 401) {
localStorage.removeItem('user'); localStorage.removeItem('user');
history.push('/chat'); history.push('/chat');
} else if(response.status === 200) { } else if (response.status === 200) {
return response; return response;
} else { } else {
message.error('请求失败,请重试! ') message.error('请求失败,请重试! ');
return Promise.reject(response.statusText); return Promise.reject(response.statusText);
} }
}) });
export function loginChatGLM(options: ILoginParams) { export function loginChatGLM(options: ILoginParams) {
return request('https://glm-mangement-api.baibaomen.com/api/app/account/login', { return request('https://glm-mangement-api.baibaomen.com/api/app/account/login', {
...@@ -42,34 +41,58 @@ export function loginChatGLM(options: ILoginParams) { ...@@ -42,34 +41,58 @@ export function loginChatGLM(options: ILoginParams) {
}); });
} }
export interface IPromptWord {
title: string;
content: string;
}
export function GetChatGLMToken(): Promise<string> { export function GetChatGLMToken(): Promise<string> {
return request('https://glm-mangement-api.baibaomen.com/user/token', { return request('https://glm-mangement-api.baibaomen.com/user/token', {
method: 'POST', method: 'POST',
}); });
} }
export function GetPromptList(): Promise<{ items: IPromptWord[] }> {
return request('https://glm-mangement-api.baibaomen.com/promptwords/page', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + JSON.parse(localStorage.getItem('user') || '')?.token,
'Content-Type': 'application/json',
},
body: JSON.stringify({ pageIndex: 0, pageSize: 10 }),
});
}
type History = [string, string];
interface ITalkParams {
prompt: string;
history: History[];
max_length?: number;
top_p?: number;
temperature?: number;
}
export const CreatedAccount = (params: any): Promise<string> => { export const CreatedAccount = (params: any): Promise<string> => {
return request('https://glm-mangement-api.baibaomen.com/User/create', { return request('https://glm-mangement-api.baibaomen.com/User/create', {
method: 'POST', method: 'POST',
params params,
}); });
} };
export const getRole = (params?: any): Promise<string> => { export const getRole = (params?: any): Promise<string> => {
return request('https://glm-mangement-api.baibaomen.com/User/roles', { return request('https://glm-mangement-api.baibaomen.com/User/roles', {
method: 'POST', method: 'POST',
params params,
}) });
} };
export const getUserMessage = (params?: any): Promise<string> => { export const getUserMessage = (params?: any): Promise<string> => {
return request('https://glm-mangement-api.baibaomen.com/User/page', { return request('https://glm-mangement-api.baibaomen.com/User/page', {
method: 'POST', method: 'POST',
data: params data: params,
}); });
} };
export const postDeleteUser = (params?: any): Promise<string>=> { export const postDeleteUser = (params?: any): Promise<string> => {
return request('https://glm-mangement-api.baibaomen.com/User/delete', { return request('https://glm-mangement-api.baibaomen.com/User/delete', {
method: 'POST', method: 'POST',
params params
...@@ -79,6 +102,6 @@ export const postDeleteUser = (params?: any): Promise<string>=> { ...@@ -79,6 +102,6 @@ export const postDeleteUser = (params?: any): Promise<string>=> {
export const postResetUser = (params?: any): Promise<string> => { export const postResetUser = (params?: any): Promise<string> => {
return request('https://glm-mangement-api.baibaomen.com/User/delete', { return request('https://glm-mangement-api.baibaomen.com/User/delete', {
method: 'POST', method: 'POST',
data: params data: params,
}) });
} };
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment