From c0b4517e7362144cc1683ee0bf0b7e00b67d539a Mon Sep 17 00:00:00 2001 From: guonan <guonan201020@163.com> Date: 星期二, 24 六月 2025 18:01:08 +0800 Subject: [PATCH] 提交初版实时模拟 --- src/components/menu/TimeLine.vue | 120 +++++++++--- src/components/tools/DebuffDetail.vue | 303 +++++++++++++++++---------------- src/components/monifangzhen/schemeCard.vue | 104 ++++++----- 3 files changed, 295 insertions(+), 232 deletions(-) diff --git a/src/components/menu/TimeLine.vue b/src/components/menu/TimeLine.vue index 5f6c297..07b79fe 100644 --- a/src/components/menu/TimeLine.vue +++ b/src/components/menu/TimeLine.vue @@ -2,20 +2,30 @@ <div class="timeline-container"> <div class="controls"> <div class="control-btn" @click="skipBackward"> - <img src="@/assets/img/timeline/left.png" class="fas fa-step-backward" /> + <img + src="@/assets/img/timeline/left.png" + class="fas fa-step-backward" + /> </div> <div class="control-btn play-btn" @click="togglePlay"> <img v-show="isPlaying" src="@/assets/img/timeline/stop.png" /> <img v-show="!isPlaying" src="@/assets/img/timeline/start.png" /> </div> <div class="control-btn" @click="skipForward"> - <img src="@/assets/img/timeline/right.png" class="fas fa-step-forward" /> + <img + src="@/assets/img/timeline/right.png" + class="fas fa-step-forward" + /> </div> - <div class="speed-control"> + <div class="speed-control" v-show="speedShow"> <div @click="toggleSpeedMenu">{{ playbackRate }}X</div> <div class="speed-menu" v-show="showSpeedMenu"> - <div v-for="rate in playbackRates" :key="rate" @click.capture="setPlaybackRate(rate)" - :class="{ active: playbackRate === rate }"> + <div + v-for="rate in playbackRates" + :key="rate" + @click.capture="setPlaybackRate(rate)" + :class="{ active: playbackRate === rate }" + > {{ rate }}X </div> </div> @@ -25,19 +35,33 @@ <div class="timeline"> <div class="dates"> <div class="current-date">褰撳墠鎾斁鏃堕棿锛歿{ currentPlayingTime }}</div> - <div v-for="(date, index) in visibleDates" :key="index" class="date-label"> + <div + v-for="(date, index) in visibleDates" + :key="index" + class="date-label" + > <!-- {{ formatDate(date) }} --> </div> <div> 涓撻娓叉煋: - <el-switch v-model="isColorRenderEnabled" @change="handleColorRenderChange" style="margin-top: -3px" - :disabled="!isPlaying || !isWaterPrimitiveCreated" /> + <el-switch + v-model="isColorRenderEnabled" + @change="handleColorRenderChange" + style="margin-top: -3px" + :disabled="!isPlaying || !isWaterPrimitiveCreated" + /> <!-- active-text="寮�" inactive-text="鍏�" --> </div> </div> <div class="timeline-track" ref="timelineTrack" @click="seekToPosition"> - <div class="timeline-progress" :style="{ width: progressPercentage + '%' }"></div> - <div class="timeline-cursor" :style="{ left: progressPercentage + '%' }"></div> + <div + class="timeline-progress" + :style="{ width: progressPercentage + '%' }" + ></div> + <div + class="timeline-cursor" + :style="{ left: progressPercentage + '%' }" + ></div> <div class="scale-markers"> <div class="scale-marker" style="left: 0%"></div> <div class="scale-marker" style="left: 25%"></div> @@ -46,8 +70,12 @@ <div class="scale-marker" style="left: 100%"></div> </div> <div class="time-markers"> - <div v-for="(time, index) in timeMarkers" :key="index" class="time-marker" - :style="{ left: `${index * 25}%`, transform: 'translateX(-50%)' }"> + <div + v-for="(time, index) in timeMarkers" + :key="index" + class="time-marker" + :style="{ left: `${index * 25}%`, transform: 'translateX(-50%)' }" + > <div class="date-part">{{ time.split(" ")[0] }}</div> <div class="time-part">{{ time.split(" ")[1] }}</div> </div> @@ -56,27 +84,38 @@ </div> <div> <div style="display: flex"> - <ratelevel ref="ratelevelRef" :playing-time="sendCurrentPlayingTime" - @finish-calculation="handleFinishCalculation" style=" + <ratelevel + ref="ratelevelRef" + :playing-time="sendCurrentPlayingTime" + @finish-calculation="handleFinishCalculation" + style=" margin-top: 12px; margin-left: 28px; margin-right: 10px; justify-content: flex-end; - " /> - <crossanalysis ref="crossRef" style=" + " + /> + <crossanalysis + ref="crossRef" + style=" margin-top: 12px; margin-left: 16px; margin-right: 20px; justify-content: flex-end; - " /> + " + /> </div> - <el-button @click="handleBack" style=" + <el-button + @click="handleBack" + style=" margin-top: 3px; margin-left: 28px; margin-right: 10px; width: 75%; height: 30%; - ">缁撴潫妯℃嫙</el-button> + " + >缁撴潫妯℃嫙</el-button + > </div> </div> </template> @@ -143,13 +182,15 @@ const playbackRate = ref(1); const playbackRates = ref([1, 2, 4, 8]); const showSpeedMenu = ref(false); +const speedShow = ref(false); + const waterTimestamps = ref([]); // 瀛樺偍鏃堕棿杞存暟鎹� const timeMarkers = ref([]); const timelineTrack = ref(null); const isColorRenderEnabled = ref(false); // 鍋囪杩欐槸浣犵殑棰滆壊娓叉煋寮�鍏崇姸鎬� const isWaterPrimitiveCreated = ref(false); let playInterval = null; -let rainTotalInfo = ([]); +let rainTotalInfo = []; const isRainEnabled = ref(false); const rainParams = reactive({ rainSize: 0.5, @@ -259,8 +300,11 @@ currentTime.value = (nextTimestamp - baseTimestamp) / 1000; // 瑙﹀彂鏇存柊 - updateWaterColorByTime() - updateWeatherByProgress(); + if (selectedScheme.value.type !== 2) { + updateWaterColorByTime(); + updateWeatherByProgress(); + } + const progress = currentTime.value / duration.value; emit("timeUpdate", progress * 100); }, 1000 / playbackRate.value); // 鏍规嵁鎾斁閫熺巼璋冩暣闂撮殧 @@ -303,7 +347,7 @@ const rainfallList = data.rainfalls; console.log("鏈�缁堢殑 rainfallList:", rainfallList); - rainTotalInfo.value = rainfallList + rainTotalInfo.value = rainfallList; // 鎻愬彇 intensity 鍊� rainFallValues.value = rainfallList.map((r) => r.intensity); @@ -373,7 +417,7 @@ } } // 榛樿鏃犻洦鐘舵�� - + return { name: "鏃犻洦", size: 0.3, speed: 10, density: 10, color: "#F0F8FF" }; } // 鏍规嵁鎾斁杩涘害鏇存柊澶╂皵鏁堟灉锛堝凡浼樺寲锛� @@ -393,20 +437,20 @@ const nextTotal = nextData.total; const total = currentTotal + (nextTotal - currentTotal) * alpha; // 鏍规嵁 total 璁剧疆棰滆壊 - let color = '#D4F2E7'; // 榛樿钃濊壊 + let color = "#D4F2E7"; // 榛樿钃濊壊 if (total >= 150) { - color = '#663300'; // 榛� - 澶ч洦 + color = "#663300"; // 榛� - 澶ч洦 } else if (total >= 125) { - color = '#B26633'; // 榛勭豢 - 涓洦 + color = "#B26633"; // 榛勭豢 - 涓洦 } else if (total >= 100) { - color = '#CC9966'; // 缁� - 涓洦 + color = "#CC9966"; // 缁� - 涓洦 } else if (total >= 75) { - color = '#CCE5FF'; // 闈掔豢 - 灏忛洦 + color = "#CCE5FF"; // 闈掔豢 - 灏忛洦 } else if (total >= 50) { - color = '#99CCFF'; // 澶╄摑 - 灏忛洦 + color = "#99CCFF"; // 澶╄摑 - 灏忛洦 } else if (total >= 25) { - color = '#66B3FF'; // 娴呰摑 - 寰噺 + color = "#66B3FF"; // 娴呰摑 - 寰噺 } // console.log(`褰撳墠 total: ${total.toFixed(2)}, 棰滆壊: ${color}`); // updateWaterColor(color) @@ -426,7 +470,11 @@ // const rainValue = currentRain + (nextRain - currentRain) * alpha; const rainValue = currentRain + (nextRain - currentRain); // 鎵撳嵃褰撳墠澶勭悊鐨勯洦閲忔暟鎹� - console.log(`姝e湪澶勭悊鐨勯洦閲忔暟鎹偣: 褰撳墠=${currentRain}, 涓嬩竴涓�=${nextRain}, 鎻掑�煎悗=${rainValue.toFixed(2)}, 绱㈠紩=${index}`); + console.log( + `姝e湪澶勭悊鐨勯洦閲忔暟鎹偣: 褰撳墠=${currentRain}, 涓嬩竴涓�=${nextRain}, 鎻掑�煎悗=${rainValue.toFixed( + 2 + )}, 绱㈠紩=${index}` + ); // 濡傛灉褰撳墠绱㈠紩鏈彉鍖栦笖鎻掑�煎樊寮備笉澶э紝璺宠繃閲嶅鏇存柊 if (index === lastUsedIndex && Math.abs(rainValue - lastRainValue) < 0.1) { // console.log('鐢变簬鏁版嵁鏃犳樉钁楀彉鍖栵紝璺宠繃鏈鏇存柊'); @@ -612,9 +660,15 @@ // 褰撳墠鏂规鐨勬墍鏈変俊鎭� const schemeInfo = selectedScheme.value; serviceInfo = schemeInfo.serviceName; + if (selectedScheme.value.type == 2) { + speedShow.value = false; + } else { + getRainfallData(); + speedShow.value = true; + } // console.log('鑾峰彇鍒扮殑 serviceName:', serviceInfo); - getRainfallData(); + // 鏍规嵁layer.json鍘昏幏鍙栨椂闂磋酱淇℃伅 const { waterTimestamps: timestamps, diff --git a/src/components/monifangzhen/schemeCard.vue b/src/components/monifangzhen/schemeCard.vue index 2888c7d..a25acd1 100644 --- a/src/components/monifangzhen/schemeCard.vue +++ b/src/components/monifangzhen/schemeCard.vue @@ -16,10 +16,6 @@ <span style="color: aquamarine"> {{ item.result === "-1" ? "鍑洪敊" : item.result || "鍒涘缓浠跨湡" }} </span> - <!-- <span style="color: aquamarine">{{ item.result || "鍒涘缓浠跨湡" }}</span> --> - <!-- <span style="color: aquamarine">{{ - statusText[item.status] || "鏈煡" - }}</span> --> </p> </div> <div class="cardMenu"> @@ -37,10 +33,7 @@ :selectedScheme="currentScheme" @back="handleBack" /> - <flowRateTab - v-if="schemeInfoShow"> - 123 - </flowRateTab> + <flowRateTab v-if="schemeInfoShow"> 123 </flowRateTab> </div> <Message @close="close" @@ -81,13 +74,6 @@ selectedId.value = id; } -const statusText = { - 0: "鍒涘缓浠跨湡", - 1: "棰勫鐞�", - 2: "鍒嗘瀽涓�", - 10: "瀹屾垚", - 20: "鍑洪敊", -}; function formatTime(time) { return dayjs(time).format("YYYY-MM-DD HH:mm:ss"); @@ -108,62 +94,80 @@ messageShow.value = false; } -function startPlay(item) { - // 鍒嗘瀽涓� - if (item.status == 2) { +async function startPlay(item) { + if (item.status === 2) { ElMessage.warning("褰撳墠鏂规姝e湪鍒嗘瀽涓�,鏃犳硶杩涘叆妯℃嫙锛�"); return; } - // 鍑洪敊 - if (item.status == 20) { + + if (item.status === 20) { ElMessage.error("褰撳墠鏂规鍒嗘瀽鍑洪敊,璇烽噸鏂版柊寤烘柟妗堬紒"); return; } - // 璋冪敤姹傝В鍣ㄥ苟鎷垮埌鏈�鏂扮敓鎴愮殑serviceName - // 鏂板垱寤虹殑鏂规娌℃湁鐘舵�佷互鍙妔erviceName鍒欐墽琛岃皟鐢ㄦ眰瑙e櫒 - if (!item.status && !item.serviceName) { - getSimStart(item.id).then((res) => { - getSimDataById(item.id).then((res) => { - item.serviceName = res.data[0].serviceName; - simStore.setSelectedScheme(item); - console.log(item, "鏃犳湇鍔″悕绉�"); - ElMessage.warning("褰撳墠鏂规姝e湪鍒嗘瀽涓�,璇风◢鍚庡啀妯℃嫙"); - getScheme(); - }); - }); - } else { + + // 濡傛灉鏄凡瀹屾垚鐨勬柟妗堬紙status == 10锛� + if (item.status === 10) { + const flyHeight = item.areaType === 1 ? 100000 : 50000; simStore.setSelectedScheme(item); - console.log("鏈夋湇鍔″悕绉�"); - } - const flyHeight = ref(100000); - - const shouldShowFill = false; - - // 姹傝В鍣ㄦ眰瑙e畬鎴愪箣鍚庢墠鍙互鏄剧ず鏃堕棿杞� - if (item.status == 10) { - // 鍙湁琛屾斂鍖哄垝鎵ц - if (item.areaType == 1) { - flyHeight.value = 100000; + if (item.areaType === 1) { EventBus.emit("select-geom", { geom: item.geom, - flyHeight: flyHeight.value, - shouldShowFill: shouldShowFill, + flyHeight, + shouldShowFill: false, }); } else { - // 瀛欒儭娌熷尯鍩熻烦杞瑙� initeWaterPrimitiveView(); } + currentScheme.value = item; schemeInfoShow.value = true; emit("closeBtn", false); emit("start"); + return; } + + // 璋冪敤姹傝В鍣紙涓嶅湪瀹炴椂妯℃嫙鐨勬儏鍐典笅锛� + if (!item.status && !item.serviceName && item.type !== 2) { + try { + await getSimStart(item.id); + const res = await getSimDataById(item.id); + + item.serviceName = res.data[0]?.serviceName || null; + simStore.setSelectedScheme(item); + ElMessage.warning("褰撳墠鏂规姝e湪鍒嗘瀽涓�,璇风◢鍚庡啀妯℃嫙"); + getScheme(); + } catch (e) { + console.error("鑾峰彇妯℃嫙鏁版嵁澶辫触锛�", e); + } + return; + } + + // 瀹炴椂妯℃嫙 + if (item.type === 2) { + try { + // 瀹炴椂妯℃嫙璋冪敤姹傝В鍣ㄤ細鐩存帴鍦ㄦ帴鍙d腑杩斿洖缁撴灉 + const ress = await getSimStart(item.id); + const res = await getSimDataById(item.id); + item.serviceName = res.data[0]?.serviceName || null; + simStore.setSelectedScheme(item); + getScheme(); + + if (ress.code === 200) { + initeWaterPrimitiveView(); + emit("start"); + } + } catch (e) { + console.error("瀹炴椂妯℃嫙鑾峰彇妯℃嫙鏁版嵁澶辫触锛�", e); + } + return; + } + + // 榛樿鎯呭喌锛氭湁鏈嶅姟鍚嶇О + simStore.setSelectedScheme(item); } -function endPlay() { - emit("end"); -} + function handleBack(value) { if (value === false) { diff --git a/src/components/tools/DebuffDetail.vue b/src/components/tools/DebuffDetail.vue index a8f6bf4..f5b1506 100644 --- a/src/components/tools/DebuffDetail.vue +++ b/src/components/tools/DebuffDetail.vue @@ -1,15 +1,15 @@ <template> - <div class="detail"> - <div class="detail-top">缁熻鍒嗘瀽缁撴灉</div> - <!-- <div class="detail-btn" @click="showMsg">鏌ョ湅璇︽儏</div> --> - <div class="detail-close" @click="closeMsg"></div> - <div class="detail-context"> - <div v-for="(item, key) in detailList" :key="key" class="detail-item"> - <div class="detail-name">{{ item.name }}</div> - <div class="detail-value">{{ item.value }}</div> - </div> - </div> - </div> + <div class="detail"> + <div class="detail-top">缁熻鍒嗘瀽缁撴灉</div> + <!-- <div class="detail-btn" @click="showMsg">鏌ョ湅璇︽儏</div> --> + <div class="detail-close" @click="closeMsg"></div> + <div class="detail-context"> + <div v-for="(item, key) in detailList" :key="key" class="detail-item"> + <div class="detail-name">{{ item.name }}</div> + <div class="detail-value">{{ item.value }}</div> + </div> + </div> + </div> </template> <script> @@ -20,171 +20,176 @@ const { selectedScheme } = storeToRefs(simStore); export default { - name: "detail", - components: {}, - props: { - areaName: { - type: String, - default: "灏瑰瑗挎矡", - }, - }, - data() { - return { - show: false, - detailList: [ - { - name: "鏈�澶ч洦寮猴細", - value: Number(Math.random() * 100).toFixed(2) + " mm/h", - }, - { - name: "骞冲潎闆ㄥ己锛�", - value: Number(Math.random() * 10).toFixed(2) + " mm/h", - }, - { - name: "鏈�澶ф按娣憋細", - value: "1.86 m", - }, - { - name: "鏈�澶ф祦閫燂細", - value: "7 m/s", - }, - { - name: "濞佽儊鎴垮眿锛�", - value: "406 闂�", - }, - { - name: "濞佽儊浜哄彛锛�", - value: "145 鎴�", - }, - { - name: "濞佽儊璐骇锛�", - value: "4872 涓囧厓", - }, - ], - } - }, - mounted() { - this.getRainfallData(); // 缁勪欢鎸傝浇鍚庢墽琛岃幏鍙栭洦閲忔暟鎹� - }, - methods: { - getRainfallData() { - if (!selectedScheme.value || !selectedScheme.value.data) { - console.warn("selectedScheme 鎴� data 涓嶅瓨鍦�"); - return; - } - let data = selectedScheme.value.data; - // 濡傛灉鏄瓧绗︿覆锛屽垯灏濊瘯瑙f瀽鎴愬璞� - if (typeof data === 'string') { - try { - data = JSON.parse(data); - } catch (e) { - console.error("data 涓嶆槸鏈夋晥鐨� JSON 瀛楃涓�"); - return; - } - } - const rainfallList = data.rainfalls; + name: "detail", + components: {}, + props: { + areaName: { + type: String, + default: "灏瑰瑗挎矡", + }, + }, + data() { + return { + show: false, + detailList: [ + { + name: "鏈�澶ч洦寮猴細", + value: Number(Math.random() * 100).toFixed(2) + " mm/h", + }, + { + name: "骞冲潎闆ㄥ己锛�", + value: Number(Math.random() * 10).toFixed(2) + " mm/h", + }, + { + name: "鏈�澶ф按娣憋細", + value: "1.86 m", + }, + { + name: "鏈�澶ф祦閫燂細", + value: "7 m/s", + }, + { + name: "濞佽儊鎴垮眿锛�", + value: "406 闂�", + }, + { + name: "濞佽儊浜哄彛锛�", + value: "145 鎴�", + }, + { + name: "濞佽儊璐骇锛�", + value: "4872 涓囧厓", + }, + ], + }; + }, + mounted() { + this.getRainfallData(); // 缁勪欢鎸傝浇鍚庢墽琛岃幏鍙栭洦閲忔暟鎹� + }, + methods: { + getRainfallData() { + if (!selectedScheme.value || !selectedScheme.value.data) { + console.warn("selectedScheme 鎴� data 涓嶅瓨鍦�"); + return; + } + let data = selectedScheme.value.data; + // 濡傛灉鏄瓧绗︿覆锛屽垯灏濊瘯瑙f瀽鎴愬璞� + if (typeof data === "string") { + try { + data = JSON.parse(data); + } catch (e) { + console.error("data 涓嶆槸鏈夋晥鐨� JSON 瀛楃涓�"); + return; + } + } - // 鎻愬彇 intensity 鍊� - const rainValues = rainfallList.map(r => r.intensity); - const minRain = Math.min(...rainValues); - const maxRain = Math.max(...rainValues); - const avgRain = rainValues.reduce((sum, val) => sum + val, 0) / rainValues.length; + if (selectedScheme.value.type !== 2) { + const rainfallList = data.rainfalls; - // 鏇存柊 detailList 涓殑鈥滄渶澶ч洦寮衡�濆拰鈥滃钩鍧囬洦寮衡�� - this.detailList[0].value = maxRain.toFixed(2) + " mm/h"; // 鏈�澶ч洦寮� - this.detailList[1].value = avgRain.toFixed(2) + " mm/h"; // 骞冲潎闆ㄥ己 + // 鎻愬彇 intensity 鍊� + const rainValues = rainfallList.map((r) => r.intensity); + const minRain = Math.min(...rainValues); + const maxRain = Math.max(...rainValues); + const avgRain = + rainValues.reduce((sum, val) => sum + val, 0) / rainValues.length; - console.log('褰撳墠鏂规涓嬫渶灏忛洦閲忋�佹渶澶ч洦閲忋�佸钩鍧囬洦閲忥細', - minRain.toFixed(2), - maxRain.toFixed(2), - avgRain.toFixed(2) - ); - }, - closeMsg() { - this.$emit("close") - }, - showMsg() { - this.$emit("open") - }, - }, -} + // 鏇存柊 detailList 涓殑鈥滄渶澶ч洦寮衡�濆拰鈥滃钩鍧囬洦寮衡�� + this.detailList[0].value = maxRain.toFixed(2) + " mm/h"; // 鏈�澶ч洦寮� + this.detailList[1].value = avgRain.toFixed(2) + " mm/h"; // 骞冲潎闆ㄥ己 + + console.log( + "褰撳墠鏂规涓嬫渶灏忛洦閲忋�佹渶澶ч洦閲忋�佸钩鍧囬洦閲忥細", + minRain.toFixed(2), + maxRain.toFixed(2), + avgRain.toFixed(2) + ); + } + }, + closeMsg() { + this.$emit("close"); + }, + showMsg() { + this.$emit("open"); + }, + }, +}; </script> <style lang="less" scoped> .detail { - background: url("@/assets/img/tools/messagebg.png"); - background-size: 100% 100%; - width: 391px; - height: 420px; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - z-index: 99; + background: url("@/assets/img/tools/messagebg.png"); + background-size: 100% 100%; + width: 391px; + height: 420px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 99; } .detail-top { - position: absolute; - top: 5px; - left: 20px; - font-weight: 700; - font-size: 18px; - font-weight: 700; - color: #fff; - line-height: 40px; - width: 270px; - cursor: pointer; + position: absolute; + top: 5px; + left: 20px; + font-weight: 700; + font-size: 18px; + font-weight: 700; + color: #fff; + line-height: 40px; + width: 270px; + cursor: pointer; } .detail-close { - position: absolute; - right: 3px; - top: 10px; - width: 20px; - height: 20px; - text-align: center; - line-height: 20px; - text-align: center; + position: absolute; + right: 3px; + top: 10px; + width: 20px; + height: 20px; + text-align: center; + line-height: 20px; + text-align: center; - font-weight: 700; - font-size: 18px; - font-weight: 700; - color: #fff; - cursor: pointer; + font-weight: 700; + font-size: 18px; + font-weight: 700; + color: #fff; + cursor: pointer; } .detail-context { - position: absolute; - top: 40px; - left: 20px; - width: 350px; + position: absolute; + top: 40px; + left: 20px; + width: 350px; } .detail-item { - height: 23px; - margin-top: 15px; - margin-left: 10px; + height: 23px; + margin-top: 15px; + margin-left: 10px; } .detail-name { - float: left; - font-weight: 700; - color: #94e0c4; + float: left; + font-weight: 700; + color: #94e0c4; } .detail-value { - float: left; - color: #e1eee9; + float: left; + color: #e1eee9; } .detail-btn { - background: url("@/assets/img/tools/messagebtn.png") no-repeat; - position: absolute; - bottom: 60px; - right: 60px; - width: 105px; - height: 26px; - text-align: center; - color: #fff; - cursor: pointer; + background: url("@/assets/img/tools/messagebtn.png") no-repeat; + position: absolute; + bottom: 60px; + right: 60px; + width: 105px; + height: 26px; + text-align: center; + color: #fff; + cursor: pointer; } </style> -- Gitblit v1.9.3