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
e2bc19ec
authored
May 13, 2024
by
QuentinHsu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: 运营设置-倍率设置
parent
1042408f
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
242 additions
and
260 deletions
+242
-260
web/src/components/OperationSetting.js
+49
-260
web/src/pages/Setting/Operation/SettingsMagnification.js
+193
-0
No files found.
web/src/components/OperationSetting.js
View file @
e2bc19ec
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
Divider
,
Form
,
Grid
,
Header
}
from
'semantic-ui-react'
;
import
{
Divider
,
Form
,
Grid
,
Header
}
from
'semantic-ui-react'
;
import
{
Card
}
from
'@douyinfe/semi-ui'
;
import
{
Card
,
Spin
}
from
'@douyinfe/semi-ui'
;
import
SettingsGeneral
from
'../pages/Setting/Operation/SettingsGeneral.js'
;
import
SettingsGeneral
from
'../pages/Setting/Operation/SettingsGeneral.js'
;
import
SettingsDrawing
from
'../pages/Setting/Operation/SettingsDrawing.js'
;
import
SettingsDrawing
from
'../pages/Setting/Operation/SettingsDrawing.js'
;
import
SettingsSensitiveWords
from
'../pages/Setting/Operation/SettingsSensitiveWords.js'
;
import
SettingsSensitiveWords
from
'../pages/Setting/Operation/SettingsSensitiveWords.js'
;
...
@@ -8,6 +8,7 @@ import SettingsLog from '../pages/Setting/Operation/SettingsLog.js';
...
@@ -8,6 +8,7 @@ import SettingsLog from '../pages/Setting/Operation/SettingsLog.js';
import
SettingsDataDashboard
from
'../pages/Setting/Operation/SettingsDataDashboard.js'
;
import
SettingsDataDashboard
from
'../pages/Setting/Operation/SettingsDataDashboard.js'
;
import
SettingsMonitoring
from
'../pages/Setting/Operation/SettingsMonitoring.js'
;
import
SettingsMonitoring
from
'../pages/Setting/Operation/SettingsMonitoring.js'
;
import
SettingsCreditLimit
from
'../pages/Setting/Operation/SettingsCreditLimit.js'
;
import
SettingsCreditLimit
from
'../pages/Setting/Operation/SettingsCreditLimit.js'
;
import
SettingsMagnification
from
'../pages/Setting/Operation/SettingsMagnification.js'
;
import
{
import
{
API
,
API
,
...
@@ -17,10 +18,7 @@ import {
...
@@ -17,10 +18,7 @@ import {
verifyJSON
,
verifyJSON
,
}
from
'../helpers'
;
}
from
'../helpers'
;
import
{
useTheme
}
from
'../context/Theme'
;
const
OperationSetting
=
()
=>
{
const
OperationSetting
=
()
=>
{
let
now
=
new
Date
();
let
[
inputs
,
setInputs
]
=
useState
({
let
[
inputs
,
setInputs
]
=
useState
({
QuotaForNewUser
:
0
,
QuotaForNewUser
:
0
,
QuotaForInviter
:
0
,
QuotaForInviter
:
0
,
...
@@ -58,7 +56,7 @@ const OperationSetting = () => {
...
@@ -58,7 +56,7 @@ const OperationSetting = () => {
DefaultCollapseSidebar
:
false
,
// 默认折叠侧边栏
DefaultCollapseSidebar
:
false
,
// 默认折叠侧边栏
RetryTimes
:
0
,
RetryTimes
:
0
,
});
});
const
[
originInputs
,
setOriginInputs
]
=
useState
({});
let
[
loading
,
setLoading
]
=
useState
(
false
);
let
[
loading
,
setLoading
]
=
useState
(
false
);
const
getOptions
=
async
()
=>
{
const
getOptions
=
async
()
=>
{
...
@@ -86,271 +84,62 @@ const OperationSetting = () => {
...
@@ -86,271 +84,62 @@ const OperationSetting = () => {
});
});
setInputs
(
newInputs
);
setInputs
(
newInputs
);
setOriginInputs
(
newInputs
);
}
else
{
}
else
{
showError
(
message
);
showError
(
message
);
}
}
};
};
async
function
onRefresh
()
{
const
theme
=
useTheme
();
try
{
const
isDark
=
theme
===
'dark'
;
setLoading
(
true
);
await
getOptions
();
showSuccess
(
'刷新成功'
);
}
catch
(
error
)
{
showError
(
'刷新失败'
);
}
finally
{
setLoading
(
false
);
}
}
useEffect
(()
=>
{
useEffect
(()
=>
{
getOptions
()
.
then
()
;
getOptions
();
},
[]);
},
[]);
const
updateOption
=
async
(
key
,
value
)
=>
{
setLoading
(
true
);
if
(
key
.
endsWith
(
'Enabled'
))
{
value
=
inputs
[
key
]
===
'true'
?
'false'
:
'true'
;
}
if
(
key
===
'DefaultCollapseSidebar'
)
{
value
=
inputs
[
key
]
===
'true'
?
'false'
:
'true'
;
}
console
.
log
(
key
,
value
);
const
res
=
await
API
.
put
(
'/api/option/'
,
{
key
,
value
,
});
const
{
success
,
message
}
=
res
.
data
;
if
(
success
)
{
setInputs
((
inputs
)
=>
({
...
inputs
,
[
key
]:
value
}));
}
else
{
showError
(
message
);
}
setLoading
(
false
);
};
const
handleInputChange
=
async
(
e
,
{
name
,
value
})
=>
{
if
(
name
.
endsWith
(
'Enabled'
)
||
name
===
'DataExportInterval'
||
name
===
'DataExportDefaultTime'
||
name
===
'DefaultCollapseSidebar'
)
{
if
(
name
===
'DataExportDefaultTime'
)
{
localStorage
.
setItem
(
'data_export_default_time'
,
value
);
}
else
if
(
name
===
'MjNotifyEnabled'
)
{
localStorage
.
setItem
(
'mj_notify_enabled'
,
value
);
}
await
updateOption
(
name
,
value
);
}
else
{
setInputs
((
inputs
)
=>
({
...
inputs
,
[
name
]:
value
}));
}
};
const
submitConfig
=
async
(
group
)
=>
{
switch
(
group
)
{
case
'monitor'
:
if
(
originInputs
[
'ChannelDisableThreshold'
]
!==
inputs
.
ChannelDisableThreshold
)
{
await
updateOption
(
'ChannelDisableThreshold'
,
inputs
.
ChannelDisableThreshold
,
);
}
if
(
originInputs
[
'QuotaRemindThreshold'
]
!==
inputs
.
QuotaRemindThreshold
)
{
await
updateOption
(
'QuotaRemindThreshold'
,
inputs
.
QuotaRemindThreshold
,
);
}
break
;
case
'ratio'
:
if
(
originInputs
[
'ModelRatio'
]
!==
inputs
.
ModelRatio
)
{
if
(
!
verifyJSON
(
inputs
.
ModelRatio
))
{
showError
(
'模型倍率不是合法的 JSON 字符串'
);
return
;
}
await
updateOption
(
'ModelRatio'
,
inputs
.
ModelRatio
);
}
if
(
originInputs
[
'CompletionRatio'
]
!==
inputs
.
CompletionRatio
)
{
if
(
!
verifyJSON
(
inputs
.
CompletionRatio
))
{
showError
(
'模型补全倍率不是合法的 JSON 字符串'
);
return
;
}
await
updateOption
(
'CompletionRatio'
,
inputs
.
CompletionRatio
);
}
if
(
originInputs
[
'GroupRatio'
]
!==
inputs
.
GroupRatio
)
{
if
(
!
verifyJSON
(
inputs
.
GroupRatio
))
{
showError
(
'分组倍率不是合法的 JSON 字符串'
);
return
;
}
await
updateOption
(
'GroupRatio'
,
inputs
.
GroupRatio
);
}
if
(
originInputs
[
'ModelPrice'
]
!==
inputs
.
ModelPrice
)
{
if
(
!
verifyJSON
(
inputs
.
ModelPrice
))
{
showError
(
'模型固定价格不是合法的 JSON 字符串'
);
return
;
}
await
updateOption
(
'ModelPrice'
,
inputs
.
ModelPrice
);
}
break
;
case
'words'
:
if
(
originInputs
[
'SensitiveWords'
]
!==
inputs
.
SensitiveWords
)
{
await
updateOption
(
'SensitiveWords'
,
inputs
.
SensitiveWords
);
}
break
;
case
'quota'
:
if
(
originInputs
[
'QuotaForNewUser'
]
!==
inputs
.
QuotaForNewUser
)
{
await
updateOption
(
'QuotaForNewUser'
,
inputs
.
QuotaForNewUser
);
}
if
(
originInputs
[
'QuotaForInvitee'
]
!==
inputs
.
QuotaForInvitee
)
{
await
updateOption
(
'QuotaForInvitee'
,
inputs
.
QuotaForInvitee
);
}
if
(
originInputs
[
'QuotaForInviter'
]
!==
inputs
.
QuotaForInviter
)
{
await
updateOption
(
'QuotaForInviter'
,
inputs
.
QuotaForInviter
);
}
if
(
originInputs
[
'PreConsumedQuota'
]
!==
inputs
.
PreConsumedQuota
)
{
await
updateOption
(
'PreConsumedQuota'
,
inputs
.
PreConsumedQuota
);
}
break
;
case
'general'
:
if
(
originInputs
[
'TopUpLink'
]
!==
inputs
.
TopUpLink
)
{
await
updateOption
(
'TopUpLink'
,
inputs
.
TopUpLink
);
}
if
(
originInputs
[
'ChatLink'
]
!==
inputs
.
ChatLink
)
{
await
updateOption
(
'ChatLink'
,
inputs
.
ChatLink
);
}
if
(
originInputs
[
'ChatLink2'
]
!==
inputs
.
ChatLink2
)
{
await
updateOption
(
'ChatLink2'
,
inputs
.
ChatLink2
);
}
if
(
originInputs
[
'QuotaPerUnit'
]
!==
inputs
.
QuotaPerUnit
)
{
await
updateOption
(
'QuotaPerUnit'
,
inputs
.
QuotaPerUnit
);
}
if
(
originInputs
[
'RetryTimes'
]
!==
inputs
.
RetryTimes
)
{
await
updateOption
(
'RetryTimes'
,
inputs
.
RetryTimes
);
}
break
;
}
};
return
(
return
(
<>
<>
{
/* 通用设置 */
}
<
Spin
spinning
=
{
loading
}
size
=
'large'
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
{
/* 通用设置 */
}
<
SettingsGeneral
options
=
{
inputs
}
/
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
<
/Card
>
<
SettingsGeneral
options
=
{
inputs
}
/
>
{
/* 绘图设置 */
}
<
/Card
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
{
/* 绘图设置 */
}
<
SettingsDrawing
options
=
{
inputs
}
/
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
<
/Card
>
<
SettingsDrawing
options
=
{
inputs
}
/
>
{
/* 屏蔽词过滤设置 */
}
<
/Card
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
{
/* 屏蔽词过滤设置 */
}
<
SettingsSensitiveWords
options
=
{
inputs
}
/
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
<
/Card
>
<
SettingsSensitiveWords
options
=
{
inputs
}
/
>
{
/* 日志设置 */
}
<
/Card
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
{
/* 日志设置 */
}
<
SettingsLog
options
=
{
inputs
}
/
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
<
/Card
>
<
SettingsLog
options
=
{
inputs
}
/
>
{
/* 数据看板 */
}
<
/Card
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
{
/* 数据看板 */
}
<
SettingsDataDashboard
options
=
{
inputs
}
/
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
<
/Card
>
<
SettingsDataDashboard
options
=
{
inputs
}
/
>
{
/* 监控设置 */
}
<
/Card
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
{
/* 监控设置 */
}
<
SettingsMonitoring
options
=
{
inputs
}
/
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
<
/Card
>
<
SettingsMonitoring
options
=
{
inputs
}
/
>
{
/* 额度设置 */
}
<
/Card
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
{
/* 额度设置 */
}
<
SettingsCreditLimit
options
=
{
inputs
}
/
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
<
/Card
>
<
SettingsCreditLimit
options
=
{
inputs
}
/
>
<
Grid
columns
=
{
1
}
>
<
/Card
>
<
Grid
.
Column
>
{
/* 倍率设置 */
}
<
Form
loading
=
{
loading
}
inverted
=
{
isDark
}
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
{
/*<Form.Group inline>*/
}
<
SettingsMagnification
options
=
{
inputs
}
/
>
{
/* <Form.Checkbox*/
}
<
/Card
>
{
/* checked={inputs.StopOnSensitiveEnabled === 'true'}*/
}
<
/Spin
>
{
/* label='在检测到屏蔽词时,立刻停止生成,否则替换屏蔽词'*/
}
{
/* name='StopOnSensitiveEnabled'*/
}
{
/* onChange={handleInputChange}*/
}
{
/* />*/
}
{
/*</Form.Group>*/
}
{
/*<Form.Group>*/
}
{
/* <Form.Input*/
}
{
/* label="流模式下缓存队列,默认不缓存,设置越大检测越准确,但是回复会有卡顿感"*/
}
{
/* name="StreamCacheTextLength"*/
}
{
/* onChange={handleInputChange}*/
}
{
/* value={inputs.StreamCacheQueueLength}*/
}
{
/* type="number"*/
}
{
/* min="0"*/
}
{
/* placeholder="例如:10"*/
}
{
/* />*/
}
{
/*</Form.Group>*/
}
<
Divider
/>
<
Header
as
=
'h3'
inverted
=
{
isDark
}
>
倍率设置
<
/Header
>
<
Form
.
Group
widths
=
'equal'
>
<
Form
.
TextArea
label
=
'模型固定价格(一次调用消耗多少刀,优先级大于模型倍率)'
name
=
'ModelPrice'
onChange
=
{
handleInputChange
}
style
=
{{
minHeight
:
250
,
fontFamily
:
'JetBrains Mono, Consolas'
,
}}
autoComplete
=
'new-password'
value
=
{
inputs
.
ModelPrice
}
placeholder
=
'为一个 JSON 文本,键为模型名称,值为一次调用消耗多少刀,比如 "gpt-4-gizmo-*": 0.1,一次消耗0.1刀'
/>
<
/Form.Group
>
<
Form
.
Group
widths
=
'equal'
>
<
Form
.
TextArea
label
=
'模型倍率'
name
=
'ModelRatio'
onChange
=
{
handleInputChange
}
style
=
{{
minHeight
:
250
,
fontFamily
:
'JetBrains Mono, Consolas'
,
}}
autoComplete
=
'new-password'
value
=
{
inputs
.
ModelRatio
}
placeholder
=
'为一个 JSON 文本,键为模型名称,值为倍率'
/>
<
/Form.Group
>
<
Form
.
Group
widths
=
'equal'
>
<
Form
.
TextArea
label
=
'模型补全倍率(仅对自定义模型有效)'
name
=
'CompletionRatio'
onChange
=
{
handleInputChange
}
style
=
{{
minHeight
:
250
,
fontFamily
:
'JetBrains Mono, Consolas'
,
}}
autoComplete
=
'new-password'
value
=
{
inputs
.
CompletionRatio
}
placeholder
=
'为一个 JSON 文本,键为分组名称,值为倍率'
/>
<
/Form.Group
>
<
Form
.
Group
widths
=
'equal'
>
<
Form
.
TextArea
label
=
'分组倍率'
name
=
'GroupRatio'
onChange
=
{
handleInputChange
}
style
=
{{
minHeight
:
250
,
fontFamily
:
'JetBrains Mono, Consolas'
,
}}
autoComplete
=
'new-password'
value
=
{
inputs
.
GroupRatio
}
placeholder
=
'为一个 JSON 文本,键为分组名称,值为倍率'
/>
<
/Form.Group
>
<
Form
.
Button
onClick
=
{()
=>
{
submitConfig
(
'ratio'
).
then
();
}}
>
保存倍率设置
<
/Form.Button
>
<
/Form
>
<
/Grid.Column
>
<
/Grid
>
<
/
>
<
/
>
);
);
};
};
...
...
web/src/pages/Setting/Operation/SettingsMagnification.js
0 → 100644
View file @
e2bc19ec
import
React
,
{
useEffect
,
useState
,
useRef
}
from
'react'
;
import
{
Button
,
Col
,
Form
,
Row
,
Spin
}
from
'@douyinfe/semi-ui'
;
import
{
compareObjects
,
API
,
showError
,
showSuccess
,
showWarning
,
verifyJSON
,
}
from
'../../../helpers'
;
export
default
function
SettingsMagnification
(
props
)
{
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
inputs
,
setInputs
]
=
useState
({
ModelPrice
:
''
,
ModelRatio
:
''
,
CompletionRatio
:
''
,
GroupRatio
:
''
,
});
const
refForm
=
useRef
();
const
[
inputsRow
,
setInputsRow
]
=
useState
(
inputs
);
async
function
onSubmit
()
{
try
{
await
refForm
.
current
.
validate
();
const
updateArray
=
compareObjects
(
inputs
,
inputsRow
);
if
(
!
updateArray
.
length
)
return
showWarning
(
'你似乎并没有修改什么'
);
const
requestQueue
=
updateArray
.
map
((
item
)
=>
{
let
value
=
''
;
if
(
typeof
inputs
[
item
.
key
]
===
'boolean'
)
{
value
=
String
(
inputs
[
item
.
key
]);
}
else
{
value
=
inputs
[
item
.
key
];
}
return
API
.
put
(
'/api/option/'
,
{
key
:
item
.
key
,
value
,
});
});
setLoading
(
true
);
Promise
.
all
(
requestQueue
)
.
then
((
res
)
=>
{
if
(
requestQueue
.
length
===
1
)
{
if
(
res
.
includes
(
undefined
))
return
;
}
else
if
(
requestQueue
.
length
>
1
)
{
if
(
res
.
includes
(
undefined
))
return
showError
(
'部分更新失败'
);
}
showSuccess
(
'更新成功'
);
})
.
catch
(()
=>
{
showError
(
'更新失败'
);
})
.
finally
(()
=>
{
setLoading
(
false
);
setInputsRow
(
structuredClone
(
inputs
));
});
}
catch
(
error
)
{
showError
(
'请检查输入'
);
console
.
error
(
error
);
}
finally
{
}
}
useEffect
(()
=>
{
const
currentInputs
=
{};
for
(
let
key
in
props
.
options
)
{
if
(
Object
.
keys
(
inputs
).
includes
(
key
))
{
currentInputs
[
key
]
=
props
.
options
[
key
];
}
}
setInputs
(
currentInputs
);
setInputsRow
(
structuredClone
(
currentInputs
));
refForm
.
current
.
setValues
(
currentInputs
);
},
[
props
.
options
]);
return
(
<>
<
Spin
spinning
=
{
loading
}
>
<
Form
values
=
{
inputs
}
getFormApi
=
{(
formAPI
)
=>
(
refForm
.
current
=
formAPI
)}
style
=
{{
marginBottom
:
15
}}
>
<
Form
.
Section
text
=
{
'倍率设置'
}
>
<
Row
gutter
=
{
16
}
>
<
Col
span
=
{
16
}
>
<
Form
.
TextArea
label
=
{
'模型固定价格'
}
extraText
=
{
'一次调用消耗多少刀,优先级大于模型倍率'
}
placeholder
=
{
'为一个 JSON 文本,键为模型名称,值为一次调用消耗多少刀,比如 "gpt-4-gizmo-*": 0.1,一次消耗0.1刀'
}
field
=
{
'ModelPrice'
}
autosize
=
{{
minRows
:
6
,
maxRows
:
12
}}
trigger
=
'blur'
rules
=
{[
{
validator
:
(
rule
,
value
)
=>
verifyJSON
(
value
),
message
:
'不是合法的 JSON 字符串'
,
},
]}
onChange
=
{(
value
)
=>
setInputs
({
...
inputs
,
ModelPrice
:
value
,
})
}
/
>
<
/Col
>
<
/Row
>
<
Row
gutter
=
{
16
}
>
<
Col
span
=
{
16
}
>
<
Form
.
TextArea
label
=
{
'模型倍率'
}
extraText
=
{
''
}
placeholder
=
{
'为一个 JSON 文本,键为模型名称,值为倍率'
}
field
=
{
'ModelRatio'
}
autosize
=
{{
minRows
:
6
,
maxRows
:
12
}}
trigger
=
'blur'
rules
=
{[
{
validator
:
(
rule
,
value
)
=>
verifyJSON
(
value
),
message
:
'不是合法的 JSON 字符串'
,
},
]}
onChange
=
{(
value
)
=>
setInputs
({
...
inputs
,
ModelRatio
:
value
,
})
}
/
>
<
/Col
>
<
/Row
>
<
Row
gutter
=
{
16
}
>
<
Col
span
=
{
16
}
>
<
Form
.
TextArea
label
=
{
'模型补全倍率'
}
extraText
=
{
'仅对自定义模型有效'
}
placeholder
=
{
'为一个 JSON 文本,键为模型名称,值为倍率'
}
field
=
{
'CompletionRatio'
}
autosize
=
{{
minRows
:
6
,
maxRows
:
12
}}
trigger
=
'blur'
rules
=
{[
{
validator
:
(
rule
,
value
)
=>
verifyJSON
(
value
),
message
:
'不是合法的 JSON 字符串'
,
},
]}
onChange
=
{(
value
)
=>
setInputs
({
...
inputs
,
CompletionRatio
:
value
,
})
}
/
>
<
/Col
>
<
/Row
>
<
Row
gutter
=
{
16
}
>
<
Col
span
=
{
16
}
>
<
Form
.
TextArea
label
=
{
'分组倍率'
}
extraText
=
{
''
}
placeholder
=
{
'为一个 JSON 文本,键为分组名称,值为倍率'
}
field
=
{
'GroupRatio'
}
autosize
=
{{
minRows
:
6
,
maxRows
:
12
}}
trigger
=
'blur'
rules
=
{[
{
validator
:
(
rule
,
value
)
=>
verifyJSON
(
value
),
message
:
'不是合法的 JSON 字符串'
,
},
]}
onChange
=
{(
value
)
=>
setInputs
({
...
inputs
,
GroupRatio
:
value
,
})
}
/
>
<
/Col
>
<
/Row
>
<
Row
>
<
Button
size
=
'large'
onClick
=
{
onSubmit
}
>
保存倍率设置
<
/Button
>
<
/Row
>
<
/Form.Section
>
<
/Form
>
<
/Spin
>
<
/
>
);
}
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