feat: add system config item for reward image, add app config item to use custom text2img param json file

This commit is contained in:
RockYang 2023-10-08 17:48:50 +08:00
parent 0270ec26fb
commit fbd599194c
9 changed files with 296 additions and 131 deletions

View File

@ -34,7 +34,7 @@ func NewDefaultConfig() *types.AppConfig {
},
},
MjConfig: types.MidJourneyConfig{Enabled: false},
SdConfig: types.StableDiffusionConfig{Enabled: false},
SdConfig: types.StableDiffusionConfig{Enabled: false, Txt2ImgJsonPath: "res/text2img.json"},
WeChatBot: false,
}
}

View File

@ -42,9 +42,10 @@ type WeChatConfig struct {
}
type StableDiffusionConfig struct {
Enabled bool
ApiURL string
ApiKey string
Enabled bool
ApiURL string
ApiKey string
Txt2ImgJsonPath string
}
type AliYunSmsConfig struct {
@ -112,4 +113,5 @@ type SystemConfig struct {
EnabledRegister bool `json:"enabled_register"`
EnabledMsg bool `json:"enabled_msg"` // 启用短信验证码服务
EnabledDraw bool `json:"enabled_draw"` // 启动 AI 绘画功能
RewardImg string `json:"reward_img"` // 众筹收款二维码地址
}

203
api/res/text2img.json Normal file
View File

@ -0,0 +1,203 @@
{
"fn_index": 405,
"data": [
"task(x690lsugziqd8x9)",
"A chinese girl Walking the streets of ancient China",
"",
[],
20,
"DPM++ 2M Karras",
false,
false,
1,
1,
7,
-1,
-1,
0,
0,
0,
false,
256,
256,
false,
0.7,
2,
"Latent",
0,
0,
0,
[],
"None",
false,
"MultiDiffusion",
false,
10,
1,
1,
64,
false,
true,
1024,
1024,
96,
96,
48,
1,
"None",
2,
false,
false,
false,
false,
false,
0.4,
0.4,
0.2,
0.2,
"",
"",
"Background",
0.2,
-1,
false,
0.4,
0.4,
0.2,
0.2,
"",
"",
"Background",
0.2,
-1,
false,
0.4,
0.4,
0.2,
0.2,
"",
"",
"Background",
0.2,
-1,
false,
0.4,
0.4,
0.2,
0.2,
"",
"",
"Background",
0.2,
-1,
false,
0.4,
0.4,
0.2,
0.2,
"",
"",
"Background",
0.2,
-1,
false,
0.4,
0.4,
0.2,
0.2,
"",
"",
"Background",
0.2,
-1,
false,
0.4,
0.4,
0.2,
0.2,
"",
"",
"Background",
0.2,
-1,
false,
0.4,
0.4,
0.2,
0.2,
"",
"",
"Background",
0.2,
-1,
false,
false,
true,
true,
false,
1536,
96,
false,
false,
"LoRA",
"None",
1,
1,
"LoRA",
"None",
1,
1,
"LoRA",
"None",
1,
1,
"LoRA",
"None",
1,
1,
"LoRA",
"None",
1,
1,
null,
"Refresh models",
null,
null,
null,
null,
false,
false,
"positive",
"comma",
0,
false,
false,
"",
"Seed",
"",
"Nothing",
"",
"Nothing",
"",
true,
false,
false,
false,
0,
null,
false,
null,
false,
null,
false,
null,
false,
50,
[],
"",
"",
""
],
"event_data": null,
"session_hash": "fxz5yw7n1a4"
}

View File

@ -8,11 +8,13 @@ import (
"chatplus/store/vo"
"chatplus/utils"
"context"
"encoding/json"
"fmt"
"github.com/go-redis/redis/v8"
"github.com/imroc/req/v3"
"gorm.io/gorm"
"io"
"os"
"strconv"
"time"
)
@ -85,11 +87,18 @@ func (s *Service) PushTask(task types.SdTask) {
// Txt2Img 文生图 API
func (s *Service) Txt2Img(task types.SdTask) error {
var data []interface{}
err := utils.JsonDecode(Text2ImgParamTemplate, &data)
var taskInfo TaskInfo
bytes, err := os.ReadFile(s.config.Txt2ImgJsonPath)
if err != nil {
return err
return fmt.Errorf("error with load text2img json template file: %s", err.Error())
}
err = json.Unmarshal(bytes, &taskInfo)
if err != nil {
return fmt.Errorf("error with decode json params: %s", err.Error())
}
data := taskInfo.Data
params := task.Params
data[ParamKeys["task_id"]] = params.TaskId
data[ParamKeys["prompt"]] = params.Prompt
@ -107,16 +116,12 @@ func (s *Service) Txt2Img(task types.SdTask) error {
data[ParamKeys["hd_scale_alg"]] = params.HdScaleAlg
data[ParamKeys["hd_sample_num"]] = params.HdSteps
taskInfo.SessionId = task.SessionId
taskInfo.TaskId = params.TaskId
taskInfo.Data = data
taskInfo.JobId = task.Id
go func() {
s.runTask(TaskInfo{
SessionId: task.SessionId,
JobId: task.Id,
TaskId: params.TaskId,
Data: data,
EventData: nil,
FnIndex: 232,
SessionHash: "ycaxgzm9ah",
}, s.httpClient)
s.runTask(taskInfo, s.httpClient)
}()
return nil
}
@ -177,9 +182,7 @@ func (s *Service) runTask(taskInfo TaskInfo, client *req.Client) {
return
}
//for k, v := range info {
// fmt.Println(k, " => ", v)
//}
// 获取真实的 seed 值
cbReq.ImageName = images[0].Name
seed, _ := strconv.ParseInt(utils.InterfaceToString(info["seed"]), 10, 64)
cbReq.Seed = seed
@ -278,7 +281,7 @@ func (s *Service) callback(data CBReq) {
return
}
if data.Progress < 100 {
if data.Progress < 100 && data.ImageData != "" {
jobVo.ImgURL = data.ImageData
}
@ -295,7 +298,7 @@ func (s *Service) callback(data CBReq) {
utils.ReplyChunkMessage(client, vo.SdJob{
Id: uint(data.JobId),
Progress: -1,
Prompt: fmt.Sprintf("任务[%s]执行失败,已删除!", data.TaskId),
TaskId: data.TaskId,
})
}
}

View File

@ -5,13 +5,13 @@ import logger2 "chatplus/logger"
var logger = logger2.GetLogger()
type TaskInfo struct {
SessionId string
JobId int
TaskId string
Data []interface{}
EventData interface{}
FnIndex int
SessionHash string
SessionId string `json:"session_id"`
JobId int `json:"job_id"`
TaskId string `json:"task_id"`
Data []interface{} `json:"data"`
EventData interface{} `json:"event_data"`
FnIndex int `json:"fn_index"`
SessionHash string `json:"session_hash"`
}
type CBReq struct {
@ -43,97 +43,3 @@ var ParamKeys = map[string]int{
"hd_scale_alg": 22, // 高清修复放大算法
"hd_sample_num": 23, // 高清修复采样次数
}
const Text2ImgParamTemplate = `[
"task(6sm0b3j17tag2gd)",
"A beautiful Chinese girl wearing a cheongsam walks on the bluestone street",
"",
[],
50,
"Euler a",
false,
false,
1,
1,
15,
null,
-1,
0,
0,
0,
false,
768,
512,
false,
0.7,
2,
"ESRGAN_4x",
10,
0,
0,
"Use same sampler",
"",
"",
[],
"None",
null,
false,
false,
"positive",
"comma",
0,
false,
false,
"",
"Seed",
"",
[],
"Nothing",
"",
[],
"Nothing",
"",
[],
true,
false,
false,
false,
0,
"Not set",
true,
true,
"",
"",
"",
"",
"",
1.3,
"Not set",
"Not set",
1.3,
"Not set",
1.3,
"Not set",
1.3,
1.3,
"Not set",
1.3,
"Not set",
1.3,
"Not set",
1.3,
"Not set",
1.3,
"Not set",
1.3,
"Not set",
false,
"None",
null,
false,
50,
[],
"",
"",
""
]`

View File

@ -2,16 +2,13 @@ package main
import (
"fmt"
"net/url"
"path"
"os"
)
func main() {
imgURL := "https://www.baidu.com/static/upload/2023/10/1696497571220711277.png?ex=6530f4a2&is=651e7fa28hmFd709d069ca05d7855ebdae42e5aa436883a36f9310d546"
parse, err := url.Parse(imgURL)
bytes, err := os.ReadFile("res/text2img.json")
if err != nil {
panic(err)
}
fmt.Println(path.Ext(parse.Path))
fmt.Println(string(bytes))
}

View File

@ -358,6 +358,7 @@ onMounted(() => {
httpGet("/api/admin/config/get?key=system").then(res => {
title.value = res.data.title
rewardImg.value = res.data.reward_img
}).catch(e => {
ElMessage.error("获取系统配置失败:" + e.message)
})

View File

@ -241,7 +241,7 @@
</div>
<div class="param-line pt">
<span>图片比例</span>
<span>反向提示词</span>
<el-tooltip
effect="light"
content="不希望出现的元素,下面给了默认的起手式"
@ -486,12 +486,13 @@
import {onMounted, ref} from "vue"
import {DocumentCopy, InfoFilled, Picture} from "@element-plus/icons-vue";
import {httpGet, httpPost} from "@/utils/http";
import {ElMessage} from "element-plus";
import {ElMessage, ElNotification} from "element-plus";
import ItemList from "@/components/ItemList.vue";
import Clipboard from "clipboard";
import {checkSession} from "@/action/session";
import {useRouter} from "vue-router";
import {getSessionId, getUserToken} from "@/store/session";
import {removeArrayItem} from "@/utils/libs";
const listBoxHeight = ref(window.innerHeight - 40)
const mjBoxHeight = ref(window.innerHeight - 150)
@ -569,6 +570,14 @@ const connect = () => {
finishedJobs.value.unshift(data)
}
previewImgList.value.unshift(data["img_url"])
} else if (data.progress === -1) { //
ElNotification({
title: '任务执行失败',
message: "任务ID" + data['task_id'],
type: 'error',
})
runningJobs.value = removeArrayItem(runningJobs.value, data, (v1, v2) => v1.id === v2.id)
} else { //
for (let i = 0; i < runningJobs.value.length; i++) {
if (runningJobs.value[i].id === data.id) {

View File

@ -24,6 +24,21 @@
<el-form-item label="开放AI绘画" prop="enabled_draw">
<el-switch v-model="system['enabled_draw']"/>
</el-form-item>
<el-form-item label="收款二维码" prop="reward_img">
<el-input v-model="system['reward_img']" placeholder="众筹收款二维码地址">
<template #append>
<el-upload
:auto-upload="true"
:show-file-list="false"
:http-request="uploadRewardImg"
>
<el-icon class="uploader-icon">
<UploadFilled/>
</el-icon>
</el-upload>
</template>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="save('system')">保存</el-button>
</el-form-item>
@ -93,7 +108,9 @@
<script setup>
import {onMounted, reactive, ref} from "vue";
import {httpGet, httpPost} from "@/utils/http";
import Compressor from "compressorjs";
import {ElMessage} from "element-plus";
import {UploadFilled} from "@element-plus/icons-vue";
const system = ref({models: []})
const chat = ref({
@ -169,9 +186,30 @@ const save = function (key) {
}
})
}
}
//
const uploadRewardImg = (file) => {
//
new Compressor(file.file, {
quality: 0.6,
success(result) {
const formData = new FormData();
formData.append('file', result, result.name);
//
httpPost('/api/upload', formData).then((res) => {
system.value['reward_img'] = res.data
ElMessage.success('上传成功')
}).catch((e) => {
ElMessage.error('上传失败:' + e.message)
})
},
error(err) {
console.log(err.message);
},
});
};
</script>
<style lang="stylus" scoped>
@ -195,6 +233,12 @@ const save = function (key) {
font-size 12px;
line-height 1.5;
}
.uploader-icon {
font-size 24px
position relative
top 3px
}
}
}