diff --git a/common/redis.go b/common/redis.go index 49d3ec78..ba35331a 100644 --- a/common/redis.go +++ b/common/redis.go @@ -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 { diff --git a/controller/channel.go b/controller/channel.go index a31e1f47..a4ef87c3 100644 --- a/controller/channel.go +++ b/controller/channel.go @@ -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 +} diff --git a/model/token_cache.go b/model/token_cache.go index 0fe02fea..b2e0c951 100644 --- a/model/token_cache.go +++ b/model/token_cache.go @@ -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 } diff --git a/model/user_cache.go b/model/user_cache.go index bc412e77..d74877bd 100644 --- a/model/user_cache.go +++ b/model/user_cache.go @@ -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 diff --git a/router/api-router.go b/router/api-router.go index 1720ff57..6251c8a2 100644 --- a/router/api-router.go +++ b/router/api-router.go @@ -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()) diff --git a/web/src/components/table/MjLogsTable.js b/web/src/components/table/MjLogsTable.js index 48513eb1..b4cf046e 100644 --- a/web/src/components/table/MjLogsTable.js +++ b/web/src/components/table/MjLogsTable.js @@ -462,7 +462,7 @@ const LogsTable = () => { percent={text ? parseInt(text.replace('%', '')) : 0} showInfo={true} aria-label='drawing progress' - style={{ minWidth: '200px' }} + style={{ minWidth: '160px' }} /> } @@ -483,6 +483,7 @@ const LogsTable = () => { setModalImageUrl(text); setIsModalOpenurl(true); }} + className="!rounded-full" > {t('查看图片')} diff --git a/web/src/components/table/TaskLogsTable.js b/web/src/components/table/TaskLogsTable.js index 4e329d29..91ccc06c 100644 --- a/web/src/components/table/TaskLogsTable.js +++ b/web/src/components/table/TaskLogsTable.js @@ -395,7 +395,7 @@ const LogsTable = () => { percent={text ? parseInt(text.replace('%', '')) : 0} showInfo={true} aria-label='task progress' - style={{ minWidth: '200px' }} + style={{ minWidth: '160px' }} /> ) } diff --git a/web/src/index.js b/web/src/index.js index 0f57f5a1..ef8a3a07 100644 --- a/web/src/index.js +++ b/web/src/index.js @@ -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'; diff --git a/web/src/pages/Channel/EditTagModal.js b/web/src/pages/Channel/EditTagModal.js index 52dd4bbb..695ed2b4 100644 --- a/web/src/pages/Channel/EditTagModal.js +++ b/web/src/pages/Channel/EditTagModal.js @@ -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) => {
{t('模型')} +