From 55bd7fb6365909a0cbcf0957333c7876bd791bb9 Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期四, 21 十一月 2024 16:35:12 +0800 Subject: [PATCH] 问题整改界面 1. 优化各项状态展示效果 2. 新增左侧关键字筛选功能 --- src/components/FYImageSelectDialog.vue | 284 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 256 insertions(+), 28 deletions(-) diff --git a/src/components/FYImageSelectDialog.vue b/src/components/FYImageSelectDialog.vue index f9f249c..e12c42f 100644 --- a/src/components/FYImageSelectDialog.vue +++ b/src/components/FYImageSelectDialog.vue @@ -1,23 +1,24 @@ <template> <el-dialog - v-model="anyPhotoDialog" + :model-value="dialogVisible" + @opened="handleOpen" + @closed="handleClose" width="66%" - title="浠绘剰鍥剧墖" destroy-on-close > <div class="main"> - <el-row justify="end" class="btns" v-if="!readonly"> + <el-row justify="end" v-if="!readonly"> <el-text size="small" type="info" class="m-r-8" >鏈�澶氶�夋嫨{{ maxSelect }}寮犲浘鐗�</el-text > <el-button size="small" type="primary" - @click="sendSelectedImg(true)" + @click="handleSubmit" :disabled="selectedImgUrlList.length == 0" >纭畾</el-button > - <el-button size="small" type="primary" @click="sendSelectedImg(false)" + <el-button size="small" type="primary" @click="handleCancel" >鍙栨秷</el-button > </el-row> @@ -28,35 +29,51 @@ v-for="item in typeList" :key="item.typeId" :label=" - item.typeName + ' (' + typeImgMap.get(activeId).length + ')' + item.typeName + ' (' + typeImgMap.get(item.typeId).length + ')' " :name="item.typeId" > </el-tab-pane> </el-tabs> - <el-empty v-if="isEmpty" description="鏆傛棤璁板綍" /> - <el-scrollbar class="imgs"> + <el-scrollbar + v-if="typeImgMap.get(activeId) && typeImgMap.get(activeId).length > 0" + class="imgs" + > <el-image + v-loading="img.loading" v-for="(img, i) in typeImgMap.get(activeId)" :key="i" :class="[img.isSelect ? 'selected' : 'noActive', 'image']" fit="cover" :src="img.url" - lazy @click="onSelect(img, i)" + @load="onOneImgLoadSuccess(img)" + @error="onOneImgLoadError(img)" /> </el-scrollbar> + <el-row v-else justify="space-between"> + <el-empty description="鏆傛棤璁板綍" /> + </el-row> </div> </div> </el-dialog> </template> <script setup> -import { ref, watch } from 'vue'; +import { ref, watch, computed, onMounted, onUnmounted } from 'vue'; const props = defineProps({ + dialogVisible: Boolean, + /** + * 鍥剧墖鍒嗙被 + * 缁撴瀯{ typeId, typeName } + */ typeList: { type: Array, default: () => [] + }, + typeImgMap: { + type: Array, + default: () => new Map() }, // 鏄惁浠ュ彧璇荤殑褰㈠紡鏌ョ湅褰撳墠椤甸潰 readonly: { @@ -74,26 +91,237 @@ } }); -const activeId = ref(''); -const typeImgMap = ref(new Map()); -const selectedImgList = ref([]); +const emit = defineEmits(['submit', 'cancel', 'update:dialogVisible']); -watch(typeImgMap, (newMap, oldMap) => { - if (newMap.get(activeId.value) == undefined) { - return; +const activeId = ref(''); +// const typeImgMap = ref(new Map()); +const selectedImgUrlList = ref([]); + +let loadedImgCount = ref(0); +// 鍔犺浇鐘舵�� +const loading = computed(() => { + if (activeId.value == '') { + return false; } - newMap.get(activeId.value).forEach( - (i) => { - if (i.isSelect == true) { - return; - } - props.defaultFile.forEach((imgItem) => { - if (imgItem.url == i.url) { - i.isSelect = true; - } - }); - }, - { deep: true } + // 淇濊瘉鏈�寮�濮嬫槸鍔犺浇鐘舵�侊紝涓夊垎涔嬩竴鍔犺浇涔嬪悗鍋滄灞曠ず鍔犺浇鐘舵�� + return !( + props.typeImgMap.get(activeId.value).length / 3 <= + loadedImgCount.value ); }); +function onOneImgLoadError(img) { + img.loading = false + loadedImgCount.value++; +} +function onOneImgLoadSuccess(img) { + img.loading = false + loadedImgCount.value++; +} +watch( + () => activeId.value, + (nV, oV) => { + loadedImgCount.value = 0; + }, + { immediate: true } +); + +function onSelect(img, i) { + if (props.readonly) { + return; + } + const imgList = selectedImgUrlList.value; + const index = imgList.indexOf(img); + if (index == -1) { + if (props.maxSelect == 1) { + img.isSelect = true; + imgList.push(img); + if (imgList.length > 1) { + imgList.splice(0, 1).forEach((e) => { + e.isSelect = false; + }); + } + } else if (props.maxSelect > 1) { + if (imgList.length < props.maxSelect) { + img.isSelect = true; + imgList.push(img); + } + } + } else { + imgList.splice(index, 1); + img.isSelect = false; + } +} +function handleOpen() { + // if (props.typeImgMap.get(activeId.value) == undefined) { + // return; + // } + // props.typeImgMap.get(activeId.value).forEach((i) => { + // if (i.isSelect == true) { + // return; + // } + // props.defaultFile.forEach((imgItem) => { + // if (imgItem.url == i.url) { + // i.isSelect = true; + // selectedImgUrlList.value.push(i); + // } + // }); + // }); + emit('update:dialogVisible', true) +} +function handleClose() { + selectedImgUrlList.value.forEach(item => item.isSelect = false) + selectedImgUrlList.value = [] + emit('update:dialogVisible', false) +} +function handleSubmit() { + emit('submit', selectedImgUrlList.value); + emit('update:dialogVisible', false); +} + +function handleCancel() { + emit('cancel'); + emit('update:dialogVisible', false); +} + +watch( + () => props.typeList, + (nV, oV) => { + if (nV != oV && nV.length > 0) { + activeId.value = nV[0].typeId; + } + }, + { immediate: true } +); +// watch( +// () => props.defaultFile, +// (nV, oV) => { +// if (props.typeImgMap.get(activeId.value) == undefined) { +// return; +// } +// props.typeImgMap.get(activeId.value).forEach((i) => { +// if (i.isSelect == true) { +// return; +// } +// nV.forEach((imgItem) => { +// if (imgItem.url == i.url) { +// i.isSelect = true; +// selectedImgUrlList.value.push(i); +// } +// }); +// }); +// }, +// { deep: true, immediate: true } +// ); + +// watch( +// () => props.typeImgMap, +// (newMap, oldMap) => { +// if (newMap.get(activeId.value) == undefined) { +// return; +// } +// newMap.get(activeId.value).forEach((i) => { +// if (i.isSelect == true) { +// return; +// } +// props.defaultFile.forEach((imgItem) => { +// if (imgItem.url == i.url) { +// i.isSelect = true; +// selectedImgUrlList.value.push(i); +// } +// }); +// }); +// }, +// { immediate: true } +// ); </script> +<style scoped> +.center { + display: flex; + flex-direction: column; + align-items: center; +} +.text { + padding: 20px; +} + +.main { + margin: 0 auto; /* 浣跨埗鍏冪礌灞呬腑 */ + height: 72vh; + width: 100%; +} + +.imgs { + height: 60vh; + width: 100%; + min-height: 100px !important; + /* border-style:solid; + border-radius: 1px; */ + /* height: 100%; */ + flex-grow: 1 !important; + overflow-y: auto !important; + /* 鍐呭鐨勫唴杈硅窛 */ + display: flex !important; + flex-wrap: wrap !important; + /* overflow: hidden; */ +} + +.image { + margin: 5px; + height: 210px; + width: 200px; + border-radius: 4px; +} + +.active { + padding: 5px; + width: 20%; + height: 200px; + border: 0.5rem outset rgb(52, 155, 4); +} + +.selected { + margin: 3px; + color: #4abe84; + box-shadow: 0 2px 7px 0 rgba(85, 110, 97, 0.35); + border: 2px solid rgba(74, 190, 132, 1); +} + +.selected:before { + content: ''; + position: absolute; + right: 0; + bottom: 0; + border: 17px solid #4abe84; + border-top-color: transparent; + border-left-color: transparent; +} + +.selected:after { + content: ''; + width: 5px; + height: 12px; + position: absolute; + right: 6px; + bottom: 6px; + border: 2px solid #fff; + border-top-color: transparent; + border-left-color: transparent; + transform: rotate(45deg); +} + +.noActive { + /* padding: 5px; */ +} + +.blurry { + filter: blur(3px); +} +.filters { + display: flex; + padding: 5px; +} + +::v-deep .el-dialog__body { + padding: 10px calc(var(--el-dialog-padding-primary) + 10px) !important; +} +</style> -- Gitblit v1.9.3