571 lines
15 KiB
Vue
571 lines
15 KiB
Vue
<template>
|
||
<view class="home-second">
|
||
<view class="hs-search-title">
|
||
<text @click="toWall">推荐作品</text>
|
||
<image :src="fileUrl+blackStar"></image>
|
||
</view>
|
||
<!-- 筛选项 -->
|
||
<scroll-view :scroll-x="true" class="hs-search">
|
||
<view class="hs-scroll">
|
||
<view v-for="(item,index) in serviceList" :key="index" class="search-tag"
|
||
:class="siftIndex===index ? 'search-tag-selected' : ''" @click="sift(item,index)">{{ item.name }}</view>
|
||
</view>
|
||
</scroll-view>
|
||
<!-- 第一栏——轮播图+服务 -->
|
||
<view class="hs-swiper">
|
||
<view class="hs-carousel">
|
||
<el-carousel>
|
||
<el-carousel-item v-for="(item,index) in swiperList" :key="index">
|
||
<image @click="linkTo(item.url)" class="swiper-image" :src="item.path"
|
||
:style="{cursor: item.url ? 'pointer' : 'default'}"></image>
|
||
</el-carousel-item>
|
||
</el-carousel>
|
||
</view>
|
||
|
||
<view class="hs-second">
|
||
<u-section class="hss-lam" title="AI工具" sub-title="更多"
|
||
font-size="50" @click="$emit('handleChangeService')"/>
|
||
<view class="hss-scroll">
|
||
<view class="hss-left" @click="scrollTo(0)" v-show="showScroll[0]">
|
||
<u-icon name="arrow-left" size="34"></u-icon>
|
||
</view>
|
||
<scroll-view class="hss-scroll-view" @scroll="scroller" ref="scrollView"
|
||
scroll-with-animation :scroll-left="scrollLeft" scroll-x>
|
||
<view class="hss-services">
|
||
<view class="hss-service" v-for="(item,index) in serviceList.slice(1)" :key="index" @click="$emit('handleChangeService', item.id)">
|
||
<image :src="encodeURI(staticIp+item.icon)"></image>
|
||
{{ item.name }}
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
<view class="hss-right" @click="scrollTo(1)" v-show="showScroll[1]">
|
||
<u-icon name="arrow-right" size="34"></u-icon>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="hs-services">
|
||
<!-- 瀑布流布局图片 -->
|
||
<masonry :cols="7" gutter="1em">
|
||
<view class="hs-service" v-for="(item,index) in workList" :key="item.id">
|
||
<u-lazy-load @click="preview(item)" :title="item.serviceName||'暂无'" border-radius="30" class="hss-picture"
|
||
:image="getWorkPath(item.path)" v-loading="item.loading"></u-lazy-load>
|
||
<view class="sign-text">{{ item.serviceName || '暂无' }}</view>
|
||
<image :lazy-load="true" class="sign" :src="fileUrl+sign"></image>
|
||
<view class="work-todo">
|
||
<view class="wt-same" @click.stop="$emit('handleChangeService', item.serviceId)">
|
||
<image :src="fileUrl+magicWand"></image>
|
||
<text>做同款</text>
|
||
</view>
|
||
<view class="wt-same wt-download" @click="download(item)">
|
||
<u-icon name="download" size="36" color="#c9fe76" />
|
||
<text>下载 </text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</masonry>
|
||
<!-- 下面这里等后端有了之后,用isFinish判断 -->
|
||
<view class="last-tip" :class="recommendForm.isFinish?'':'clickable'" @click="getMore">
|
||
{{ recommendForm.isFinish ? '~~ 已加载全部 ~~' : '~~ 点击加载更多 ~~' }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import configService from '@/common/config.service.js';
|
||
import { tools } from '@/utils/utils.js';
|
||
export default {
|
||
data(){
|
||
return{
|
||
// 基础地址
|
||
staticIp: configService.ip,
|
||
aliUrl: configService.aliUrl.split("://")[1],
|
||
fileUrl: configService.fileUrl + 'pixel/',
|
||
aliIp: configService.aliUrl,
|
||
otherAliIp: configService.otherAliUrl,
|
||
anotherAliIp: configService.anotherAliUrl,
|
||
// 选择黑星图片
|
||
blackStar: 'work/black-star.png',
|
||
// 魔术棒
|
||
magicWand: 'home/magic-wand.png',
|
||
// 标签图标
|
||
sign: 'home/typelam.png',
|
||
// 轮播图列表
|
||
swiperList: [],
|
||
// 服务列表
|
||
serviceList: [],
|
||
// 推荐作品列表
|
||
workList: [],
|
||
// 筛选项
|
||
siftIndex: 0,
|
||
// 滚动程度
|
||
scrollLeft: 0,
|
||
// 是否滚动到最左/右边
|
||
showScroll: [false,true],
|
||
// ai工具栏scroll宽度
|
||
scrollViewWidth: 0,
|
||
// 推荐作品表单
|
||
recommendForm: {
|
||
current: 1,
|
||
size: 20,
|
||
isFinish: true,
|
||
serviceName: '',
|
||
isBackend: 0
|
||
},
|
||
// 下载加载
|
||
downLoading: false,
|
||
}
|
||
},
|
||
mounted() {
|
||
// 获取ai工具栏宽度
|
||
this.scrollViewWidth = this.$refs.scrollView.$el.clientWidth;
|
||
this.getBanner();
|
||
this.getServices();
|
||
this.recommendForm = {current: 1,size: 20,isFinish: false,serviceName: '',isBackend: 0};
|
||
this.getWorkList();
|
||
},
|
||
methods:{
|
||
// 获取轮播图
|
||
async getBanner(){
|
||
let res = await this.$api.allBanners();
|
||
if(res?.success){
|
||
this.swiperList = res.data.map(item=>{
|
||
return {...item,path: encodeURI(this.staticIp+item.path)}
|
||
});
|
||
}else{
|
||
this.$emit('showToast',{type:'error',title: "轮播图获取失败!"});
|
||
}
|
||
},
|
||
// 获取服务筛选列表
|
||
async getServices(){
|
||
let res = await this.$api.allServices();
|
||
if(res.success){
|
||
const arr = res.data;
|
||
this.serviceList = [{id: -1,name:"全部"},...arr];
|
||
}else{
|
||
this.$emit('showToast',{type:'error',title: "筛选列表获取失败!"});
|
||
}
|
||
},
|
||
// 获取推荐作品列表
|
||
async getWorkList(){
|
||
if(this.recommendForm.isFinish) return;
|
||
let res = await this.$api.getRecommend(this.recommendForm);
|
||
if(res?.success){
|
||
const { records, total, current, size } = res.data;
|
||
const result = records;
|
||
if(current === 1){
|
||
this.workList = result;
|
||
}else{
|
||
this.workList.push(...result);
|
||
}
|
||
this.recommendForm.isFinish = current*size >= total;
|
||
this.$forceUpdate();
|
||
}else{
|
||
this.$emit('showToast',{type:'error',title: "推荐作品获取失败!"});
|
||
}
|
||
},
|
||
// 筛选
|
||
sift(item, index){
|
||
this.siftIndex = index;
|
||
this.recommendForm.serviceName = item.name === '全部' ? '' : item.name;
|
||
this.recommendForm.current = 1;
|
||
this.recommendForm.isFinish = false;
|
||
this.getWorkList();
|
||
},
|
||
// 图片格式化
|
||
getWorkPath(path){
|
||
if(!path) return;
|
||
let index = path?.indexOf('?');
|
||
let judge = path?.includes(configService.anotherAliUrl);
|
||
return path?.includes('://') ? path.substring(0,(judge||!index||index===-1) ? path.length : index) : encodeURI(this.staticIp+path);
|
||
},
|
||
// 轮播图跳转
|
||
linkTo(url){
|
||
if(url) window.open(encodeURI(url));
|
||
},
|
||
// 预览图片
|
||
preview(item){
|
||
const array = [this.getWorkPath(item.path)];
|
||
if(item.sourcePath) array.push(this.getWorkPath(item.sourcePath));
|
||
tools.methods.lookImage(0,array);
|
||
},
|
||
// ai工具栏滚动——0左滚、1右滚
|
||
scrollTo(type = 0){
|
||
let endo = 1000;
|
||
type === 0 ? this.scrollLeft -= endo : this.scrollLeft += endo;
|
||
},
|
||
// ai工具栏滚动监听
|
||
scroller({detail}){
|
||
const { scrollLeft, scrollWidth, deltaX } = detail;
|
||
this.showScroll[0] = scrollLeft !== 0;
|
||
this.showScroll[1] = (scrollLeft + this.scrollViewWidth - (deltaX || 0)) < scrollWidth;
|
||
this.$forceUpdate();
|
||
},
|
||
// 图片下载
|
||
async download(item){
|
||
let that = this;
|
||
let path = item.path;
|
||
item.loading = true;
|
||
if(!path || path==='') {
|
||
this.$emit('showToast',{type:'error',title: "该作品暂不可下载!"});
|
||
item.loading = false;
|
||
return;
|
||
}
|
||
|
||
// 下载地址
|
||
// let downloadUrl = await path.replace(that.aliIp, "/ossUpload");
|
||
let downloadUrl = path;
|
||
if(path.includes(that.aliIp)||path.includes(that.otherAliIp)||path.includes(that.anotherAliIp)){window.open(downloadUrl);item.loading = false;}
|
||
else
|
||
uni.request({
|
||
url: encodeURI(downloadUrl),
|
||
method: 'GET',
|
||
header: { 'token' : that.$store.state.vuex_token },
|
||
responseType: 'arraybuffer',
|
||
success(res) {
|
||
const arrayBuffer = res.data;
|
||
const blob = new Blob([arrayBuffer], {type: 'image/png'}); // 创建 Blob 对象
|
||
const imageUrl = URL.createObjectURL(blob); // 通过 Blob 对象创建图片 URL
|
||
let a = document.createElement('a'); //创建一个 a 标签
|
||
a.href = imageUrl; //把路径赋到a标签的href上
|
||
a.download = 'pixel.png';
|
||
a.click();
|
||
URL.revokeObjectURL(imageUrl);
|
||
a = null;
|
||
that.$emit('showToast',{type:'success',title: "图片下载成功!"});
|
||
},
|
||
fail() {
|
||
that.$emit('showToast',{type:'error',title: "图片下载失败,请重试!"});
|
||
},
|
||
complete() {
|
||
item.loading = false;
|
||
}
|
||
});
|
||
},
|
||
// 查看更多
|
||
getMore(){
|
||
if(this.recommendForm.isFinish) return;
|
||
this.recommendForm.current++;
|
||
this.getWorkList();
|
||
},
|
||
// 前往作品墙
|
||
toWall(){
|
||
this.$emit('toWall');
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.home-second{
|
||
width: 100%;
|
||
min-height: 73.5em;
|
||
background-image: linear-gradient(to left top, #ffffff, #fcfbfc, #f8f8f9, #f5f4f7, #f1f1f4, #eef0f6, #eaeff7, #e5eff8, #ddf3f9, #d9f6f2, #def7e6, #eef6d9);
|
||
.hs-search-title{
|
||
padding: 100rpx 40rpx 40rpx;
|
||
margin-left: 14rpx;
|
||
font-size: 40rpx;
|
||
font-weight: bold;
|
||
position: relative;
|
||
text{
|
||
background-image: linear-gradient(to right, #222 , #999, #222, #999, #222);
|
||
background-clip: text;
|
||
-webkit-background-clip: text;
|
||
background-size: 200% 100%;
|
||
color: transparent;
|
||
animation: light 2s infinite linear;
|
||
cursor: pointer;
|
||
&:hover{
|
||
opacity: 0.8;
|
||
}
|
||
&:active{
|
||
opacity: 0.6;
|
||
}
|
||
}
|
||
image{
|
||
position: absolute;
|
||
top: 84rpx;
|
||
width: 30rpx;
|
||
height: 34rpx;
|
||
}
|
||
}
|
||
.hs-search{
|
||
padding: 0rpx 40rpx 40rpx;
|
||
.hs-scroll{
|
||
display: flex;
|
||
align-items: center;
|
||
.search-tag{
|
||
white-space: nowrap;
|
||
border: 2rpx solid #ebebec;
|
||
color: #909399;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 20rpx 30rpx;
|
||
margin: 0 14rpx;
|
||
height: 74rpx;
|
||
border-radius: 16rpx;
|
||
background-color: #f4f4f5;
|
||
cursor: pointer;
|
||
&:hover{
|
||
border-color: #c2e7b0;
|
||
color: #49cc90;
|
||
background-color: #e8f6f0;
|
||
}
|
||
}
|
||
.search-tag-selected{
|
||
border-color: #c2e7b0;
|
||
color: #49cc90;
|
||
background-color: #e8f6f0;
|
||
}
|
||
}
|
||
}
|
||
.hs-swiper{
|
||
height: 600rpx;
|
||
display: flex;
|
||
margin: 40rpx 40rpx 2em;
|
||
|
||
.hs-carousel{
|
||
min-width: 1250rpx;
|
||
border-radius: 16rpx;
|
||
background-color: #e2fd7d;
|
||
.swiper-image{
|
||
width: 100%;
|
||
height: 100%;
|
||
border-radius: 16rpx;
|
||
}
|
||
}
|
||
.hs-second{
|
||
display: flex;
|
||
flex-direction: column;
|
||
width: 2460rpx;
|
||
margin: 0 0 0 2em;
|
||
background: red;
|
||
border-radius: 40rpx;
|
||
background-image: linear-gradient(0deg,#e1ecfd,#cee2ff);
|
||
padding: 50rpx;
|
||
.hss-lam{}
|
||
.hss-scroll{
|
||
flex: 1;
|
||
background-image: linear-gradient(235deg,#e1ecfd 31.76%,#cee2ff 86.2%);
|
||
margin-top: 30rpx;
|
||
border-radius: 30rpx;
|
||
padding: 50rpx;
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
.hss-scroll-view{
|
||
.hss-services{
|
||
height: 100%;
|
||
display: flex;
|
||
white-space: nowrap;
|
||
// overflow-x: scroll;
|
||
align-items: center;
|
||
.hss-service{
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
margin: 0 40rpx 0 0;
|
||
cursor: pointer;
|
||
font-size: 30rpx;
|
||
&:nth-last-child(1){
|
||
margin-right: 0;
|
||
}
|
||
image{
|
||
width: 266rpx;
|
||
height: 260rpx;
|
||
border-radius: 32rpx;
|
||
border: 6rpx solid #eee;
|
||
margin-bottom: 10rpx;
|
||
}
|
||
&:hover{
|
||
color: #dcffe9;
|
||
image{
|
||
box-shadow: 0 0 20rpx #eee;
|
||
border-color: #daf6f3;
|
||
}
|
||
}
|
||
&:active{
|
||
opacity: 0.8;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.hss-left,.hss-right{
|
||
z-index: 1;
|
||
position: absolute;
|
||
border-radius: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
background-color: rgba(240,240,240,0.9);
|
||
cursor: pointer;
|
||
opacity: 0;
|
||
transition: 0.5s;
|
||
&:hover{
|
||
opacity: 0.9 !important;
|
||
}
|
||
&:active{
|
||
opacity: 0.6 !important;
|
||
}
|
||
}
|
||
.hss-left{
|
||
left: 30rpx;
|
||
}
|
||
.hss-right{
|
||
right: 30rpx;
|
||
}
|
||
&:hover{
|
||
.hss-left,.hss-right{
|
||
opacity: 0.6;
|
||
}
|
||
}
|
||
}
|
||
::v-deep .u-section__right-info{
|
||
cursor: pointer;
|
||
&:hover{
|
||
opacity: 0.8;
|
||
}
|
||
&:active{
|
||
opacity: 0.6;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.hs-services{
|
||
padding: 0rpx 40rpx 40rpx;
|
||
// column-count:5;
|
||
// -moz-column-count:5; /* Firefox */
|
||
// -webkit-column-count:5; /* Safari 和 Chrome */
|
||
// column-gap: 2em;
|
||
// -moz-column-gap: 2em;
|
||
// -webkit-column-gap: 2em;
|
||
.hs-service{
|
||
-webkit-column-break-inside: avoid;
|
||
break-inside: avoid; /*防止断点*/
|
||
// width: 400rpx;
|
||
margin-bottom: 1em;
|
||
position: relative;
|
||
overflow: hidden;
|
||
border-radius: 30rpx;
|
||
.hss-picture{
|
||
cursor: pointer;
|
||
border: 2rpx solid #d5ff00;
|
||
border-radius: 30rpx;
|
||
// 骗系统开启硬件加速
|
||
transform: transition3d(0, 0, 0);
|
||
// 防止图片加载“闪一下”
|
||
will-change: transform;
|
||
}
|
||
.sign{
|
||
border: none;
|
||
border-radius: 0;
|
||
position: absolute;
|
||
top: 0.8em;
|
||
left: 0.6em;
|
||
width: 190rpx;
|
||
height: 54rpx;
|
||
}
|
||
.sign-text{
|
||
width: 160rpx;
|
||
text-overflow: ellipsis;
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
color: #ffffff;
|
||
font-size: 30rpx;
|
||
position: absolute;
|
||
top: 0.9em;
|
||
left: 0.9em;
|
||
z-index: 1;
|
||
}
|
||
.work-todo{
|
||
width: 100%;
|
||
height: 100rpx;
|
||
position: absolute;
|
||
z-index: 1;
|
||
border-radius: 8rpx 8rpx 30rpx 30rpx;
|
||
bottom: -100rpx;
|
||
// bottom: 2rpx;
|
||
left: 0;
|
||
background-color: rgba(0, 0, 0, 0.3);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-around;
|
||
font-size: 30rpx;
|
||
transition: 0.5s;
|
||
.wt-same{
|
||
width: 200rpx;
|
||
height: 70rpx;
|
||
border-radius: 56rpx;
|
||
border: 2rpx solid #a3d4ff;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background-color: rgba(242, 245, 247, 0.2);
|
||
text{
|
||
font-weight: bold;
|
||
background-image: linear-gradient(to right, #cdfbf2 0%, #a3d4ff 100%);
|
||
background-clip: text;
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
}
|
||
image{
|
||
margin-right: 10rpx;
|
||
width: 34rpx;
|
||
height: 34rpx;
|
||
}
|
||
&:hover{
|
||
opacity: 0.8;
|
||
}
|
||
&:active{
|
||
opacity: 0.6;
|
||
}
|
||
}
|
||
.wt-download{
|
||
width: 180rpx;
|
||
border-color: #c5fe6e;
|
||
text{
|
||
background-image: linear-gradient(to right, #c9fe76 0%, #a5fe2f 100%);
|
||
}
|
||
}
|
||
}
|
||
&:hover{
|
||
.work-todo{
|
||
bottom: 2rpx;
|
||
}
|
||
}
|
||
}
|
||
.last-tip{
|
||
font-size: 36rpx;
|
||
text-align: center;
|
||
margin-top: 20rpx;
|
||
margin-bottom: 20rpx;
|
||
background-image: linear-gradient(to right, #a3d4ff 0%, #bee7df 100%);
|
||
background-clip: text;
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
}
|
||
.clickable{
|
||
cursor: pointer;
|
||
&:hover{
|
||
opacity: 0.8;
|
||
}
|
||
&:active{
|
||
opacity: 0.6;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
@keyframes light {
|
||
0% {
|
||
background-position: 0 0;
|
||
}
|
||
100% {
|
||
background-position: -100% 0;
|
||
}
|
||
}
|
||
</style> |