Skip to content

Commit df71ef0

Browse files
feat: add new theme berry (songquanpeng#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 <[email protected]>
1 parent 4ac6674 commit df71ef0

File tree

157 files changed

+13979
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

157 files changed

+13979
-5
lines changed

controller/model.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ func init() {
436436
Id: "PaLM-2",
437437
Object: "model",
438438
Created: 1677649963,
439-
OwnedBy: "google",
439+
OwnedBy: "google palm",
440440
Permission: permission,
441441
Root: "PaLM-2",
442442
Parent: nil,
@@ -445,7 +445,7 @@ func init() {
445445
Id: "gemini-pro",
446446
Object: "model",
447447
Created: 1677649963,
448-
OwnedBy: "google",
448+
OwnedBy: "google gemini",
449449
Permission: permission,
450450
Root: "gemini-pro",
451451
Parent: nil,
@@ -454,7 +454,7 @@ func init() {
454454
Id: "gemini-pro-vision",
455455
Object: "model",
456456
Created: 1677649963,
457-
OwnedBy: "google",
457+
OwnedBy: "google gemini",
458458
Permission: permission,
459459
Root: "gemini-pro-vision",
460460
Parent: nil,

controller/user.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"one-api/common"
88
"one-api/model"
99
"strconv"
10+
"time"
1011

1112
"github.com/gin-contrib/sessions"
1213
"github.com/gin-gonic/gin"
@@ -248,6 +249,29 @@ func GetUser(c *gin.Context) {
248249
return
249250
}
250251

252+
func GetUserDashboard(c *gin.Context) {
253+
id := c.GetInt("id")
254+
now := time.Now()
255+
startOfDay := now.Truncate(24*time.Hour).AddDate(0, 0, -6).Unix()
256+
endOfDay := now.Truncate(24 * time.Hour).Add(24*time.Hour - time.Second).Unix()
257+
258+
dashboards, err := model.SearchLogsByDayAndModel(id, int(startOfDay), int(endOfDay))
259+
if err != nil {
260+
c.JSON(http.StatusOK, gin.H{
261+
"success": false,
262+
"message": "无法获取统计信息",
263+
"data": nil,
264+
})
265+
return
266+
}
267+
c.JSON(http.StatusOK, gin.H{
268+
"success": true,
269+
"message": "",
270+
"data": dashboards,
271+
})
272+
return
273+
}
274+
251275
func GenerateAccessToken(c *gin.Context) {
252276
id := c.GetInt("id")
253277
user, err := model.GetUserById(id, true)

model/log.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ package model
33
import (
44
"context"
55
"fmt"
6-
"gorm.io/gorm"
76
"one-api/common"
7+
8+
"gorm.io/gorm"
89
)
910

1011
type Log struct {
@@ -182,3 +183,42 @@ func DeleteOldLog(targetTimestamp int64) (int64, error) {
182183
result := DB.Where("created_at < ?", targetTimestamp).Delete(&Log{})
183184
return result.RowsAffected, result.Error
184185
}
186+
187+
type LogStatistic struct {
188+
Day string `gorm:"column:day"`
189+
ModelName string `gorm:"column:model_name"`
190+
RequestCount int `gorm:"column:request_count"`
191+
Quota int `gorm:"column:quota"`
192+
PromptTokens int `gorm:"column:prompt_tokens"`
193+
CompletionTokens int `gorm:"column:completion_tokens"`
194+
}
195+
196+
func SearchLogsByDayAndModel(userId, start, end int) (LogStatistics []*LogStatistic, err error) {
197+
groupSelect := "DATE_FORMAT(FROM_UNIXTIME(created_at), '%Y-%m-%d') as day"
198+
199+
if common.UsingPostgreSQL {
200+
groupSelect = "TO_CHAR(date_trunc('day', to_timestamp(created_at)), 'YYYY-MM-DD') as day"
201+
}
202+
203+
if common.UsingSQLite {
204+
groupSelect = "strftime('%Y-%m-%d', datetime(created_at, 'unixepoch')) as day"
205+
}
206+
207+
err = DB.Raw(`
208+
SELECT `+groupSelect+`,
209+
model_name, count(1) as request_count,
210+
sum(quota) as quota,
211+
sum(prompt_tokens) as prompt_tokens,
212+
sum(completion_tokens) as completion_tokens
213+
FROM logs
214+
WHERE type=2
215+
AND userId= ?
216+
AND created_at BETWEEN ? AND ?
217+
GROUP BY day, model_name
218+
ORDER BY day, model_name
219+
`, userId, start, end).Scan(&LogStatistics).Error
220+
221+
fmt.Println(userId, start, end)
222+
223+
return LogStatistics, err
224+
}

router/api-router.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func SetApiRouter(router *gin.Engine) {
3535
selfRoute := userRoute.Group("/")
3636
selfRoute.Use(middleware.UserAuth())
3737
{
38+
selfRoute.GET("/dashboard", controller.GetUserDashboard)
3839
selfRoute.GET("/self", controller.GetSelf)
3940
selfRoute.PUT("/self", controller.UpdateSelf)
4041
selfRoute.DELETE("/self", controller.DeleteSelf)

web/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,36 @@
11
# One API 的前端界面
2+
23
> 每个文件夹代表一个主题,欢迎提交你的主题
34
45
## 提交新的主题
6+
57
> 欢迎在页面底部保留你和 One API 的版权信息以及指向链接
8+
69
1.`web` 文件夹下新建一个文件夹,文件夹名为主题名。
710
2. 把你的主题文件放到这个文件夹下。
811
3. 修改 `package.json` 文件,把 `build` 命令改为:`"build": "react-scripts build && mv -f build ../build/default"`,其中 `default` 为你的主题名。
912

1013
## 主题列表
14+
1115
### 主题:default
16+
1217
默认主题,由 [JustSong](https://github.com/songquanpeng) 开发。
1318

1419
预览:
1520
|![image](https://github.com/songquanpeng/one-api/assets/39998050/ccfbc668-3a7f-4bc1-87da-7eacfd7bf371)|![image](https://github.com/songquanpeng/one-api/assets/39998050/a63ed547-44b9-45db-b43a-ecea07d60840)|
1621
|:---:|:---:|
1722

23+
### 主题:berry
24+
25+
[MartialBE](https://github.com/MartialBE) 开发。
26+
27+
预览:
28+
|||
29+
|:---:|:---:|
30+
|![image](https://github.com/songquanpeng/one-api/assets/42402987/36aff5c6-c5ff-4a90-8e3d-33d5cff34cbf)|![image](https://github.com/songquanpeng/one-api/assets/42402987/9ac63b36-5140-4064-8fad-fc9d25821509)|
31+
|![image](https://github.com/songquanpeng/one-api/assets/42402987/fb2b1c64-ef24-4027-9b80-0cd9d945a47f)|![image](https://github.com/songquanpeng/one-api/assets/42402987/b6b649ec-2888-4324-8b2d-d5e11554eed6)|
32+
|![image](https://github.com/songquanpeng/one-api/assets/42402987/6d3b22e0-436b-4e26-8911-bcc993c6a2bd)|![image](https://github.com/songquanpeng/one-api/assets/42402987/eef1e224-7245-44d7-804e-9d1c8fa3f29c)|
33+
34+
#### 开发说明
35+
36+
请查看 [web/berry/README.md](https://github.com/songquanpeng/one-api/tree/main/web/berry/README.md)

web/THEMES

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
default
1+
default
2+
berry

web/berry/.gitignore

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# production
12+
/build
13+
14+
# misc
15+
.DS_Store
16+
.env.local
17+
.env.development.local
18+
.env.test.local
19+
.env.production.local
20+
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*
24+
.idea
25+
package-lock.json
26+
yarn.lock

web/berry/README.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# One API 前端界面
2+
3+
这个项目是 One API 的前端界面,它基于 [Berry Free React Admin Template](https://github.com/codedthemes/berry-free-react-admin-template) 进行开发。
4+
5+
## 使用的开源项目
6+
7+
使用了以下开源项目作为我们项目的一部分:
8+
9+
- [Berry Free React Admin Template](https://github.com/codedthemes/berry-free-react-admin-template)
10+
- [minimal-ui-kit](minimal-ui-kit)
11+
12+
## 开发说明
13+
14+
当添加新的渠道时,需要修改以下地方:
15+
16+
1. `web/berry/src/constants/ChannelConstants.js`
17+
18+
在该文件中的 `CHANNEL_OPTIONS` 添加新的渠道
19+
20+
```js
21+
export const CHANNEL_OPTIONS = {
22+
//key 为渠道ID
23+
1: {
24+
key: 1, // 渠道ID
25+
text: "OpenAI", // 渠道名称
26+
value: 1, // 渠道ID
27+
color: "primary", // 渠道列表显示的颜色
28+
},
29+
};
30+
```
31+
32+
2. `web/berry/src/views/Channel/type/Config.js`
33+
34+
在该文件中的`typeConfig`添加新的渠道配置, 如果无需配置,可以不添加
35+
36+
```js
37+
const typeConfig = {
38+
// key 为渠道ID
39+
3: {
40+
inputLabel: {
41+
// 输入框名称 配置
42+
// 对应的字段名称
43+
base_url: "AZURE_OPENAI_ENDPOINT",
44+
other: "默认 API 版本",
45+
},
46+
prompt: {
47+
// 输入框提示 配置
48+
// 对应的字段名称
49+
base_url: "请填写AZURE_OPENAI_ENDPOINT",
50+
51+
// 注意:通过判断 `other` 是否有值来判断是否需要显示 `other` 输入框, 默认是没有值的
52+
other: "请输入默认API版本,例如:2023-06-01-preview",
53+
},
54+
modelGroup: "openai", // 模型组名称,这个值是给 填入渠道支持模型 按钮使用的。 填入渠道支持模型 按钮会根据这个值来获取模型组,如果填写默认是 openai
55+
},
56+
};
57+
```
58+
59+
## 许可证
60+
61+
本项目中使用的代码遵循 MIT 许可证。

web/berry/jsconfig.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"compilerOptions": {
3+
"target": "esnext",
4+
"module": "commonjs",
5+
"baseUrl": "src"
6+
},
7+
"include": ["src/**/*"],
8+
"exclude": ["node_modules"]
9+
}

web/berry/package.json

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
{
2+
"name": "one_api_web",
3+
"version": "1.0.0",
4+
"proxy": "http://127.0.0.1:3000",
5+
"private": true,
6+
"homepage": "",
7+
"dependencies": {
8+
"@emotion/cache": "^11.9.3",
9+
"@emotion/react": "^11.9.3",
10+
"@emotion/styled": "^11.9.3",
11+
"@mui/icons-material": "^5.8.4",
12+
"@mui/lab": "^5.0.0-alpha.88",
13+
"@mui/material": "^5.8.6",
14+
"@mui/system": "^5.8.6",
15+
"@mui/utils": "^5.8.6",
16+
"@mui/x-date-pickers": "^6.18.5",
17+
"@tabler/icons-react": "^2.44.0",
18+
"apexcharts": "^3.35.3",
19+
"axios": "^0.27.2",
20+
"dayjs": "^1.11.10",
21+
"formik": "^2.2.9",
22+
"framer-motion": "^6.3.16",
23+
"history": "^5.3.0",
24+
"marked": "^4.1.1",
25+
"material-ui-popup-state": "^4.0.1",
26+
"notistack": "^3.0.1",
27+
"prop-types": "^15.8.1",
28+
"react": "^18.2.0",
29+
"react-apexcharts": "^1.4.0",
30+
"react-device-detect": "^2.2.2",
31+
"react-dom": "^18.2.0",
32+
"react-perfect-scrollbar": "^1.5.8",
33+
"react-redux": "^8.0.2",
34+
"react-router": "6.3.0",
35+
"react-router-dom": "6.3.0",
36+
"react-scripts": "^5.0.1",
37+
"react-turnstile": "^1.1.2",
38+
"redux": "^4.2.0",
39+
"yup": "^0.32.11"
40+
},
41+
"scripts": {
42+
"start": "react-scripts start",
43+
"build": "react-scripts build && mv -f build ../build/berry",
44+
"test": "react-scripts test",
45+
"eject": "react-scripts eject"
46+
},
47+
"eslintConfig": {
48+
"extends": [
49+
"react-app"
50+
]
51+
},
52+
"babel": {
53+
"presets": [
54+
"@babel/preset-react"
55+
]
56+
},
57+
"browserslist": {
58+
"production": [
59+
"defaults",
60+
"not IE 11"
61+
],
62+
"development": [
63+
"last 1 chrome version",
64+
"last 1 firefox version",
65+
"last 1 safari version"
66+
]
67+
},
68+
"devDependencies": {
69+
"@babel/core": "^7.21.4",
70+
"@babel/eslint-parser": "^7.21.3",
71+
"eslint": "^8.38.0",
72+
"eslint-config-prettier": "^8.8.0",
73+
"eslint-config-react-app": "^7.0.1",
74+
"eslint-plugin-flowtype": "^8.0.3",
75+
"eslint-plugin-import": "^2.27.5",
76+
"eslint-plugin-jsx-a11y": "^6.7.1",
77+
"eslint-plugin-prettier": "^4.2.1",
78+
"eslint-plugin-react": "^7.32.2",
79+
"eslint-plugin-react-hooks": "^4.6.0",
80+
"immutable": "^4.3.0",
81+
"prettier": "^2.8.7",
82+
"sass": "^1.53.0"
83+
}
84+
}

0 commit comments

Comments
 (0)