Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
38869e0a
authored
Jun 05, 2026
by
renyizhao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
获取模型列表接口
parent
8cbaffa1
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
253 additions
and
0 deletions
+253
-0
computility-module-apihub/computility-module-apihub-biz/src/main/java/com/luhu/computility/module/apihub/controller/app/aimodel/AppAiModelController.java
+0
-0
computility-module-apihub/computility-module-apihub-biz/src/main/java/com/luhu/computility/module/apihub/controller/app/aimodel/vo/AppModelPricingVO.java
+59
-0
computility-module-apihub/computility-module-apihub-biz/src/main/java/com/luhu/computility/module/apihub/controller/app/aimodel/vo/AppModelVO.java
+39
-0
computility-module-apihub/computility-module-apihub-biz/src/main/java/com/luhu/computility/module/apihub/controller/app/aimodel/vo/AppPricingVO.java
+34
-0
computility-module-apihub/computility-module-apihub-biz/src/main/java/com/luhu/computility/module/apihub/service/newapi/NewApiClient.java
+121
-0
No files found.
computility-module-apihub/computility-module-apihub-biz/src/main/java/com/luhu/computility/module/apihub/controller/app/aimodel/AppAiModelController.java
0 → 100644
View file @
38869e0a
This diff is collapsed.
Click to expand it.
computility-module-apihub/computility-module-apihub-biz/src/main/java/com/luhu/computility/module/apihub/controller/app/aimodel/vo/AppModelPricingVO.java
0 → 100644
View file @
38869e0a
package
com
.
luhu
.
computility
.
module
.
apihub
.
controller
.
app
.
aimodel
.
vo
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
java.math.BigDecimal
;
import
java.util.List
;
import
java.util.Map
;
/**
* APP端 - 模型定价信息 VO(聚合后)
*/
@Data
@Schema
(
description
=
"APP端 - 模型定价信息"
)
public
class
AppModelPricingVO
{
@Schema
(
description
=
"模型名"
)
private
String
modelName
;
@Schema
(
description
=
"图标名(lobehub 风格,如 Qwen.Color)"
)
private
String
icon
;
@Schema
(
description
=
"供应商名"
)
private
String
vendorName
;
@Schema
(
description
=
"支持的端点列表"
)
private
List
<
String
>
supportedEndpoints
;
@Schema
(
description
=
"支持的分组列表"
)
private
List
<
String
>
enableGroups
;
@Schema
(
description
=
"计价方式:0-按倍率,1-按固定价"
)
private
Integer
quotaType
;
@Schema
(
description
=
"模型倍率"
)
private
BigDecimal
modelRatio
;
@Schema
(
description
=
"固定价(元/1k tokens)"
)
private
BigDecimal
modelPrice
;
@Schema
(
description
=
"补全价格倍率"
)
private
BigDecimal
completionRatio
;
@Schema
(
description
=
"当前用户分组倍率"
)
private
BigDecimal
groupRatio
;
@Schema
(
description
=
"输入价格(元/1k tokens),已乘 groupRatio"
)
private
BigDecimal
inputPrice
;
@Schema
(
description
=
"输出价格(元/1k tokens),已乘 groupRatio"
)
private
BigDecimal
outputPrice
;
@Schema
(
description
=
"状态:1-启用,0-禁用"
)
private
Integer
status
;
@Schema
(
description
=
"模型描述(未设置则为空)"
)
private
String
description
;
}
computility-module-apihub/computility-module-apihub-biz/src/main/java/com/luhu/computility/module/apihub/controller/app/aimodel/vo/AppModelVO.java
0 → 100644
View file @
38869e0a
package
com
.
luhu
.
computility
.
module
.
apihub
.
controller
.
app
.
aimodel
.
vo
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
java.util.List
;
/**
* APP端 - 模型信息 VO
*/
@Data
@Schema
(
description
=
"APP端 - 模型信息"
)
public
class
AppModelVO
{
@Schema
(
description
=
"模型ID"
)
private
Long
id
;
@Schema
(
description
=
"模型名"
)
private
String
modelName
;
@Schema
(
description
=
"图标名"
)
private
String
icon
;
@Schema
(
description
=
"供应商名(自动匹配)"
)
private
String
vendorName
;
@Schema
(
description
=
"支持的端点"
)
private
List
<
String
>
endpoints
;
@Schema
(
description
=
"支持的分组"
)
private
List
<
String
>
enableGroups
;
@Schema
(
description
=
"状态:1-启用,0-禁用"
)
private
Integer
status
;
@Schema
(
description
=
"模型描述(未设置则为空)"
)
private
String
description
;
}
computility-module-apihub/computility-module-apihub-biz/src/main/java/com/luhu/computility/module/apihub/controller/app/aimodel/vo/AppPricingVO.java
0 → 100644
View file @
38869e0a
package
com
.
luhu
.
computility
.
module
.
apihub
.
controller
.
app
.
aimodel
.
vo
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
java.util.List
;
import
java.util.Map
;
/**
* APP端 - 定价信息 VO
*/
@Data
@Schema
(
description
=
"APP端 - 定价信息"
)
public
class
AppPricingVO
{
@Schema
(
description
=
"当前用户所属分组名"
)
private
String
group
;
@Schema
(
description
=
"当前分组倍率"
)
private
java
.
math
.
BigDecimal
groupRatio
;
@Schema
(
description
=
"所有可用分组及倍率"
)
private
Map
<
String
,
java
.
math
.
BigDecimal
>
groupRatios
;
@Schema
(
description
=
"支持的端点"
)
private
Map
<
String
,
Object
>
supportedEndpoint
;
@Schema
(
description
=
"供应商列表(用于图标 fallback)"
)
private
List
<
Map
<
String
,
Object
>>
vendors
;
@Schema
(
description
=
"模型定价列表(原始数据)"
)
private
List
<
Map
<
String
,
Object
>>
modelPricing
;
}
computility-module-apihub/computility-module-apihub-biz/src/main/java/com/luhu/computility/module/apihub/service/newapi/NewApiClient.java
View file @
38869e0a
...
...
@@ -5,6 +5,8 @@ import cn.hutool.http.HttpRequest;
import
cn.hutool.http.HttpResponse
;
import
cn.hutool.json.JSONObject
;
import
cn.hutool.json.JSONUtil
;
import
com.fasterxml.jackson.core.type.TypeReference
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.luhu.computility.module.apihub.config.NewApiProperties
;
import
com.luhu.computility.module.apihub.controller.admin.newapi.*
;
import
lombok.extern.slf4j.Slf4j
;
...
...
@@ -21,6 +23,9 @@ public class NewApiClient {
@Resource
private
NewApiProperties
newApiProperties
;
@Resource
private
ObjectMapper
objectMapper
;
private
static
final
String
HEADER_USER
=
"New-Api-User"
;
private
static
final
String
HEADER_AUTH
=
"Authorization"
;
private
static
final
String
USER_ANONYMOUS
=
"-1"
;
...
...
@@ -283,6 +288,122 @@ public class NewApiClient {
}
}
/**
* 获取定价信息(含模型定价、分组倍率、支持端点)
* GET /api/pricing
*
* @param accessToken 用户访问令牌(可空)。传入后使用对应账号权限请求,group_ratio.default 即为该用户实际倍率;不传则匿名请求。
* @param userId 用户在 New API 的 userId(与 accessToken 配套传入,用于 New-Api-User 头)。可空。
*/
public
NewApiResponse
<
Map
<
String
,
Object
>>
getPricing
(
String
accessToken
,
String
userId
)
{
String
url
=
newApiProperties
.
getBaseUrl
()
+
"/api/pricing"
;
log
.
info
(
"[NewApiClient.getPricing] 请求URL: {}, 带token={}, 带userId={}"
,
url
,
StrUtil
.
isNotBlank
(
accessToken
),
StrUtil
.
isNotBlank
(
userId
));
try
{
HttpRequest
request
=
HttpRequest
.
get
(
url
).
timeout
(
30000
);
if
(
StrUtil
.
isBlank
(
accessToken
))
{
// 匿名请求
request
.
header
(
HEADER_USER
,
USER_ANONYMOUS
);
}
else
{
// 带 token 时同时传 New-Api-User 头
if
(
StrUtil
.
isNotBlank
(
userId
))
{
request
.
header
(
HEADER_USER
,
userId
);
}
request
.
header
(
HEADER_AUTH
,
"Bearer "
+
accessToken
);
}
HttpResponse
response
=
request
.
execute
();
log
.
info
(
"[NewApiClient.getPricing] 响应状态: {}"
,
response
.
getStatus
());
return
parseMapResponse
(
response
);
}
catch
(
Exception
e
)
{
log
.
error
(
"[NewApiClient.getPricing] 请求异常"
,
e
);
return
NewApiResponse
.<
Map
<
String
,
Object
>>
builder
()
.
success
(
false
)
.
message
(
"请求异常: "
+
e
.
getMessage
())
.
httpResponse
(
null
)
.
build
();
}
}
/**
* 获取模型列表(管理员权限)
* GET /api/models/?p=0&page_size=100
*/
public
NewApiResponse
<
Map
<
String
,
Object
>>
getModels
(
Integer
page
,
Integer
pageSize
)
{
String
url
=
newApiProperties
.
getBaseUrl
()
+
"/api/models/"
;
if
(
page
!=
null
||
pageSize
!=
null
)
{
StringBuilder
sb
=
new
StringBuilder
(
url
).
append
(
"?"
);
if
(
page
!=
null
)
sb
.
append
(
"p="
).
append
(
page
);
if
(
page
!=
null
&&
pageSize
!=
null
)
sb
.
append
(
"&"
);
if
(
pageSize
!=
null
)
sb
.
append
(
"page_size="
).
append
(
pageSize
);
url
=
sb
.
toString
();
}
log
.
info
(
"[NewApiClient.getModels] 请求URL: {}"
,
url
);
try
{
HttpResponse
response
=
HttpRequest
.
get
(
url
)
.
header
(
HEADER_USER
,
newApiProperties
.
getAdminUserId
())
.
header
(
HEADER_AUTH
,
"Bearer "
+
newApiProperties
.
getAdminToken
())
.
timeout
(
30000
)
.
execute
();
log
.
info
(
"[NewApiClient.getModels] 响应状态: {}"
,
response
.
getStatus
());
return
parseMapResponse
(
response
);
}
catch
(
Exception
e
)
{
log
.
error
(
"[NewApiClient.getModels] 请求异常"
,
e
);
return
NewApiResponse
.<
Map
<
String
,
Object
>>
builder
()
.
success
(
false
)
.
message
(
"请求异常: "
+
e
.
getMessage
())
.
httpResponse
(
null
)
.
build
();
}
}
@SuppressWarnings
(
"unchecked"
)
private
NewApiResponse
<
Map
<
String
,
Object
>>
parseMapResponse
(
HttpResponse
response
)
{
try
{
String
body
=
response
.
body
();
if
(
StrUtil
.
isBlank
(
body
))
{
log
.
warn
(
"[NewApiClient.parseMapResponse] 响应为空,status={}"
,
response
.
getStatus
());
return
NewApiResponse
.<
Map
<
String
,
Object
>>
builder
()
.
success
(
false
)
.
message
(
"Empty response"
)
.
httpResponse
(
response
)
.
build
();
}
// 调试日志:记录原始响应体(截断避免过长)
String
bodyPreview
=
body
.
length
()
>
500
?
body
.
substring
(
0
,
500
)
+
"..."
:
body
;
log
.
info
(
"[NewApiClient.parseMapResponse] status={}, body={}"
,
response
.
getStatus
(),
bodyPreview
);
// 使用 Jackson 解析(兼容 New API 返回的含特殊字符 JSON)
Map
<
String
,
Object
>
root
=
objectMapper
.
readValue
(
body
,
new
TypeReference
<
Map
<
String
,
Object
>>()
{});
NewApiResponse
<
Map
<
String
,
Object
>>
result
=
new
NewApiResponse
<>();
result
.
setSuccess
(
root
.
get
(
"success"
)
==
null
?
null
:
Boolean
.
valueOf
(
root
.
get
(
"success"
).
toString
()));
result
.
setMessage
(
root
.
get
(
"message"
)
==
null
?
null
:
root
.
get
(
"message"
).
toString
());
result
.
setHttpResponse
(
response
);
if
(
root
.
containsKey
(
"data"
)
&&
root
.
get
(
"data"
)
!=
null
)
{
Object
data
=
root
.
get
(
"data"
);
if
(
data
instanceof
Map
)
{
result
.
setData
((
Map
<
String
,
Object
>)
data
);
}
else
{
// data 是其他类型(List 等),原样返回,调用方自行处理
Map
<
String
,
Object
>
wrapper
=
new
HashMap
<>();
wrapper
.
put
(
"data"
,
data
);
result
.
setData
(
wrapper
);
}
}
return
result
;
}
catch
(
Exception
e
)
{
log
.
error
(
"[NewApiClient.parseMapResponse] 解析响应异常,body={}"
,
response
.
body
(),
e
);
return
NewApiResponse
.<
Map
<
String
,
Object
>>
builder
()
.
success
(
false
)
.
message
(
"解析响应失败: "
+
e
.
getMessage
())
.
build
();
}
}
@SuppressWarnings
(
"unchecked"
)
private
<
T
>
NewApiResponse
<
T
>
parseResponse
(
HttpResponse
response
,
Class
<
T
>
dataClass
)
{
try
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment