diff --git a/controller/group_cluster.go b/controller/group_cluster.go new file mode 100644 index 0000000000..08c88f7905 --- /dev/null +++ b/controller/group_cluster.go @@ -0,0 +1,27 @@ +package controller + +import ( + "net/http" + + "github.com/QuantumNous/new-api/common" + "github.com/QuantumNous/new-api/model" + "github.com/gin-gonic/gin" +) + +// GetGroupClusters 返回所有类型为 'group_cluster' 的预填充分组,供用户端令牌创建时快捷选择。 +func GetGroupClusters(c *gin.Context) { + groups, err := model.GetAllPrefillGroups("group_cluster") + if err != nil { + common.SysError("failed to get group clusters: " + err.Error()) + c.JSON(http.StatusOK, gin.H{ + "success": false, + "message": "获取分组群失败,请稍后重试", + }) + return + } + c.JSON(http.StatusOK, gin.H{ + "success": true, + "message": "", + "data": groups, + }) +} diff --git a/router/api-router.go b/router/api-router.go index e2ef2f531b..9a837c137e 100644 --- a/router/api-router.go +++ b/router/api-router.go @@ -68,6 +68,7 @@ func SetApiRouter(router *gin.Engine) { selfRoute.Use(middleware.UserAuth()) { selfRoute.GET("/self/groups", controller.GetUserGroups) + selfRoute.GET("/self/group_clusters", controller.GetGroupClusters) selfRoute.GET("/self", controller.GetSelf) selfRoute.GET("/models", controller.GetUserModels) selfRoute.PUT("/self", controller.UpdateSelf) diff --git a/web/src/components/table/tokens/modals/EditTokenModal.jsx b/web/src/components/table/tokens/modals/EditTokenModal.jsx index fce4820146..1b103cc488 100644 --- a/web/src/components/table/tokens/modals/EditTokenModal.jsx +++ b/web/src/components/table/tokens/modals/EditTokenModal.jsx @@ -41,6 +41,7 @@ import { Form, Col, Row, + Tooltip, } from '@douyinfe/semi-ui'; import { IconCreditCard, @@ -62,6 +63,7 @@ const EditTokenModal = (props) => { const formApiRef = useRef(null); const [models, setModels] = useState([]); const [groups, setGroups] = useState([]); + const [groupClusters, setGroupClusters] = useState([]); const isEdit = props.editingToken.id !== undefined; const getInitValues = () => ({ @@ -149,6 +151,17 @@ const EditTokenModal = (props) => { } }; + const loadGroupClusters = async () => { + try { + const res = await API.get('/api/user/self/group_clusters'); + if (res.data.success) { + setGroupClusters(res.data.data || []); + } + } catch { + // ignore + } + }; + const loadToken = async () => { setLoading(true); let res = await API.get(`/api/token/${props.editingToken.id}`); @@ -179,6 +192,7 @@ const EditTokenModal = (props) => { } loadModels(); loadGroups(); + loadGroupClusters(); }, [props.editingToken.id]); useEffect(() => { @@ -378,6 +392,56 @@ const EditTokenModal = (props) => { /> )} + {groupClusters.length > 0 && ( +