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

458 lines
8.7 KiB
Vue

<template>
<div
ref="indexRef"
:class="prefixCls">
<div :class="`${prefixCls}-banner`">
<a-carousel>
<a-carousel-item
v-for="item in images"
@click="jumpUrl(item)">
<a-image
:src="item.imageUrl"
:preview="false"
fit="cover"
width="100%"
height="100%" />
</a-carousel-item>
</a-carousel>
</div>
<div :class="`${prefixCls}-wrap`">
<a-row :gutter="10">
<a-col
v-for="item in dataList"
:xl="6"
:xs="12">
<div :class="`${prefixCls}-item`">
<div
:class="`${prefixCls}-item-image`"
@click="checkPermission(item.result)">
<button
v-if="item.type == 21"
:class="`${prefixCls}-item-play`"></button>
<mf-video
:width="292"
:height="320"
:controls="false"
:modelValue="item.result"
v-if="item.type == 21" />
<a-image
v-else
fit="cover"
:preview="false"
:height="320"
:src="item.result" />
<!-- <div :class="`${prefixCls}-item-shadow`">
</div> -->
<mf-button
type="primary"
@click.stop="doSame(item)">
{{ $t('common.doSame') }}
</mf-button>
</div>
<!-- <div :class="`${prefixCls}-item-content`">
<div :class="`${prefixCls}-item-title`">
{{ item.title }}
</div>
<div :class="`${prefixCls}-item-tags`">
<div
:class="`${prefixCls}-item-tag`"
v-for="tag in item.tags">
#{{ tag }}
</div>
</div>
</div> -->
</div>
</a-col>
</a-row>
<div
ref="loadMoreRef"
class="loading">
{{
loading
? $t('common.loadingText')
: hasMore
? ''
: $t('common.noMore')
}}
</div>
</div>
<mf-preview
:visible="previewVisible"
:url="previewUrl"
:loading="previewLoading"
@cancel="cancelPreview" />
</div>
</template>
<script>
export default {
data() {
return {
prefixCls: 'index',
dataList: [],
images: [],
pagination: {
total: 0,
pageNum: 1,
pageSize: 12,
layout: 'total, sizes, prev, pager, next'
},
previewUrl: '',
previewVisible: false,
previewLoading: false,
loading: false,
hasMore: true,
reachBottom: false
}
},
mounted() {
this.getBanner()
this.getData()
this.$refs.indexRef.addEventListener('scroll', this.handleScroll)
},
beforeUnmount() {
this.$refs.indexRef.removeEventListener('scroll', this.handleScroll)
},
methods: {
doSame(item) {
if (item.type == 21) {
this.$router.push(`/fast-video?text=${item.text}`)
} else if (item.type == 1) {
this.$router.push(`/fast-image?text=${item.text}`)
} else if (item.type == 11) {
this.$router.push(`/image-to-image`) //?text=${item.text}
} else if (item.type == 12) {
this.$router.push(`/image-to-image?type=2&text=${item.text}`)
} else if (item.type == 13) {
this.$router.push(
`/change-face` //?text=${item.text}
)
}
},
cancelPreview() {
this.previewVisible = false
this.previewUrl = ''
this.previewLoading = false
},
async checkPermission(url) {
let res = await this.$axios({
url: '/api/user/checkIsStandard',
method: 'GET'
}).then((res) => {
return { result: res.result, totalAmount: res.totalAmount }
})
if (!res.result) {
this.$message.warning(
this.$t('common.permissionError', {
total: res.totalAmount
})
)
return
}
this.viewDetail(url)
},
viewDetail(url) {
let suffix = this.$file.getSuffix(url)
if (['jpeg', 'jpg', 'png'].indexOf(suffix) > -1) {
this.$viewerApi({
options: {
initialViewIndex: 0,
toolbar: true
},
images: [url]
})
} else if (['mp4', 'mov'].indexOf(suffix) > -1) {
this.previewUrl = url
this.previewVisible = true
} else {
if (url.startsWith('cgt-')) {
this.viewVideo(url)
} else {
window.open(url)
}
}
},
viewVideo(videoId) {
if (!videoId) return
this.previewVisible = true
this.previewLoading = true
this.$axios({
url: `api/ai/${videoId}`,
method: 'GET'
})
.then((res) => {
this.previewLoading = false
if (res.code == 200) {
if (res.data.status == 'succeeded') {
this.previewUrl = res.data.content.video_url
} else {
this.$message.warning(
this.$t('common.videoLoadingText')
)
}
}
})
.catch((_) => {
this.previewLoading = false
})
},
jumpUrl(item) {
if (item.type == 0) {
this.$router.push(item.jumpUrl)
} else if (item.type == 1) {
window.open(item.jumpUrl)
}
},
getBanner() {
this.$axios({
url: 'api/banner/getBannerList',
method: 'GET',
data: {
position: 0
}
}).then((res) => {
this.images = res.rows
})
},
handleScroll() {
let ref = this.$refs.indexRef
if (!ref || this.loading) return
const scrollTop = ref.scrollTop
const clientHeight = ref.clientHeight
const scrollHeight = ref.scrollHeight
const isBottom = scrollTop + clientHeight >= scrollHeight - 50
if (isBottom && !this.reachBottom) {
this.reachBottom = true
this.loadMore()
}
if (!isBottom) {
this.reachBottom = false
}
},
loadMore() {
if (this.loading) return
this.pagination.pageNum++
this.getData(true)
},
getData(loadMore = false) {
if (this.loading || !this.hasMore) return
if (loadMore) this.loading = true
this.$axios({
url: 'api/work/getAiWorkList',
method: 'GET',
data: {
pageNum: this.pagination.pageNum,
pageSize: this.pagination.pageSize
}
})
.then((res) => {
this.loading = false
if (loadMore) {
this.dataList = this.dataList.concat(res.rows)
} else {
this.dataList = res.rows
}
this.hasMore = this.dataList.length < res.total
})
.catch((_) => {
this.loading = false
})
}
}
}
</script>
<style lang="less" scoped>
.index {
height: 100%;
overflow-y: auto;
padding: 0 20px 30px 20px;
.loading {
color: #fff;
text-align: center;
margin-top: 20px;
}
&-banner {
width: 100%;
aspect-ratio: 6 / 1;
margin-bottom: 40px;
border-radius: 10px;
overflow: hidden;
cursor: pointer;
:deep(.arco-carousel) {
width: 100%;
height: 100%;
&-arrow {
> div {
width: 36px;
height: 36px;
background-color: rgba(0, 0, 0, 0.3);
.arco-icon {
width: 20px;
height: 20px;
}
}
}
}
}
&-wrap {
width: 1200px;
margin: 0 auto;
}
&-item {
border-radius: 10px;
overflow: hidden;
background: #1a1b20;
height: 320px;
margin-bottom: 16px;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
// border: 1px solid rgba(#e0e0e0, 0.1);
&:hover {
transform: translateY(-5px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
// background-color: rgb(var(--primary-6));
.arco-image {
transform: scale(1.1);
}
}
:deep(.arco-image-error) {
background-color: transparent;
}
.arco-image {
transform: scale(1);
transition: all 1s;
}
&-play {
width: 50px;
height: 50px;
position: absolute;
border-radius: 50%;
left: 50%;
top: 50%;
transition: all 0.4s;
cursor: pointer;
font-size: 3em;
line-height: 1.5em;
transform: translate(-50%, -50%);
background-color: rgba(43, 51, 63, 0.7);
border: 2px solid #fff;
z-index: 1;
&:before {
content: '\f101';
font-family: VideoJS;
font-weight: normal;
font-style: normal;
text-align: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 30px;
}
}
&-image {
width: 100%;
overflow: hidden;
height: 320px;
:deep(.arco-image) {
width: 100%;
img {
width: 100%;
}
}
}
&-title {
font-size: 14px;
color: #ffffff;
margin-top: 14px;
margin-bottom: 14px;
}
&-content {
padding: 16px 8px;
}
.mf-button {
position: absolute;
bottom: 0;
right: 0;
border-top-left-radius: 10px;
}
&-shadow {
width: 100%;
height: 100%;
left: 0;
top: 0;
position: absolute;
background-color: rgba(0, 0, 0, 0.25);
display: flex;
align-items: flex-end;
justify-content: flex-end;
pointer-events: none;
.mf-button {
border-top-left-radius: 10px;
}
}
}
}
@media (max-width: 576px) {
.index {
padding: 0 10px;
:deep(.arco-carousel) {
.arco-image {
height: 100%;
img {
height: 100%;
}
}
}
&-banner {
margin-bottom: 10px;
}
&-wrap {
width: 100%;
}
&-item {
height: 250px;
&-image {
height: 250px;
}
}
.video-js {
width: 100%;
height: 250px;
}
}
}
</style>