Skip to content

Commit

Permalink
feat: 新增邀请和提成系统以及相关优化
Browse files Browse the repository at this point in the history
  • Loading branch information
79E committed Jun 16, 2023
1 parent 961b165 commit 5530c83
Show file tree
Hide file tree
Showing 36 changed files with 4,250 additions and 1,651 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ A commercially-viable ChatGpt web application built with React.
## 🐶 Demo
### Link

[Web Demo: https://www.aizj.top/](https://www.aizj.top/)
[demo: https://www.aizj.top/](https://www.aizj.top/)

[Web 演示: https://www.aizj.top/](https://www.aizj.top/)

[Admin Demo: https://www.aizj.top/admin](https://www.aizj.top/admin)

[Admin 演示: https://www.aizj.top/admin](https://www.aizj.top/admin)
```
演示地址:https://www.aizj.top
后台地址:https://www.aizj.top/admin
管理账号:[email protected]
管理密码:admin123
```

If you need help, please submit [Issues](https://github.com/79E/ChatGPT-Web/issues) Or leave contact information when appreciating.
### Snapshot
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "chatgpt-web",
"private": false,
"version": "1.2.2",
"version": "1.3.0",
"description": "ChatGPT Web",
"author": "79E",
"keywords": [
Expand Down Expand Up @@ -34,7 +34,7 @@
"express": "^4.18.2",
"express-async-errors": "^3.1.1",
"form-data": "^4.0.0",
"gpt-tokens": "^1.0.7",
"gpt-tokens": "^1.0.8",
"highlight.js": "^11.7.0",
"html2canvas": "^1.4.1",
"ioredis": "^5.3.2",
Expand Down
65 changes: 54 additions & 11 deletions src/components/LoginModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,37 @@ import {
import { LoginForm, ProFormCaptcha, ProFormText } from '@ant-design/pro-form'
import { Form, FormInstance, Modal, Space, Tabs } from 'antd'
import { useState } from 'react'
import { useNavigation, useLocation } from 'react-router-dom'

type Props = {
open: boolean
onCancel: () => void
}

type LoginType = 'code' | 'password' | string;
type LoginType = 'code' | 'password' | 'register' | string;

export function LoginCard(props: {
form: FormInstance<RequestLoginParams>
onSuccess: () => void
onSuccess: () => void,
type?: LoginType
}) {

const [loginType, setLoginType] = useState<LoginType>('code');
const location = useLocation();

function getQueryParam(key: string) {
const queryString = location.search || window.location.search;
const urlParams = new URLSearchParams(queryString);
return urlParams.get(key) || '';
}

const { type = 'password' } = props;

const [loginType, setLoginType] = useState<LoginType>(type);

return (
<LoginForm<RequestLoginParams>
form={props.form}
logo={import.meta.env.VITE_APP_LOGO}
logo="https://u1.dl0.cn/icon/openailogo.svg"
title=""
subTitle="全网最便宜的人工智能对话"
actions={(
Expand All @@ -46,10 +58,15 @@ export function LoginCard(props: {
maxWidth: '340px',
minWidth: '100px'
}}
submitter={{
searchConfig: {
submitText: loginType === 'register' ? '注册&登录' : '登录',
}
}}
onFinish={async (e) => {
return new Promise((resolve, reject) => {
userAsync
.fetchLogin({ ...e })
.fetchLogin({ ...e, invite_code: getQueryParam('invite_code') })
.then((res) => {
if (res.code) {
reject(false)
Expand All @@ -70,10 +87,21 @@ export function LoginCard(props: {
onChange={(activeKey) => {
setLoginType(activeKey)
}}
>
<Tabs.TabPane key="code" tab="登录/注册" />
<Tabs.TabPane key="password" tab="密码登录" />
</Tabs>
items={[
{
key: 'password',
label: '密码登录',
},
{
key: 'code',
label: '邮箱登录',
},
{
key: 'register',
label: '注册账号',
},
]}
/>
<ProFormText
fieldProps={{
size: 'large',
Expand All @@ -90,7 +118,7 @@ export function LoginCard(props: {
]}
/>
{
loginType === 'code' && (
loginType !== 'password' && (
<ProFormCaptcha
fieldProps={{
size: 'large',
Expand Down Expand Up @@ -134,7 +162,7 @@ export function LoginCard(props: {
)
}
{
loginType === 'password' && (
loginType !== 'code' && (
<ProFormText.Password
name="password"
fieldProps={{
Expand All @@ -152,6 +180,21 @@ export function LoginCard(props: {
/>
)
}
{/* <ProFormText
name="invite_code"
fieldProps={{
size: 'large',
prefix: <LockOutlined className={'prefixIcon'} />,
}}
placeholder="请输入密码"
rules={[
{
required: true,
message: '8位及以上至少包含一个字母和一个数字',
pattern: /^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z\d]{8,}$/
},
]}
/> */}
<div
style={{
marginBlockEnd: 24
Expand Down
19 changes: 13 additions & 6 deletions src/components/UserInfoCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,20 @@ function UserInfoCard(props: { info?: UserInfo, children?: React.ReactNode; })

const vipDay = useMemo(() => {
if (!props.info?.vip_expire_time) return 0
const today = new Date()
today.setHours(0, 0, 0, 0)
const todayTime = today.getTime()
const todayTime = new Date().getTime()
const vipExpireTime = new Date(props.info?.vip_expire_time || 0).getTime()
if (vipExpireTime < todayTime) return 0
const time = Math.ceil((vipExpireTime - todayTime) / 86400000)
return time
const second = vipExpireTime - todayTime
const day = second / 86400000
if(day < 1){
const s = Math.floor(second / 1000);
const h = Math.floor(s / 3600);
const m = Math.floor((s % 3600) / 60);
// const rs = s % 60;
return `${h}小时${m}分`
}

return Math.ceil(day) + '天'
}, [props])

const isSvip = useMemo(()=>{
Expand Down Expand Up @@ -53,7 +60,7 @@ function UserInfoCard(props: { info?: UserInfo, children?: React.ReactNode; })
<div className={styles.userInfo_vip}>
<Space wrap size="large">
<Statistic title="积分" value={info?.integral} />
<Statistic title="会员(天)" value={vipDay} />
<Statistic title="会员" value={vipDay} />
</Space>
</div>
</div>
Expand Down
Loading

0 comments on commit 5530c83

Please sign in to comment.