Compare commits

..

23 Commits

Author SHA1 Message Date
Calcium-Ion 762d2c81f5 Merge pull request #1179 from QuantumNous/alpha
merge alpha to main
2025-06-08 14:34:24 +08:00
Calcium-Ion f115342784 Merge pull request #1162 from RedwindA/fix-redis-hdel
fix: Rename and refactor RedisHDelObj to RedisDelKey
2025-06-08 14:33:48 +08:00
Calcium-Ion 58f235af5e Merge pull request #1176 from RedwindA/feat/tagMode-channelModelList
feat: 标签聚合模式编辑渠道时复用渠道模型列表
2025-06-08 13:52:36 +08:00
RedwindA b197dfb95d 🐛 fix(EditTagModal): add info banner to clarify modelList behavior 2025-06-08 13:23:59 +08:00
Apple\Apple e0ff3b6f28 feat(token): auto-generate default token names when user input is empty
When creating tokens, if the user doesn't provide a token name (empty or whitespace-only),
the system will now automatically generate a name using the format "default-xxxxxx" where
"xxxxxx" is a 6-character random alphanumeric string.

This enhancement ensures that all created tokens have meaningful names and improves the
user experience by removing the requirement to manually input token names for quick token
creation scenarios.

Changes:
- Modified token creation logic to detect empty token names
- Added automatic fallback to "default" base name when user input is missing
- Maintained existing behavior for multiple token creation with random suffixes
- Ensured consistent naming pattern across single and batch token creation
2025-06-08 12:38:03 +08:00
Apple\Apple 5040235919 💄 style(Logs): Add rounded corners to image view button in MjLogsTable
- Add rounded-full class to "查看图片" (View Image) button for consistent UI styling
- All other buttons in both MjLogsTable.js and TaskLogsTable.js already have rounded corners applied
- Ensures uniform button styling across the log tables interface
2025-06-08 12:23:54 +08:00
Apple\Apple 07f141e8c8 🎨 fix: Import Semi UI CSS explicitly to resolve missing component styles
- Add explicit import of '@douyinfe/semi-ui/dist/css/semi.css' in index.js
- Ensures Semi Design components render with proper styling
- Resolves issue where Semi components appeared unstyled after dependency updates

