mirror of
https://github.com/yangjian102621/geekai.git
synced 2026-05-10 19:54:25 +08:00
optimize jimeng power config
This commit is contained in:
@@ -8,15 +8,7 @@ type JimengConfig struct {
|
|||||||
// 火山引擎大模型专用的验证方式
|
// 火山引擎大模型专用的验证方式
|
||||||
ApiKey string `json:"api_key"`
|
ApiKey string `json:"api_key"`
|
||||||
// 算力配置
|
// 算力配置
|
||||||
Power JimengPower `json:"power"`
|
Powers map[string]int `json:"powers"`
|
||||||
}
|
|
||||||
|
|
||||||
// JimengPower 即梦AI算力配置
|
|
||||||
type JimengPower struct {
|
|
||||||
Image int `json:"image"` // 图片生成算力,单位:积分/张
|
|
||||||
Video int `json:"video"` // 视频生成算力,单位:积分/秒
|
|
||||||
VirtualHuman int `json:"virtual_human"` // 数字人视频生成算力,单位:积分/秒
|
|
||||||
ActionTransfer int `json:"action_transfer"` // 视频动作迁移算力,单位:积分/秒
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// JMTaskStatus 任务状态
|
// JMTaskStatus 任务状态
|
||||||
|
|||||||
@@ -231,21 +231,15 @@ func (h *AdminJimengHandler) UpdateConfig(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 验证算力配置
|
// 验证算力配置
|
||||||
if req.Power.Image <= 0 {
|
if len(req.Powers) == 0 {
|
||||||
resp.ERROR(c, "图片生成算力必须大于0")
|
resp.ERROR(c, "请至少配置一个模型的积分")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if req.Power.Video <= 0 {
|
for key, val := range req.Powers {
|
||||||
resp.ERROR(c, "视频生成算力必须大于0")
|
if val <= 0 {
|
||||||
|
resp.ERROR(c, fmt.Sprintf("模型 %s 的积分必须大于0", key))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if req.Power.VirtualHuman <= 0 {
|
|
||||||
resp.ERROR(c, "数字人生成算力必须大于0")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if req.Power.ActionTransfer <= 0 {
|
|
||||||
resp.ERROR(c, "视频动作迁移算力必须大于0")
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存配置
|
// 保存配置
|
||||||
|
|||||||
@@ -39,12 +39,12 @@ func NewJimengHandler(app *core.AppServer, jimengService *jimeng.Service, db *go
|
|||||||
// RegisterRoutes 注册路由,新增统一任务接口
|
// RegisterRoutes 注册路由,新增统一任务接口
|
||||||
func (h *JimengHandler) RegisterRoutes() {
|
func (h *JimengHandler) RegisterRoutes() {
|
||||||
group := h.App.Engine.Group("/api/jimeng/")
|
group := h.App.Engine.Group("/api/jimeng/")
|
||||||
|
group.GET("power-config", h.GetPowerConfig)
|
||||||
|
|
||||||
// 需要用户授权的接口
|
// 需要用户授权的接口
|
||||||
group.Use(middleware.UserAuthMiddleware(h.App.Config.Session.SecretKey, h.App.Redis))
|
group.Use(middleware.UserAuthMiddleware(h.App.Config.Session.SecretKey, h.App.Redis))
|
||||||
{
|
{
|
||||||
group.POST("task", h.CreateTask)
|
group.POST("task", h.CreateTask)
|
||||||
group.GET("power-config", h.GetPowerConfig)
|
|
||||||
group.POST("jobs", h.Jobs)
|
group.POST("jobs", h.Jobs)
|
||||||
group.GET("remove", h.Remove)
|
group.GET("remove", h.Remove)
|
||||||
group.GET("retry", h.Retry)
|
group.GET("retry", h.Retry)
|
||||||
@@ -125,15 +125,31 @@ func (h *JimengHandler) CreateTask(c *gin.Context) {
|
|||||||
|
|
||||||
func (h *JimengHandler) getTaskRemark(req types.JimengTaskRequest, jobId uint) string {
|
func (h *JimengHandler) getTaskRemark(req types.JimengTaskRequest, jobId uint) string {
|
||||||
remark := fmt.Sprintf("即梦任务%s,任务ID:%d", req.ReqKey, jobId)
|
remark := fmt.Sprintf("即梦任务%s,任务ID:%d", req.ReqKey, jobId)
|
||||||
|
perUnit, ok := h.App.SysConfig.Jimeng.Powers[req.ReqKey]
|
||||||
|
if !ok || perUnit <= 0 {
|
||||||
|
return remark // Fallback if power not found or invalid
|
||||||
|
}
|
||||||
switch req.TaskType {
|
switch req.TaskType {
|
||||||
case types.JMTaskTypeImage:
|
case types.JMTaskTypeImage:
|
||||||
remark = fmt.Sprintf("即梦图片生成,任务ID:%d,%d积分/张", jobId, h.App.SysConfig.Jimeng.Power.Image)
|
remark = fmt.Sprintf("即梦图片生成,任务ID:%d,%d积分/张", jobId, perUnit)
|
||||||
case types.JMTaskTypeVideo:
|
case types.JMTaskTypeVideo:
|
||||||
remark = fmt.Sprintf("即梦视频生成,任务ID:%d,%d积分/秒, %d秒", jobId, h.App.SysConfig.Jimeng.Power.Video, req.Power/h.App.SysConfig.Jimeng.Power.Video)
|
seconds := 0
|
||||||
|
if perUnit > 0 {
|
||||||
|
seconds = req.Power / perUnit
|
||||||
|
}
|
||||||
|
remark = fmt.Sprintf("即梦视频生成,任务ID:%d,%d积分/秒, %d秒", jobId, perUnit, seconds)
|
||||||
case types.JMTaskTypeVirtualHuman:
|
case types.JMTaskTypeVirtualHuman:
|
||||||
remark = fmt.Sprintf("即梦数字人视频生成,任务ID:%d,%d积分/秒, %d秒", jobId, h.App.SysConfig.Jimeng.Power.VirtualHuman, req.Power/h.App.SysConfig.Jimeng.Power.VirtualHuman)
|
seconds := 0
|
||||||
|
if perUnit > 0 {
|
||||||
|
seconds = req.Power / perUnit
|
||||||
|
}
|
||||||
|
remark = fmt.Sprintf("即梦数字人视频生成,任务ID:%d,%d积分/秒, %d秒", jobId, perUnit, seconds)
|
||||||
case types.JMTaskTypeActionTransfer:
|
case types.JMTaskTypeActionTransfer:
|
||||||
remark = fmt.Sprintf("即梦视频动作迁移,任务ID:%d,%d积分/秒, %d秒", jobId, h.App.SysConfig.Jimeng.Power.ActionTransfer, req.Power/h.App.SysConfig.Jimeng.Power.ActionTransfer)
|
seconds := 0
|
||||||
|
if perUnit > 0 {
|
||||||
|
seconds = req.Power / perUnit
|
||||||
|
}
|
||||||
|
remark = fmt.Sprintf("即梦视频动作迁移,任务ID:%d,%d积分/秒, %d秒", jobId, perUnit, seconds)
|
||||||
}
|
}
|
||||||
return remark
|
return remark
|
||||||
}
|
}
|
||||||
@@ -299,20 +315,22 @@ func (h *JimengHandler) Retry(c *gin.Context) {
|
|||||||
resp.SUCCESS(c, gin.H{"message": "重试任务已提交"})
|
resp.SUCCESS(c, gin.H{"message": "重试任务已提交"})
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPowerFromConfig 从配置中获取指定类型的算力消耗
|
|
||||||
func (h *JimengHandler) getTaskPower(req types.JimengTaskRequest) (int, error) {
|
func (h *JimengHandler) getTaskPower(req types.JimengTaskRequest) (int, error) {
|
||||||
logger.Debugf("getTaskPower req: %+v", req)
|
logger.Debugf("getTaskPower req: %+v", req)
|
||||||
config := h.App.SysConfig.Jimeng
|
config := h.App.SysConfig.Jimeng
|
||||||
|
basePower, ok := config.Powers[req.ReqKey]
|
||||||
|
if !ok || basePower <= 0 {
|
||||||
|
return 0, errors.New("未配置模型积分或配置不合法")
|
||||||
|
}
|
||||||
switch req.TaskType {
|
switch req.TaskType {
|
||||||
case types.JMTaskTypeImage:
|
case types.JMTaskTypeImage:
|
||||||
return config.Power.Image, nil
|
return basePower, nil
|
||||||
case types.JMTaskTypeVideo:
|
case types.JMTaskTypeVideo:
|
||||||
if req.Duration == 0 {
|
if req.Duration == 0 {
|
||||||
return 0, errors.New("视频时长不能为0")
|
return 0, errors.New("视频时长不能为0")
|
||||||
}
|
}
|
||||||
return config.Power.Video * req.Duration, nil
|
return basePower * req.Duration, nil
|
||||||
case types.JMTaskTypeVirtualHuman:
|
case types.JMTaskTypeVirtualHuman:
|
||||||
// TODO 计算音频时长
|
|
||||||
if req.AudioURL == "" {
|
if req.AudioURL == "" {
|
||||||
return 0, errors.New("音频URL不能为空")
|
return 0, errors.New("音频URL不能为空")
|
||||||
}
|
}
|
||||||
@@ -320,9 +338,12 @@ func (h *JimengHandler) getTaskPower(req types.JimengTaskRequest) (int, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return config.Power.VirtualHuman * int(audioDuration.Seconds()), nil
|
seconds := int(audioDuration.Seconds())
|
||||||
|
if seconds <= 0 {
|
||||||
|
return 0, errors.New("音频时长无效")
|
||||||
|
}
|
||||||
|
return basePower * seconds, nil
|
||||||
case types.JMTaskTypeActionTransfer:
|
case types.JMTaskTypeActionTransfer:
|
||||||
// TODO 计算视频时长
|
|
||||||
if req.VideoURL == "" {
|
if req.VideoURL == "" {
|
||||||
return 0, errors.New("视频URL不能为空")
|
return 0, errors.New("视频URL不能为空")
|
||||||
}
|
}
|
||||||
@@ -330,7 +351,11 @@ func (h *JimengHandler) getTaskPower(req types.JimengTaskRequest) (int, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return config.Power.ActionTransfer * int(videoDuration.Seconds()), nil
|
seconds := int(videoDuration.Seconds())
|
||||||
|
if seconds <= 0 {
|
||||||
|
return 0, errors.New("视频时长无效")
|
||||||
|
}
|
||||||
|
return basePower * seconds, nil
|
||||||
default:
|
default:
|
||||||
return 0, errors.New("任务类型不支持")
|
return 0, errors.New("任务类型不支持")
|
||||||
}
|
}
|
||||||
@@ -340,9 +365,6 @@ func (h *JimengHandler) getTaskPower(req types.JimengTaskRequest) (int, error) {
|
|||||||
func (h *JimengHandler) GetPowerConfig(c *gin.Context) {
|
func (h *JimengHandler) GetPowerConfig(c *gin.Context) {
|
||||||
config := h.App.SysConfig.Jimeng
|
config := h.App.SysConfig.Jimeng
|
||||||
resp.SUCCESS(c, gin.H{
|
resp.SUCCESS(c, gin.H{
|
||||||
"image": config.Power.Image,
|
"powers": config.Powers,
|
||||||
"video": config.Power.Video,
|
|
||||||
"virtual_human": config.Power.VirtualHuman,
|
|
||||||
"action_transfer": config.Power.ActionTransfer,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -341,6 +341,7 @@
|
|||||||
// 提示词指南样式
|
// 提示词指南样式
|
||||||
.prompt-guide {
|
.prompt-guide {
|
||||||
margin: 12px 0 16px;
|
margin: 12px 0 16px;
|
||||||
|
background-color: var(--el-fill-color-blank);
|
||||||
|
|
||||||
.guide-title {
|
.guide-title {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export const useJimengStore = defineStore('jimeng', () => {
|
|||||||
const shareStore = useSharedStore()
|
const shareStore = useSharedStore()
|
||||||
|
|
||||||
// 积分消耗配置
|
// 积分消耗配置
|
||||||
const powerConfig = reactive({})
|
const powerConfig = reactive({ powers: {} })
|
||||||
const currentPowerCost = ref('0积分')
|
const currentPowerCost = ref('0积分')
|
||||||
|
|
||||||
// 功能配置
|
// 功能配置
|
||||||
@@ -83,12 +83,10 @@ export const useJimengStore = defineStore('jimeng', () => {
|
|||||||
// 获取状态类型
|
// 获取状态类型
|
||||||
const getTaskType = (type) => {
|
const getTaskType = (type) => {
|
||||||
const typeMap = {
|
const typeMap = {
|
||||||
text_to_image: 'primary',
|
image: 'info',
|
||||||
image_to_image: 'primary',
|
video: 'primary',
|
||||||
image_edit: 'primary',
|
virtual_human: 'success',
|
||||||
image_effects: 'primary',
|
action_transfer: 'warning',
|
||||||
text_to_video: 'success',
|
|
||||||
image_to_video: 'success',
|
|
||||||
}
|
}
|
||||||
return typeMap[type] || 'primary'
|
return typeMap[type] || 'primary'
|
||||||
}
|
}
|
||||||
@@ -124,7 +122,7 @@ export const useJimengStore = defineStore('jimeng', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
total.value = data.total || 0
|
total.value = data.total || 0
|
||||||
if (data.items.length < pageSize.value) {
|
if (!data.items || data.items.length < pageSize.value) {
|
||||||
isOver.value = true
|
isOver.value = true
|
||||||
}
|
}
|
||||||
if (pageNum === 1) {
|
if (pageNum === 1) {
|
||||||
@@ -150,7 +148,7 @@ export const useJimengStore = defineStore('jimeng', () => {
|
|||||||
page_size: 20,
|
page_size: 20,
|
||||||
})
|
})
|
||||||
const data = response.data
|
const data = response.data
|
||||||
if (data.items.length === 0) {
|
if (!data.items || data.items.length === 0) {
|
||||||
stopPolling()
|
stopPolling()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -184,7 +182,6 @@ export const useJimengStore = defineStore('jimeng', () => {
|
|||||||
shareStore.setShowLoginDialog(true)
|
shareStore.setShowLoginDialog(true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log(formData.value)
|
|
||||||
for (const key in requiredKeys.value) {
|
for (const key in requiredKeys.value) {
|
||||||
if (!formData.value[key]) {
|
if (!formData.value[key]) {
|
||||||
showMessageError('缺少参数:' + requiredKeys.value[key].label)
|
showMessageError('缺少参数:' + requiredKeys.value[key].label)
|
||||||
@@ -284,20 +281,32 @@ export const useJimengStore = defineStore('jimeng', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const setFunctionPowers = () => {
|
const setFunctionPowers = () => {
|
||||||
if (activeFunction.value === 'image') {
|
nextTick(() => {
|
||||||
currentPowerCost.value = `${powerConfig.image}积分/张`
|
const key = formData.value.req_key
|
||||||
} else {
|
const perUnit = key ? powerConfig.powers[key] : 0
|
||||||
currentPowerCost.value = `${powerConfig.video}积分/秒`
|
if (!perUnit) {
|
||||||
|
currentPowerCost.value = '未配置积分'
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
currentPowerCost.value =
|
||||||
|
activeFunction.value === 'image' ? `${perUnit}积分/张` : `${perUnit}积分/秒`
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => formData.value,
|
||||||
|
() => {
|
||||||
|
setFunctionPowers()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// 初始化方法
|
// 初始化方法
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
try {
|
try {
|
||||||
// 获取积分消耗配置
|
// 获取积分消耗配置
|
||||||
const powerRes = await httpGet('/api/jimeng/power-config')
|
const powerRes = await httpGet('/api/jimeng/power-config')
|
||||||
if (powerRes.data) {
|
if (powerRes.data) {
|
||||||
Object.assign(powerConfig, powerRes.data)
|
powerConfig.powers = powerRes.data.powers || {}
|
||||||
setFunctionPowers()
|
setFunctionPowers()
|
||||||
}
|
}
|
||||||
const user = await checkSession()
|
const user = await checkSession()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 提示词编写指南(可折叠) -->
|
<!-- 提示词编写指南(可折叠) -->
|
||||||
<div class="prompt-guide">
|
<div class="prompt-guide pl-2">
|
||||||
<el-collapse v-model="guideActive">
|
<el-collapse v-model="guideActive">
|
||||||
<el-collapse-item name="guide">
|
<el-collapse-item name="guide">
|
||||||
<template #title>
|
<template #title>
|
||||||
|
|||||||
@@ -82,59 +82,44 @@
|
|||||||
<el-divider />
|
<el-divider />
|
||||||
<!-- 算力配置分组 -->
|
<!-- 算力配置分组 -->
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<h3 class="heading-3 mb-3">算力配置</h3>
|
<h3 class="heading-3 mb-3">任务积分配置</h3>
|
||||||
<el-form-item>
|
<Alert type="info" class="mb-3">
|
||||||
<template #label>
|
<div class="text-gray-500">
|
||||||
<div class="text-gray-500 text-sm">
|
图片类模型统一都是 0.2 元一张,假如你100积分售价1元,建议设置:20积分/张。
|
||||||
生成图片消耗的积分,包括:文生图、图生图、图片编辑、图片特效,<el-tag type="primary"
|
</div>
|
||||||
>单位:积分/张</el-tag
|
<div class="text-gray-500">
|
||||||
|
视频/数字人/动作迁移单位:积分/秒,但是不同的模型的价格不一样,建议去火山方舟控制台查看,根据价格设置积分。
|
||||||
|
</div>
|
||||||
|
</Alert>
|
||||||
|
|
||||||
|
<div v-for="func in functions" :key="func.key" class="mb-4">
|
||||||
|
<h4 class="mb-2 text-base font-bold flex items-center gap-2">
|
||||||
|
<i class="iconfont" :class="func.icon"></i>
|
||||||
|
{{ func.name }}
|
||||||
|
<el-tag size="small" type="info">{{ getUnit(func.key) }}</el-tag>
|
||||||
|
</h4>
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||||
|
<div
|
||||||
|
v-for="model in params[func.key]"
|
||||||
|
:key="model.key"
|
||||||
|
class="p-3 rounded-md border border-gray-100"
|
||||||
>
|
>
|
||||||
|
<div class="text-sm mb-2">
|
||||||
|
<div class="font-bold">{{ model.name }}</div>
|
||||||
|
<div class="text-gray-500 line-clamp-2" :title="model.label">
|
||||||
|
{{ model.label }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
<el-input-number
|
|
||||||
v-model="jimengConfig.power.image"
|
|
||||||
:min="1"
|
|
||||||
placeholder="请输入图片生成算力消耗"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template #label>
|
|
||||||
<div class="text-gray-500 text-sm">
|
|
||||||
生成视频消耗的积分,包括:文生视频、图生视频,<el-tag type="primary"
|
|
||||||
>单位:积分/秒</el-tag
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="jimengConfig.power.video"
|
v-model="jimengConfig.powers[model.key]"
|
||||||
:min="1"
|
:min="1"
|
||||||
placeholder="请输入视频生成算力消耗"
|
:placeholder="`对应模型:${model.key}(${getUnit(func.key)})`"
|
||||||
|
class="w-full"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
<div class="text-xs text-gray-400 mt-1">对应模型:{{ model.key }}</div>
|
||||||
<el-form-item>
|
</div>
|
||||||
<template #label>
|
|
||||||
<div class="text-gray-500 text-sm">
|
|
||||||
生成数字人视频消耗的积分,<el-tag type="primary">单位:积分/秒</el-tag>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
<el-input-number
|
|
||||||
v-model="jimengConfig.power.virtual_human"
|
|
||||||
:min="1"
|
|
||||||
placeholder="请输入数字人视频生成算力消耗"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template #label>
|
|
||||||
<div class="text-gray-500 text-sm">
|
|
||||||
生成视频动作迁移消耗的积分,<el-tag type="primary">单位:积分/秒</el-tag>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
<el-input-number
|
|
||||||
v-model="jimengConfig.power.action_transfer"
|
|
||||||
:min="1"
|
|
||||||
placeholder="请输入视频动作迁移算力消耗"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
</div>
|
||||||
<div style="padding: 10px">
|
<div style="padding: 10px">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -149,6 +134,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import Alert from '@/components/ui/Alert.vue'
|
import Alert from '@/components/ui/Alert.vue'
|
||||||
|
import { JimengFunctions, JimengParams } from '@/store/data/jimeng_params'
|
||||||
import { httpGet, httpPost } from '@/utils/http'
|
import { httpGet, httpPost } from '@/utils/http'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
@@ -156,20 +142,15 @@ import { onMounted, ref } from 'vue'
|
|||||||
const jimengConfig = ref({
|
const jimengConfig = ref({
|
||||||
access_key: '',
|
access_key: '',
|
||||||
secret_key: '',
|
secret_key: '',
|
||||||
power: {
|
api_key: '',
|
||||||
text_to_image: 10,
|
powers: {},
|
||||||
image_to_image: 15,
|
|
||||||
image_edit: 20,
|
|
||||||
image_effects: 25,
|
|
||||||
text_to_video: 30,
|
|
||||||
image_to_video: 35,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const saving = ref(false)
|
const saving = ref(false)
|
||||||
const testing = ref(false)
|
|
||||||
const configFormRef = ref()
|
const configFormRef = ref()
|
||||||
|
const functions = JimengFunctions
|
||||||
|
const params = JimengParams
|
||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
const rules = {
|
const rules = {
|
||||||
@@ -177,6 +158,8 @@ const rules = {
|
|||||||
secret_key: [{ required: true, message: '请输入SecretKey', trigger: 'blur' }],
|
secret_key: [{ required: true, message: '请输入SecretKey', trigger: 'blur' }],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getUnit = (funcKey) => (funcKey === 'image' ? '积分/张' : '积分/秒')
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadConfig()
|
loadConfig()
|
||||||
})
|
})
|
||||||
@@ -185,7 +168,9 @@ onMounted(() => {
|
|||||||
const loadConfig = async () => {
|
const loadConfig = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await httpGet('/api/admin/config/get?key=jimeng')
|
const res = await httpGet('/api/admin/config/get?key=jimeng')
|
||||||
jimengConfig.value = res.data
|
const cfg = res.data || {}
|
||||||
|
cfg.powers = cfg.powers || {}
|
||||||
|
jimengConfig.value = cfg
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ElMessage.error('加载配置失败: ' + e.message)
|
ElMessage.error('加载配置失败: ' + e.message)
|
||||||
} finally {
|
} finally {
|
||||||
@@ -214,14 +199,8 @@ const resetConfig = () => {
|
|||||||
jimengConfig.value = {
|
jimengConfig.value = {
|
||||||
access_key: '',
|
access_key: '',
|
||||||
secret_key: '',
|
secret_key: '',
|
||||||
power: {
|
api_key: '',
|
||||||
text_to_image: 10,
|
powers: {},
|
||||||
image_to_image: 15,
|
|
||||||
image_edit: 20,
|
|
||||||
image_effects: 25,
|
|
||||||
text_to_video: 30,
|
|
||||||
image_to_video: 35,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
ElMessage.info('配置已重置')
|
ElMessage.info('配置已重置')
|
||||||
}
|
}
|
||||||
@@ -237,7 +216,7 @@ const resetConfig = () => {
|
|||||||
|
|
||||||
.container {
|
.container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 800px;
|
max-width: 1000px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heading-3 {
|
.heading-3 {
|
||||||
|
|||||||
Reference in New Issue
Block a user