PixelAI-mobile/pages/pc_web/work/work.vue
2025-02-19 15:51:04 +08:00

561 lines
15 KiB
Vue
Raw Permalink 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="pc-work" :style="windowHeight>1000?{}:{ minHeight: windowHeight+'px'}">
<!-- 左侧图片列表 -->
<view class="work-images">
<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="110" 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)" :title="item.type || '暂无'"
class="work-item" v-for="(item,index) in leftList" :key="index">
<u-lazy-load border-radius="30" class="work-picture"
:image="getImagePath(item.path)"></u-lazy-load>
<image :lazy-load="true" class="sign" :src="fileUrl+sign"></image>
<view class="sign-text">{{ item.type || '暂无' }}</view>
</view>
</template>
<template v-slot:right="{rightList}">
<view @click="maskTouchend(item,index)" :title="item.type || '暂无'"
class="work-item" v-for="(item,index) in rightList" :key="index">
<u-lazy-load border-radius="30" class="work-picture"
:image="getImagePath(item.path)"></u-lazy-load>
<image :lazy-load="true" class="sign" :src="fileUrl+sign"></image>
<view class="sign-text">{{ item.type || '暂无' }}</view>
</view>
</template>
</u-waterfall>
<!-- 下面这里等后端有了之后用isFinish判断 -->
<view class="last-tip" :class="(current === 0 ? workForm.isFinish : collectForm.isFinish)?'':'clickable'" @click="getMore">
{{ (current === 0 ? workForm.isFinish : collectForm.isFinish) ? '~~ 已加载全部 ~~' : '~~ 点击加载更多 ~~' }}
</view>
</view>
</view>
<view class="work-big">
<view class="big-image" :class="Object.keys(selectItem).length !== 0 ? 'big-image-none' : ''">
<view v-if="Object.keys(selectItem).length !== 0" class="bi-show-image">
<view class="bi-hover">
<u-icon size="90" title="预览" :name="fileUrl+previewIcon" @click="handlePreview"></u-icon>
<u-icon size="90" title="下载" :name="fileUrl+downloadIcon" @click="handleDownload"></u-icon>
<u-icon size="90" title="发布" :name="fileUrl+publicIcon" @click="handlePublic" v-if="current===0"></u-icon>
<u-icon size="90" title="收藏" :name="fileUrl+collectIcon" @click="handleCollect" v-if="current===0"></u-icon>
<u-icon size="90" :title=" current===0?'删除':'取消收藏'" :name="fileUrl+deleteIcon" @click="handleDelete"></u-icon>
</view>
<image :src="getImagePath(selectItem.path)" mode="aspectFit" class="big-preview"></image>
</view>
<view class="big-image" v-else>
<image :src="fileUrl+sleep"></image>
<view class="none-tips">
暂无{{ current===0? '作':'藏' }}品,前往<text @click="$emit('changeService', '')">工作室</text>创作!
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import configService from '@/common/config.service.js';
import { tools } from '@/utils/utils.js';
export default {
data(){
return{
// 基础路径
fileUrl: configService.fileUrl + 'pixel/',
// 筛选项
selectList: ["我的创作", "我的藏品"],
// 顶部背景
topBackground: 'work/background.png',
// 选择黑星图片
blackStar: 'work/black-star.png',
// 选择白底图片
selectBottom: 'work/select-bottom.png',
// 选择红星
redStar: 'work/red-star.png',
// 标签图标
sign: 'home/typelam.png',
// 禁用pc端的缺省图
sleep: 'pc/sleep.png',
// 下载图标
downloadIcon: 'pc/workshops/download.png',
// 删除图标
deleteIcon: 'pc/workshops/delete.png',
// 预览图标
previewIcon: 'pc/workshops/preview.png',
// 发布图标
publicIcon: 'pc/workshops/public.png',
// 收藏图标
collectIcon: 'pc/workshops/collect.png',
// 数字滚动开始数字
startVal: 0,
// 屏幕高度
windowHeight: 0,
// 当前选项
current: 0,
// 收藏作品列表
collectList:[],
// 我的创作
workList:[],
// 我的创作Form
workForm: {
current: 1,
size: 10,
isFinish: true,
total: 0
},
// 我的收藏Form
collectForm: {
current: 1,
size: 10,
isFinish: true,
total: 0
},
// 选中图片
selectItem:{},
}
},
computed: {
// 切换栏选中样式
getSwitchItemStyle(){
return (index) => {
return this.current===index ? {backgroundImage: `url(${this.fileUrl+this.selectBottom})`,
color: `rgba(33,33,33,1)`}:{}
}
},
},
beforeMount() {
// 计算当前窗口高度
this.windowHeight = window.screen.height;
},
mounted() {
this.init();
},
methods:{
// 切换选项
changeSelect(index){
this.current = index;
this.startVal = index===0?this.collectForm.total:this.workForm.total;
this.init();
},
// 初始化
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(){
let that = this;
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;
this.selectItem = result.length > 0 ? result[0] : {};
}else{
this.workList.push(...result);
}
this.workForm.total = total;
this.workForm.isFinish = current*size >= total;
}else{
this.$emit('toast',{type:'error',title: "我的创作获取失败!"});
}
},
// 获取我的藏品
async getCollections(){
let that = this;
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;
this.selectItem = result.length > 0 ? result[0] : {};
}else{
this.collectList.push(...result);
}
this.collectForm.total = total;
this.collectForm.isFinish = current*size >= total;
}else{
this.$emit('toast',{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);
},
// 图片点击事件
maskTouchend(item,index){
this.selectItem = item;
},
// 图片预览
handlePreview(){
let item = this.selectItem;
const array = [this.getImagePath(item.path)];
if(item.sourcePath) array.push(this.getImagePath(item.sourcePath));
tools.methods.lookImage(0,array);
},
// 下载图片
handleDownload(){
window.open(this.getImagePath(this.selectItem.path));
},
// 删除图片——收藏/作品
handleDelete(){
let that = this;
let current = this.current===0;
let item = this.selectItem;
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.workForm.total-- : that.collectForm.total--;
that.$refs.uWaterfall.remove(item.id);
that.selectItem = current ? that.workList[0] : that.collectList[0];
that.$forceUpdate();
that.$emit('toast',{type:'success',title: `已${current?'删除':'取消收藏'}该作品!`});
}else{
that.$emit('toast',{type:'error',title: `作品${current?'删除':'取消收藏'}失败!`});
}
}
}
});
},
// 分享作品
handlePublic(){
let that = this;
let item = this.selectItem;
uni.showModal({
title: '提示',
content: `作品分享需经过审核,审核期间可前往“我的-分享作品查看结果”,是否确认分享该作品?`,
confirmColor: '#94d500',
success: async (res) => {
if (res.confirm) {
let res = await that.$api.publicWork({
creationId: item.id,
});
if(res?.success){
that.$refs.uWaterfall.$forceUpdate();
that.$emit('toast',{type:'success',title: '作品上传分享成功!'});
}else{
that.$emit('toast',{type:'error',title: res?.errorMsg || '作品上传分享失败!'});
}
}
}
});
},
// 收藏作品
handleCollect(){
let that = this;
let item = this.selectItem;
uni.showModal({
title: '提示',
content: `是否确认收藏该作品?`,
confirmColor: '#94d500',
success: async (res) => {
if (res.confirm) {
let res = await that.$api.addCollections({
creationId: item.id,
});
if(res?.success){
that.$refs.uWaterfall.$forceUpdate();
that.$emit('toast',{type:'success',title: '作品收藏成功!'});
}else{
that.$emit('toast',{type:'error',title: res?.data || '作品收藏失败!'});
}
}
}
});
},
}
}
</script>
<style scoped lang="scss">
.pc-work{
background-image: linear-gradient(to left top, #ffffff, #fcfbfc, #f8f8f9, #f5f4f7, #f1f1f4, #eef0f6, #eaeff7, #e5eff8, #ddf3f9, #d9f6f2, #def7e6, #eef6d9);
margin-top: 20rpx;
min-height: 2050rpx;
display: flex;
align-items: center;
padding: 40rpx 50rpx;
.work-images{
margin-left: 200rpx;
width: 900rpx;
height: 1620rpx;
background-color: #fff;
border-radius: 40rpx;
transition: 0.3s;
display: flex;
flex-direction: column;
overflow: hidden;
border: 2rpx solid #d5d5d5;
box-shadow: 0 0 20rpx #c6c6c6;
.mw-top{
width: 100%;
height: 350rpx;
display: flex;
flex-direction: column;
background-size: cover;
.mwt-one{
margin-top: 65rpx;
display: flex;
.mwto-item{
font-size: 42rpx;
font-weight: bold;
color: rgba(33,33,33,0.8);
margin-left: 44rpx;
position: relative;
padding: 5rpx 10rpx;
background-size: contain;
background-repeat: no-repeat;
background-position: bottom;
background-size: 100%;
transition: 0.5s;
cursor: pointer;
&:hover{
opacity: 0.8;
}
&:active{
opacity: 0.6;
}
.mwto-star{
position: absolute;
right: -16rpx;
top: -7rpx;
width: 30rpx;
height: 34rpx;
}
}
}
.mwt-two{
display: flex;
margin-left: 65rpx;
margin-top: 40rpx;
align-items: flex-end;
.mwtt-num{
font-weight: bolder;
margin-right: 20rpx;
position: relative;
.mwtt-star{
position: absolute;
right: -30rpx;
top: -10rpx;
width: 30rpx;
height: 34rpx;
}
}
.mwtt-unit{
font-size: 40rpx;
font-weight: bold;
color: rgba(33,33,33,0.8);
line-height: 90rpx;
}
}
}
.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;
overflow-y: scroll;
.show-work{
margin: 20rpx 45rpx 0;
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;
&:hover{
.work-picture{
filter: drop-shadow(0 0 10rpx #d5ff00);
}
}
&:active{
opacity: 0.8;
}
.work-picture{
cursor: pointer;
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: 186rpx;
height: 47rpx;
z-index: 1;
}
.sign-text{
width: 142rpx;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
color: #ffffff;
font-size: 28rpx;
position: absolute;
top: 1.8em;
left: 0.9em;
z-index: 2;
}
}
}
.last-tip{
color: #d5ff00;
font-size: 28rpx;
text-align: center;
margin-top: 20rpx;
margin-bottom: 40rpx;
}
.clickable{
cursor: pointer;
&:hover{
opacity: 0.8;
}
&:active{
opacity: 0.6;
}
}
}
&:hover{
box-shadow: 0 0 20rpx #8a8a8a;
}
}
.work-big{
flex: 1;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
border-radius: 40rpx;
.big-image{
width: 1350rpx;
height: 1350rpx;
background-color: #ffffff;
border: 4rpx dashed #99d7ff;
border-radius: 40rpx;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
transition: 0.3s;
overflow: hidden;
.bi-show-image{
width: 100%;
height: 100%;
position: relative;
.big-preview{
width: 100%;
height: 100%;
}
.bi-hover{
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(0,0,0,0.5);
z-index: 1;
transition: 0.5s;
opacity: 0;
.u-icon{
margin: 0 30rpx;
cursor: pointer;
&:hover{
opacity: 0.8;
}
&:active{
opacity: 0.6;
}
}
}
}
.none-tips{
margin-top: 30rpx;
color: #9a702d;
font-size: 50rpx;
text{
cursor: pointer;
color: #53411e;
&:hover{
opacity: 0.8;
}
&:active{
opacity: 0.6;
}
}
}
&:hover{
box-shadow: 0 0 20rpx #d3d3d3;
.bi-hover{
opacity: 1;
}
}
}
.big-image-none{
background-color: #ffffff00;
border: none;
}
}
}
</style>