This change addresses the style loading issue that occurred after adding antd
dependency and updating the build configuration. The explicit import ensures
consistent style loading regardless of plugin behavior changes.
2025-06-08 12:14:49 +08:00
CaIon e1039c67f7 chore: update CI workflows 2025-06-08 03:37:17 +08:00
CaIon 594636bace fix: update import statement for vite-plugin-semi to use default import 2025-06-08 03:35:04 +08:00
CaIon e647163969 chore: update CI workflow to use latest Bun version and adjust build environment variables 2025-06-08 03:28:36 +08:00
CaIon c3a205e792 chore: update Bun version in CI workflow to 1.2.8 2025-06-08 02:57:44 +08:00
CaIon e7289297e2 chore: update package.json to replace sse dependency and add trustedDependencies 2025-06-08 02:56:09 +08:00
CaIon 2e04d28483 chore: update CI workflows to use Bun for package management across all platforms 2025-06-08 02:45:18 +08:00
CaIon 4069b3f789 chore: update CI workflows to support manual triggers and rename Docker image workflow 2025-06-08 02:42:27 +08:00
CaIon 2cb067f485 chore: remove deprecated Docker image workflow for amd64 2025-06-08 02:39:53 +08:00
CaIon 550c068994 Merge branch 'alpha' 2025-06-08 02:38:49 +08:00
CaIon 8b55c9b917 Merge remote-tracking branch 'origin/alpha' into alpha 2025-06-08 02:34:22 +08:00
CaIon e09931558e chore: update CI workflows to use Bun for package management and build process 2025-06-08 02:34:06 +08:00
RedwindA 18f82f120c 🐛 fix(EditTagModal): add fetchTagModels function to retrieve models based on tag 2025-06-08 01:16:39 +08:00
RedwindA c4f664f376 🎨 feat(channel): add endpoint to retrieve models by tag 2025-06-08 01:16:27 +08:00
CaIon 28a2387dff Merge remote-tracking branch 'origin/alpha' into alpha 2025-06-08 00:11:28 +08:00
RedwindA 098c1e8829 refactor: rename RedisHDelObj to RedisDelKey and update references 2025-06-05 21:17:57 +08:00
RedwindA 15607996e6 fix: change RedisHDelObj to use Del instead of HDel 2025-06-05 20:42:56 +08:00
19 changed files with 123 additions and 98 deletions
-54
View File
@@ -1,54 +0,0 @@
name: Publish Docker image (amd64)
on:
push:
tags:
- '*'
workflow_dispatch:
inputs:
name:
description: 'reason'
required: false
jobs:
push_to_registries:
name: Push Docker image to multiple registries
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Check out the repo
uses: actions/checkout@v4
- name: Save version info
run: |
git describe --tags > VERSION
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: |
calciumion/new-api
ghcr.io/${{ github.repository }}
- name: Build and push Docker images
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
+1 -6
View File
@@ -1,14 +1,9 @@
name: Publish Docker image (arm64)
name: Publish Docker image (Multi Registries)
on:
push:
tags:
- '*'
workflow_dispatch:
inputs:
name:
description: 'reason'
required: false
jobs:
push_to_registries:
name: Push Docker image to multiple registries
+9 -4
View File
@@ -3,6 +3,11 @@ permissions:
contents: write
on:
workflow_dispatch:
inputs:
name:
description: 'reason'
required: false
push:
tags:
- '*'
@@ -15,16 +20,16 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-node@v3
- uses: oven-sh/setup-bun@v2
with:
node-version: 18
bun-version: latest
- name: Build Frontend
env:
CI: ""
run: |
cd web
npm install
REACT_APP_VERSION=$(git describe --tags) npm run build
bun install
DISABLE_ESLINT_PLUGIN='true' VITE_REACT_APP_VERSION=$(git describe --tags) bun run build
cd ..
- name: Set up Go
uses: actions/setup-go@v3
+9 -4
View File
@@ -3,6 +3,11 @@ permissions:
contents: write
on:
workflow_dispatch:
inputs:
name:
description: 'reason'
required: false
push:
tags:
- '*'
@@ -15,16 +20,16 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-node@v3
- uses: oven-sh/setup-bun@v2
with:
node-version: 18
bun-version: latest
- name: Build Frontend
env:
CI: ""
run: |
cd web
npm install
REACT_APP_VERSION=$(git describe --tags) npm run build
bun install
DISABLE_ESLINT_PLUGIN='true' VITE_REACT_APP_VERSION=$(git describe --tags) bun run build
cd ..
- name: Set up Go
uses: actions/setup-go@v3
+9 -4
View File
@@ -3,6 +3,11 @@ permissions:
contents: write
on:
workflow_dispatch:
inputs:
name:
description: 'reason'
required: false
push:
tags:
- '*'
@@ -18,16 +23,16 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-node@v3
- uses: oven-sh/setup-bun@v2
with:
node-version: 18
bun-version: latest
- name: Build Frontend
env:
CI: ""
run: |
cd web
npm install
REACT_APP_VERSION=$(git describe --tags) npm run build
bun install
DISABLE_ESLINT_PLUGIN='true' VITE_REACT_APP_VERSION=$(git describe --tags) bun run build
cd ..
- name: Set up Go
uses: actions/setup-go@v3
+3 -3
View File
@@ -92,12 +92,12 @@ func RedisDel(key string) error {
return RDB.Del(ctx, key).Err()
}
func RedisHDelObj(key string) error {
func RedisDelKey(key string) error {
if DebugEnabled {
SysLog(fmt.Sprintf("Redis HDEL: key=%s", key))
SysLog(fmt.Sprintf("Redis DEL Key: key=%s", key))
}
ctx := context.Background()
return RDB.HDel(ctx, key).Err()
return RDB.Del(ctx, key).Err()
}
func RedisHSetObj(key string, obj interface{}, expiration time.Duration) error {
+41
View File
@@ -623,3 +623,44 @@ func BatchSetChannelTag(c *gin.Context) {
})
return
}
func GetTagModels(c *gin.Context) {
tag := c.Query("tag")
if tag == "" {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": "tag不能为空",
})
return
}
channels, err := model.GetChannelsByTag(tag, false) // Assuming false for idSort is fine here
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": err.Error(),
})
return
}
var longestModels string
maxLength := 0
// Find the longest models string among all channels with the given tag
for _, channel := range channels {
if channel.Models != "" {
currentModels := strings.Split(channel.Models, ",")
if len(currentModels) > maxLength {
maxLength = len(currentModels)
longestModels = channel.Models
}
}
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "",
"data": longestModels,
})
return
}
+1 -1
View File
@@ -19,7 +19,7 @@ func cacheSetToken(token Token) error {
func cacheDeleteToken(key string) error {
key = common.GenerateHMAC(key)
err := common.RedisHDelObj(fmt.Sprintf("token:%s", key))
err := common.RedisDelKey(fmt.Sprintf("token:%s", key))
if err != nil {
return err
}
+3 -2
View File
@@ -3,11 +3,12 @@ package model
import (
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"one-api/common"
"one-api/constant"
"time"
"github.com/gin-gonic/gin"
"github.com/bytedance/gopkg/util/gopool"
)
@@ -57,7 +58,7 @@ func invalidateUserCache(userId int) error {
if !common.RedisEnabled {
return nil
}
return common.RedisHDelObj(getUserCacheKey(userId))
return common.RedisDelKey(getUserCacheKey(userId))
}
// updateUserCache updates all user cache fields using hash
+1
View File
@@ -105,6 +105,7 @@ func SetApiRouter(router *gin.Engine) {
channelRoute.GET("/fetch_models/:id", controller.FetchUpstreamModels)
channelRoute.POST("/fetch_models", controller.FetchModels)
channelRoute.POST("/batch/tag", controller.BatchSetChannelTag)
channelRoute.GET("/tag/models", controller.GetTagModels)
}
tokenRoute := apiRouter.Group("/token")
tokenRoute.Use(middleware.UserAuth())
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -39,7 +39,7 @@
"remark-math": "^6.0.0",
"semantic-ui-offline": "^2.5.0",
"semantic-ui-react": "^2.1.3",
"sse": "https://github.com/mpetazzoni/sse.js",
"sse.js": "^2.6.0",
"unist-util-visit": "^5.0.0",
"use-debounce": "^10.0.4"
},
@@ -69,7 +69,7 @@
]
},
"devDependencies": {
"@douyinfe/semi-webpack-plugin": "^2.78.0",
"@douyinfe/vite-plugin-semi": "^2.74.0-alpha.6",
"@so1ve/prettier-config": "^3.1.0",
"@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.21",
+2 -1
View File
@@ -462,7 +462,7 @@ const LogsTable = () => {
percent={text ? parseInt(text.replace('%', '')) : 0}
showInfo={true}
aria-label='drawing progress'
style={{ minWidth: '200px' }}
style={{ minWidth: '160px' }}
/>
}
</div>
@@ -483,6 +483,7 @@ const LogsTable = () => {
setModalImageUrl(text);
setIsModalOpenurl(true);
}}
className="!rounded-full"
>
{t('查看图片')}
</Button>
+1 -1
View File
@@ -395,7 +395,7 @@ const LogsTable = () => {
percent={text ? parseInt(text.replace('%', '')) : 0}
showInfo={true}
aria-label='task progress'
style={{ minWidth: '200px' }}
style={{ minWidth: '160px' }}
/>
)
}
+1 -1
View File
@@ -1,6 +1,6 @@
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { SSE } from 'sse';
import { SSE } from 'sse.js';
import {
API_ENDPOINTS,
MESSAGE_STATUS,
+1
View File
@@ -1,6 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import '@douyinfe/semi-ui/dist/css/semi.css';
import { UserProvider } from './context/User';
import 'react-toastify/dist/ReactToastify.css';
import { StatusProvider } from './context/Status';
+25 -1
View File
@@ -194,6 +194,24 @@ const EditTagModal = (props) => {
}, [originModelOptions, inputs.models]);
useEffect(() => {
const fetchTagModels = async () => {
if (!tag) return;
setLoading(true);
try {
const res = await API.get(`/api/channel/tag/models?tag=${tag}`);
if (res?.data?.success) {
const models = res.data.data ? res.data.data.split(',') : [];
setInputs((inputs) => ({ ...inputs, models: models }));
} else {
showError(res.data.message);
}
} catch (error) {
showError(error.message);
} finally {
setLoading(false);
}
};
setInputs({
...originInputs,
tag: tag,
@@ -201,7 +219,8 @@ const EditTagModal = (props) => {
});
fetchModels().then();
fetchGroups().then();
}, [visible]);
fetchTagModels().then(); // Call the new function
}, [visible, tag]); // Add tag to dependency array
const addCustomModels = () => {
if (customModel.trim() === '') return;
@@ -347,6 +366,11 @@ const EditTagModal = (props) => {
<div className="space-y-4">
<div>
<Text strong className="block mb-2">{t('模型')}</Text>
<Banner
type="info"
description={t('当前模型列表为该标签下所有渠道模型列表最长的一个,并非所有渠道的并集,请注意可能导致某些渠道模型丢失。')}
className="!rounded-lg mb-4"
/>
<Select
placeholder={t('请选择该渠道所支持的模型,留空则不更改')}
name='models'
+9 -3
View File
@@ -219,9 +219,15 @@ const EditToken = (props) => {
let successCount = 0; // 记录成功创建的令牌数量
for (let i = 0; i < tokenCount; i++) {
let localInputs = { ...inputs };
if (i !== 0) {
// 如果用户想要创建多个令牌,则给每个令牌一个序号后缀
localInputs.name = `${inputs.name}-${generateRandomSuffix()}`;
// 检查用户是否填写了令牌名称
const baseName = inputs.name.trim() === '' ? 'default' : inputs.name;
if (i !== 0 || inputs.name.trim() === '') {
// 如果创建多个令牌(i !== 0)或者用户没有填写名称,则添加随机后缀
localInputs.name = `${baseName}-${generateRandomSuffix()}`;
} else {
localInputs.name = baseName;
}
localInputs.remain_quota = parseInt(localInputs.remain_quota);
+5 -11
View File
@@ -1,6 +1,7 @@
import react from '@vitejs/plugin-react';
import { defineConfig, transformWithEsbuild } from 'vite';
import semiWebpackPlugin from '@douyinfe/semi-webpack-plugin';
import pkg from '@douyinfe/vite-plugin-semi';
const { vitePluginSemi } = pkg;
// https://vitejs.dev/config/
export default defineConfig({
@@ -21,16 +22,9 @@ export default defineConfig({
},
},
react(),
{
name: 'semi-plugin',
apply: 'build',
configResolved() {
// Apply SemiWebpackPlugin during build
new semiWebpackPlugin({
cssLayer: true
});
}
}
vitePluginSemi({
cssLayer: true
})
],
optimizeDeps: {
force: true,