feat: able to customize home page with link (close #60)

This commit is contained in:
JustSong 2023-05-14 15:34:14 +08:00
parent cf6883778e
commit 224bebe67a
3 changed files with 91 additions and 78 deletions

View File

@ -43,8 +43,8 @@ _✨ All in one 的 OpenAI 接口,整合各种 API 访问方式,开箱即用
## 功能 ## 功能
1. 支持多种 API 访问渠道,欢迎 PR 或提 issue 添加更多渠道: 1. 支持多种 API 访问渠道,欢迎 PR 或提 issue 添加更多渠道:
+ [x] OpenAI 官方通道 + [x] OpenAI 官方通道
+ [x] [API2D](https://api2d.com/r/197971)
+ [x] Azure OpenAI API + [x] Azure OpenAI API
+ [x] [API2D](https://api2d.com/r/197971)
+ [x] [CloseAI](https://console.openai-asia.com) + [x] [CloseAI](https://console.openai-asia.com)
+ [x] [OpenAI-SB](https://openai-sb.com) + [x] [OpenAI-SB](https://openai-sb.com)
+ [x] [OpenAI Max](https://openaimax.com) + [x] [OpenAI Max](https://openaimax.com)
@ -55,15 +55,16 @@ _✨ All in one 的 OpenAI 接口,整合各种 API 访问方式,开箱即用
4. 支持 HTTP SSE可以通过流式传输实现打字机效果。 4. 支持 HTTP SSE可以通过流式传输实现打字机效果。
5. 支持设置令牌的过期时间和使用次数。 5. 支持设置令牌的过期时间和使用次数。
6. 支持批量生成和导出兑换码,可使用兑换码为令牌进行充值。 6. 支持批量生成和导出兑换码,可使用兑换码为令牌进行充值。
7. 支持为新用户设置初始配额。 7. 支持批量创建通道。
8. 支持自定义首页,发布公告,自定义关于页面,设置充值链接,自定义页脚。 8. 支持发布公告,自定义关于页面,设置充值链接,自定义页脚。
9. 支持通过系统访问令牌访问管理 API。 9. 支持自定义首页,可以选择使用 HTML & Markdown 代码进行自定义,或者使用一个单独的网页通过 iframe 嵌入。
10. 多种用户登录注册方式: 10. 支持通过系统访问令牌访问管理 API。
11. 多种用户登录注册方式:
+ 邮箱登录注册以及通过邮箱进行密码重置。 + 邮箱登录注册以及通过邮箱进行密码重置。
+ [GitHub 开放授权](https://github.com/settings/applications/new)。 + [GitHub 开放授权](https://github.com/settings/applications/new)。
+ 微信公众号授权(需要额外部署 [WeChat Server](https://github.com/songquanpeng/wechat-server))。 + 微信公众号授权(需要额外部署 [WeChat Server](https://github.com/songquanpeng/wechat-server))。
11. 支持用户管理 12. 支持用户管理,支持为新用户设置初始配额。
12. 未来其他大模型开放 API 后,将第一时间支持,并将其封装成同样的 API 访问方式。 13. 未来其他大模型开放 API 后,将第一时间支持,并将其封装成同样的 API 访问方式。
## 部署 ## 部署
### 基于 Docker 进行部署 ### 基于 Docker 进行部署

View File

@ -117,7 +117,7 @@ const OtherSetting = () => {
<Form.Group widths='equal'> <Form.Group widths='equal'>
<Form.TextArea <Form.TextArea
label='首页内容' label='首页内容'
placeholder='在此输入首页内容,支持 Markdown & HTML 代码,设置后首页的状态信息将不再显示' placeholder='在此输入首页内容,支持 Markdown & HTML 代码,设置后首页的状态信息将不再显示。\n如果输入的是一个链接则会使用该链接作为 iframe 的 src 属性,这允许你设置任意网页作为首页。'
value={inputs.HomePageContent} value={inputs.HomePageContent}
name='HomePageContent' name='HomePageContent'
onChange={handleInputChange} onChange={handleInputChange}

View File

@ -6,6 +6,7 @@ import { marked } from 'marked';
const Home = () => { const Home = () => {
const [statusState, statusDispatch] = useContext(StatusContext); const [statusState, statusDispatch] = useContext(StatusContext);
const [homePageContentLoaded, setHomePageContentLoaded] = useState(false);
const [homePageContent, setHomePageContent] = useState(''); const [homePageContent, setHomePageContent] = useState('');
const displayNotice = async () => { const displayNotice = async () => {
@ -23,16 +24,21 @@ const Home = () => {
}; };
const displayHomePageContent = async () => { const displayHomePageContent = async () => {
setHomePageContent(localStorage.getItem('home_page_content') || '');
const res = await API.get('/api/home_page_content'); const res = await API.get('/api/home_page_content');
const { success, message, data } = res.data; const { success, message, data } = res.data;
if (success) { if (success) {
let HTMLContent = marked.parse(data); let content = data;
localStorage.setItem('home_page_content', HTMLContent); if (!data.startsWith('https://')) {
setHomePageContent(HTMLContent); content = marked.parse(data);
}
setHomePageContent(content);
localStorage.setItem('home_page_content', content);
} else { } else {
showError(message); showError(message);
setHomePageContent('加载首页内容失败...'); setHomePageContent('加载首页内容失败...');
} }
setHomePageContentLoaded(true);
}; };
const getStartTimeString = () => { const getStartTimeString = () => {
@ -46,73 +52,79 @@ const Home = () => {
}, []); }, []);
return ( return (
<> <>
<Segment> {
{ homePageContentLoaded && homePageContent === '' ? <>
homePageContent === '' ? <> <Segment>
<Header as='h3'>系统状况</Header> <Header as='h3'>系统状况</Header>
<Grid columns={2} stackable> <Grid columns={2} stackable>
<Grid.Column> <Grid.Column>
<Card fluid> <Card fluid>
<Card.Content> <Card.Content>
<Card.Header>系统信息</Card.Header> <Card.Header>系统信息</Card.Header>
<Card.Meta>系统信息总览</Card.Meta> <Card.Meta>系统信息总览</Card.Meta>
<Card.Description> <Card.Description>
<p>名称{statusState?.status?.system_name}</p> <p>名称{statusState?.status?.system_name}</p>
<p>版本{statusState?.status?.version}</p> <p>版本{statusState?.status?.version}</p>
<p> <p>
源码 源码
<a <a
href='https://github.com/songquanpeng/one-api' href='https://github.com/songquanpeng/one-api'
target='_blank' target='_blank'
> >
https://github.com/songquanpeng/one-api https://github.com/songquanpeng/one-api
</a> </a>
</p> </p>
<p>启动时间{getStartTimeString()}</p> <p>启动时间{getStartTimeString()}</p>
</Card.Description> </Card.Description>
</Card.Content> </Card.Content>
</Card> </Card>
</Grid.Column> </Grid.Column>
<Grid.Column> <Grid.Column>
<Card fluid> <Card fluid>
<Card.Content> <Card.Content>
<Card.Header>系统配置</Card.Header> <Card.Header>系统配置</Card.Header>
<Card.Meta>系统配置总览</Card.Meta> <Card.Meta>系统配置总览</Card.Meta>
<Card.Description> <Card.Description>
<p> <p>
邮箱验证 邮箱验证
{statusState?.status?.email_verification === true {statusState?.status?.email_verification === true
? '已启用' ? '已启用'
: '未启用'} : '未启用'}
</p> </p>
<p> <p>
GitHub 身份验证 GitHub 身份验证
{statusState?.status?.github_oauth === true {statusState?.status?.github_oauth === true
? '已启用' ? '已启用'
: '未启用'} : '未启用'}
</p> </p>
<p> <p>
微信身份验证 微信身份验证
{statusState?.status?.wechat_login === true {statusState?.status?.wechat_login === true
? '已启用' ? '已启用'
: '未启用'} : '未启用'}
</p> </p>
<p> <p>
Turnstile 用户校验 Turnstile 用户校验
{statusState?.status?.turnstile_check === true {statusState?.status?.turnstile_check === true
? '已启用' ? '已启用'
: '未启用'} : '未启用'}
</p> </p>
</Card.Description> </Card.Description>
</Card.Content> </Card.Content>
</Card> </Card>
</Grid.Column> </Grid.Column>
</Grid> </Grid>
</> : <> </Segment>
<div dangerouslySetInnerHTML={{ __html: homePageContent}}></div> </> : <>
</> {
} homePageContent.startsWith('https://') ? <iframe
</Segment> src={homePageContent}
style={{ width: '100%', height: '100vh', border: 'none' }}
/> : <div style={{ fontSize: 'larger' }} dangerouslySetInnerHTML={{ __html: homePageContent }}></div>
}
</>
}
</> </>
); );
}; };