feat: mj for mobile page payout is ready

This commit is contained in:
RockYang 2024-01-30 18:34:01 +08:00
parent 7a833e2233
commit a558b7e104
5 changed files with 230 additions and 84 deletions

View File

@ -2,3 +2,49 @@
width: 100px;
text-align: right;
}
.mobile-mj .content .text-line {
padding: 6px;
font-size: 14px;
}
.mobile-mj .content .text-line .van-row .van-col .rate {
display: flex;
justify-content: center;
background-color: #f5f5f5;
padding: 5px 10px;
margin: 5px 0;
border-radius: 5px;
flex-flow: column;
}
.mobile-mj .content .text-line .van-row .van-col .rate .icon {
text-align: center;
}
.mobile-mj .content .text-line .van-row .van-col .rate .icon .van-image {
max-width: 20px;
}
.mobile-mj .content .text-line .van-row .van-col .rate .text {
text-align: center;
color: #555;
}
.mobile-mj .content .text-line .van-row .van-col .model {
display: flex;
justify-content: center;
background-color: #f5f5f5;
padding: 6px;
margin: 5px 0;
border-radius: 5px;
flex-flow: column;
}
.mobile-mj .content .text-line .van-row .van-col .model .icon {
text-align: center;
}
.mobile-mj .content .text-line .van-row .van-col .model .icon .van-image {
width: 100%;
height: 50px;
}
.mobile-mj .content .text-line .van-row .van-col .model .text {
text-align: center;
color: #555;
}
.mobile-mj .content .text-line .van-row .van-col .active {
background-color: #e5e5e5;
}

View File

@ -4,5 +4,65 @@
width 100px
text-align right
}
.text-line {
padding 6px
font-size 14px
.van-row {
.van-col {
.rate {
display: flex;
justify-content center
background-color #f5f5f5
padding 5px 10px
margin 5px 0
border-radius 5px
flex-flow column
.icon {
text-align center
.van-image {
max-width 20px
}
}
.text {
text-align center
color #555555
}
}
.model {
display: flex;
justify-content center
background-color #f5f5f5
padding 6px
margin 5px 0
border-radius 5px
flex-flow column
.icon {
text-align center
.van-image {
width 100%
height 50px
}
}
.text {
text-align center
color #555555
}
}
.active {
background-color #e5e5e5
}
}
}
}
}
}

View File

@ -8,6 +8,7 @@ import {
Button,
Cell,
CellGroup,
Col,
ConfigProvider,
Dialog,
DropdownItem,
@ -22,8 +23,10 @@ import {
Overlay,
Picker,
Popup,
Row,
Search,
ShareSheet,
Slider,
Sticky,
SwipeCell,
Switch,
@ -67,6 +70,9 @@ app.use(Uploader);
app.use(Tag);
app.use(V3waterfall)
app.use(Overlay)
app.use(Col)
app.use(Row)
app.use(Slider)
app.use(router).use(ElementPlus).mount('#app')

View File

@ -446,6 +446,8 @@ recognition.onresult = function (event) {
};
recognition.onerror = function (event) {
showMic.value = false
recognition.stop()
showNotify({type: 'danger', message: '语音识别错误:' + event.error})
};

View File

@ -3,46 +3,84 @@
<van-nav-bar :title="title"/>
<div class="content">
<van-form @submit="save">
<van-cell-group inset v-model="form">
<van-form @submit="generate">
<div class="text-line">图片比例</div>
<div class="text-line">
<van-row :gutter="10">
<van-col :span="4" v-for="item in rates" :key="item.value">
<div
:class="item.value === params.rate ? 'rate active' : 'rate'"
@click="changeRate(item)">
<div class="icon">
<van-image :src="item.img" fit="cover"></van-image>
</div>
<div class="text">{{ item.text }}</div>
</div>
</van-col>
</van-row>
</div>
<div class="text-line">模型选择</div>
<div class="text-line">
<van-row :gutter="10">
<van-col :span="8" v-for="item in models" :key="item.value">
<div :class="item.value === params.model ? 'model active' : 'model'"
@click="changeModel(item)">
<div class="icon">
<van-image :src="item.img" fit="cover"></van-image>
</div>
<div class="text">{{ item.text }}</div>
</div>
</van-col>
</van-row>
</div>
<div class="text-line">
<van-field label="创意度">
<template #input>
<van-slider v-model.number="params.chaos" :max="100" :step="1"
@update:model-value="showToast('当前值:' + params.chaos)"/>
</template>
</van-field>
</div>
<div class="text-line">
<van-field label="风格化">
<template #input>
<van-slider v-model.number="params.stylize" :max="1000" :step="1"
@update:model-value="showToast('当前值:' + params.stylize)"/>
</template>
</van-field>
</div>
<div class="text-line">
<van-field label="原始模式">
<template #input>
<van-switch v-model="params.raw"/>
</template>
</van-field>
</div>
<div class="text-line">
<van-field label="垫图">
<template #input>
<van-uploader v-model="imgList" :after-read="afterRead"/>
</template>
</van-field>
</div>
<div class="text-line">
<van-field
v-model="form.mobile"
name="手机号"
label="手机号"
readonly
disabled
placeholder="手机号"
v-model="params.prompt"
rows="3"
autosize
label="提示词"
type="textarea"
placeholder="如:一个美丽的中国女孩站在电影院门口,手上拿着爆米花,微笑,写实风格,电影灯光效果,半身像"
/>
<van-field label="头像">
<template #input>
<van-uploader v-model="fileList"
reupload max-count="1"
:deletable="false"
:after-read="afterRead"/>
</template>
</van-field>
</div>
<van-field label="剩余对话次数">
<template #input>
<van-tag type="primary">{{ form.calls }}</van-tag>
</template>
</van-field>
<van-field label="剩余绘图次数">
<template #input>
<van-tag type="primary">{{ form.img_calls }}</van-tag>
</template>
</van-field>
<van-field label="累计消耗tokens">
<template #input>
<van-tag type="primary">{{ form.total_tokens }}</van-tag>
</template>
</van-field>
</van-cell-group>
<div style="margin: 16px;">
<div class="text-line">
<van-button round block type="primary" native-type="submit">
提交
立即生成
</van-button>
</div>
</van-form>
@ -52,62 +90,56 @@
<script setup>
import {onMounted, ref} from "vue";
import {showFailToast, showNotify, showSuccessToast} from "vant";
import {showFailToast, showNotify, showSuccessToast, showToast} from "vant";
import {httpGet, httpPost} from "@/utils/http";
import Compressor from 'compressorjs';
const title = ref('MidJourney 绘画')
const form = ref({
username: '',
nickname: '',
mobile: '',
avatar: '',
calls: 0,
tokens: 0
})
const fileList = ref([
{
url: 'https://fastly.jsdelivr.net/npm/@vant/assets/leaf.jpeg',
message: '上传中...',
}
]);
onMounted(() => {
httpGet('/api/user/profile').then(res => {
form.value = res.data
fileList.value[0].url = form.value.avatar
}).catch((e) => {
console.log(e.message)
showFailToast('获取用户信息失败')
});
const rates = [
{css: "square", value: "1:1", text: "1:1", img: "/images/mj/rate_1_1.png"},
{css: "size2-3", value: "2:3", text: "2:3", img: "/images/mj/rate_3_4.png"},
{css: "size3-4", value: "3:4", text: "3:4", img: "/images/mj/rate_3_4.png"},
{css: "size4-3", value: "4:3", text: "4:3", img: "/images/mj/rate_4_3.png"},
{css: "size16-9", value: "16:9", text: "16:9", img: "/images/mj/rate_16_9.png"},
{css: "size9-16", value: "9:16", text: "9:16", img: "/images/mj/rate_9_16.png"},
]
const models = [
{text: "写实模式MJ-6.0", value: " --v 6", img: "/images/mj/mj-v6.png"},
{text: "优质模式MJ-5.2", value: " --v 5.2", img: "/images/mj/mj-v5.2.png"},
{text: "动漫风niji5 原始", value: " --niji 5", img: "/images/mj/mj-niji.png"},
{text: "动漫风niji5 可爱", value: " --niji 5 --style cute", img: "/images/mj/nj1.jpg"},
{text: "动漫风niji5 风景", value: " --niji 5 --style scenic", img: "/images/mj/nj2.jpg"},
{text: "动漫风niji5 表现力", value: " --niji 5 --style expressive", img: "/images/mj/nj3.jpg"},
]
const imgList = ref([])
const params = ref({
task_type: "image",
rate: rates[0].value,
model: models[0].value,
chaos: 0,
stylize: 100,
seed: 0,
img_arr: [],
raw: false,
weight: 0.25,
prompt: "",
neg_prompt: "",
tile: false,
quality: 0
})
const afterRead = (file) => {
file.status = 'uploading';
file.message = '上传中...';
//
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) => {
form.value.avatar = res.data
file.status = 'success'
showNotify({type: 'success', message: '上传成功'})
}).catch((e) => {
console.log(e.message)
showNotify({type: 'danger', message: '上传失败'})
})
},
error(err) {
console.log(err.message);
},
});
};
//
const changeRate = (item) => {
params.value.rate = item.value
}
//
const changeModel = (item) => {
params.value.model = item.value
}
const save = () => {
const generate = () => {
httpPost('/api/user/profile/update', form.value).then(() => {
showSuccessToast('保存成功')
}).catch(() => {