Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-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
1c471889
authored
Dec 14, 2024
by
Calcium-Ion
Committed by
GitHub
Dec 14, 2024
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #618 from HynoR/feat/modeledit
feat: 可视化模型定价编辑器
parents
5f74f7c3
9f274608
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
301 additions
and
0 deletions
+301
-0
web/src/components/OperationSetting.js
+5
-0
web/src/pages/Setting/Operation/ModelSettingsVisualEditor.js
+296
-0
No files found.
web/src/components/OperationSetting.js
View file @
1c471889
...
...
@@ -8,6 +8,7 @@ import SettingsDataDashboard from '../pages/Setting/Operation/SettingsDataDashbo
import
SettingsMonitoring
from
'../pages/Setting/Operation/SettingsMonitoring.js'
;
import
SettingsCreditLimit
from
'../pages/Setting/Operation/SettingsCreditLimit.js'
;
import
SettingsMagnification
from
'../pages/Setting/Operation/SettingsMagnification.js'
;
import
ModelSettingsVisualEditor
from
'../pages/Setting/Operation/ModelSettingsVisualEditor.js'
;
import
{
API
,
showError
,
showSuccess
}
from
'../helpers'
;
import
SettingsChats
from
'../pages/Setting/Operation/SettingsChats.js'
;
...
...
@@ -141,6 +142,10 @@ const OperationSetting = () => {
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
<
SettingsMagnification
options
=
{
inputs
}
refresh
=
{
onRefresh
}
/
>
<
/Card
>
{
/*可视化倍率设置*/
}
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
<
ModelSettingsVisualEditor
options
=
{
inputs
}
refresh
=
{
onRefresh
}
/
>
<
/Card
>
<
/Spin
>
<
/
>
);
...
...
web/src/pages/Setting/Operation/ModelSettingsVisualEditor.js
0 → 100644
View file @
1c471889
// ModelSettingsVisualEditor.js
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
Table
,
Button
,
Input
,
Modal
,
Form
,
Space
}
from
'@douyinfe/semi-ui'
;
import
{
IconDelete
,
IconPlus
,
IconSearch
,
IconSave
}
from
'@douyinfe/semi-icons'
;
import
{
showError
,
showSuccess
}
from
'../../../helpers'
;
import
{
API
}
from
'../../../helpers'
;
export
default
function
ModelSettingsVisualEditor
(
props
)
{
const
[
models
,
setModels
]
=
useState
([]);
const
[
visible
,
setVisible
]
=
useState
(
false
);
const
[
currentModel
,
setCurrentModel
]
=
useState
(
null
);
const
[
searchText
,
setSearchText
]
=
useState
(
''
);
const
[
currentPage
,
setCurrentPage
]
=
useState
(
1
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
pageSize
=
10
;
useEffect
(()
=>
{
try
{
const
modelPrice
=
JSON
.
parse
(
props
.
options
.
ModelPrice
||
'{}'
);
const
modelRatio
=
JSON
.
parse
(
props
.
options
.
ModelRatio
||
'{}'
);
const
completionRatio
=
JSON
.
parse
(
props
.
options
.
CompletionRatio
||
'{}'
);
// 合并所有模型名称
const
modelNames
=
new
Set
([
...
Object
.
keys
(
modelPrice
),
...
Object
.
keys
(
modelRatio
),
...
Object
.
keys
(
completionRatio
)
]);
const
modelData
=
Array
.
from
(
modelNames
).
map
(
name
=>
({
name
,
price
:
modelPrice
[
name
]
===
undefined
?
''
:
modelPrice
[
name
],
ratio
:
modelRatio
[
name
]
===
undefined
?
''
:
modelRatio
[
name
],
completionRatio
:
completionRatio
[
name
]
===
undefined
?
''
:
completionRatio
[
name
]
}));
setModels
(
modelData
);
}
catch
(
error
)
{
console
.
error
(
'JSON解析错误:'
,
error
);
}
},
[
props
.
options
]);
// 首先声明分页相关的工具函数
const
getPagedData
=
(
data
,
currentPage
,
pageSize
)
=>
{
const
start
=
(
currentPage
-
1
)
*
pageSize
;
const
end
=
start
+
pageSize
;
return
data
.
slice
(
start
,
end
);
};
// 在 return 语句之前,先处理过滤和分页逻辑
const
filteredModels
=
models
.
filter
(
model
=>
searchText
?
model
.
name
.
toLowerCase
().
includes
(
searchText
.
toLowerCase
())
:
true
);
// 然后基于过滤后的数据计算分页数据
const
pagedData
=
getPagedData
(
filteredModels
,
currentPage
,
pageSize
);
const
SubmitData
=
async
()
=>
{
setLoading
(
true
);
const
output
=
{
ModelPrice
:
{},
ModelRatio
:
{},
CompletionRatio
:
{}
};
let
currentConvertModelName
=
''
;
try
{
// 数据转换
models
.
forEach
(
model
=>
{
currentConvertModelName
=
model
.
name
;
if
(
model
.
price
!==
''
)
{
// 如果价格不为空,则转换为浮点数,忽略倍率参数
output
.
ModelPrice
[
model
.
name
]
=
parseFloat
(
model
.
price
)
}
else
{
if
(
model
.
ratio
!==
''
)
output
.
ModelRatio
[
model
.
name
]
=
parseFloat
(
model
.
ratio
);
if
(
model
.
completionRatio
!=
''
)
output
.
CompletionRatio
[
model
.
name
]
=
parseFloat
(
model
.
completionRatio
);
}
});
// 准备API请求数组
const
finalOutput
=
{
ModelPrice
:
JSON
.
stringify
(
output
.
ModelPrice
,
null
,
2
),
ModelRatio
:
JSON
.
stringify
(
output
.
ModelRatio
,
null
,
2
),
CompletionRatio
:
JSON
.
stringify
(
output
.
CompletionRatio
,
null
,
2
)
};
const
requestQueue
=
Object
.
entries
(
finalOutput
).
map
(([
key
,
value
])
=>
{
return
API
.
put
(
'/api/option/'
,
{
key
,
value
});
});
// 批量处理请求
const
results
=
await
Promise
.
all
(
requestQueue
);
// 验证结果
if
(
requestQueue
.
length
===
1
)
{
if
(
results
.
includes
(
undefined
))
return
;
}
else
if
(
requestQueue
.
length
>
1
)
{
if
(
results
.
includes
(
undefined
))
{
return
showError
(
'部分保存失败,请重试'
);
}
}
// 检查每个请求的结果
for
(
const
res
of
results
)
{
if
(
!
res
.
data
.
success
)
{
return
showError
(
res
.
data
.
message
);
}
}
showSuccess
(
'保存成功'
);
props
.
refresh
();
}
catch
(
error
)
{
console
.
error
(
'保存失败:'
,
error
);
showError
(
'保存失败,请重试'
);
}
finally
{
setLoading
(
false
);
}
};
const
columns
=
[
{
title
:
'模型名称'
,
dataIndex
:
'name'
,
key
:
'name'
,
},
{
title
:
'固定价格'
,
dataIndex
:
'price'
,
key
:
'price'
,
render
:
(
text
,
record
)
=>
(
<
Input
value
=
{
text
}
placeholder
=
"按量计价"
onChange
=
{
value
=>
updateModel
(
record
.
name
,
'price'
,
value
)}
/
>
)
},
{
title
:
'模型倍率'
,
dataIndex
:
'ratio'
,
key
:
'ratio'
,
render
:
(
text
,
record
)
=>
(
<
Input
value
=
{
text
}
placeholder
=
{
record
.
price
!==
''
?
'固定价格'
:
'默认补全倍率'
}
disabled
=
{
record
.
price
!==
''
}
onChange
=
{
value
=>
updateModel
(
record
.
name
,
'ratio'
,
value
)}
/
>
)
},
{
title
:
'补全倍率'
,
dataIndex
:
'completionRatio'
,
key
:
'completionRatio'
,
render
:
(
text
,
record
)
=>
(
<
Input
value
=
{
text
}
placeholder
=
{
record
.
price
!==
''
?
'固定价格'
:
'默认补全倍率'
}
disabled
=
{
record
.
price
!==
''
}
onChange
=
{
value
=>
updateModel
(
record
.
name
,
'completionRatio'
,
value
)}
/
>
)
},
{
title
:
'操作'
,
key
:
'action'
,
render
:
(
_
,
record
)
=>
(
<
Button
icon
=
{
<
IconDelete
/>
}
type
=
"danger"
onClick
=
{()
=>
deleteModel
(
record
.
name
)}
/
>
)
}
];
const
updateModel
=
(
name
,
field
,
value
)
=>
{
if
(
isNaN
(
value
))
{
showError
(
'请输入数字'
);
return
;
}
setModels
(
prev
=>
prev
.
map
(
model
=>
model
.
name
===
name
?
{
...
model
,
[
field
]:
value
}
:
model
)
);
};
const
deleteModel
=
(
name
)
=>
{
setModels
(
prev
=>
prev
.
filter
(
model
=>
model
.
name
!==
name
));
};
const
addModel
=
(
values
)
=>
{
// 检查模型名称是否存在, 如果存在则拒绝添加
if
(
models
.
some
(
model
=>
model
.
name
===
values
.
name
))
{
showError
(
'模型名称已存在'
);
return
;
}
// 不允许同时添加固定价格和倍率
if
(
values
.
price
!==
''
&&
(
values
.
ratio
!==
''
||
values
.
completionRatio
!==
''
))
{
showError
(
'固定价格和倍率不能同时存在'
);
return
;
}
setModels
(
prev
=>
[{
name
:
values
.
name
,
price
:
values
.
price
||
''
,
ratio
:
values
.
ratio
||
''
,
completionRatio
:
values
.
completionRatio
||
''
},
...
prev
]);
setVisible
(
false
);
showSuccess
(
'添加成功'
);
};
return
(
<>
<
h3
>
模型价格
<
/h3
>
<
Space
vertical
align
=
"start"
style
=
{{
width
:
'100%'
}}
>
<
Space
>
<
Button
icon
=
{
<
IconPlus
/>
}
onClick
=
{()
=>
setVisible
(
true
)}
>
添加模型
<
/Button
>
<
Button
type
=
"primary"
icon
=
{
<
IconSave
/>
}
onClick
=
{
SubmitData
}
>
应用更改
<
/Button
>
<
Input
prefix
=
{
<
IconSearch
/>
}
placeholder
=
"搜索模型名称"
value
=
{
searchText
}
onChange
=
{
value
=>
{
setSearchText
(
value
)
// 搜索时重置页码
setCurrentPage
(
1
);
}}
style
=
{{
width
:
200
}}
/
>
<
/Space
>
<
Table
columns
=
{
columns
}
dataSource
=
{
pagedData
}
// 使用分页后的数据
pagination
=
{{
currentPage
:
currentPage
,
pageSize
:
pageSize
,
total
:
filteredModels
.
length
,
onPageChange
:
page
=>
setCurrentPage
(
page
),
showTotal
:
true
,
showSizeChanger
:
false
}}
/
>
<
/Space
>
<
Modal
title
=
"添加模型"
visible
=
{
visible
}
onCancel
=
{()
=>
setVisible
(
false
)}
onOk
=
{()
=>
{
currentModel
&&
addModel
(
currentModel
);
}}
>
<
Form
>
<
p
>
请输入固定价格或者模型倍率
+
补全倍率
<
/p
>
<
Form
.
Input
field
=
"name"
label
=
"模型名称"
placeholder
=
"strawberry"
required
onChange
=
{
value
=>
setCurrentModel
(
prev
=>
({
...
prev
,
name
:
value
}))}
/
>
<
Form
.
Input
field
=
"price"
label
=
"固定价格(每次)"
placeholder
=
"输入每次价格"
onChange
=
{
value
=>
setCurrentModel
(
prev
=>
({
...
prev
,
price
:
value
}))}
/
>
<
Form
.
Input
field
=
"ratio"
label
=
"模型倍率"
placeholder
=
"输入模型倍率"
onChange
=
{
value
=>
setCurrentModel
(
prev
=>
({
...
prev
,
ratio
:
value
}))}
/
>
<
Form
.
Input
field
=
"completionRatio"
label
=
"补全倍率"
placeholder
=
"输入补全价格"
onChange
=
{
value
=>
setCurrentModel
(
prev
=>
({
...
prev
,
completionRatio
:
value
}))}
/
>
<
/Form
>
<
/Modal
>
<
/
>
);
}
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