468 lines
11 KiB
Vue
468 lines
11 KiB
Vue
<script setup lang="ts">
|
|
import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
|
|
import { VueDraggable } from "vue-draggable-plus"
|
|
import contentItem from "./contentItem.vue"
|
|
import selectMenu from '@/component/modules/selectMenu.vue'
|
|
import deleteDrafts from './deleteDrafts.vue'
|
|
import { Https } from '@/tool/https'
|
|
import { message } from 'ant-design-vue'
|
|
import { useRouter } from 'vue-router'
|
|
|
|
//const props = defineProps({
|
|
//})
|
|
//const emit = defineEmits([
|
|
//])
|
|
let data = reactive({
|
|
showDrafts: false,
|
|
})
|
|
const publishData = reactive({
|
|
pageSize: 10,
|
|
pageNum: 1,
|
|
isShowMark:false,
|
|
isNoData:false,
|
|
})
|
|
const noPublishData = reactive({
|
|
pageSize: 10,
|
|
pageNum: 1,
|
|
isShowMark:false,
|
|
isNoData:false,
|
|
})
|
|
const list = ref([
|
|
])
|
|
const list2 = ref([
|
|
])
|
|
const config = ref({
|
|
"data-container-type": "root",
|
|
"data-parent-id": "null",
|
|
animation: 250,
|
|
handle: ".item", // 可拖动的元素
|
|
"ghost-class": "ghost", // 拖动时的类名
|
|
"chosen-class": "chosen", // 选中时的类名
|
|
"drag-class": "drag", // 拖动时的类名
|
|
"swap-threshold": 0.5,
|
|
"empty-insert-threshold": 5,
|
|
"force-fallback": false,
|
|
"fallback-tolerance": 3,
|
|
"scroll-sensitivity": 100,
|
|
"scroll-speed": 10,
|
|
onEnd: (e) => {}
|
|
})
|
|
const domSize = ref('Small')
|
|
const domSizeList = ref([
|
|
{
|
|
label:'Small',
|
|
value:'Small',
|
|
},
|
|
{
|
|
label:'Medium',
|
|
value:'Medium',
|
|
},
|
|
{
|
|
label:'Large',
|
|
value:'Large',
|
|
},
|
|
])
|
|
|
|
const visible = ref(false)
|
|
const deleteDraftsRef = ref(null)
|
|
const router = useRouter()
|
|
|
|
const deleteDraft = (item: any)=>{
|
|
deleteDraftsRef.value.open(item,()=>{
|
|
putListingStatus(item,2).then(()=>{
|
|
list2.value = list2.value.filter((v: any)=>v.id != item.id)
|
|
})
|
|
})
|
|
}
|
|
|
|
const vObserve = {
|
|
mounted (el,binding) {
|
|
// console.log(binding.instance);
|
|
data.isShowMark = false
|
|
data.isNoData = false
|
|
let parentDom = el.parentNode
|
|
new IntersectionObserver(
|
|
(entries, observer) => {
|
|
// 如果不是相交,则直接返回
|
|
// console.log(entries[0]);
|
|
if (!entries[0].intersectionRatio) return;
|
|
data.pageNum += 1
|
|
binding.value()
|
|
},
|
|
// { root:worksPage }
|
|
).observe(el);
|
|
}
|
|
}
|
|
|
|
const getPublishedData = async ()=>{
|
|
if(publishData.isShowMark && !publishData.isNoData)return
|
|
publishData.isShowMark = true
|
|
let value = {
|
|
pageSize: publishData.pageSize,
|
|
pageNum: publishData.pageNum,
|
|
status: 1,
|
|
}
|
|
await getPublishList(value).then((res)=>{
|
|
if(res.content.length == 0)publishData.isNoData = true
|
|
publishData.pageNum += 1
|
|
list.value.push(...res.content)
|
|
})
|
|
publishData.isShowMark = false
|
|
}
|
|
const getNoPublishedData = async ()=>{
|
|
if(noPublishData.isShowMark && !noPublishData.isNoData)return
|
|
noPublishData.isShowMark = true
|
|
let value = {
|
|
pageSize: noPublishData.pageSize,
|
|
pageNum: noPublishData.pageNum,
|
|
status: 0,
|
|
}
|
|
await getPublishList(value).then((res)=>{
|
|
if(res.content.length == 0)noPublishData.isNoData = true
|
|
noPublishData.pageNum += 1
|
|
list2.value.push(...res.content)
|
|
})
|
|
noPublishData.isShowMark = false
|
|
}
|
|
const getPublishList = (data:any)=>{
|
|
return new Promise<void>((resolve, reject) => {
|
|
Https.axiosGet(Https.httpUrls.getListingList,{params:data}).then((res:any)=>{
|
|
resolve(res)
|
|
}).catch((err:any)=>{
|
|
reject(err)
|
|
})
|
|
})
|
|
}
|
|
|
|
const putListingStatus = async (item,status:number)=>{
|
|
return new Promise<void>((resolve, reject) => {
|
|
let data = {
|
|
id:item.id,
|
|
status:status,
|
|
}
|
|
Https.axiosPut(Https.httpUrls.putListingStatus,data).then((res:any)=>{
|
|
resolve(res)
|
|
}).catch((err:any)=>{
|
|
reject(err)
|
|
})
|
|
})
|
|
}
|
|
|
|
|
|
const draftListing = async (item: any)=>{
|
|
//数组前面添加item
|
|
await putListingStatus(item,0).then(()=>{
|
|
list2.value.unshift(item)
|
|
list.value = list.value.filter((v: any)=>v.id != item.id)
|
|
})
|
|
message.success('Product moved to drafts and stats reset.')
|
|
}
|
|
|
|
const publishListing = async (item: any)=>{
|
|
await putListingStatus(item,1).then(()=>{
|
|
list.value.unshift(item)
|
|
list2.value = list2.value.filter((v: any)=>v.id != item.id)
|
|
})
|
|
message.success('Item is now live on the Marketplace.')
|
|
}
|
|
|
|
const editListing = (item: any)=>{
|
|
router.push({
|
|
path:'/home/seller/myListings/edit',
|
|
state: {
|
|
id:item.id,
|
|
type:'edit'
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
const listingsBoxRef = ref(null) as any
|
|
let resizeObserver = null as any
|
|
|
|
const gap = ref({
|
|
Small: '16px',
|
|
Medium: '24px',
|
|
Large: '30px',
|
|
})
|
|
|
|
//根据宽度设置列表宽度
|
|
let upDataDomWidthTime = null
|
|
const setDomSize = (width: number)=>{
|
|
if(!listingsBoxRef.value)return
|
|
let listDom = listingsBoxRef.value.querySelector('.list')
|
|
let listItemDom = listDom.querySelector('.item')
|
|
let offsetWidth = listItemDom?.getBoundingClientRect?.()?.width
|
|
let lineNum = Math.floor(width / offsetWidth)
|
|
let itemNum = Math.floor((width - (lineNum - 1) * parseInt(gap.value[domSize.value])) / offsetWidth)
|
|
listDom.style.maxWidth = ((itemNum - 1) * parseInt(gap.value[domSize.value]) + itemNum * (offsetWidth)) + 'px'
|
|
}
|
|
|
|
const changeDomSize = ()=>{
|
|
setTimeout(()=>{
|
|
setDomSize(listingsBoxRef.value.clientWidth)
|
|
},350)
|
|
}
|
|
|
|
const unfoldDrafits = ()=>{
|
|
data.showDrafts = !data.showDrafts
|
|
}
|
|
onMounted(()=>{
|
|
// 创建观察器
|
|
nextTick(()=>{
|
|
resizeObserver = new ResizeObserver((entries) => {
|
|
for (const entry of entries) {
|
|
const width = entry.contentRect.width
|
|
if(upDataDomWidthTime)clearTimeout(upDataDomWidthTime)
|
|
upDataDomWidthTime = setTimeout(()=>{
|
|
setDomSize(width)
|
|
},200)
|
|
}
|
|
})
|
|
// 开始监听
|
|
if(resizeObserver)resizeObserver.observe(listingsBoxRef.value)
|
|
})
|
|
})
|
|
onUnmounted(()=>{
|
|
// 停止监听
|
|
if(listingsBoxRef?.value)resizeObserver?.unobserve(listingsBoxRef?.value)
|
|
})
|
|
defineExpose({})
|
|
const { showDrafts } = toRefs(data);
|
|
</script>
|
|
<template>
|
|
<div class="listings">
|
|
<div class="listingsBox listingsBox1">
|
|
<div class="box" :class="domSize" ref="listingsBoxRef">
|
|
<div class="title">
|
|
<div class="left">
|
|
<i class="fi fi-rs-comments"></i>
|
|
<span>Active Listings</span>
|
|
</div>
|
|
<div class="right">
|
|
<div class="generalModel_state">
|
|
<div>
|
|
<selectMenu
|
|
:selectList="domSizeList"
|
|
@change="changeDomSize"
|
|
:isBtnOpen='true'
|
|
:style="{
|
|
'border-radius':'0rem',
|
|
'border':'none',
|
|
'font-weight': '900',
|
|
'line-height': '3rem',
|
|
'height': '3rem',
|
|
'background': 'rgba(0,0,0,0)',
|
|
}"
|
|
v-model:select="domSize"
|
|
>
|
|
<template v-slot:btnText>
|
|
{{ $t('Header.Size') }}
|
|
</template>
|
|
</selectMenu>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<VueDraggable
|
|
v-model="list"
|
|
class="list"
|
|
:style="{gap: gap[domSize] || '1.6rem'}"
|
|
v-bind="config"
|
|
:group="{
|
|
name: 'sortable',
|
|
pull: false,
|
|
put: true
|
|
}"
|
|
>
|
|
|
|
<contentItem
|
|
v-for="v in list"
|
|
:key="v.id"
|
|
:item="v"
|
|
type="listings"
|
|
:domSize="domSize"
|
|
@draftListing="draftListing"
|
|
@editListing="editListing"
|
|
/>
|
|
<div v-show="!publishData.isNoData" class="material_content_list_loding">
|
|
<span class="page_loading" v-show="!publishData.isShowMark" v-observe="getPublishedData"></span>
|
|
<span v-show="publishData.isShowMark">
|
|
<a-spin size="large" />
|
|
</span>
|
|
</div>
|
|
</VueDraggable>
|
|
</div>
|
|
<div class="openOrCloseDrafts" :class="{'active': showDrafts}" @click="unfoldDrafits">
|
|
<span class="icon iconfont icon-xiala"></span>
|
|
</div>
|
|
</div>
|
|
<div class="listingsBox listingsBox2" :class="{'active': showDrafts}">
|
|
<div class="box Small">
|
|
<div class="title">
|
|
<div class="left">
|
|
<i class="fi fi-rs-comments"></i>
|
|
<span>Drafts</span>
|
|
</div>
|
|
</div>
|
|
<VueDraggable
|
|
v-model="list2"
|
|
class="list2"
|
|
v-bind="config"
|
|
:group="{
|
|
name: 'sortable',
|
|
pull: false,
|
|
put: true
|
|
}"
|
|
>
|
|
<contentItem
|
|
v-for="v in list2"
|
|
:key="v.id"
|
|
:item="v"
|
|
domSize="Small"
|
|
type="drafts"
|
|
@deleteDraft="deleteDraft"
|
|
@editListing="editListing"
|
|
@publishListing="publishListing"
|
|
/>
|
|
<div v-show="!noPublishData.isNoData" class="material_content_list_loding">
|
|
<span class="page_loading" v-show="!noPublishData.isShowMark" v-observe="getNoPublishedData"></span>
|
|
<span v-show="noPublishData.isShowMark">
|
|
<a-spin size="large" />
|
|
</span>
|
|
</div>
|
|
</VueDraggable>
|
|
</div>
|
|
</div>
|
|
<deleteDrafts ref="deleteDraftsRef" v-model:visible="visible"></deleteDrafts>
|
|
</div>
|
|
</template>
|
|
<style lang="less" scoped>
|
|
.listings{
|
|
position: absolute;
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
gap: 2rem;
|
|
.listingsBox{
|
|
background-color: #f9fafa;
|
|
border-radius: 2rem;
|
|
position: relative;
|
|
// overflow: hidden;
|
|
display: flex;
|
|
transition: all .3s;
|
|
.box{
|
|
width: 100%;
|
|
padding: 2.4rem 0;
|
|
padding-bottom: 0;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex: 1;
|
|
padding: 2.4rem 4rem;
|
|
> .title{
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 3rem;
|
|
> .left{
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
font-family: pingfang_heavy;
|
|
font-weight: 400;
|
|
font-size: 1.8rem;
|
|
line-height: 130%;
|
|
letter-spacing: 0%;
|
|
gap: 1.2rem;
|
|
align-content: flex-start;
|
|
> i{
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
font-size: 2.4rem;
|
|
}
|
|
}
|
|
}
|
|
.list2{
|
|
gap: 1.6rem;
|
|
width: 100%;
|
|
.item{
|
|
width: 19.2rem;
|
|
}
|
|
}
|
|
.list,.list2{
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
// flex: 1;
|
|
margin: 0 auto;
|
|
align-items: flex-start;
|
|
overflow: auto;
|
|
&::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
> .material_content_list_loding{
|
|
width: 100%;
|
|
height: 5rem;
|
|
aspect-ratio: 1/1;
|
|
overflow: hidden;
|
|
display: flex;
|
|
justify-content: center;
|
|
> img{
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: contain;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.listingsBox1{
|
|
width: 100%;
|
|
flex: 1;
|
|
}
|
|
.listingsBox2{
|
|
width: 48.8rem;
|
|
overflow: hidden;
|
|
&.active{
|
|
width: 0;
|
|
}
|
|
.box{
|
|
width: 48.8rem;
|
|
}
|
|
}
|
|
.openOrCloseDrafts{
|
|
position: absolute;
|
|
width: 3.4rem;
|
|
height: 8rem;
|
|
border-top-right-radius: 2rem;
|
|
border-bottom-right-radius: 2rem;
|
|
border-width: 1.5px, 1.5px, 1.5px, 0px;
|
|
border-style: solid;
|
|
border-color: #000000;
|
|
right: 1.5px;
|
|
top: 50%;
|
|
transform: translate(100%,-50%);
|
|
cursor: pointer;
|
|
transition: all 0.3s ease-in-out;
|
|
border-left: none;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background-color: #fff;
|
|
z-index: 2;
|
|
> span{
|
|
transform: rotate(-90deg);
|
|
transition: all .3s;
|
|
}
|
|
&.active{
|
|
> span{
|
|
transform: rotate(90deg);
|
|
}
|
|
}
|
|
&:hover{
|
|
width: 4.5rem;
|
|
}
|
|
}
|
|
}
|
|
</style> |