mirror of
https://github.com/palxiao/poster-design.git
synced 2025-06-20 15:42:53 +08:00
310 lines
8.2 KiB
Vue
310 lines
8.2 KiB
Vue
<!--
|
|
* @Author: ShawnPhang
|
|
* @Date: 2022-02-13 22:18:35
|
|
* @Description: 我的
|
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
|
* @LastEditTime: 2024-03-11 01:42:44
|
|
-->
|
|
<template>
|
|
<div class="wrap">
|
|
<el-tabs v-model="state.tabActiveName" :stretch="true" class="tabs" @tab-change="tabChange">
|
|
<el-tab-pane label="资源管理" name="pics"> </el-tab-pane>
|
|
<el-tab-pane label="我的作品" name="design"> </el-tab-pane>
|
|
</el-tabs>
|
|
<div v-show="state.tabActiveName === 'pics'">
|
|
<uploader v-model="state.percent" class="upload" @done="uploadDone">
|
|
<el-button class="upload-btn" plain>上传图片 <i class="iconfont icon-upload" /></el-button>
|
|
</uploader>
|
|
<el-button class="upload-btn upload-psd" plain type="primary" @click="openPSD">上传 PSD 模板</el-button>
|
|
<div style="margin: 1rem; height: 100vh">
|
|
<photo-list
|
|
ref="imgListRef"
|
|
:edit="state.editOptions.photo" :isDone="state.isDone"
|
|
:listData="state.imgList"
|
|
@load="load" @drag="dragStart" @select="selectImg"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div v-show="state.tabActiveName === 'design'" class="wrap">
|
|
<ul ref="listRef" v-infinite-scroll="loadDesign" class="infinite-list" :infinite-scroll-distance="150" style="overflow: auto">
|
|
<img-water-fall :edit="state.editOptions.works" :listData="state.designList" @select="selectDesign" />
|
|
<!-- <div v-show="loading" class="loading"><i class="el-icon-loading"></i>拼命加载中..</div> -->
|
|
<div v-show="state.isDone" class="loading">全部加载完毕</div>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { reactive, toRefs, watch, nextTick, ref, onMounted } from 'vue'
|
|
import { ElTabPane, ElTabs, TabPaneName } from 'element-plus'
|
|
import { useRouter } from 'vue-router'
|
|
// import { useStore } from 'vuex'
|
|
import uploader from '@/components/common/Uploader'
|
|
import api from '@/api'
|
|
// import wImage from '../../widgets/wImage/wImage.vue'
|
|
import wImageSetting from '../../widgets/wImage/wImageSetting'
|
|
import setImageData, { TItem2DataParam } from '@/common/methods/DesignFeatures/setImage'
|
|
import useConfirm from '@/common/methods/confirm'
|
|
import { TGetImageListResult, TMyPhotoResult } from '@/api/material'
|
|
import photoList from './components/photoList.vue'
|
|
import imgWaterFall from './components/imgWaterFall.vue'
|
|
import { TUploadDoneData } from '@/components/common/Uploader/index.vue'
|
|
import { IGetTempListData } from '@/api/home'
|
|
import eventBus from '@/utils/plugins/eventBus'
|
|
import { storeToRefs } from 'pinia'
|
|
import { useControlStore, usePageStore, useWidgetStore } from '@/store'
|
|
|
|
type TProps = {
|
|
active?: number
|
|
}
|
|
|
|
type TState = {
|
|
prePath: string,
|
|
percent: { num: number }, // 当前上传进度
|
|
imgList: IGetTempListData[],
|
|
designList: IGetTempListData[],
|
|
isDone: boolean,
|
|
editOptions: Record<string, any>,
|
|
tabActiveName: string,
|
|
}
|
|
|
|
const props = defineProps<TProps>()
|
|
|
|
const router = useRouter()
|
|
|
|
// const store = useStore()
|
|
const controlStore = useControlStore()
|
|
const widgetStore = useWidgetStore()
|
|
|
|
const { dPage } = storeToRefs(usePageStore())
|
|
const listRef = ref<HTMLElement | null>(null)
|
|
const imgListRef = ref<typeof photoList | null>(null)
|
|
|
|
const state = reactive<TState>({
|
|
prePath: 'user',
|
|
percent: { num: 0 }, // 当前上传进度
|
|
imgList: [],
|
|
designList: [],
|
|
isDone: false,
|
|
editOptions: [],
|
|
tabActiveName: '',
|
|
})
|
|
|
|
let loading = false
|
|
let page = 0
|
|
let listPage = 0
|
|
|
|
const load = (init?: boolean) => {
|
|
if (init) {
|
|
state.imgList = []
|
|
page = 0
|
|
state.isDone = false
|
|
}
|
|
if (state.isDone || loading) {
|
|
return
|
|
}
|
|
loading = true
|
|
page += 1
|
|
api.material.getMyPhoto({ page }).then(({ list }) => {
|
|
|
|
if (list.length <= 0) {
|
|
state.isDone = true
|
|
} else {
|
|
state.imgList = state.imgList.concat(list)
|
|
}
|
|
setTimeout(() => {
|
|
loading = false
|
|
if (!imgListRef.value) return
|
|
checkHeight(imgListRef.value.getRef(), load)
|
|
}, 100)
|
|
})
|
|
}
|
|
|
|
const loadDesign = (init: boolean = false) => {
|
|
if (init) {
|
|
state.designList = []
|
|
listPage = 0
|
|
state.isDone = false
|
|
}
|
|
if (state.isDone || loading) {
|
|
return
|
|
}
|
|
loading = true
|
|
listPage += 1
|
|
api.home.getMyDesign({ page: listPage, pageSize: 10 }).then(({ list }) => {
|
|
list.length <= 0
|
|
? (state.isDone = true)
|
|
: (state.designList = state.designList.concat(
|
|
list.map((x) => {
|
|
x.cover = x.cover + '?r=' + Math.random()
|
|
return x
|
|
}),
|
|
))
|
|
setTimeout(() => {
|
|
loading = false
|
|
if (!listRef.value) return
|
|
checkHeight(listRef.value, loadDesign)
|
|
}, 100)
|
|
})
|
|
}
|
|
|
|
function checkHeight(el: HTMLElement, loadFn: Function) {
|
|
// 检查高度是否占满,否则继续请求下一页
|
|
if (el.offsetHeight && el.firstElementChild) {
|
|
const isLess = el.offsetHeight > (el.firstElementChild as HTMLElement).offsetHeight
|
|
isLess && loadFn()
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
load(true)
|
|
nextTick(() => {
|
|
state.tabActiveName = 'pics'
|
|
})
|
|
})
|
|
|
|
const selectImg = async (index: number) => {
|
|
const item = state.imgList[index]
|
|
|
|
// store.commit('setShowMoveable', false) // 清理掉上一次的选择
|
|
controlStore.setShowMoveable(false) // 清理掉上一次的选择
|
|
|
|
let setting = JSON.parse(JSON.stringify(wImageSetting))
|
|
const img = await setImageData(item)
|
|
setting.width = img.width
|
|
setting.height = img.height // parseInt(100 / item.value.ratio, 10)
|
|
setting.imgUrl = item.url
|
|
const { width: pW, height: pH } = dPage.value
|
|
setting.left = pW / 2 - img.width / 2
|
|
setting.top = pH / 2 - img.height / 2
|
|
|
|
widgetStore.addWidget(setting)
|
|
// store.dispatch('addWidget', setting)
|
|
}
|
|
|
|
type controlImgParam = {
|
|
i: number
|
|
item: Required<TItem2DataParam>
|
|
}
|
|
|
|
const deleteImg = async ({ i, item }: controlImgParam) => {
|
|
|
|
// store.commit('setShowMoveable', false) // 清理掉上一次的选择框
|
|
controlStore.setShowMoveable(false) // 清理掉上一次的选择框
|
|
|
|
const isPass = await useConfirm('警告', '删除后不可找回,已引用资源将会失效,请谨慎操作', 'warning')
|
|
if (!isPass) {
|
|
return false
|
|
}
|
|
const arr = item.url.split('/')
|
|
let key = arr.splice(3, arr.length - 1).join('/')
|
|
api.material.deleteMyPhoto({ id: item.id, key })
|
|
if (!imgListRef.value) return
|
|
imgListRef.value.delItem(i) // 通知标记
|
|
}
|
|
const deleteWorks = async ({ i, item }: controlImgParam) => {
|
|
const isPass = await useConfirm('警告', '删除后不可找回,请确认操作', 'warning')
|
|
if (isPass) {
|
|
await api.material.deleteMyWorks({ id: item.id })
|
|
setTimeout(() => {
|
|
router.push({ path: '/home', query: { }, replace: true })
|
|
loadDesign(true)
|
|
}, 300);
|
|
}
|
|
}
|
|
|
|
state.editOptions = {
|
|
photo: [
|
|
{
|
|
name: '删除',
|
|
fn: deleteImg,
|
|
},
|
|
],
|
|
works: [
|
|
{
|
|
name: '删除',
|
|
fn: deleteWorks,
|
|
},
|
|
]
|
|
}
|
|
|
|
const dragStart = (index: number) => {
|
|
const item = state.imgList[index]
|
|
widgetStore.setSelectItem({ data: { value: item }, type: 'image' })
|
|
// store.commit('selectItem', { data: { value: item }, type: 'image' })
|
|
}
|
|
const uploadDone = async (res: TUploadDoneData) => {
|
|
await api.material.addMyPhoto(res)
|
|
state.imgList = []
|
|
load(true)
|
|
}
|
|
|
|
const tabChange = (tabName: TabPaneName) => {
|
|
if (tabName === 'design') {
|
|
loadDesign(true)
|
|
}
|
|
}
|
|
|
|
const selectDesign = async (item: IGetTempListData) => {
|
|
// const { id }: any = state.designList[index]
|
|
const { id } = item
|
|
window.open(`${window.location.protocol + '//' + window.location.host}/home?id=${id}`)
|
|
}
|
|
|
|
const openPSD = () => {
|
|
window.open(router.resolve('/psd').href, '_blank')
|
|
}
|
|
|
|
eventBus.on('refreshUserImages', () => {
|
|
state.imgList = []
|
|
load(true)
|
|
})
|
|
|
|
defineExpose({
|
|
selectDesign,
|
|
loadDesign,
|
|
load,
|
|
uploadDone,
|
|
selectImg,
|
|
deleteImg,
|
|
dragStart,
|
|
tabChange,
|
|
openPSD,
|
|
})
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.infinite-list {
|
|
height: 100%;
|
|
padding-bottom: 150px;
|
|
}
|
|
.loading {
|
|
padding-top: 1rem;
|
|
text-align: center;
|
|
font-size: 14px;
|
|
color: #999;
|
|
}
|
|
|
|
.tabs {
|
|
padding: 0.2rem 0;
|
|
}
|
|
.upload {
|
|
width: auto;
|
|
margin: 0 0 0 1rem;
|
|
display: inline-block;
|
|
&-btn {
|
|
width: 160px;
|
|
font-size: 14px;
|
|
}
|
|
&-psd {
|
|
width: 124px;
|
|
margin-left: 10px;
|
|
}
|
|
}
|
|
.wrap {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
</style>
|