From 069da66fbe2748d51b1f3bc63f9ae00e660083c6 Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期一, 04 十一月 2024 14:45:18 +0800 Subject: [PATCH] 场景报告模块(暂存) --- src/views/fysp/data-product/ProdSceneReport.vue | 17 + src/views/fysp/check/components/ArbitraryPhoto.vue | 27 ++- src/views/fysp/data-product/components/CompProblemTable.vue | 132 +++++++++++++-- src/components/FYImageSelectDialog.vue | 193 ++++++++++++++++++++++-- src/views/fysp/data-product/components/CompProblemPicSelect.vue | 42 +++++ src/components.d.ts | 4 src/assets/image/unchange.png | 0 src/views/fysp/data-product/components/CompImgInfo.vue | 21 ++ src/views/fysp/data-product/ProdDailyReport.vue | 43 +++- 9 files changed, 411 insertions(+), 68 deletions(-) diff --git a/src/assets/image/unchange.png b/src/assets/image/unchange.png new file mode 100644 index 0000000..1ac0b23 --- /dev/null +++ b/src/assets/image/unchange.png Binary files differ diff --git a/src/components.d.ts b/src/components.d.ts index e7b8095..f9748ca 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -19,6 +19,7 @@ ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem'] ElButton: typeof import('element-plus/es')['ElButton'] ElCard: typeof import('element-plus/es')['ElCard'] + ElCascader: typeof import('element-plus/es')['ElCascader'] ElCol: typeof import('element-plus/es')['ElCol'] ElCollapse: typeof import('element-plus/es')['ElCollapse'] ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem'] @@ -43,6 +44,8 @@ ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup'] ElOption: typeof import('element-plus/es')['ElOption'] ElPopover: typeof import('element-plus/es')['ElPopover'] + ElRadioButton: typeof import('element-plus/es')['ElRadioButton'] + ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] ElRow: typeof import('element-plus/es')['ElRow'] ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] ElSelect: typeof import('element-plus/es')['ElSelect'] @@ -56,6 +59,7 @@ ElTabs: typeof import('element-plus/es')['ElTabs'] ElTag: typeof import('element-plus/es')['ElTag'] ElText: typeof import('element-plus/es')['ElText'] + ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElTree: typeof import('element-plus/es')['ElTree'] ElUpload: typeof import('element-plus/es')['ElUpload'] Footer: typeof import('./components/core/Footer.vue')['default'] diff --git a/src/components/FYImageSelectDialog.vue b/src/components/FYImageSelectDialog.vue index f9f249c..744b866 100644 --- a/src/components/FYImageSelectDialog.vue +++ b/src/components/FYImageSelectDialog.vue @@ -1,23 +1,25 @@ <template> <el-dialog - v-model="anyPhotoDialog" + :model-value="dialogVisible" + @opened="$emit('update:dialogVisible', true)" + @closed="$emit('update:dialogVisible', false)" 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> @@ -34,8 +36,10 @@ > </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-for="(img, i) in typeImgMap.get(activeId)" :key="i" @@ -46,6 +50,9 @@ @click="onSelect(img, i)" /> </el-scrollbar> + <el-row v-else justify="space-between"> + <el-empty description="鏆傛棤璁板綍" /> + </el-row> </div> </div> </el-dialog> @@ -54,9 +61,18 @@ import { ref, watch } from 'vue'; const props = defineProps({ + dialogVisible: Boolean, + /** + * 鍥剧墖鍒嗙被 + * 缁撴瀯{ typeId, typeName } + */ typeList: { type: Array, default: () => [] + }, + typeImgMap: { + type: Array, + default: () => new Map() }, // 鏄惁浠ュ彧璇荤殑褰㈠紡鏌ョ湅褰撳墠椤甸潰 readonly: { @@ -74,26 +90,169 @@ } }); -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) { +const activeId = ref(''); +// const typeImgMap = ref(new Map()); +const selectedImgUrlList = ref([]); + +function onSelect(img, i) { + if (props.readonly) { return; } - newMap.get(activeId.value).forEach( - (i) => { + 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 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.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); } }); - }, - { deep: true } - ); -}); + }); + }, + { immediate: true } +); </script> +<style scoped> +.center { + display: flex; + flex-direction: column; + align-items: center; +} +.text { + padding: 20px; +} + +.main { + margin: 0 auto; /* 浣跨埗鍏冪礌灞呬腑 */ + height: 100%; + width: 100%; +} + +.imgs { + height: 50vh; + 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 { + height: 60vh; + padding: 10px calc(var(--el-dialog-padding-primary) + 10px) !important; +} +</style> diff --git a/src/views/fysp/check/components/ArbitraryPhoto.vue b/src/views/fysp/check/components/ArbitraryPhoto.vue index bd24994..058136a 100644 --- a/src/views/fysp/check/components/ArbitraryPhoto.vue +++ b/src/views/fysp/check/components/ArbitraryPhoto.vue @@ -134,12 +134,11 @@ this.defaultFile.forEach((imgItem) => { if (imgItem.url == i.url) { i.isSelect = true; + this.selectedImgUrlList.push(i); } }); }); }, - - deep: true } }, mounted() { @@ -160,6 +159,9 @@ // } this.typeImgMap.clear(); this.typeList = []; + + const imgMap = new Map(); + const _typeList = []; mediafileApi.getRoutineByStGuid(this.subtask.stGuid).then((res) => { this.isEmpty = false; let data = res.data; @@ -171,7 +173,7 @@ let businesstypeid = e.businesstypeid; let businesstype = e.businesstype; let hasThisType = false; - this.typeImgMap.forEach((v, k, m) => { + imgMap.forEach((v, k, m) => { if (k == businesstypeid) { hasThisType = true; var isAlreadyHas = false; @@ -190,14 +192,16 @@ } }); if (!hasThisType) { - this.typeImgMap.set(businesstypeid, Array.of(e)); - this.typeList.push(e); + imgMap.set(businesstypeid, Array.of(e)); + _typeList.push(e); } this.imgUrlList.push(e); // TODO imgUrl鍏ㄥ眬閰嶇疆 e.url = $fysp.imgUrl + e.extension1 + e.guid + '.jpg'; e.isSelect = false; } + this.typeImgMap = imgMap; + this.typeList = _typeList; this.initSelectedTab(); }); }, @@ -263,14 +267,15 @@ let result = []; if (!isOk) { this.$emit('selectByAnyPhonoEvent', result); - } - for (const item of this.imgUrlList) { - if (item.isSelect == true) { - result.push(item); + } else { + for (const item of this.imgUrlList) { + if (item.isSelect == true) { + result.push(item); + } } + this.isClose = true; + this.$emit('selectByAnyPhonoEvent', result); } - this.isClose = true; - this.$emit('selectByAnyPhonoEvent', result); } } }; diff --git a/src/views/fysp/data-product/ProdDailyReport.vue b/src/views/fysp/data-product/ProdDailyReport.vue index 209e2ff..ec520f7 100644 --- a/src/views/fysp/data-product/ProdDailyReport.vue +++ b/src/views/fysp/data-product/ProdDailyReport.vue @@ -246,7 +246,7 @@ handler(nV, oV) { // this.getCanClickDay(); }, - deep: true, + deep: true // immediate: true } }, @@ -255,16 +255,29 @@ }, methods: { disabledDate(time) { - this.getCanClickDay() + this.getCanClickDay(); let disabled = this.canClickDay.filter((item) => { - let date = dayjs(time) - let itemDay = new Date(item) - console.log("curr preview time canClickDay", itemDay.getFullYear(), itemDay.getMonth(), itemDay.getDate()); - console.log("curr preview time date", date.year(), date.month(), date.date()); - return date.year() == itemDay.getFullYear() && date.month() == itemDay.getMonth() && date.date() == itemDay.getDate() - }) - .length == 0; + let date = dayjs(time); + let itemDay = new Date(item); + console.log( + 'curr preview time canClickDay', + itemDay.getFullYear(), + itemDay.getMonth(), + itemDay.getDate() + ); + console.log( + 'curr preview time date', + date.year(), + date.month(), + date.date() + ); + return ( + date.year() == itemDay.getFullYear() && + date.month() == itemDay.getMonth() && + date.date() == itemDay.getDate() + ); + }).length == 0; return !disabled; }, getSelectedCityname() { @@ -301,13 +314,15 @@ .map((topTask) => { taskApi.fetchDayTasks(topTask.tguid).then((res) => { res.forEach((r) => { - let formSearchDate = dayjs(this.formSearch.time) - let date = new Date() - dayjs(date).year(formSearchDate.year()).month(formSearchDate.month()).date(Number(r.date.slice(8, 10))) + let formSearchDate = dayjs(this.formSearch.time); + let date = new Date(); + dayjs(date) + .year(formSearchDate.year()) + .month(formSearchDate.month()) + .date(Number(r.date.slice(8, 10))); this.canClickDay.push(date); }); - console.log("this.canClickDay", this.canClickDay); - + console.log('this.canClickDay', this.canClickDay); }); }); }); diff --git a/src/views/fysp/data-product/ProdSceneReport.vue b/src/views/fysp/data-product/ProdSceneReport.vue index a6abc18..0e94a8d 100644 --- a/src/views/fysp/data-product/ProdSceneReport.vue +++ b/src/views/fysp/data-product/ProdSceneReport.vue @@ -36,6 +36,15 @@ </el-space> <el-divider /> <el-text tag="h1">C銆佺幇鍦烘薄鏌撻棶棰樹笌鏁存敼鎯呭喌</el-text> + <el-space wrap> + <CompProblemTable + v-for="(item, i) in curProList" + :key="i" + :problem="item" + ></CompProblemTable> + </el-space> + <el-text tag="h1">D銆佹壃灏樻薄鏌撻槻娌诲缓璁�</el-text> + </el-scrollbar> </template> </BaseContentLayout> @@ -81,6 +90,7 @@ import ArbitraryPhoto from '@/views/fysp/check/components/ArbitraryPhoto.vue'; import CompDevicePhono from '@/views/fysp/check/components/CompDevicePhono.vue'; import CompImgInfo from '@/views/fysp/data-product/components/CompImgInfo.vue'; +import CompProblemTable from './components/CompProblemTable.vue'; /************************* 宸︿晶宸℃煡浠诲姟閫夊崟 **********************************/ const curSubtask = ref({}); @@ -140,12 +150,14 @@ mainLoading.value = false; }); fetchDeviceList(s); - fetchProblems(s) + fetchProblems(s); } /************************* 鍦烘櫙鍩烘湰淇℃伅 **********************************/ const formSubScene = ref({}); function fetchSceneInfo(sceneId) { + formSubScene.value = {}; + sceneImg.value = {}; return sceneApi.getSceneDetail(sceneId).then((res) => { //鍦烘櫙 // if (res.data.scense) formScene = res.data.scense; @@ -166,7 +178,7 @@ function handleSelectAnyPhoto(data) { anyPhotoDialog.value = false; if (data.length > 0) { - sceneImg.value = { url: data[0].url }; + sceneImg.value = data[0]; } } /************************* 鍦烘櫙璁惧淇℃伅 **********************************/ @@ -263,6 +275,7 @@ const curProList = ref([]); function fetchProblems(s) { + curProList.value = []; taskApi.getProBySubtask(s.data.stGuid).then((res) => { curProList.value = res; }); diff --git a/src/views/fysp/data-product/components/CompImgInfo.vue b/src/views/fysp/data-product/components/CompImgInfo.vue index 5fcfd7e..5afab32 100644 --- a/src/views/fysp/data-product/components/CompImgInfo.vue +++ b/src/views/fysp/data-product/components/CompImgInfo.vue @@ -20,7 +20,15 @@ :initial-index="0" fit="cover" lazy - /> + > + <template #error> + <div class="image-slot"> + <el-button type="primary" size="small" @click="$emit('change')" + >閫夋嫨鍥剧墖</el-button + > + </div> + </template> + </el-image> </td> </tr> <tr v-if="downTitle"> @@ -50,6 +58,8 @@ } }); +// const unchangeImg = '../../../../assets/image/unchange.png' + const emit = defineEmits(['change']); </script> <style scoped> @@ -77,4 +87,13 @@ border-style: solid; border-color: #666666; */ } + +.image-slot { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + background: var(--el-fill-color-light); +} </style> diff --git a/src/views/fysp/data-product/components/CompProblemPicSelect.vue b/src/views/fysp/data-product/components/CompProblemPicSelect.vue new file mode 100644 index 0000000..27e4689 --- /dev/null +++ b/src/views/fysp/data-product/components/CompProblemPicSelect.vue @@ -0,0 +1,42 @@ +<template> + <FYImageSelectDialog + :typeList="typeList" + :typeImgMap="typeImgMap" + :maxSelect="1" + ></FYImageSelectDialog> +</template> +<script setup> +import { ref, watch, computed } from 'vue'; +const props = defineProps({ + // 灞曠ず妯″紡锛宲roblem锛氶棶棰樺浘鐗囷紱change锛氭暣鏀瑰浘鐗� + mode: { + type: String, + default: 'problem' + }, + pics: Array +}); + +const typeList = computed(() => { + if (props.mode == 'problem') { + return [{ typeId: 1, typeName: '闂' }]; + } else if (props.mode == 'change') { + return [{ typeId: 1, typeName: '鏁存敼' }]; + } else { + return [{ typeId: 1, typeName: '鏈寚瀹�' }]; + } +}); +const typeImgMap = ref(new Map()); + +watch( + () => props.pics, + (nV, oV) => { + typeImgMap.value.set( + 1, + nV.map((v) => { + return { url: v }; + }) + ); + }, + { immediate: true } +); +</script> diff --git a/src/views/fysp/data-product/components/CompProblemTable.vue b/src/views/fysp/data-product/components/CompProblemTable.vue index 0d3d6df..3f145ce 100644 --- a/src/views/fysp/data-product/components/CompProblemTable.vue +++ b/src/views/fysp/data-product/components/CompProblemTable.vue @@ -2,56 +2,100 @@ <table> <tbody> <tr> - <td>{{ title }}</td> + <td colspan="2">{{ title }}</td> </tr> <tr> - <td> + <td style="position: relative"> <el-image class="image" :src="seletcedProblemPic" - :preview-src-list="[seletcedProblemPic]" + :preview-src-list="seletcedProblemPic ? [seletcedProblemPic] : []" :initial-index="0" fit="cover" lazy - /> + > + <template #error v-if="!seletcedProblemPic"> + <div class="image-slot"> + <el-text>闂鍥剧墖鏈笂浼�</el-text> + </div> + </template> + </el-image> + <el-button + class="pop-button" + size="small" + @click="proDialog = true" + >{{ btnName }}</el-button + > </td> - <td> + <td style="position: relative"> <el-image class="image" - :src="seletcedChangePic" - :preview-src-list="[seletcedChangePic]" + :src="seletcedChangePic ? seletcedChangePic : unchangeImg" + :preview-src-list="seletcedChangePic ? [seletcedChangePic] : []" :initial-index="0" fit="cover" lazy /> + <el-button + class="pop-button" + size="small" + @click="changeDialog = true" + >{{ btnName }}</el-button + > </td> </tr> <tr> <td> - <el-row justify="space-between" align="middle"> - <div>浣嶇疆锛歿{ problem.location }}</div> - <div>鎻忚堪锛歿{ problem.problemname }}</div> - <el-button size="small" @click="$emit('change')">{{ - btnName - }}</el-button> - </el-row> + <div>浣嶇疆锛歿{ problem.location }}</div> + <div> + 鎻忚堪锛� + <el-input + size="small" + v-model="problemDes" + placeholder="闂鎻忚堪" + style="width: 150px" + /> + </div> </td> <td> - <el-row justify="space-between" align="middle"> - <div>浣嶇疆锛歿{ problem.location }}</div> - <div>鎻忚堪锛歿{ problem.problemname }}</div> - <el-button size="small" @click="$emit('change')">{{ - btnName - }}</el-button> - </el-row> + <div>浣嶇疆锛歿{ problem.location }}</div> + <div> + 鎻忚堪锛� + <el-input + size="small" + v-model="changeDes" + placeholder="鏁存敼鎻忚堪" + style="width: 150px" + /> + </div> </td> </tr> </tbody> </table> + <CompProblemPicSelect + v-if="pics.length > 0" + v-model:dialog-visible="proDialog" + mode="problem" + :pics="pics[0].path" + :defaultFile="[{ url: seletcedProblemPic }]" + @submit="handleProPicSelect" + ></CompProblemPicSelect> + <CompProblemPicSelect + v-if="pics.length > 1" + v-model:dialog-visible="changeDialog" + mode="change" + :pics="pics[1].path" + :defaultFile="[{ url: seletcedChangePic }]" + @submit="handleChangePicSelect" + ></CompProblemPicSelect> </template> <script setup> -import { ref, watch } from 'vue'; -import ProCheckProxy from '@/views/check/ProCheckProxy'; +import { ref, watch, computed } from 'vue'; +import dayjs from 'dayjs'; +import ProCheckProxy from '@/views/fysp/check/ProCheckProxy'; +import unchangeImg from '@/assets/image/unchange.png'; + +import CompProblemPicSelect from './CompProblemPicSelect.vue'; const props = defineProps({ problem: { @@ -59,14 +103,27 @@ default: () => { return {}; } + }, + btnName: { + type: String, + default: '淇敼' } }); const emit = defineEmits(['change']); const pics = ref([]); +const proDialog = ref(false); const seletcedProblemPic = ref(); +const changeDialog = ref(false); const seletcedChangePic = ref(); +const problemDes = ref(''); +const changeDes = ref('鏈暣鏀�'); + +const title = computed(() => { + const time = dayjs(props.problem.time).format('M鏈�'); + return `${time}鐜板満闂鍙婃暣鏀瑰浘鐗嘸; +}); function getPics() { pics.value = ProCheckProxy.proPics(props.problem); @@ -78,11 +135,25 @@ } } +function handleProPicSelect(imgList) { + if (imgList && imgList.length > 0) { + seletcedProblemPic.value = imgList[0].url; + } +} + +function handleChangePicSelect(imgList) { + if (imgList && imgList.length > 0) { + seletcedChangePic.value = imgList[0].url; + } +} + watch( () => props.problem, (nV, oV) => { if (nV != oV) { getPics(); + problemDes.value = nV.problemname; + changeDes.value = nV.ischanged ? '宸叉暣鏀�' : '鏈暣鏀�'; } }, { immediate: true } @@ -113,4 +184,19 @@ border-style: solid; border-color: #666666; */ } + +.pop-button { + position: absolute; + bottom: 0; + right: 0; +} + +.image-slot { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + background: var(--el-fill-color-light); +} </style> -- Gitblit v1.9.3