feat: add mj_action_power system config item

This commit is contained in:
RockYang 2024-03-28 09:53:41 +08:00
parent 4fb2c5803c
commit 1f964c74e9
7 changed files with 98 additions and 23 deletions

View File

@ -147,9 +147,10 @@ type SystemConfig struct {
VipInfoText string `json:"vip_info_text"` // 会员页面充值说明 VipInfoText string `json:"vip_info_text"` // 会员页面充值说明
DefaultModels []int `json:"default_models,omitempty"` // 默认开通的 AI 模型 DefaultModels []int `json:"default_models,omitempty"` // 默认开通的 AI 模型
MjPower int `json:"mj_power,omitempty"` // MJ 绘画消耗算力 MjPower int `json:"mj_power,omitempty"` // MJ 绘画消耗算力
SdPower int `json:"sd_power,omitempty"` // SD 绘画消耗算力 MjActionPower int `json:"mj_action_power"` // MJ 操作(放大,变换)消耗算力
DallPower int `json:"dall_power,omitempty"` // DALLE3 绘图消耗算力 SdPower int `json:"sd_power,omitempty"` // SD 绘画消耗算力
DallPower int `json:"dall_power,omitempty"` // DALLE3 绘图消耗算力
WechatCardURL string `json:"wechat_card_url,omitempty"` // 微信客服地址 WechatCardURL string `json:"wechat_card_url,omitempty"` // 微信客服地址

View File

@ -245,6 +245,7 @@ func (h *MidJourneyHandler) Upscale(c *gin.Context) {
TaskId: taskId, TaskId: taskId,
Progress: 0, Progress: 0,
Prompt: data.Prompt, Prompt: data.Prompt,
Power: h.App.SysConfig.MjActionPower,
CreatedAt: time.Now(), CreatedAt: time.Now(),
} }
if res := h.DB.Create(&job); res.Error != nil || res.RowsAffected == 0 { if res := h.DB.Create(&job); res.Error != nil || res.RowsAffected == 0 {
@ -268,7 +269,23 @@ func (h *MidJourneyHandler) Upscale(c *gin.Context) {
if client != nil { if client != nil {
_ = client.Send([]byte("Task Updated")) _ = client.Send([]byte("Task Updated"))
} }
// update user's power
tx := h.DB.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power - ?", job.Power))
// 记录算力变化日志
if tx.Error == nil && tx.RowsAffected > 0 {
user, _ := h.GetLoginUser(c)
h.DB.Create(&model.PowerLog{
UserId: user.Id,
Username: user.Username,
Type: types.PowerConsume,
Amount: job.Power,
Balance: user.Power - job.Power,
Mark: types.PowerSub,
Model: "mid-journey",
Remark: fmt.Sprintf("Upscale 操作任务ID%s", job.TaskId),
CreatedAt: time.Now(),
})
}
resp.SUCCESS(c) resp.SUCCESS(c)
} }
@ -295,7 +312,7 @@ func (h *MidJourneyHandler) Variation(c *gin.Context) {
TaskId: taskId, TaskId: taskId,
Progress: 0, Progress: 0,
Prompt: data.Prompt, Prompt: data.Prompt,
Power: h.App.SysConfig.MjPower, Power: h.App.SysConfig.MjActionPower,
CreatedAt: time.Now(), CreatedAt: time.Now(),
} }
if res := h.DB.Create(&job); res.Error != nil || res.RowsAffected == 0 { if res := h.DB.Create(&job); res.Error != nil || res.RowsAffected == 0 {

View File

@ -162,11 +162,9 @@ func (p *ServicePool) SyncTaskProgress() {
for _, job := range items { for _, job := range items {
// 失败或者 30 分钟还没完成的任务删除并退回算力 // 失败或者 30 分钟还没完成的任务删除并退回算力
if time.Now().Sub(job.CreatedAt) > time.Minute*30 || job.Progress == -1 { if time.Now().Sub(job.CreatedAt) > time.Minute*30 || job.Progress == -1 {
// 删除任务
p.db.Delete(&job) p.db.Delete(&job)
// 略过 Upscale 任务 // 退回算力
if job.Type != types.TaskUpscale.String() {
continue
}
tx := p.db.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power + ?", job.Power)) tx := p.db.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power + ?", job.Power))
if tx.Error == nil && tx.RowsAffected > 0 { if tx.Error == nil && tx.RowsAffected > 0 {
var user model.User var user model.User

View File

@ -67,7 +67,7 @@ func (s *Service) Run() {
continue continue
} }
// 翻译提示词 // 如果是 mj-proxy 则自动翻译提示词
if utils.HasChinese(task.Prompt) && strings.HasPrefix(s.Name, "mj-proxy-service") { if utils.HasChinese(task.Prompt) && strings.HasPrefix(s.Name, "mj-proxy-service") {
content, err := utils.OpenAIRequest(s.db, fmt.Sprintf(service.TranslatePromptTemplate, task.Prompt)) content, err := utils.OpenAIRequest(s.db, fmt.Sprintf(service.TranslatePromptTemplate, task.Prompt))
if err == nil { if err == nil {

View File

@ -506,7 +506,7 @@ const options = [
] ]
const router = useRouter() const router = useRouter()
const params = ref({ const initParams = {
task_type: "image", task_type: "image",
rate: rates[0].value, rate: rates[0].value,
model: models[0].value, model: models[0].value,
@ -520,7 +520,8 @@ const params = ref({
neg_prompt: "", neg_prompt: "",
tile: false, tile: false,
quality: 0 quality: 0
}) }
const params = ref(initParams)
const imgList = ref([]) const imgList = ref([])
@ -618,6 +619,15 @@ onUnmounted(() => {
clipboard.value.destroy() clipboard.value.destroy()
}) })
const mjPower = ref(1)
const mjActionPower = ref(1)
httpGet("/api/config/get?key=system").then(res => {
mjPower.value = res.data["mj_power"]
mjActionPower.value = res.data["mj_action_power"]
}).catch(e => {
ElMessage.error("获取系统配置失败:" + e.message)
})
// //
const fetchRunningJobs = () => { const fetchRunningJobs = () => {
httpGet(`/api/mj/jobs?status=0`).then(res => { httpGet(`/api/mj/jobs?status=0`).then(res => {
@ -632,7 +642,11 @@ const fetchRunningJobs = () => {
type: 'error', type: 'error',
duration: 0, duration: 0,
}) })
power.value += 1 if (jobs[i].type === 'image') {
power.value += mjPower.value
} else {
power.value += mjActionPower.value
}
continue continue
} }
_jobs.push(jobs[i]) _jobs.push(jobs[i])
@ -749,7 +763,8 @@ const generate = () => {
params.value.img_arr = imgList.value params.value.img_arr = imgList.value
httpPost("/api/mj/image", params.value).then(() => { httpPost("/api/mj/image", params.value).then(() => {
ElMessage.success("绘画任务推送成功,请耐心等待任务执行...") ElMessage.success("绘画任务推送成功,请耐心等待任务执行...")
power.value -= 1 power.value -= mjPower.value
params.value = initParams
}).catch(e => { }).catch(e => {
ElMessage.error("任务推送失败:" + e.message) ElMessage.error("任务推送失败:" + e.message)
}) })
@ -775,7 +790,7 @@ const send = (url, index, item) => {
prompt: item.prompt, prompt: item.prompt,
}).then(() => { }).then(() => {
ElMessage.success("任务推送成功,请耐心等待任务执行...") ElMessage.success("任务推送成功,请耐心等待任务执行...")
power.value -= 1 power.value -= mjActionPower.value
}).catch(e => { }).catch(e => {
ElMessage.error("任务推送失败:" + e.message) ElMessage.error("任务推送失败:" + e.message)
}) })

View File

@ -44,8 +44,39 @@
</div> </div>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="MidJourney算力" prop="mj_power"> <el-form-item label="MJ绘图算力" prop="mj_power">
<el-input v-model.number="system['mj_power']" placeholder="使用MidJourney画一张图消耗算力"/> <div class="tip-input">
<el-input v-model.number="system['mj_power']" placeholder=""/>
<div class="info">
<el-tooltip
effect="dark"
content="使用MidJourney画一张图消耗算力"
raw-content
placement="right"
>
<el-icon>
<InfoFilled/>
</el-icon>
</el-tooltip>
</div>
</div>
</el-form-item>
<el-form-item label="MJ操作算力" prop="mj_action_power">
<div class="tip-input">
<el-input v-model.number="system['mj_action_power']" placeholder=""/>
<div class="info">
<el-tooltip
effect="dark"
content="放大,变换,重绘操作一次消耗的算力"
raw-content
placement="right"
>
<el-icon>
<InfoFilled/>
</el-icon>
</el-tooltip>
</div>
</div>
</el-form-item> </el-form-item>
<el-form-item label="Stable-Diffusion算力" prop="sd_power"> <el-form-item label="Stable-Diffusion算力" prop="sd_power">
<el-input v-model.number="system['sd_power']" placeholder="使用Stable-Diffusion画一张图消耗算力"/> <el-input v-model.number="system['sd_power']" placeholder="使用Stable-Diffusion画一张图消耗算力"/>

View File

@ -91,7 +91,7 @@
<div class="text-line"> <div class="text-line">
<van-button round block type="primary" native-type="submit"> <van-button round block type="primary" native-type="submit">
<van-tag type="success">可用额度:{{ imgCalls }}</van-tag> <van-tag type="success">可用算力额度:{{ power }}</van-tag>
立即生成 立即生成
</van-button> </van-button>
</div> </div>
@ -253,16 +253,16 @@ const params = ref({
tile: false, tile: false,
quality: 0 quality: 0
}) })
const imgCalls = ref(0)
const userId = ref(0) const userId = ref(0)
const router = useRouter() const router = useRouter()
const runningJobs = ref([]) const runningJobs = ref([])
const finishedJobs = ref([]) const finishedJobs = ref([])
const socket = ref(null) const socket = ref(null)
const power = ref(0)
onMounted(() => { onMounted(() => {
checkSession().then(user => { checkSession().then(user => {
imgCalls.value = user['img_calls'] power.value = user['power']
userId.value = user.id userId.value = user.id
fetchRunningJobs() fetchRunningJobs()
@ -278,6 +278,15 @@ onUnmounted(() => {
socket.value = null socket.value = null
}) })
const mjPower = ref(1)
const mjActionPower = ref(1)
httpGet("/api/config/get?key=system").then(res => {
mjPower.value = res.data["mj_power"]
mjActionPower.value = res.data["mj_action_power"]
}).catch(e => {
ElMessage.error("获取系统配置失败:" + e.message)
})
const heartbeatHandle = ref(null) const heartbeatHandle = ref(null)
const connect = () => { const connect = () => {
let host = process.env.VUE_APP_WS_HOST let host = process.env.VUE_APP_WS_HOST
@ -335,7 +344,11 @@ const fetchRunningJobs = (userId) => {
message: `任务执行失败:${jobs[i]['err_msg']}`, message: `任务执行失败:${jobs[i]['err_msg']}`,
type: 'danger', type: 'danger',
}) })
imgCalls.value += 1 if (jobs[i].type === 'image') {
power.value += mjPower.value
} else {
power.value += mjActionPower.value
}
continue continue
} }
_jobs.push(jobs[i]) _jobs.push(jobs[i])
@ -437,7 +450,7 @@ const send = (url, index, item) => {
prompt: item.prompt, prompt: item.prompt,
}).then(() => { }).then(() => {
ElMessage.success("任务推送成功,请耐心等待任务执行...") ElMessage.success("任务推送成功,请耐心等待任务执行...")
imgCalls.value -= 1 power.value -= mjActionPower.value
}).catch(e => { }).catch(e => {
ElMessage.error("任务推送失败:" + e.message) ElMessage.error("任务推送失败:" + e.message)
}) })
@ -464,7 +477,7 @@ const generate = () => {
params.value.img_arr = imgList.value.map(img => img.url) params.value.img_arr = imgList.value.map(img => img.url)
httpPost("/api/mj/image", params.value).then(() => { httpPost("/api/mj/image", params.value).then(() => {
showToast("绘画任务推送成功,请耐心等待任务执行") showToast("绘画任务推送成功,请耐心等待任务执行")
imgCalls.value -= 1 power.value -= mjPower.value
}).catch(e => { }).catch(e => {
showFailToast("任务推送失败:" + e.message) showFailToast("任务推送失败:" + e.message)
}) })