mirror of
https://github.com/songquanpeng/one-api.git
synced 2025-12-19 06:15:56 +08:00
feat: add new theme berry (#860)
* feat: add theme berry * docs: add development notes * fix: fix blank page * chore: update implementation * fix: fix package.json * chore: update ui copy --------- Co-authored-by: JustSong <songquanpeng@foxmail.com>
This commit is contained in:
80
web/berry/src/views/Topup/component/InviteCard.js
Normal file
80
web/berry/src/views/Topup/component/InviteCard.js
Normal file
@@ -0,0 +1,80 @@
|
||||
import { Stack, Typography, Container, Box, OutlinedInput, InputAdornment, Button } from '@mui/material';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import SubCard from 'ui-component/cards/SubCard';
|
||||
import inviteImage from 'assets/images/invite/cwok_casual_19.webp';
|
||||
import { useState } from 'react';
|
||||
import { API } from 'utils/api';
|
||||
import { showError, showSuccess } from 'utils/common';
|
||||
|
||||
const InviteCard = () => {
|
||||
const theme = useTheme();
|
||||
const [inviteUl, setInviteUrl] = useState('');
|
||||
|
||||
const handleInviteUrl = async () => {
|
||||
if (inviteUl) {
|
||||
navigator.clipboard.writeText(inviteUl);
|
||||
showSuccess(`邀请链接已复制到剪切板`);
|
||||
return;
|
||||
}
|
||||
const res = await API.get('/api/user/aff');
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
let link = `${window.location.origin}/register?aff=${data}`;
|
||||
setInviteUrl(link);
|
||||
navigator.clipboard.writeText(link);
|
||||
showSuccess(`邀请链接已复制到剪切板`);
|
||||
} else {
|
||||
showError(message);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box component="div">
|
||||
<SubCard
|
||||
sx={{
|
||||
background: theme.palette.primary.dark
|
||||
}}
|
||||
>
|
||||
<Stack justifyContent="center" alignItems={'flex-start'} padding={'40px 24px 0px'} spacing={3}>
|
||||
<Container sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
||||
<img src={inviteImage} alt="invite" width={'250px'} />
|
||||
</Container>
|
||||
</Stack>
|
||||
</SubCard>
|
||||
<SubCard
|
||||
sx={{
|
||||
marginTop: '-20px'
|
||||
}}
|
||||
>
|
||||
<Stack justifyContent="center" alignItems={'center'} spacing={3}>
|
||||
<Typography variant="h3" sx={{ color: theme.palette.primary.dark }}>
|
||||
邀请奖励
|
||||
</Typography>
|
||||
<Typography variant="body" sx={{ color: theme.palette.primary.dark }}>
|
||||
分享您的邀请链接,邀请好友注册,即可获得奖励!
|
||||
</Typography>
|
||||
|
||||
<OutlinedInput
|
||||
id="invite-url"
|
||||
label="邀请链接"
|
||||
type="text"
|
||||
value={inviteUl}
|
||||
name="invite-url"
|
||||
placeholder="点击生成邀请链接"
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<Button variant="contained" onClick={handleInviteUrl}>
|
||||
{inviteUl ? '复制' : '生成'}
|
||||
</Button>
|
||||
</InputAdornment>
|
||||
}
|
||||
aria-describedby="helper-text-channel-quota-label"
|
||||
disabled={true}
|
||||
/>
|
||||
</Stack>
|
||||
</SubCard>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default InviteCard;
|
||||
122
web/berry/src/views/Topup/component/TopupCard.js
Normal file
122
web/berry/src/views/Topup/component/TopupCard.js
Normal file
@@ -0,0 +1,122 @@
|
||||
import { Typography, Stack, OutlinedInput, InputAdornment, Button, InputLabel, FormControl } from '@mui/material';
|
||||
import { IconWallet } from '@tabler/icons-react';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import SubCard from 'ui-component/cards/SubCard';
|
||||
import UserCard from 'ui-component/cards/UserCard';
|
||||
|
||||
import { API } from 'utils/api';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { showError, showInfo, showSuccess, renderQuota } from 'utils/common';
|
||||
|
||||
const TopupCard = () => {
|
||||
const theme = useTheme();
|
||||
const [redemptionCode, setRedemptionCode] = useState('');
|
||||
const [topUpLink, setTopUpLink] = useState('');
|
||||
const [userQuota, setUserQuota] = useState(0);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const topUp = async () => {
|
||||
if (redemptionCode === '') {
|
||||
showInfo('请输入充值码!');
|
||||
return;
|
||||
}
|
||||
setIsSubmitting(true);
|
||||
try {
|
||||
const res = await API.post('/api/user/topup', {
|
||||
key: redemptionCode
|
||||
});
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
showSuccess('充值成功!');
|
||||
setUserQuota((quota) => {
|
||||
return quota + data;
|
||||
});
|
||||
setRedemptionCode('');
|
||||
} else {
|
||||
showError(message);
|
||||
}
|
||||
} catch (err) {
|
||||
showError('请求失败');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
const openTopUpLink = () => {
|
||||
if (!topUpLink) {
|
||||
showError('超级管理员未设置充值链接!');
|
||||
return;
|
||||
}
|
||||
window.open(topUpLink, '_blank');
|
||||
};
|
||||
|
||||
const getUserQuota = async () => {
|
||||
let res = await API.get(`/api/user/self`);
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
setUserQuota(data.quota);
|
||||
} else {
|
||||
showError(message);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let status = localStorage.getItem('siteInfo');
|
||||
if (status) {
|
||||
status = JSON.parse(status);
|
||||
if (status.top_up_link) {
|
||||
setTopUpLink(status.top_up_link);
|
||||
}
|
||||
}
|
||||
getUserQuota().then();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<UserCard>
|
||||
<Stack direction="row" alignItems="center" justifyContent="center" spacing={2} paddingTop={'20px'}>
|
||||
<IconWallet color={theme.palette.primary.main} />
|
||||
<Typography variant="h4">当前额度:</Typography>
|
||||
<Typography variant="h4">{renderQuota(userQuota)}</Typography>
|
||||
</Stack>
|
||||
<SubCard
|
||||
sx={{
|
||||
marginTop: '40px'
|
||||
}}
|
||||
>
|
||||
<FormControl fullWidth variant="outlined">
|
||||
<InputLabel htmlFor="key">兑换码</InputLabel>
|
||||
<OutlinedInput
|
||||
id="key"
|
||||
label="兑换码"
|
||||
type="text"
|
||||
value={redemptionCode}
|
||||
onChange={(e) => {
|
||||
setRedemptionCode(e.target.value);
|
||||
}}
|
||||
name="key"
|
||||
placeholder="请输入兑换码"
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<Button variant="contained" onClick={topUp} disabled={isSubmitting}>
|
||||
{isSubmitting ? '兑换中...' : '兑换'}
|
||||
</Button>
|
||||
</InputAdornment>
|
||||
}
|
||||
aria-describedby="helper-text-channel-quota-label"
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<Stack justifyContent="center" alignItems={'center'} spacing={3} paddingTop={'20px'}>
|
||||
<Typography variant={'h4'} color={theme.palette.grey[700]}>
|
||||
还没有兑换码? 点击获取兑换码:
|
||||
</Typography>
|
||||
<Button variant="contained" onClick={openTopUpLink}>
|
||||
获取兑换码
|
||||
</Button>
|
||||
</Stack>
|
||||
</SubCard>
|
||||
</UserCard>
|
||||
);
|
||||
};
|
||||
|
||||
export default TopupCard;
|
||||
26
web/berry/src/views/Topup/index.js
Normal file
26
web/berry/src/views/Topup/index.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Stack, Alert } from '@mui/material';
|
||||
import Grid from '@mui/material/Unstable_Grid2';
|
||||
import TopupCard from './component/TopupCard';
|
||||
import InviteCard from './component/InviteCard';
|
||||
|
||||
const Topup = () => {
|
||||
return (
|
||||
<Grid container spacing={2}>
|
||||
<Grid xs={12}>
|
||||
<Alert severity="warning">
|
||||
充值记录以及邀请记录请在日志中查询。充值记录请在日志中选择类型【充值】查询;邀请记录请在日志中选择【系统】查询{' '}
|
||||
</Alert>
|
||||
</Grid>
|
||||
<Grid xs={12} md={6} lg={8}>
|
||||
<Stack spacing={2}>
|
||||
<TopupCard />
|
||||
</Stack>
|
||||
</Grid>
|
||||
<Grid xs={12} md={6} lg={4}>
|
||||
<InviteCard />
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default Topup;
|
||||
Reference in New Issue
Block a user