Skip to content

Commit 6c101e6

Browse files
TAYOTOoOclaude
andcommitted
feat: 分组群功能(用户端 API + 前端快捷填充)
新增分组群(Group Clusters)功能,允许管理员预定义分组组合,用户创建令牌时可一键填充。 - 新增 controller/group_cluster.go 用户端接口,返回 type='group_cluster' 的预填组 - router/api-router.go 新增 GET /api/user/self/group_clusters 路由 - EditTokenModal.jsx 加载分组群数据,显示快捷填充按钮 - 悬浮显示分组群包含的分组列表 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f77381c commit 6c101e6

3 files changed

Lines changed: 90 additions & 0 deletions

File tree

controller/group_cluster.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package controller
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/QuantumNous/new-api/common"
7+
"github.com/QuantumNous/new-api/model"
8+
"github.com/gin-gonic/gin"
9+
)
10+
11+
// GetGroupClusters 返回所有类型为 'group_cluster' 的预填充分组,供用户端令牌创建时快捷选择。
12+
func GetGroupClusters(c *gin.Context) {
13+
groups, err := model.GetAllPrefillGroups("group_cluster")
14+
if err != nil {
15+
common.SysError("failed to get group clusters: " + err.Error())
16+
c.JSON(http.StatusOK, gin.H{
17+
"success": false,
18+
"message": "获取分组群失败,请稍后重试",
19+
})
20+
return
21+
}
22+
c.JSON(http.StatusOK, gin.H{
23+
"success": true,
24+
"message": "",
25+
"data": groups,
26+
})
27+
}

router/api-router.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func SetApiRouter(router *gin.Engine) {
6868
selfRoute.Use(middleware.UserAuth())
6969
{
7070
selfRoute.GET("/self/groups", controller.GetUserGroups)
71+
selfRoute.GET("/self/group_clusters", controller.GetGroupClusters)
7172
selfRoute.GET("/self", controller.GetSelf)
7273
selfRoute.GET("/models", controller.GetUserModels)
7374
selfRoute.PUT("/self", controller.UpdateSelf)

web/src/components/table/tokens/modals/EditTokenModal.jsx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
Form,
4242
Col,
4343
Row,
44+
Tooltip,
4445
} from '@douyinfe/semi-ui';
4546
import {
4647
IconCreditCard,
@@ -62,6 +63,7 @@ const EditTokenModal = (props) => {
6263
const formApiRef = useRef(null);
6364
const [models, setModels] = useState([]);
6465
const [groups, setGroups] = useState([]);
66+
const [groupClusters, setGroupClusters] = useState([]);
6567
const isEdit = props.editingToken.id !== undefined;
6668

6769
const getInitValues = () => ({
@@ -149,6 +151,17 @@ const EditTokenModal = (props) => {
149151
}
150152
};
151153

154+
const loadGroupClusters = async () => {
155+
try {
156+
const res = await API.get('/api/user/self/group_clusters');
157+
if (res.data.success) {
158+
setGroupClusters(res.data.data || []);
159+
}
160+
} catch {
161+
// ignore
162+
}
163+
};
164+
152165
const loadToken = async () => {
153166
setLoading(true);
154167
let res = await API.get(`/api/token/${props.editingToken.id}`);
@@ -179,6 +192,7 @@ const EditTokenModal = (props) => {
179192
}
180193
loadModels();
181194
loadGroups();
195+
loadGroupClusters();
182196
}, [props.editingToken.id]);
183197

184198
useEffect(() => {
@@ -378,6 +392,54 @@ const EditTokenModal = (props) => {
378392
/>
379393
)}
380394
</Col>
395+
{groupClusters.length > 0 && (
396+
<Col span={24}>
397+
<Form.Slot label={t('分组群快捷填充')}>
398+
<Space wrap>
399+
{groupClusters.map((cluster) => {
400+
let tooltipContent = '';
401+
try {
402+
tooltipContent = cluster.items
403+
? JSON.parse(cluster.items).join(', ')
404+
: '';
405+
} catch {
406+
tooltipContent = cluster.items || '';
407+
}
408+
return (
409+
<Tooltip
410+
key={cluster.id}
411+
content={tooltipContent}
412+
>
413+
<Button
414+
size='small'
415+
theme='light'
416+
onClick={() => {
417+
try {
418+
const items = JSON.parse(cluster.items);
419+
if (
420+
Array.isArray(items) &&
421+
items.length > 0 &&
422+
formApiRef.current
423+
) {
424+
formApiRef.current.setValue(
425+
'group',
426+
items[0],
427+
);
428+
}
429+
} catch {
430+
// ignore
431+
}
432+
}}
433+
>
434+
{cluster.name}
435+
</Button>
436+
</Tooltip>
437+
);
438+
})}
439+
</Space>
440+
</Form.Slot>
441+
</Col>
442+
)}
381443
<Col
382444
span={24}
383445
style={{

0 commit comments

Comments
 (0)