Commit 24190bf3 by Calcium-Ion Committed by GitHub

Merge pull request #616 from Calcium-Ion/panel

feat: 完善数据看板功能
parents 7ae97088 330dc1a7
...@@ -85,7 +85,7 @@ func SaveQuotaDataCache() { ...@@ -85,7 +85,7 @@ func SaveQuotaDataCache() {
//quotaDataDB.Count += quotaData.Count //quotaDataDB.Count += quotaData.Count
//quotaDataDB.Quota += quotaData.Quota //quotaDataDB.Quota += quotaData.Quota
//DB.Table("quota_data").Save(quotaDataDB) //DB.Table("quota_data").Save(quotaDataDB)
increaseQuotaData(quotaData.UserID, quotaData.Username, quotaData.ModelName, quotaData.Count, quotaData.Quota, quotaData.CreatedAt) increaseQuotaData(quotaData.UserID, quotaData.Username, quotaData.ModelName, quotaData.Count, quotaData.Quota, quotaData.CreatedAt, quotaData.TokenUsed)
} else { } else {
DB.Table("quota_data").Create(quotaData) DB.Table("quota_data").Create(quotaData)
} }
...@@ -94,11 +94,12 @@ func SaveQuotaDataCache() { ...@@ -94,11 +94,12 @@ func SaveQuotaDataCache() {
common.SysLog(fmt.Sprintf("保存数据看板数据成功,共保存%d条数据", size)) common.SysLog(fmt.Sprintf("保存数据看板数据成功,共保存%d条数据", size))
} }
func increaseQuotaData(userId int, username string, modelName string, count int, quota int, createdAt int64) { func increaseQuotaData(userId int, username string, modelName string, count int, quota int, createdAt int64, tokenUsed int) {
err := DB.Table("quota_data").Where("user_id = ? and username = ? and model_name = ? and created_at = ?", err := DB.Table("quota_data").Where("user_id = ? and username = ? and model_name = ? and created_at = ?",
userId, username, modelName, createdAt).Updates(map[string]interface{}{ userId, username, modelName, createdAt).Updates(map[string]interface{}{
"count": gorm.Expr("count + ?", count), "count": gorm.Expr("count + ?", count),
"quota": gorm.Expr("quota + ?", quota), "quota": gorm.Expr("quota + ?", quota),
"token_used": gorm.Expr("token_used + ?", tokenUsed),
}).Error }).Error
if err != nil { if err != nil {
common.SysLog(fmt.Sprintf("increaseQuotaData error: %s", err)) common.SysLog(fmt.Sprintf("increaseQuotaData error: %s", err))
...@@ -127,6 +128,6 @@ func GetAllQuotaDates(startTime int64, endTime int64, username string) (quotaDat ...@@ -127,6 +128,6 @@ func GetAllQuotaDates(startTime int64, endTime int64, username string) (quotaDat
// 从quota_data表中查询数据 // 从quota_data表中查询数据
// only select model_name, sum(count) as count, sum(quota) as quota, model_name, created_at from quota_data group by model_name, created_at; // only select model_name, sum(count) as count, sum(quota) as quota, model_name, created_at from quota_data group by model_name, created_at;
//err = DB.Table("quota_data").Where("created_at >= ? and created_at <= ?", startTime, endTime).Find(&quotaDatas).Error //err = DB.Table("quota_data").Where("created_at >= ? and created_at <= ?", startTime, endTime).Find(&quotaDatas).Error
err = DB.Table("quota_data").Select("model_name, sum(count) as count, sum(quota) as quota, created_at").Where("created_at >= ? and created_at <= ?", startTime, endTime).Group("model_name, created_at").Find(&quotaDatas).Error err = DB.Table("quota_data").Select("model_name, sum(count) as count, sum(quota) as quota, sum(token_used) as token_used, created_at").Where("created_at >= ? and created_at <= ?", startTime, endTime).Group("model_name, created_at").Find(&quotaDatas).Error
return quotaDatas, err return quotaDatas, err
} }
...@@ -74,12 +74,6 @@ const SiderBar = () => { ...@@ -74,12 +74,6 @@ const SiderBar = () => {
icon: <IconCommentStroked />, icon: <IconCommentStroked />,
}, },
{ {
text: '模型价格',
itemKey: 'pricing',
to: '/pricing',
icon: <IconPriceTag />,
},
{
text: '渠道', text: '渠道',
itemKey: 'channel', itemKey: 'channel',
to: '/channel', to: '/channel',
...@@ -103,6 +97,16 @@ const SiderBar = () => { ...@@ -103,6 +97,16 @@ const SiderBar = () => {
icon: <IconKey />, icon: <IconKey />,
}, },
{ {
text: '数据看板',
itemKey: 'detail',
to: '/detail',
icon: <IconCalendarClock />,
className:
localStorage.getItem('enable_data_export') === 'true'
? 'semi-navigation-item-normal'
: 'tableHiddle',
},
{
text: '兑换码', text: '兑换码',
itemKey: 'redemption', itemKey: 'redemption',
to: '/redemption', to: '/redemption',
...@@ -129,16 +133,6 @@ const SiderBar = () => { ...@@ -129,16 +133,6 @@ const SiderBar = () => {
icon: <IconHistogram />, icon: <IconHistogram />,
}, },
{ {
text: '数据看板',
itemKey: 'detail',
to: '/detail',
icon: <IconCalendarClock />,
className:
localStorage.getItem('enable_data_export') === 'true'
? 'semi-navigation-item-normal'
: 'tableHiddle',
},
{
text: '绘图', text: '绘图',
itemKey: 'midjourney', itemKey: 'midjourney',
to: '/midjourney', to: '/midjourney',
......
...@@ -268,6 +268,44 @@ const colors = [ ...@@ -268,6 +268,44 @@ const colors = [
'yellow', 'yellow',
]; ];
// 基础10色色板 (N ≤ 10)
const baseColors = [
'#1664FF', // 主色
'#1AC6FF',
'#FF8A00',
'#3CC780',
'#7442D4',
'#FFC400',
'#304D77',
'#B48DEB',
'#009488',
'#FF7DDA'
];
// 扩展20色色板 (10 < N ≤ 20)
const extendedColors = [
'#1664FF',
'#B2CFFF',
'#1AC6FF',
'#94EFFF',
'#FF8A00',
'#FFCE7A',
'#3CC780',
'#B9EDCD',
'#7442D4',
'#DDC5FA',
'#FFC400',
'#FAE878',
'#304D77',
'#8B959E',
'#B48DEB',
'#EFE3FF',
'#009488',
'#59BAA8',
'#FF7DDA',
'#FFCFEE'
];
export const modelColorMap = { export const modelColorMap = {
'dall-e': 'rgb(147,112,219)', // 深紫色 'dall-e': 'rgb(147,112,219)', // 深紫色
// 'dall-e-2': 'rgb(147,112,219)', // 介于紫色和蓝色之间的色调 // 'dall-e-2': 'rgb(147,112,219)', // 介于紫色和蓝色之间的色调
...@@ -312,14 +350,33 @@ export const modelColorMap = { ...@@ -312,14 +350,33 @@ export const modelColorMap = {
'claude-2.1': 'rgb(255,209,190)', // 浅橙色(略有区别) 'claude-2.1': 'rgb(255,209,190)', // 浅橙色(略有区别)
}; };
export function modelToColor(modelName) {
// 1. 如果模型在预定义的 modelColorMap 中,使用预定义颜色
if (modelColorMap[modelName]) {
return modelColorMap[modelName];
}
// 2. 生成一个稳定的数字作为索引
let hash = 0;
for (let i = 0; i < modelName.length; i++) {
hash = ((hash << 5) - hash) + modelName.charCodeAt(i);
hash = hash & hash; // Convert to 32-bit integer
}
hash = Math.abs(hash);
// 3. 根据模型名称长度选择不同的色板
const colorPalette = modelName.length > 10 ? extendedColors : baseColors;
// 4. 使用hash值选择颜色
const index = hash % colorPalette.length;
return colorPalette[index];
}
export function stringToColor(str) { export function stringToColor(str) {
let sum = 0; let sum = 0;
// 对字符串中的每个字符进行操作
for (let i = 0; i < str.length; i++) { for (let i = 0; i < str.length; i++) {
// 将字符的ASCII值加到sum中
sum += str.charCodeAt(i); sum += str.charCodeAt(i);
} }
// 使用模运算得到个位数
let i = sum % colors.length; let i = sum % colors.length;
return colors[i]; return colors[i];
} }
...@@ -21,7 +21,21 @@ body { ...@@ -21,7 +21,21 @@ body {
font-weight: 600 !important; font-weight: 600 !important;
} }
.semi-descriptions-double-small .semi-descriptions-item {
padding-right: 30px;
}
.panel-desc-card {
/*min-width: 320px;*/
}
@media only screen and (max-width: 767px) { @media only screen and (max-width: 767px) {
#root > section > header > section > div > div > div > div.semi-navigation-header-list-outer > div.semi-navigation-list-wrapper > ul > div > a > li {
padding: 0 5px;
}
#root > section > header > section > div > div > div > div.semi-navigation-footer > div:nth-child(1) > a > li {
padding: 0 5px;
}
.semi-table-tbody, .semi-table-tbody,
.semi-table-row, .semi-table-row,
.semi-table-row-cell { .semi-table-row-cell {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment