ai_images/portal-ui/src/views/FastImage.vue

376 lines
6.9 KiB
Vue

<template>
<div :class="prefixCls">
<div class="left">
<div
class="tags"
v-for="tag in tags">
<div class="tags-title">{{ tag.title }}</div>
<a-radio-group
:model-value="selectedTags[tag.id]"
@change="handleGroupChange(tag.id, $event)">
<a-radio
v-for="item in tag.children"
:value="item.value">
{{ item.title }}
</a-radio>
</a-radio-group>
</div>
<!-- <div class="text">
<a-textarea
v-model="text"
:placeholder="$t('common.textPlaceholder')" />
</div> -->
<mf-button
class="submit"
type="primary"
:loading="generateLoading"
size="large"
@click="generateImage">
{{
price
? $t('common.generateImage', { score: price })
: $t('common.generateImageNow')
}}
</mf-button>
<div class="submit-tip">
{{ $t('common.generateTip') }}
</div>
</div>
<div
class="right lab-canvas-bg"
v-if="showResult">
<div class="right-close">
<mf-icon
value="icon-close"
@click="close" />
</div>
<a-image
class="result-image"
fit="contain"
:src="imageUrl" />
<div
class="action"
v-show="imageUrl">
<mf-button @click="saveImage">
<a-image
:width="20"
:height="20"
:preview="false"
src="/images/btn_bctp@2x.png" />
{{ $t('common.saveImage') }}
</mf-button>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
data() {
return {
prefixCls: 'fast-image',
text: '',
current: 1,
tags: [],
selectedTags: {},
generateLoading: false,
imageUrl: null,
price: null,
showResult: !this.$base.isMobile(),
id: null
}
},
mounted() {
let { text } = this.$route.query || {}
if (text) {
this.text = text
}
this.$axios({
url: 'api/manager/selectInfo',
method: 'GET',
data: {
aiType: '1'
}
}).then((res) => {
this.price = res.data?.price
this.id = res.data?.id;
this.getTags()
})
},
computed: {
...mapGetters(['lang'])
},
watch: {
lang() {
this.getTags()
}
},
methods: {
handleGroupChange(id, value) {
this.selectedTags[id] = value
},
close() {
this.showResult = false
},
getTags() {
this.$axios({
url: 'api/tag/list',
method: 'GET',
data: {
aiId: this.id
}
}).then((res) => {
this.tags = this.$datas.recurrence(res.data)
if (!this.$datas.isEmpty(this.tags)) {
this.tags.map((item) => {
let children = item.children || []
let firstChild = children[0]
if (firstChild) {
this.selectedTags[item.id] = firstChild.id
}
})
}
})
},
saveImage() {
this.$file.downloadFile(this.imageUrl)
},
generateImage() {
// if (!this.text) {
// this.$message.error(this.$t('common.textError'))
// return
// }
let tags = []
Object.keys(this.selectedTags).map((key) => {
let tagValue = this.selectedTags[key]
let item = this.$datas.deepFind(
this.tags,
(d) => d.id == tagValue
)
let prompt = item.prompt
if (prompt) {
let arr = prompt.split(',')
const randomIndex = Math.floor(Math.random() * arr.length)
prompt = arr[randomIndex]
// tags.push(prompt)
} else {
// tags.push(item.title)
}
tags.push(item.id)
})
this.generateLoading = true
this.$axios({
url: 'api/ai/promptToImg',
method: 'POST',
data: {
text: this.text,
functionType: '1',
tags: tags.join(',')
}
})
.then((res) => {
this.generateLoading = false
if (res.code == 200) {
this.showResult = true
this.imageUrl = res.msg
} else if (res.code == -1) {
this.$confirm({
title: this.$t('common.notice'),
content: this.$t('common.balenceLow'),
okText: this.$t('common.confirm'),
cancelText: this.$t('common.cancel'),
onOk: (_) => {
this.$router.push('/recharge')
}
})
} else if (res.code == -2) {
this.$modal.error({
title: this.$t('common.notice'),
content: this.$t('common.createFailed'),
okText: this.$t('common.confirm')
})
} else if (res.code == -3) {
this.$modal.error({
title: this.$t('common.notice'),
content: this.$t('common.createTagFailed'),
okText: this.$t('common.confirm')
})
}
})
.catch((_) => {
this.generateLoading = false
})
}
}
}
</script>
<style lang="less" scoped>
.fast-image {
display: flex;
height: 100%;
.left {
width: 400px;
padding: 20px 40px;
height: 100%;
overflow-y: auto;
flex-shrink: 0;
.submit {
width: 100%;
margin-top: 20px;
border-radius: 10px;
&-tip {
font-size: 12px;
color: #5c5d68;
margin-top: 20px;
text-align: center;
}
}
.arco-textarea-wrapper {
background: #1a1b20;
color: #fff;
height: 100px;
margin-top: 20px;
}
.tags {
padding-top: 20px;
border-top: 1px solid rgba(255, 255, 255, 0.1);
&:first-child {
border: none;
padding-top: 0;
}
&-title {
color: #fff;
margin-bottom: 24px;
}
:deep(.arco-radio-group) {
.arco-radio {
margin-bottom: 12px;
&-label {
font-size: 14px;
color: #5c5d68;
}
&:hover {
.arco-radio-icon-hover::before {
background-color: transparent;
}
}
.arco-icon-hover:hover::before {
background-color: transparent;
}
}
}
}
}
.right {
flex: 1;
height: 100%;
overflow: auto;
padding: 0 100px 20px 100px;
:deep(.arco-image-error) {
background-color: transparent;
}
:deep(.result-image) {
width: 100%;
min-width: 600px;
height: calc(100% - 60px);
.arco-image-img {
width: 100%;
height: 100%;
}
}
.action {
display: flex;
align-items: center;
justify-content: center;
margin-top: 20px;
.mf-button {
display: flex;
align-items: center;
justify-content: center;
width: 200px;
height: 40px;
background: #1a1b20;
border-radius: 10px;
color: #fff;
margin: 0 15px;
:deep(.arco-image) {
margin-right: 8px;
&-img {
vertical-align: unset;
}
}
}
}
}
}
@media (max-width: 576px) {
.fast-image {
.left {
width: 100%;
}
.right {
display: flex;
flex-direction: column;
align-items: center;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
padding: 100px 40px;
background: linear-gradient(
0deg,
rgba(#050b15, 1) 0%,
rgba(#0f1011, 1) 49%,
rgba(#111215, 1) 100%
);
&-close {
right: 20px;
top: 80px;
position: fixed;
display: block;
cursor: pointer;
color: #fff;
.mf-icon {
font-size: 16px;
}
}
.result-image {
width: 100%;
min-width: auto;
}
.action {
.mf-button {
width: calc(50% - 8px);
margin: 0 10px;
background-color: rgb(var(--primary-6));
}
}
}
}
}
</style>