Files
aida_front/src/component/HomePage/PrintboardUpload.vue
WangXiaoDong 2fda4a8c36 commit
2023-08-23 17:50:09 +08:00

954 lines
31 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>
<div class="printboard_upload_modal">
<div class="printboard_left_upload">
<div class="left_upload_header">
<div class="upload_header_item">
<div class="switch_type_list">
<div
@click.stop="open(1)"
class="switch_type_item"
:class="[openClick == 1 ? 'select_swtich' : '']"
>
<span>Upload</span>
</div>
<div
@click.stop="open(2)"
class="switch_type_item"
:class="[openClick == 2 ? 'select_swtich' : '']"
>
<span>Library</span>
</div>
<div
@click.stop="open(3)"
class="switch_type_item"
:class="[openClick == 3 ? 'select_swtich' : '']"
>
<span>Generate</span>
</div>
</div>
</div>
</div>
<div v-show="openClick == 1" class="printboard_body">
<div class="upload_img_body">
<div class="upload_item">
<div :class="['upload_file_item']" v-for="(file, index) in fileList" :key="file">
<div class="upload_file_img_block">
<div class="upload_file_item_content" v-show="file?.status === 'uploading'">
<a-spin :indicator="indicator" tip="Uploading..."/>
</div>
<div class="upload_file_item_content" v-show="file?.status === 'done'">
<img v-lazy="file.imgUrl" class="upload_img" :key="file.imgUrl">
<div class="delete_file_block" @click.stop="deleteFile(file)">
<span
class="icon iconfont icon-shanchu"
></span>
</div>
</div>
</div>
<div class="pin_block" v-show="file?.status === 'done'">
<a-checkbox v-model:checked="file.pin">PIN</a-checkbox>
</div>
</div>
<div class="upload_file_item upload_component" v-show="fileList.length < 15">
<a-upload
v-show="fileList.length < 15"
:action="uploadUrl + '/api/element/upload'"
list-type="picture-card"
:before-upload="beforeUpload"
:data="{
...upload
}"
:headers="{Authorization:token}"
v-model:file-list="fileList"
:customRequest="function(){}"
multiple
:maxCount="15"
accept=".jpg,.png,.jpeg,.bmp"
@change="fileUploadChange"
>
<div
class="upload_tip_block"
>
<i class="fi fi-br-upload"></i>
<!-- <img class="upload_img_icon" src="@/assets/images/homePage/add_file.png"> -->
</div>
</a-upload>
</div>
</div>
</div>
</div>
<Material v-show="openClick == 2" ref="Material" @confirmSelect="confirmSelect"></Material>
<Generate v-show="openClick == 3" ref="Generate" msg="Printboard" @generateCheckbox="getgenerateCheckbox"></Generate>
</div>
<div class="modal_right">
<div class="modal_layout">
<div class="modal_text">
<div>Thumbnail preview of selected moodboard</div>
<!-- <div class="modal_btn started_btn" @click="layout()">layout</div> -->
</div>
<div class="modal_img">
<div class="modal_img_item" v-for="item,index in printboardList" :key="item" @click.stop="deleteFile(item)">
<img v-lazy="item.imgUrl">
<div class="checked" >
<i class="fi fi-rr-trash"></i>
</div>
</div>
</div>
</div>
<div v-show="openClick == 3" class="modal_accomplish">
<div class="input_box">
<input class="search_input" :class="{forbidden:generateCheckbox}" :readonly="generateCheckbox" placeholder="Caption generation" v-model="captionGeneration">
<div class="generage_btn started_btn" @click.stop="getgenerate">Generate</div>
</div>
<div class="modal_img">
<div v-for="item,index in generateList" class="modal_imgItem" :class="{ active: item?.checked }" >
<img :src="item.imgUrl" @click.stop="generageAdd(item)">
<div class="pin_block">
<a-checkbox v-model:checked="item.pin">PIN</a-checkbox>
</div>
</div>
</div>
</div>
</div>
<Cropper ref="Cropper" @handleCropperSuccess="handleCropperSuccess" @closeCropper="deletUploadFile()" :cropperFileData="cropperFileData" :isUpload="isUpload"></Cropper>
</div>
</template>
<script lang="ts">
import { defineComponent,h,ref,computed } from 'vue'
import { LoadingOutlined } from '@ant-design/icons-vue';
import {getCookie} from '@/tool/cookie'
import {getUploadUrl} from '@/tool/util'
import {useStore} from 'vuex'
import { Https } from "@/tool/https";
import { message,Upload} from 'ant-design-vue';
import Cropper from '@/component/HomePage/Cropper.vue'
import Material from '@/component/HomePage/Material.vue'
import Generate from "@/component/HomePage/Generate.vue";
import GO from "@/tool/GO";
export default defineComponent({
components:{
Cropper,
Material,
Generate
},
setup(){
let store:any =useStore()
let fileList:any = ref([]),//选中的文件id数据
printImgList:any = ref([]), //print的印花图片
moodBoards:any = computed(()=>{return store.state.UploadFilesModule.moodboardFiles})
let openClick: any = ref(1);
let generateCheckbox:any = ref()
let generateList:any = ref([
{
imgUrl: "https://illlustrations.co/static/32913fde3ee589609d98f16c51fcffa6/ee604/day8-printer.png",
id_: 1,
},
{
imgUrl: "https://illlustrations.co/static/3edf742257c1d1460eb2e2f998a1df96/ee604/day4-polariod.png",
id_: 2,
},
{
imgUrl: "https://illlustrations.co/static/475732e63175f7dc3bf93c84af8b3d11/ee604/day6-open-vault.png",
id_: 3,
},
{
imgUrl: "https://illlustrations.co/static/ca430674ef56f1a3a91f705670fd8512/ee604/day17-walkie-talkie.png",
id_: 4,
},
])
return {
fileList,
printImgList,
moodBoards,
openClick,
generateCheckbox,
generateList,
}
},
computed:{
getPinLength(){
let selectLength:any = 0
for(let item of this.fileList){
if(item.pin){
selectLength++
}
}
return selectLength
}
},
data(){
return {
swtich_type:'upload',
indicator : h(LoadingOutlined, {
style: {
fontSize: '2.4rem',
},
spin: true,
}),
upload:{
isPin:0,
level1Type:'Printboard',
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
},
token:'',
uploadUrl:'',
store:useStore(),
cropperFileData:{name:'',uid:''}, //裁剪的原始文件数据
currentFileNum:0, //当前上传的文件数
isUpload:false,
generateloading:false,
captionGeneration:'',
printboardList:computed(()=>{
return useStore().state.UploadFilesModule.printboard
}),
}
},
mounted(){
this.token = getCookie('token') || ''
this.uploadUrl = getUploadUrl()
},
methods:{
open(num: Number) {
this.openClick = num;
},
openLibrary(){
let material:any = this.$refs.Material
material.init('Printboard')
},
fileUploadChange(data:any){
let file = data.file
file.id_ = GO.id++
file.type_ = {
type1:'upload',
type2:'Moodboard'
};
file.pin = false;
let Cropper:any = this.$refs.Cropper
if(this.currentFileNum === 1){
var reader = new FileReader();
reader.onload = (e:any) => {
let data_new;
if (typeof e.target.result === 'object') {
// 把Array Buffer转化为blob 如果是base64不需要
data_new = window.URL.createObjectURL(new Blob([e.target.result]));
} else {
data_new = e.target.result;
}
Cropper.getOptionImg(data_new)
};
// 转化为base64
// reader.readAsDataURL(file)
// 转化为blob
reader.readAsArrayBuffer(file.originFileObj);
this.cropperFileData = file
Cropper.changeShowModal(true)
}else{
this.customRequest(file)
}
},
beforeUpload(file:any,fileList:any){
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/bmp';
if (!isJpgOrPng) {
message.error('You can only upload Image file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('Image must smaller than 5MB!');
}
if(isJpgOrPng && isLt2M){
this.currentFileNum = fileList.length
}else{
return (isJpgOrPng && isLt2M) || Upload.LIST_IGNORE;
}
},
deleteFile(item:any){
// this.fileList.splice(item, 1)
// this.store.commit('setPrintboardFile',this.fileList)
if(item.type_.type1 == 'generate' || item.type_.type1 == 'material'){
this.store.commit("addGenerateMaterialFils", item);
}else{
this.fileList = this.store.state.UploadFilesModule.moodboardFiles
let moodboard
this.store.state.UploadFilesModule.moodboardFiles.forEach((items:any,index:Number)=>{
if(items.id_ == item.id_){
moodboard = index
}
})
this.fileList.splice(moodboard,1)
this.store.commit("setSketchboardFile", this.fileList);
}
},
randomRange(min:any, max:any, num:any) { // min最小值max最大值 num排除的值
let index = Math.floor(Math.random() * (max - min)) + min;
while(index === num){
index = Math.floor(Math.random() * (max - min)) + min;
}
return index
},
generatePrint(){
let data:any = {}
//随机获取图片id
if(!this.moodBoards.length){ //mood没有图片
let index1 = -1
let index2 = -2
if(!this.getPinLength){ //没pin住
index1 = this.randomRange(0, this.fileList.length, -1)
index2 = this.randomRange(0, this.fileList.length, index1)
}else if(this.getPinLength === 1){ //pin住1个
this.fileList.forEach((element:any,index:number) => {
if(element.pin){
index1 = index
}
});
index2 = this.randomRange(0, this.fileList.length, index1)
}else{ //pin住多个
let selectIndexList:any = []
this.fileList.forEach((element:any,index:number) => {
if(element.pin){
selectIndexList.push(index)
}
});
index1 = this.randomRange(0, selectIndexList.length, -1) //pin住的中随机选一个
index2 = this.randomRange(0, this.fileList.length, selectIndexList[index1]) //除了选中的外再来一个
}
data = {
select1Id:this.fileList[index1].id,
select2Id:this.fileList[index2].id
}
}else{
let index1 = this.randomRange(0, this.moodBoards.length, -1)
let index2 = -2
if(!this.getPinLength){ //没pin住
index2 = this.randomRange(0, this.fileList.length, -1)
}else if(this.getPinLength === 1){ //pin住1个
this.fileList.forEach((element:any,index:number) => {
if(element.pin){
index2 = index
}
});
}else{ //pin住多个
let selectIndexList:any = []
this.fileList.forEach((element:any,index:number) => {
if(element.pin){
selectIndexList.push(index)
}
});
index2 = this.randomRange(0, selectIndexList.length, -1) //pin住的中随机选一个
}
data = {
select1Id:this.moodBoards[index1].resData.id,
select2Id:this.fileList[index2].id
}
}
data.timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone,
this.generateloading = true
Https.axiosPost(Https.httpUrls.elementGeneratePrint, data).then((rv) =>{
if(rv){
let data = {
imgUrl:rv.url,
resData:rv
}
this.printImgList.push(data)
this.store.commit('setGeneratePrintFile',this.printImgList)
this.generateloading = false
}
}).catch(res=>{
this.generateloading = false
})
},
savePrint(){
let printId = this.printImgList.map((v:any) => v.resData.id)
let data = {
printId:printId,
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
}
Https.axiosPost(Https.httpUrls.elementSavePrint, data).then((rv) =>{
if(rv){
message.success('Save successfully')
}
})
},
customRequest(data:any){
let new_data = {
...this.upload,
file:data.originFileObj
}
let fileUid = data.uid
Https.axiosPost('/api/element/upload', new_data,{headers:{'Content-Type': 'multipart/form-data'}}).then(
(rv: any) => {
if (rv) {
for(let file of this.fileList){
if(fileUid === file.uid){
file.status = 'done'
file.imgUrl = rv.url
file.pin = false
file.id = rv.id
file.resData = rv
}
}
let fileList = this.fileList.filter((v:any)=> v.status === 'done')
this.store.commit('setPrintboardFile',fileList)
}
}
).catch((res)=>{
let index = -1
this.fileList.forEach((ele:any,index1:any) => {
if(fileUid === ele.uid){
index = index1
}
});
if(index > -1){
this.fileList.splice(index, 1)
}
});
},
closeCropper(type:any){
if(this.isUpload){
return
}
if(type == 'error'){
let index = -1
this.fileList.forEach((ele:any,index1:any) => {
if(this.cropperFileData.uid === ele.uid){
index = index1
}
});
if(index > -1){
this.fileList.splice(index, 1)
}
}
let Cropper:any = this.$refs.Cropper
Cropper.closeCropper()
},
deletUploadFile(){
let index = -1
this.fileList.forEach((ele:any,index1:any) => {
if(this.cropperFileData.uid === ele.uid){
index = index1
}
});
if(index > -1){
this.fileList.splice(index, 1)
}
},
handleCropperSuccess(event:any){
let {file, fileData} =event
let new_data = {
...this.upload,
file:file
}
if(this.isUpload){
return
}
this.isUpload = true
const hide = message.loading('loading', 0);
Https.axiosPost('/api/element/upload', new_data,{headers:{'Content-Type': 'multipart/form-data'}}).then(
(rv: any) => {
for(let file of this.fileList){
if(fileData.uid === file.uid){
file.status = 'done'
file.imgUrl = rv.url
file.id = rv.id
file.resData = rv
}
}
let fileList = this.fileList.filter((v:any)=> v.status === 'done')
this.isUpload = false
this.closeCropper('success')
this.cropperFileData = {name:'',uid:''}
this.store.commit('setPrintboardFile',fileList)
hide()
}
).catch(res=>{
let index = -1
this.fileList.forEach((ele:any,index1:any) => {
if(fileData.uid === ele.uid){
index = index1
}
});
if(index > -1){
this.fileList.splice(index, 1)
}
this.cropperFileData = {name:'',uid:''}
this.isUpload = false
this.closeCropper('error')
hide()
});
},
recollection(){
let arr = JSON.parse(JSON.stringify(this.store.state.UploadFilesModule.allBoardData.printboardFiles))
let setboard = {
generate:[] as any,
material:[] as any,
moodboard:[] as any,
}
arr.forEach((v:any)=>{
if(v.type_.type1 == 'generate'){
setboard.generate.push(v)
}else if(v.type_.type1 == 'material'){
setboard.material.push(v)
}else{
setboard.moodboard.push(v)
}
})
this.store.commit("setPrintboardGenerateFiles", setboard.generate);
this.store.commit("setPrintboardMaterialFiles", setboard.material);
this.store.commit("setPrintboardFile", setboard.moodboard);
this.fileList = setboard.moodboard
// this.printImgList = JSON.parse(JSON.stringify(this.store.state.UploadFilesModule.allBoardData.generatePrintFiles))
this.store.commit('setPrintboardFile',this.fileList)
// this.store.commit('setGeneratePrintFile',this.printImgList)
},
confirmSelect(event:any){
for(let item of event){
let data = {
imgUrl:item.url,
resData:item,
pin:false,
id:item.id,
status:'done',
}
if(this.fileList.length == 15){
message.error('Maximum number of allowable file uploads has been exceeded')
break
}
this.fileList.push(data)
}
this.store.commit('setPrintboardFile',this.fileList)
},
getgenerateCheckbox(value:any){
this.generateCheckbox = value
},
getgenerate(){
let generage:any = this.$refs.Generate
let generateType = generage.checkbox.filter((v:any)=>v.type)[0].name
let data = {
generateType:generateType,
designType:'',
collectionElementId:generage.collectionElementid,
level1Type:generage.upload.level1Type,
level2Type:generage.level2Type,
// text:this.captionGeneration,
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
version:1,//为1就是Print
}
if(generateType == 'image'||generateType == 'text-image'){
if(generage.collectionElementid){
}else{
message.error(
"Please select a picture"
);
return
}
}else if(generateType == 'text'){
// this.beforeUpload(false)
// if(this.captionGeneration){
// }else{
// message.error(
// "Please enter content"
// );
// return
// }
}
if(generateType == 'text'){
data.collectionElementId = ''
data.level2Type = ''
}
Https.axiosPost(Https.httpUrls.sketchAndPrintGenerate, data).then(
(rv) => {
// if(rv){
// }
console.log(rv);
}
).catch(res=>{
});
},
generageAdd(item:any){
item.type_ = {
type1: "generate",
type2: 'Printboard',
},
this.store.commit("addGenerateMaterialFils", item);
}
}
})
</script>
<style lang="less" scoped>
.printboard_upload_modal{
// padding: 1rem 1rem 1.8rem 1rem;
height: 100%;
display: flex;
.printboard_left_upload{
// width: calc(100% - 39.8rem);
// height: 100%;
// background: #fff;
// padding: 0.5rem 2.2rem 2rem 2.6rem;
// box-sizing: border-box;
padding-top: 4rem;
width: 47%;
.switch_type_list {
display: flex;
align-items: center;
position: relative;
.switch_type_item {
display: flex;
align-items: center;
// padding: 0 2rem;
height: 4rem;
background: #fff;
border-radius: 0.8rem;
line-height: 4rem;
font-size: 1.6rem;
// margin-right: 2.2rem;
margin-right: 8rem;
color: #000;
cursor: pointer;
position: relative;
text-align: center;
transform-origin: left;
transform: scale(1);
transition: 0.3s all;
&.switch_type_item::before {
position: absolute;
content: "";
display: block;
background: #000;
height: 3px;
left: 50%;
transform: translateX(-50%);
bottom: 6px;
width: 0px;
transition: 0.3s all;
}
&.select_swtich {
color: #000;
// font-weight: 900;
transform: scale(1.15);
}
&.select_swtich::before {
width: 100%;
}
.switch_icon {
font-size: 1.8rem;
margin-right: 0.8rem;
}
}
}
.printboard_body{
height: calc(100% - 5rem);
padding-top: 2.5rem;
height: 30rem;
overflow-x: hidden;
border-right: 1px solid #e5e5e5;
&.printboard_body::-webkit-scrollbar {
display: none;
}
.upload_img_body{
height: calc(100% - 3rem);
overflow-y: auto;
margin-bottom: 1rem;
&.upload_img_body::-webkit-scrollbar {
display: none;
}
}
.upload_file_item{
margin: 0 2rem 5rem 0;
// margin: 0 2rem 2rem 0;
display: inline-block;
width: 10rem;
height: 10rem;
border: 1px solid #f5f5f5;
vertical-align: top;
position: relative;
img{
width: 100%;
height: 100%;
}
&.upload_component{
border: none;
:deep(.ant-upload-picture-card-wrapper) {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
:deep(.ant-upload-select-picture-card) {
width: 6rem;
height: 6rem;
border: 0.3rem solid #ededed;
border-radius: 10px;
margin: 0;
}
}
.checked{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
display: none;
justify-content: center;
align-items: center;
}
&.modal_img_item:hover .checked{
display: flex;
}
.upload_file_item_content{
display: flex;
align-items: center;
justify-content: center;
height: 100%;
position: relative;
cursor: pointer;
.upload_img{
display: block;
max-height: 100%;
max-width: 100%;
}
.delete_file_block{
display: none;
width: 3.2rem;
height: 3.2rem;
background: rgba(0,0,0,0.6);
border-radius: 0.4rem;
position: absolute;
top: 0.9rem;
right: 0.9rem;
text-align: center;
line-height: 3.2rem;
left: auto;
.icon-shanchu{
font-size: 1.6rem;
color: #fff;
}
}
&:hover .delete_file_block{
display: block;
}
.operate_file_block{
width: 100%;
height: 3rem;
font-size: 1.6rem;
color: #FFFFFF;
position: absolute;
left: 0;
bottom: 0;
.select_img_type{
height: 100%;
line-height: 3rem;
text-align: center;
background: rgba(0,0,0,0.6);
position: relative;
.select_category{
display: flex;
align-items: center;
justify-content: center;
.icon-xiala{
margin-left: 0.8rem;
}
}
.icon_rotate{
-moz-transform:rotate(180deg);
-webkit-transform:rotate(180deg);
transform: rotate(180deg);
animation-direction: 0.5s;
}
.category_list{
position: absolute;
width: 100%;
cursor: pointer;
position: absolute;
// top: 3.1rem;
margin-top: .2rem;
left: 0;
background: rgba(0,0,0,0.4);
border: 1px solid #343579;
border-radius: 0.8rem;
// overflow: hidden;
z-index: 2;
height: 9rem;
overflow-x: hidden;
&.category_list::-webkit-scrollbar{display: none;}
.category_item{
text-align: left;
font-size: 1.4rem;
padding: 1rem 1.9rem;
line-height: 1.6rem;
&.select_category_item{
background: linear-gradient(160deg, #AC2A3B, #292161);
}
&:hover{
background: linear-gradient(160deg, #AC2A3B, #292161);
}
}
}
}
}
}
.upload_img_icon{
width: 4.6rem;
}
}
}
}
.modal_right{
flex: 1;
margin-left: 3rem;
display: flex;
flex-direction: column;
.modal_layout,.modal_accomplish{
.modal_text{
font-size: 1.2rem;
font-weight: 400;
color: rgba(0, 0, 0, 0.45);
display: flex;
align-items: center;
justify-content: space-between;
}
}
.modal_layout{
.modal_img{
width: 40rem;
height: 5rem;
overflow-x: hidden;
display: flex;
flex-direction: row;
&.modal_img::-webkit-scrollbar {
display: none;
}
.modal_img_item{
width: 4rem;
height: 4rem;
margin: 0 1rem 1rem 0;
position: relative;
cursor: pointer;
img{
width: 100%;
height: 100%;
}
.checked{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
display: none;
justify-content: center;
align-items: center;
}
&.modal_img_item:hover .checked{
display: flex;
}
}
}
}
.modal_accomplish{
// margin-top: 2rem;
height: 30rem;
display: flex;
flex-direction: column;
flex: 1;
overflow-x: hidden;
&.modal_accomplish::-webkit-scrollbar {
display: none;
}
.modal_text{
padding-top: 2rem;
padding-block: 2rem;
}
.input_box{
input{
&.forbidden{
}
}
}
.modal_img{
flex: 1;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
.modal_imgItem{
margin: 0 2rem 5rem 0;
display: inline-block;
width: 10rem;
height: 10rem;
border: 1px solid #f5f5f5;
position: relative;
cursor: pointer;
img{
object-fit: cover;
width: 100%;
height: 100%;
}
&.active{
opacity: 0.5;
// border: 2px solid;
border-radius: 1rem;
img {
transform: scale(0.9);
}
}
}
}
}
}
}
</style>