PixelAI-mobile/pages/mobile_web/work/work.vue

623 lines
17 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="mobile-work">
<!-- #ifdef APP -->
<view class="app-top" :style="{ height: CustomBar+2+'rpx',
background: topLevel===0? 'linear-gradient(180deg, #d8fa35 0%, #f0fdbf 100%)' : `rgba(255, 255, 255,${topLevel})` }"></view>
<view :style="{ height: CustomBar+'rpx',background: 'linear-gradient(180deg, #d8fa35 0%, #f0fdbf 100%)'}"></view>
<view class="mobile-logo" :style="{backgroundColor: `rgba(255, 255, 255,${topLevel})`,marginTop: CustomBar+2+'rpx'}">
<!-- #endif -->
<!-- #ifdef MP -->
<view class="app-top" :style="{height: `${StatusBar}px`,background: topLevel===0? 'linear-gradient(180deg, #d8fa35 0%, #f0fdbf 100%)' : `rgba(255, 255, 255,${topLevel})`}"></view>
<view :style="{height: `${StatusBar}px`}"></view>
<view class="mobile-logo" :style="{marginTop: `${StatusBar}px`,height: `${CustomBarHeight}px`,backgroundColor: `rgba(255, 255, 255,${topLevel})`}">
<!-- #endif -->
<!-- #ifdef H5 -->
<view class="mobile-logo" :style="{backgroundColor: `rgba(255, 255, 255,${topLevel})`}">
<!-- #endif -->
<image :src="fileUrl+logo"></image>
</view>
<view class="mw-top" :style="{backgroundImage: `url(${fileUrl+topBackground})`}">
<view class="mwt-one">
<view class="mwto-item" :style="[getSwitchItemStyle(index)]" v-for="(item,index) in selectList" :key="index" @click="changeSelect(index)">
{{ item }}
<image v-show="current===index" :src="fileUrl+blackStar" class="mwto-star"></image>
</view>
</view>
<view class="mwt-two">
<view class="mwtt-num">
<u-count-to autoplay color="#ff4269" fontSize="100" bold
:startVal="startVal" :endVal="current===0? workForm.total:collectForm.total"></u-count-to>
<image :src="fileUrl+redStar" class="mwtt-star"></image>
</view>
<view class="mwtt-unit">
件{{ current===0? '作':'藏' }}品
</view>
</view>
</view>
<view class="mw-content">
<u-waterfall class="show-work" v-model="current===0?workList:collectList" ref="uWaterfall">
<template v-slot:left="{leftList}">
<view @click="maskTouchend(item,index)" class="work-item" v-for="(item,index) in leftList" :key="item.id">
<image class="trash" :class="item.display ? 'hideTrash' : ''" :src="fileUrl+trash" v-show="item.mask" @click.stop="deleteCollect(item,index)"></image>
<u-lazy-load border-radius="30" class="work-picture"
:image="getImagePath(item.path)"></u-lazy-load>
<view class="sign-text">{{ item.type || '暂无' }}</view>
<image :lazy-load="true" class="sign" :src="fileUrl+sign"></image>
<!-- <image class="compare-sign" mode="widthFix" :src="item.compare"></image> -->
<view class="item-mask" :class="item.display ? 'hideMask' : ''" v-show="item.mask" v-if="!current">
<button class="mask-public" @click.stop="publicWork(item,index)">发布</button>
<button class="mask-collect" @click.stop="toCollect(item,index)">收藏</button>
</view>
</view>
</template>
<template v-slot:right="{rightList}">
<view @click="maskTouchend(item,index)" class="work-item" v-for="(item,index) in rightList" :key="item.id">
<image class="trash" :class="item.display ? 'hideTrash' : ''" :src="fileUrl+trash" v-show="item.mask" @click.stop="deleteCollect(item,index)"></image>
<u-lazy-load border-radius="30" class="work-picture"
:image="getImagePath(item.path)"></u-lazy-load>
<view class="sign-text">{{ item.type || '暂无' }}</view>
<image :lazy-load="true" class="sign" :src="fileUrl+sign"></image>
<!-- <image class="compare-sign" mode="widthFix" :src="item.compare"></image> -->
<view class="item-mask" :class="item.display ? 'hideMask' : ''" v-show="item.mask" v-if="!current">
<button class="mask-public" @click.stop="publicWork(item,index)">发布</button>
<button class="mask-collect" @click.stop="toCollect(item,index)">收藏</button>
</view>
</view>
</template>
</u-waterfall>
<!-- 下面这里等后端有了之后用isFinish判断 -->
<view class="last-tip" @click="getMore">
{{ (current === 0 ? workForm.isFinish : collectForm.isFinish) ? '~~ 已加载全部 ~~' : '~~ 点击加载更多 ~~' }}
</view>
</view>
<Movable textColor="#94d500" :tipText="tipText" />
<u-toast ref="uToast"></u-toast>
</view>
</template>
<script>
import Movable from '../wall/components/movable.vue';
import configService from '@/common/config.service.js';
import { tools } from '@/utils/utils.js';
export default {
props: {
topLevel:{
type: Number,
default: 0
},
},
components: { Movable },
data(){
return{
// #ifdef MP
// 微信小程序自定义导航栏参数
StatusBar: this.StatusBar || 0,
CustomBarHeight: this.Custom.height+(this.Custom.top-this.StatusBar)*2 || 0,
// #endif
// 基础路径
ip: configService.ip,
fileUrl: configService.fileUrl + 'pixel/',
// logo图标
logo: 'home/logo-new.png',
// 筛选项
selectList: ["我的创作", "我的藏品"],
// 顶部背景
topBackground: 'work/background.png',
// 选择黑星图片
blackStar: 'work/black-star.png',
// 选择白底图片
selectBottom: 'work/select-bottom.png',
// 选择红星
redStar: 'work/red-star.png',
// 删除——垃圾桶
trash: 'work/trash.png',
// 当前选项
current: 0,
// 收藏作品列表
collectList:[],
// 我的创作
workList:[],
// 我的创作Form
workForm: {
current: 1,
size: 10,
isFinish: true,
total: 0
},
// 我的收藏Form
collectForm: {
current: 1,
size: 10,
isFinish: true,
total: 0
},
// 标签图标
sign: 'home/typelam.png',
// 点击次数
touchNum: 0,
// 数字滚动开始数字
startVal: 0,
// 操作提示
tipText: ["双击图片进行更多操作"],
}
},
computed: {
// 切换栏选中样式
getSwitchItemStyle(){
return (index) => {
return this.current===index ? {backgroundImage: `url(${this.fileUrl+this.selectBottom})`,
color: `rgba(33,33,33,1)`}:{}
}
},
},
beforeDestroy() {
this.workList = [];
this.collectList = [];
},
methods:{
// 初始化
async init(){
this.$refs.uWaterfall.clear();
if(this.current){
this.collectList = [];
this.collectForm = {current: 1,size: 10,isFinish: false,total: 0};
this.getCollections();
}else{
this.workList = [];
this.workForm = {current: 1,size: 10,isFinish: false,total: 0};
this.getMyWorks();
}
},
// 查看更多
getMore(){
if(this.current === 0 ? this.workForm.isFinish : this.collectForm.isFinish) return;
if(this.current === 0){
this.workForm.current++;
this.getMyWorks();
}else{
this.collectForm.current++;
this.getCollections();
}
},
// 获取我的创作
async getMyWorks(){
if(this.workForm.isFinish) return;
let res = await this.$api.myCreations(this.workForm);
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.workForm.total = total;
this.workForm.isFinish = current*size >= total;
// this.$forceUpdate();
}else{
this.$refs.uToast.show({type:'error',title: "我的创作获取失败!"});
}
},
// 获取我的藏品
async getCollections(){
if(this.collectForm.isFinish) return;
let res = await this.$api.getCollections(this.collectForm);
if(res.success){
const { records, total, current, size } = res.data;
const result = records;
if(current === 1){
this.collectList = result
}else{
this.collectList.push(...result);
}
this.collectForm.total = total;
this.collectForm.isFinish = current*size >= total;
// this.$forceUpdate();
}else{
this.$refs.uToast.show({type:'error',title: "我的藏品获取失败!"});
}
},
// 图片格式化
getImagePath(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.ip+path);
},
// 切换选项
changeSelect(index){
// this.$refs.uWaterfall.clear();
this.current = index;
this.startVal = index===0?this.collectForm.total:this.workForm.total;
this.init();
},
// 收藏作品
toCollect(item, index){
let that = this;
uni.showModal({
title: '提示',
content: `是否确认收藏该作品?`,
confirmColor: '#94d500',
success: async (res) => {
if (res.confirm) {
let res = await that.$api.addCollections({
creationId: item.id,
});
if(res?.success){
// 关掉蒙层
item.mask = 0;
item.display = 0;
that.$refs.uWaterfall.$forceUpdate();
that.$refs.uToast.show({type:'success',title: '作品收藏成功!'});
}else{
that.$refs.uToast.show({type:'error',title: res?.data || '作品收藏失败!'});
}
}
}
});
},
// 监听单双击,单击-预览图片、双击-显示删除图标
maskTouchend(item,index){
this.touchNum ++;
setTimeout(()=>{
if(this.touchNum == 1){
if(item.mask){
// 添加淡出的class样式
item.display = 1;
this.$refs.uWaterfall.$forceUpdate();
// 下面的操作应该替换为请求后端数据后,再停止旋转
// 模拟刷新操作这里用setTimeout模拟
setTimeout(() => {
// 移除淡出类
item.mask = 0;
item.display = 0;
this.$refs.uWaterfall.$forceUpdate();
}, 800);
}else{
const array = [this.getImagePath(item.path)];
if(item.sourcePath) array.push(this.getImagePath(item.sourcePath));
tools.methods.lookImage(0,array);
}
}
if(this.touchNum >= 2){
const result = item.mask?0:1;
if(result === 0){
// 添加淡出的class样式
item.display = 1;
this.$refs.uWaterfall.$forceUpdate();
// 下面的操作应该替换为请求后端数据后,再停止旋转
// 模拟刷新操作这里用setTimeout模拟
setTimeout(() => {
// 移除淡出类
item.mask = result;
item.display = 0;
this.$refs.uWaterfall.$forceUpdate();
}, 800);
}else{
item.mask = result;
this.$refs.uWaterfall.$forceUpdate();
}
}
this.touchNum = 0;
},250)
},
// 分享作品
publicWork(item,index){
let that = this;
uni.showModal({
title: '提示',
content: `作品分享需经过审核,审核期间可前往“我的-分享作品查看结果”,是否确认分享该作品?`,
confirmColor: '#94d500',
success: async (res) => {
if (res.confirm) {
let res = await that.$api.publicWork({
creationId: item.id,
});
if(res?.success){
// 关掉蒙层
item.mask = 0;
item.display = 0;
that.$refs.uWaterfall.$forceUpdate();
that.$refs.uToast.show({type:'success',title: '作品上传分享成功!'});
}else{
that.$refs.uToast.show({type:'error',title: res?.errorMsg || '作品上传分享失败!'});
}
}
}
});
},
// 取消收藏
deleteCollect(item,index){
let that = this;
let current = this.current===0;
uni.showModal({
title: '提示',
content: `是否确认${current?'删除':'取消收藏'}该作品?`,
confirmColor: '#94d500',
success: async (res) => {
if (res.confirm) {
let res = current ? await that.$api.deleteCreation(item.id) : await that.$api.deleteCollections(item.id);
if(res.success){
// current ? that.workList.splice(index, 1) : this.collectList.splice(index, 1);
current ? that.workForm.total-- : that.collectForm.total--;
that.$refs.uWaterfall.remove(item.id);
that.$refs.uToast.show({type:'success',title: `已${current?'删除':'取消收藏'}该作品!`});
}else{
that.$refs.uToast.show({type:'error',title: `作品${current?'删除':'取消收藏'}失败!`});
}
}
}
});
}
}
}
</script>
<style scoped lang="scss">
.mobile-work{
display: flex;
flex-direction: column;
min-height: 100vh;
// #ifdef APP || MP
.app-top{
width: 100%;
position: fixed;
z-index: 81;
}
// #endif
.mobile-logo{
width: 100%;
display: flex;
justify-content: center;
position: fixed;
z-index: 81;
padding: 15rpx 0;
image{
width: 200rpx;
height: 45rpx;
}
}
.mw-top{
width: 100%;
height: 300rpx;
display: flex;
flex-direction: column;
background-size: cover;
.mwt-one{
margin-top: 65rpx;
display: flex;
.mwto-item{
font-size: 35rpx;
font-weight: bold;
color: rgba(33,33,33,0.8);
margin-left: 40rpx;
position: relative;
padding: 5rpx 10rpx;
background-size: contain;
background-repeat: no-repeat;
background-position: bottom;
background-size: 100%;
transition: 0.5s;
.mwto-star{
position: absolute;
right: -16rpx;
top: -7rpx;
width: 30rpx;
height: 34rpx;
}
}
}
.mwt-two{
display: flex;
margin-left: 65rpx;
margin-top: 32rpx;
align-items: flex-end;
.mwtt-num{
font-weight: bolder;
margin-right: 18rpx;
position: relative;
.mwtt-star{
position: absolute;
right: -30rpx;
top: -10rpx;
width: 30rpx;
height: 34rpx;
}
}
.mwtt-unit{
font-size: 31rpx;
font-weight: bold;
color: rgba(33,33,33,0.8);
line-height: 80rpx;
}
}
}
.mw-content{
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
z-index: 80;
flex: 1;
width: 100%;
margin-top: -35rpx;
border-top-right-radius: 36rpx;
border-top-left-radius: 36rpx;
background-color: #1a1929;
.show-work{
margin: 20rpx 45rpx 0;
// column-count:2;
// -moz-column-count:2; /* Firefox */
// -webkit-column-count:2; /* Safari Chrome */
column-gap: 1em;
-moz-column-gap: 1em;
-webkit-column-gap: 1em;
.work-item{
-webkit-column-break-inside: avoid;
break-inside: avoid; /*防止断点*/
// margin-bottom: 0.5em;
position: relative;
padding-top: 30rpx;
.work-picture{
border: 0.1em solid #d5ff00;
border-radius: 30rpx;
// 骗系统开启硬件加速
transform: transition3d(0, 0, 0);
// 防止图片加载闪一下
will-change: transform;
}
.sign{
border: none;
border-radius: 0;
position: absolute;
top: 1.7em;
left: 0.6em;
width: 152rpx;
height: 47rpx;
z-index: 1;
}
.sign-text{
width: 132rpx;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
color: #ffffff;
font-size: 28rpx;
position: absolute;
top: 1.8em;
left: 0.9em;
z-index: 2;
}
.trash{
animation-duration: 0.8s;
animation-fill-mode: both;
backface-visibility: visible !important;
animation-name: showTrash;
width: 100rpx;
height: 110rpx;
position: absolute;
right: -22rpx;
margin-top: -30rpx;
z-index: 1;
}
.hideTrash {
animation-duration: calc(1s * 0.75);
backface-visibility: visible !important;
animation-name: hideTrash;
}
.compare-sign{
position: absolute;
left: 0;
bottom: 0.2em;
width: 120rpx;
border: 0.1em solid #d5ff00;
border-radius: 20rpx;
box-shadow: rgba(213, 255, 0, 0.3) 0px 4px 12px;
}
.hideMask {
animation-duration: calc(1s * 0.75);
animation-fill-mode: both;
animation-name: hideMask !important;
}
.item-mask{
position: absolute;
top: 0;
margin-top: 32rpx;
left: 0.1rpx;
width: calc(100% - 4rpx);
height: calc(100% - 34rpx);
display: flex;
flex-wrap: wrap;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.6);
border-radius: 30rpx;
animation-duration: 0.8s;
animation-name: showMask;
button{
border-radius: 56rpx;
min-width: 145rpx;
max-width: 185rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 25rpx;
color: #f9f9f9;
margin: 10% 0;
}
.mask-public{
background: linear-gradient(to right,#853ade 0%, #d450da 100%);
}
.mask-collect{
background: linear-gradient(to right,rgba(65, 222, 70, 0.8) 0%, rgba(191, 218, 133, 0.8) 100%);
}
}
}
}
.last-tip{
color: #d5ff00;
font-size: 28rpx;
text-align: center;
margin-top: 20rpx;
margin-bottom: 160rpx;
}
}
}
@keyframes showMask {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes hideMask {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes showTrash {
from {
transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
animation-timing-function: ease-in;
opacity: 0;
}
40% {
transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
animation-timing-function: ease-in;
}
60% {
transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
opacity: 1;
}
80% {
transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
}
to {
transform: perspective(400px);
}
}
@keyframes hideTrash {
from {
transform: perspective(400px);
}
30% {
transform: perspective(400px) rotate3d(0, 1, 0, -15deg);
opacity: 1;
}
to {
transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
opacity: 0;
}
}
</style>