From d1ce79c837650689ab47bbf587d076743fcb3a5f Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期一, 19 五月 2025 17:25:38 +0800 Subject: [PATCH] 1. 问题审核界面新增场景信息编辑入口 2. 问题审核界面场景图片查询新增图片类型修改功能 --- src/components/FYImageSelectDialog.vue | 282 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 235 insertions(+), 47 deletions(-) diff --git a/src/components/FYImageSelectDialog.vue b/src/components/FYImageSelectDialog.vue index f9f249c..6e283c3 100644 --- a/src/components/FYImageSelectDialog.vue +++ b/src/components/FYImageSelectDialog.vue @@ -1,99 +1,287 @@ <template> <el-dialog - v-model="anyPhotoDialog" - width="66%" - title="浠绘剰鍥剧墖" + :model-value="dialogVisible" + @opened="handleOpen" + @closed="handleClose" + top="5vh" + width="68%" destroy-on-close + :close-on-press-escape="false" > - <div class="main"> - <el-row justify="end" class="btns" v-if="!readonly"> + <el-row justify="end"> + <el-text v-if="onContextMenu != undefined" size="small" type="info">{{ + `锛�${contextMenuStr}锛塦 + }}</el-text> + <div 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> + </div> + </el-row> - <div class="center"> - <el-tabs v-if="typeList.length > 0" v-model="activeId" type="card"> - <el-tab-pane - v-for="item in typeList" - :key="item.typeId" - :label=" - item.typeName + ' (' + typeImgMap.get(activeId).length + ')' - " - :name="item.typeId" - > - </el-tab-pane> - </el-tabs> - <el-empty v-if="isEmpty" description="鏆傛棤璁板綍" /> - <el-scrollbar class="imgs"> + <div class="center"> + <el-tabs v-if="typeList.length > 0" v-model="activeId" type="card"> + <el-tab-pane + v-for="item in typeList" + :key="item.typeId" + :label=" + item.typeName + ' (' + typeImgMap.get(item.typeId).length + ')' + " + :name="item.typeId" + > + </el-tab-pane> + </el-tabs> + <el-scrollbar height="70vh"> + <div + 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 + :preview-src-list=" + readonly ? typeImgMap.get(activeId).map((v) => v.url) : [] + " + :initial-index="i" + @contextmenu="(e) => showContextMenu(e, i)" @click="onSelect(img, i)" + @load="onOneImgLoadSuccess(img)" + @error="onOneImgLoadError(img)" /> - </el-scrollbar> - </div> + </div> + <el-row v-else justify="space-between"> + <el-empty description="鏆傛棤璁板綍" /> + </el-row> + </el-scrollbar> </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: { type: Boolean, default: false }, - defaultFile: { - type: Array, - default: () => [] - }, // 鍥剧墖鍙�夋暟閲忥紝褰撲紶鍏ユ暟瀛楁椂锛屼唬琛ㄥ浘鐗囨暟閲� maxSelect: { type: Number, default: 3 + }, + // 鍥剧墖鍙抽敭鐐瑰嚮浜嬩欢 + onContextMenu: { + type: Function + }, + contextMenuStr: { + type: String, + default: '鍙抽敭鐐瑰嚮鍥剧墖瑙﹀彂棰濆鎿嶄綔' } }); + +const emit = defineEmits(['submit', 'cancel', 'update:dialogVisible']); const activeId = ref(''); -const typeImgMap = ref(new Map()); -const selectedImgList = ref([]); -watch(typeImgMap, (newMap, oldMap) => { - if (newMap.get(activeId.value) == undefined) { - return; +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() { + 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); +} + +// 鍥剧墖鍙抽敭鐐瑰嚮鏃堕棿 +function showContextMenu(event, index) { + if (props.onContextMenu) { + event.preventDefault(); + props.onContextMenu(event, activeId.value, index); + } +} + +watch( + () => props.typeList, + (nV, oV) => { + if (nV != oV && nV.length > 0) { + activeId.value = nV[0].typeId; + } + }, + { immediate: true } +); </script> +<style scoped> +.center { + display: flex; + flex-direction: column; + align-items: center; +} +.text { + padding: 20px; +} + +.main { + /* 浣跨埗鍏冪礌灞呬腑 */ + /* margin: 0 auto; */ + /* width: 100%; */ +} + +.imgs { + width: 100%; + /* 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: 250px; + width: 240px; + border-radius: 4px; +} + +.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