Skip to content

Commit

Permalink
feat: 新增密码登录&会话重试等操作
Browse files Browse the repository at this point in the history
  • Loading branch information
79E committed Jun 7, 2023
1 parent 17eda7e commit a9c26f9
Show file tree
Hide file tree
Showing 27 changed files with 1,297 additions and 536 deletions.
10 changes: 1 addition & 9 deletions README-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,12 @@ yarn build

## ⛺️ 环境变量

> 本项目大多数配置项都通过环境变量来设置。
> 如果是前后端分离模式部署项目则需要填以下配置
#### `VITE_APP_REQUEST_HOST`

请求服务端的`Host`地址。

#### `VITE_APP_TITLE`

Chat Web 标题名称。

#### `VITE_APP_LOGO`

Chat Web Logo。

## 🚧 开发

> 强烈不建议在本地进行开发或者部署,由于一些技术原因,很难在本地配置好 OpenAI API 代理,除非你能保证可以直连 OpenAI 服务器。
Expand Down
10 changes: 1 addition & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,20 +87,12 @@ yarn build

## ⛺️ Environment Variable

> Most configuration items in this project are set through environment variables.
> If it is a front-end and back-end separation mode deployment project, the following configuration needs to be filled in
#### `VITE_APP_REQUEST_HOST`

Request the `Host` address of the server.

#### `VITE_APP_TITLE`

Chat Web title.

#### `VITE_APP_LOGO`

Chat Web Logo.

## 🚧 Develop

> It is strongly not recommended to develop or deploy locally. Due to technical reasons, it is difficult to configure OpenAI API proxies locally, unless you can guarantee direct connection to the OpenAI server.
Expand Down
2 changes: 1 addition & 1 deletion src/components/ConfigModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function ConfigModal(props: Props) {
<ProFormSlider name="limit_message" max={10} min={0} step={1} />
</FormItemCard> */}
<FormItemCard title="随机性" describe="值越大,回复越随机,大于 1 的值可能会导致乱码">
<ProFormSlider name="temperature" max={2} min={-2} step={0.1} />
<ProFormSlider name="temperature" max={2} min={0} step={0.1} />
</FormItemCard>
<FormItemCard title="话题新鲜度" describe="值越大,越有可能扩展到新话题">
<ProFormSlider name="presence_penalty" max={2} min={-2} step={0.1} />
Expand Down
27 changes: 21 additions & 6 deletions src/components/FormItemCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,41 @@
import useDocumentResize from '@/hooks/useDocumentResize'
import styles from './index.module.less'
import { useMemo } from 'react'

type Props = {
title: string
describe: string
describe?: string
direction?: 'vertical' | 'horizontal'
children?: React.ReactNode
}

function FormItemCard(props: Props) {

const { direction = 'horizontal' } = props;

const { width } = useDocumentResize()

const style: React.CSSProperties = useMemo(()=>{
if(direction === 'vertical'){
return {
flexDirection: 'column',
alignItems: 'normal'
}
}
return {
flexDirection: width < 600 ? 'column' : 'row',
alignItems: width < 600 ? 'normal' : 'center'
}
}, [direction, width])

return (
<div
className={styles.formItemCard}
style={{
flexDirection: width < 600 ? 'column' : 'row',
alignItems: width < 600 ? 'normal' : 'center'
}}
style={style}
>
<div className={styles.formItemCard_text}>
<p>{props.title}</p>
<span>{props.describe}</span>
{props.describe && <span>{props.describe}</span>}
</div>
<div className={styles.formItemCard_field}>{props.children}</div>
</div>
Expand Down
4 changes: 3 additions & 1 deletion src/components/GoodsList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ProductInfo } from '@/types'
import styles from './index.module.less'
import { useEffect, useState } from 'react'
import { QuestionCircleOutlined } from '@ant-design/icons';
import { Popover } from 'antd';

function GoodsList(props: { list: Array<ProductInfo>; onChange: (item: ProductInfo) => void }) {
const [selectItem, setSelectItem] = useState<ProductInfo>()
Expand All @@ -26,7 +28,7 @@ function GoodsList(props: { list: Array<ProductInfo>; onChange: (item: ProductIn
setSelectItem(item)
}}
>
<p className={styles.goodsList_item_level}>{ item.level === 1 ? '会员' : item.level === 2 ? '超级会员' : '超级特惠' }</p>
<p className={styles.goodsList_item_level}>{ item.level === 1 ? '会员' : item.level === 2 ? '超级会员' : '超级特惠' } {item?.describe && <Popover content={item.describe} title={item.title}><QuestionCircleOutlined /></Popover>}</p>
{item.type === 'integral' ? <h3>{item.value}积分</h3> : <h3>{item.value}</h3>}
<div className={styles.goodsList_item_price}>
<p className={styles.sales_price}>{(item.price / 100).toFixed(2)}<span></span></p>
Expand Down
161 changes: 101 additions & 60 deletions src/components/Layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,68 +1,109 @@
import { MenuDataItem, ProLayout } from '@ant-design/pro-components';
import HeaderRender from '../HeaderRender';
import { ChatsInfo } from '@/types';
import React from 'react';
import { MenuProps } from 'antd';
import { MenuDataItem, ProLayout } from '@ant-design/pro-components'
import HeaderRender from '../HeaderRender'
import { ChatsInfo } from '@/types'
import React, { useEffect } from 'react'
import { MenuProps } from 'antd'
import { configStore } from '@/store'

type Props = {
menuExtraRender?: () => React.ReactNode,
route?: {
path: string,
routes: Array<ChatsInfo>
menuExtraRender?: () => React.ReactNode
route?: {
path: string
routes: Array<ChatsInfo>
}
menuItemRender?: (
item: MenuDataItem & {
isUrl: boolean
onClick: () => void
},
menuItemRender?:(item: MenuDataItem & {
isUrl: boolean;
onClick: () => void;
}, defaultDom: React.ReactNode, menuProps: MenuProps | any) => React.ReactNode | undefined,
menuDataRender?: ((menuData: MenuDataItem[]) => MenuDataItem[]),
menuFooterRender?: (props?: any) => React.ReactNode,
menuProps?: MenuProps,
children?: React.ReactNode
defaultDom: React.ReactNode,
menuProps: MenuProps | any
) => React.ReactNode | undefined
menuDataRender?: (menuData: MenuDataItem[]) => MenuDataItem[]
menuFooterRender?: (props?: any) => React.ReactNode
menuProps?: MenuProps
children?: React.ReactNode
}

function Layout(props: Props) {
const { menuExtraRender = () => <></>, menuItemRender = ()=> undefined } = props;
return (
<ProLayout
title={import.meta.env.VITE_APP_TITLE}
logo={import.meta.env.VITE_APP_LOGO}
layout="mix"
splitMenus={false}
contentWidth="Fluid"
fixedHeader
fixSiderbar
headerRender={HeaderRender}
contentStyle={{
height: 'calc(100vh - 56px)',
background: '#fff'
}}
siderMenuType="group"
style={{
background: '#fff'
}}
menu={{
hideMenuWhenCollapsed: true,
locale: false,
collapsedShowGroupTitle: false
}}
suppressSiderWhenMenuEmpty
siderWidth={300}
menuExtraRender={menuExtraRender}
menuItemRender={menuItemRender}
route={props.route}
menuDataRender={props.menuDataRender}
avatarProps={{
src: 'https://cdn.jsdelivr.net/gh/duogongneng/testuitc/1682426702646avatarf3db669b024fad66-1930929abe2847093.png',
size: 'small',
render: (props, dom) => <>{dom}</>
}}
menuFooterRender={props.menuFooterRender}
menuProps={props.menuProps}
breadcrumbRender={() => []}
>
{props.children}
</ProLayout>
)
const { menuExtraRender = () => <></>, menuItemRender = () => undefined } = props

const { website_logo, website_title, website_footer, website_description, website_keywords } =
configStore()

function createMetaElement(key: string, value: string) {
const isMeta = document.querySelector(`meta[name="${key}"]`)
if (!isMeta) {
const head = document.querySelector('head')
const meta = document.createElement('meta')
meta.name = key
meta.content = value
head?.appendChild(meta)
}
}

useEffect(() => {
createMetaElement('description', website_description)
createMetaElement('keywords', website_keywords)
}, [])

return (
<ProLayout
title={website_title}
logo={website_logo}
layout="mix"
splitMenus={false}
contentWidth="Fluid"
fixedHeader
fixSiderbar
headerRender={HeaderRender}
contentStyle={{
height: 'calc(100vh - 56px)',
background: '#fff'
}}
siderMenuType="group"
style={{
background: '#fff'
}}
menu={{
hideMenuWhenCollapsed: true,
locale: false,
collapsedShowGroupTitle: false
}}
suppressSiderWhenMenuEmpty
siderWidth={300}
menuExtraRender={menuExtraRender}
menuItemRender={menuItemRender}
route={props.route}
menuDataRender={props.menuDataRender}
avatarProps={{
src: 'https://u1.dl0.cn/icon/1682426702646avatarf3db669b024fad66-1930929abe2847093.png',
size: 'small',
render: (p, dom) => <>{dom}</>
}}
menuFooterRender={(p) => {
return (
<div>
{props.menuFooterRender?.(p)}
{website_footer && (
<div
style={{
marginTop: 12
}}
dangerouslySetInnerHTML={{
__html: website_footer
}}
/>
)}
</div>
)
}}
menuProps={props.menuProps}
breadcrumbRender={() => []}
>
{props.children}
</ProLayout>
)
}

export default Layout;
export default Layout
3 changes: 2 additions & 1 deletion src/components/Reminder/index.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
&_message{
font-size: 16px;
color: #26334b;
margin-top: 4px;
margin-top: 8px;
line-height: 1.5;
span{
padding: 2px 8px;
border: 1px solid #26334b;
Expand Down
Loading

0 comments on commit a9c26f9

Please sign in to comment.