当前位置: 首页 > news >正文

微信链接网站怎么做百度官方网站入口

微信链接网站怎么做,百度官方网站入口,java做网站代码,去哪个网站找建筑图纸碰到难点 1.wss 心跳机制 实现前端和后端双向绑定 只要后端发送了消息 前端通过全局总线去触发你想要的函数。 全局总线 vue3可以全局总线下一个mitt 新建一个eventBus.js import mitt from "mitt"; const eventBus mitt();export default eventBus; 然后wss…

碰到难点 

1.wss 心跳机制

实现前端和后端双向绑定 只要后端发送了消息 前端通过全局总线去触发你想要的函数。

全局总线

vue3可以全局总线下一个mitt

新建一个eventBus.js

import mitt from "mitt";
const eventBus = mitt();export default eventBus;

然后wss新建一个useWebSocket.js

import { ref } from "vue";
import eventBus from "../mixins/eventBus";// 连接状态
export const SocketStatus = {Connecting: "正在连接...", // 表示正在连接,这是初始状态。Connected: "连接已建立", // 表示连接已经建立。Disconnecting: "连接正在关闭", // 表示连接正在关闭。Disconnected: "连接已断开", // 表示连接已经关闭。
};const DEFAULT_OPTIONS = {url: "", // WebSocket URLheartBeatData: "", // 心跳数据heartBeatInterval: 60 * 1000, // 心跳间隔,单位 msreconnectInterval: 5 * 1000, // 断线重连间隔,单位 msmaxReconnectAttempts: 10, // 最大重连次数
};const SocketCloseCode = 1000;export default function useWebSocket(options = {}, onMessageCallback) {//onMessageCallback 处理回调函数 确保在收到消息时候调用const state = ref({options: { ...DEFAULT_OPTIONS, ...options },socket: null,heartBeatSendTimer: null, // 心跳发送定时器heartBeatTimeoutTimer: null, // 心跳超时定时器reconnectAttempts: 0,reconnectTimeout: null,});const status = ref(SocketStatus.Disconnected);// 连接 WebSocketconst connect = () => {disconnect(); // 断开之前的连接status.value = SocketStatus.Connecting;state.value.socket = new WebSocket(state.value.options.url);state.value.socket.onopen = (openEvent) => {console.log("socket连接:", openEvent);status.value = SocketStatus.Connected;startHeartBeat(); // 开始心跳};state.value.socket.onmessage = (msgEvent) => {console.log("socket消息:", msgEvent);if (typeof onMessageCallback === "function") {// onMessageCallback(); // 调用传入的回调函数// 广播消息
//在这边可以不用调用传入的函数 可以直接全局调用函数 懒得改了eventBus.emit("socketMessage", msgEvent.data);eventBus.emit("Messageaa");eventBus.emit("Messagebb");} else {console.error("getDate is not a function");}// if (typeof getDate === "function") {//   getDate(); // 调用 getDate 函数// } else {//   console.error("getDate is not a function");// }startHeartBeat(); // 收到消息时重新开始心跳};state.value.socket.onclose = (closeEvent) => {console.log("socket关闭:", closeEvent);status.value = SocketStatus.Disconnected;// 非正常关闭,尝试重连if (closeEvent.code !== SocketCloseCode) {reconnect();}};state.value.socket.onerror = (errEvent) => {console.log("socket报错:", errEvent);status.value = SocketStatus.Disconnected;reconnect(); // 连接失败,尝试重连};};// 断开 WebSocketconst disconnect = () => {// 如果 WebSocket 实例存在且处于开放或连接中的状态,则关闭连接。if (state.value.socket && (state.value.socket.OPEN || state.value.socket.CONNECTING)) {console.log("socket断开连接");status.value = SocketStatus.Disconnecting;state.value.socket.close(SocketCloseCode, "normal closure");state.value.socket = null;stopHeartBeat(); // 停止心跳stopReconnect(); // 停止重连}};// 开始心跳检测const startHeartBeat = () => {stopHeartBeat(); // 先清除之前的定时器state.value.heartBeatSendTimer = setTimeout(() => {if (status.value === SocketStatus.Connected) {state.value.socket.send(state.value.options.heartBeatData);console.log("socket心跳发送:", state.value.options.heartBeatData);}// 心跳超时state.value.heartBeatTimeoutTimer = setTimeout(() => {console.log("心跳超时,关闭连接");state.value.socket.close(4444, "heart timeout");}, state.value.options.heartBeatInterval);}, state.value.options.heartBeatInterval);};// 停止心跳检测const stopHeartBeat = () => {if (state.value.heartBeatSendTimer) {clearTimeout(state.value.heartBeatSendTimer);state.value.heartBeatSendTimer = null;}if (state.value.heartBeatTimeoutTimer) {clearTimeout(state.value.heartBeatTimeoutTimer);state.value.heartBeatTimeoutTimer = null;}};// 重连机制const reconnect = () => {// reconnect:如果连接状态不是 Connected 或 Connecting,并且重连尝试次数小于最大值,则尝试重连。if (status.value === SocketStatus.Connected || status.value === SocketStatus.Connecting) {return;}stopHeartBeat(); // 停止心跳if (state.value.reconnectAttempts < state.value.options.maxReconnectAttempts) {console.log("socket重连:", state.value.reconnectAttempts);// 重连间隔,5秒起步,下次递增1秒const interval = Math.max(state.value.options.reconnectInterval, state.value.reconnectAttempts * 1000);console.log("间隔时间:", interval);state.value.reconnectTimeout = setTimeout(() => {if (status.value !== SocketStatus.Connected && status.value !== SocketStatus.Connecting) {connect();}}, interval);state.value.reconnectAttempts += 1;} else {status.value = SocketStatus.Disconnected;stopReconnect(); // 停止重连}};// 停止重连const stopReconnect = () => {if (state.value.reconnectTimeout) {clearTimeout(state.value.reconnectTimeout);state.value.reconnectTimeout = null;}};return {connect,disconnect,status,};
}

重点是这步

    state.value.socket.onmessage = (msgEvent) => {console.log("socket消息:", msgEvent);if (typeof onMessageCallback === "function") {// onMessageCallback(); // 调用传入的回调函数// 广播消息
//在这边可以不用调用传入的函数 可以直接全局调用函数 懒得改了eventBus.emit("socketMessage", msgEvent.data);eventBus.emit("Messageaa");eventBus.emit("Messagebb");} else {console.error("getDate is not a function");}

然后在自己的组件

import useWebSocket, { SocketStatus } from "@/mixins/useWebSocket";
import eventBus from "@/mixins/eventBus";onMounted(() => {eventBus.on("tenDays", getDate);eventBus.on("socketMessage", getDate); // 监听 WebSocket 消息事件getDate(); // 在组件初始化时调用 getDategetUser(); //为了链接wss});
onUnmounted(() => {eventBus.off("tenDays", getDate);eventBus.off("socketMessage", getDate);disconnect(); // 断开 WebSocket 连接
});

 我传函数进去了其实不用的 懒得改了 因为 我要接收到数据 好几个函数一起被触发 所以全局总线比较好

const ID = ref("");
const getUser = () => {userInfo().then((res) => {// console.log("用户res", res);localStorage.setItem("userInof", JSON.stringify(res.data.sysUser));ID.value = res.data.sysUser.id;if (ID.value) {console.log("连接WebSocket");// setLoginCookie(); // 设置登录 Cookie(包括 token)connect(); // 连接 WebSocket} // 组件挂载时连接 WebSocket});
};const { connect, disconnect, status } = useWebSocket({url: computed(() => {// const token = Cookie.get("Authorization") || "";return ID.value? `wss://www.tbaowl.com:9992/ws/mini/websocket/${ID.value}`: "";}), // 替换为实际的 WebSocket URLheartBeatData: "ping", // 心跳数据heartBeatInterval: 30000, // 心跳间隔,30秒reconnectInterval: 5000, // 重连间隔,5秒maxReconnectAttempts: 5, // 最大重连次数},getDate
);

2.关于弹窗红色预警,逻辑。

<template><transition-group name="scroll" tag="div" class="warmTanChuan-container"><divv-if="isRunning && currentItem"class="warmTanChuan"ref="warmTanChuan":key="currentItem.id"><div class="title"><img src="@/assets/images/Frame103(91).png" alt="" /><span v-if="currentItem.deviceType == 1">摄像头警告:</span><span v-if="currentItem.deviceType == 2">灵思传感器警告:</span><span v-if="currentItem.deviceType == 3">大华电气设备警告:</span><span v-if="currentItem.deviceType == 4">消防设备警告:</span><span v-if="currentItem.deviceType == 5">车载设备警告:</span><span v-if="currentItem.deviceType == 6">海康消防设备警告:</span><span v-if="currentItem.deviceType == 7">消防传感器警告:</span><span class="time">{{ time }}s</span></div><div class="content_text"><p>{{ currentItem.incidentDescribe }}</p></div></div></transition-group><div class="test" v-if="isTestVisible && warmList.length > 0"></div>
</template><script setup>
import { ref, onMounted, watch, computed, onUnmounted, nextTick } from "vue";
import { warmEvents } from "@/api/api.js";
import dayjs from "dayjs";
import useWebSocket, { SocketStatus } from "@/mixins/useWebSocket";
import { getSystemData, userInfo } from "@/api/api";
import eventBus from "@/mixins/eventBus";
const warmList = ref([]);
const queue = ref([]); // 用于存储接收到的警告数据的队列const currentIndex = ref(0);
const time = ref(30);
const isRunning = ref(false);
const isTestVisible = ref(true);let audio = new Audio(require("@/assets/warm.mp3"));
audio.hidden = true; // 隐藏音频控件
document.body.appendChild(audio); // 将音频控件添加到页面中let interval;
onMounted(() => {eventBus.on("socketMessage", handleMessage);audio.addEventListener("ended", handleAudioEnded);
});onUnmounted(() => {eventBus.off("socketMessage", handleMessage);clearInterval(interval); // 清除1分钟的定时器clearInterval(countDown); // 清除倒计时定时器audio.pause();document.body.removeChild(audio); // 移除音频控件
});const getDate = () => {const time = new Date();const endTime = dayjs(time).format("YYYY-MM-DD HH:mm:ss");const startTime = dayjs(time).subtract(1, "days").format("YYYY-MM-DD HH:mm:ss");const equipWarnPageDTO = {startTime: startTime,endTime: endTime,};const page = {size: 999,};const obj = Object.assign(equipWarnPageDTO, page);warmEvents(obj).then((res) => {if (res.code == 0) {const records = res.data?.records ?? [];warmList.value = [...warmList.value, ...records]; // 将新数据添加到 warmList 末尾nextTick(() => {if (warmList.value.length > 0) {playAudio();}});}});
};const handleMessage = (msg) => {const data = JSON.parse(msg);queue.value.push(data); // 将新数据添加到队列中if (!isRunning.value && !currentItem.value) {// 如果当前没有正在播放的警告信息,开始播放showNextItem();}
};const ID = ref("");
const getUser = () => {userInfo().then((res) => {localStorage.setItem("userInof", JSON.stringify(res.data.sysUser));ID.value = res.data.sysUser.id;if (ID.value) {connect(); // 连接 WebSocket}});
};const { connect, disconnect, status } = useWebSocket({url: computed(() => {return ID.value? `wss://www.tbaowl.com:9992/ws/mini/websocket/${ID.value}`: "";}),heartBeatData: "ping", // 心跳数据heartBeatInterval: 30000, // 心跳间隔,30秒reconnectInterval: 5000, // 重连间隔,5秒maxReconnectAttempts: 5, // 最大重连次数},handleMessage
);let countDown;
const startCountDown = () => {if (countDown) {clearInterval(countDown); // 清除之前的倒计时定时器}countDown = setInterval(() => {if (isRunning.value) {time.value -= 1;if (time.value <= 0) {clearInterval(countDown);handleAudioEnded();}}}, 1000);
};const showNextItem = () => {if (queue.value.length > 0) {warmList.value.push(queue.value.shift()); // 从队列中取出一条数据并添加到warmListconsole.log("queue.value", queue.value);console.log("warmList.value2222", warmList.value);isRunning.value = true; // 标记为正在播放isTestVisible.value = true;time.value = 30; // 重置时间playAudio();startCountDown(); // 开始倒计时} else {isRunning.value = false; // 如果队列为空,停止播放isTestVisible.value = false;}
};watch(currentIndex, () => {if (isRunning.value) {if (countDown) {clearInterval(countDown);startCountDown();}}
});const currentItem = computed(() => {return warmList.value.length > 0 ? warmList.value[currentIndex.value] : null;
});const playAudio = () => {audio.currentTime = 0;audio.play().catch((error) => {console.error("Error playing audio:", error);});// 设置定时器,10秒后停止音频setTimeout(() => {audio.pause();}, 10000); // 10000毫秒 = 10秒
};
const handleAudioEnded = () => {if (queue.value.length > 0) {currentIndex.value++;showNextItem();} else {isRunning.value = false; // 没有更多数据,停止播放isTestVisible.value = false;audio.pause();document.body.removeChild(audio); // 移除音频控件}
};// const handleAudioEnded = () => {
//   if (queue.value.length > 0) {
//     // 如果队列中还有未播放的数据,播放下一条
//     showNextItem();
//   } else {
//     // 如果没有更多数据,停止播放
//     isRunning.value = false;
//     audio.pause();
//     document.body.removeChild(audio); // 移除音频控件
//   }
// };
</script><style lang="scss" scoped>
.warmTanChuan-container {position: absolute;top: 25%;left: 35%;transform: translate(-50%, -50%);z-index: 999;
}.warmTanChuan {width: 327px;color: #ffffff;.title {height: 40px;line-height: 40px;background: url("@/assets/images/jbbg.png") no-repeat;background-size: 100% 100%;font-weight: bold;padding: 0 10px;font-size: 14px;img {width: 20px;height: 20px;margin: 10px;}.time {float: right;}}.content_text {background-color: #3a0e0b;border: 2px solid #be4b44;padding: 10px;font-size: 14px;position: relative;}
}.scroll-enter-active,
.scroll-leave-active {transition: transform 1s;
}
.scroll-enter {transform: translateY(100%);
}
.scroll-leave-to {transform: translateY(-100%);
}
.test {width: 972px;height: calc(100vh - 440px);background: url("@/assets/images/image2/warm.png") no-repeat;background-size: 100%;position: absolute;top: 96px;left: 50%;transform: translateX(-50%);animation: blink 1s infinite; // 添加闪烁动画
}
// 闪烁动画
@keyframes blink {0%,100% {opacity: 1;}50% {opacity: 0;}
}
</style>

难点:

1.一个是关于弹窗如何控制30s显示然后下一个显示,同时伴有警告声音10s消失?

2.数据如果是一个一个传给你或者是一次性多个传给你,怎么办?

3.闪烁动画怎么做?

先处理第三个问题:首先闪烁动画是一个比较图片的盒子,实现一闪一闪的效果

如下

 

 样式可以这样写

 

 闪烁由数据的长度和isTestVisible共同决定

 <div class="test" v-if="isTestVisible && warmList.length > 0"></div>
.test {width: 972px;height: calc(100vh - 440px);background: url("@/assets/images/image2/warm.png") no-repeat;background-size: 100%;position: absolute;top: 96px;left: 50%;transform: translateX(-50%);animation: blink 1s infinite; // 添加闪烁动画
}
// 闪烁动画
@keyframes blink {0%,            // 动画开始时100% {         // 动画结束时opacity: 1;  // 元素完全可见 (不透明)}50% {          // 动画进行到一半时opacity: 0;  // 元素完全不可见 (透明)}
}

 好 现在解决第一个问题。如何让他实现关于弹窗如何控制30s显示然后下一个显示,同时伴有警告声音10s消失。这边就会说明刚才isTestVisible是什么东西了。

首先还是从样式transition-group 来处理这些警告信息的进入和离开动画。

<template><transition-group name="scroll" tag="div" class="warmTanChuan-container"><divv-if="isRunning && currentItem"class="warmTanChuan"ref="warmTanChuan":key="currentItem.id"><div class="title"><img src="@/assets/images/Frame103(91).png" alt="" /><span v-if="currentItem.deviceType == 1">摄像头警告:</span><span v-if="currentItem.deviceType == 2">灵思传感器警告:</span><span v-if="currentItem.deviceType == 3">大华电气设备警告:</span><span v-if="currentItem.deviceType == 4">消防设备警告:</span><span v-if="currentItem.deviceType == 5">车载设备警告:</span><span v-if="currentItem.deviceType == 6">海康消防设备警告:</span><span v-if="currentItem.deviceType == 7">消防传感器警告:</span><span class="time">{{ time }}s</span></div><div class="content_text"><p>{{ currentItem.incidentDescribe }}</p></div></div></transition-group><div class="test" v-if="isTestVisible && warmList.length > 0"></div>
</template>
  1. transition-group:

    • 名称为 scroll 的 transition-group 组件,用于处理列表项的动画。
    • tag="div" 设置容器元素为 div
    • 内部包含一个动态渲染的 div 元素,用于显示当前警告信息。
  2. div:

    • 根据 isRunning 和 currentItem 的值来决定是否显示警告信息。
    • 使用 :key 绑定唯一的标识符,以便 transition-group 能够正确跟踪元素的变化。
  3. .warmTanChuan-container:

    • 定位样式,使警告信息居中显示。
  4. .test:

    • 一个用于测试的 div 元素,当 isTestVisible 为真时显示,带有闪烁动画。

 第一步肯定是拿到数据 如果没有正在播放的数据才可以播

import { ref, onMounted, watch, computed, onUnmounted, nextTick } from "vue";
import { warmEvents } from "@/api/api.js";
import dayjs from "dayjs";
import useWebSocket, { SocketStatus } from "@/mixins/useWebSocket";
import { getSystemData, userInfo } from "@/api/api";
import eventBus from "@/mixins/eventBus";
const warmList = ref([]);
const queue = ref([]); // 用于存储接收到的警告数据的队列const currentIndex = ref(0);
const time = ref(30);
const isRunning = ref(false);
const isTestVisible = ref(true);let audio = new Audio(require("@/assets/warm.mp3"));
audio.hidden = true; // 隐藏音频控件
document.body.appendChild(audio); // 将音频控件添加到页面中const currentItem = computed(() => {return warmList.value.length > 0 ? warmList.value[currentIndex.value] : null;
});const handleMessage = (msg) => {const data = JSON.parse(msg);queue.value.push(data); // 将新数据添加到队列中if (!isRunning.value && !currentItem.value) {// 如果当前没有正在播放的警告信息,开始播放showNextItem();}
};

下一条给warnList添加数据 同时queue移除

const showNextItem = () => {if (queue.value.length > 0) {warmList.value.push(queue.value.shift()); // 从队列中取出一条数据并添加到warmListconsole.log("queue.value", queue.value);console.log("warmList.value2222", warmList.value);isRunning.value = true; // 标记为正在播放isTestVisible.value = true;time.value = 30; // 重置时间playAudio();//播放声音startCountDown(); // 开始倒计时} else {isRunning.value = false; // 如果队列为空,停止播放isTestVisible.value = false;}
};

 播放声音

const playAudio = () => {audio.currentTime = 0;audio.play().catch((error) => {console.error("Error playing audio:", error);});// 设置定时器,10秒后停止音频setTimeout(() => {audio.pause();}, 10000); // 10000毫秒 = 10秒
};

 开始倒计时

const startCountDown = () => {if (countDown) {clearInterval(countDown); // 清除之前的倒计时定时器}countDown = setInterval(() => {if (isRunning.value) {time.value -= 1;if (time.value <= 0) {clearInterval(countDown);handleAudioEnded();}}}, 1000);
};

 

const handleAudioEnded = () => {if (queue.value.length > 0) {currentIndex.value++;showNextItem();} else {isRunning.value = false; // 没有更多数据,停止播放isTestVisible.value = false;audio.pause();document.body.removeChild(audio); // 移除音频控件}
};

 

watch(currentIndex, () => {if (isRunning.value) {if (countDown) {clearInterval(countDown);startCountDown();}}
});

 因为warmList肯定是有数据的所以再加一个条件isTestVisible来控制闪烁动画。

3.地图部分的数据筛选。

效果如图

代码:

<template><div class="DataSelectModal" ref="DataSelectModal" v-if="isModalVisible"><div class="title">预警数据筛选<imgsrc="@/assets/images/Frame103(37).png"alt=""@click="close"class="closeModals"/></div><div class="warmSelectContent"><div class="slect">常用:<!-- <div class="ofenUse" @click="getTime()">总计</div><div class="ofenUse" @click="getTime(1)">过去24小时</div><div class="ofenUse" @click="getTime(7)">过去7天</div><div class="ofenUse" @click="getTime(30)">过去30天</div><div class="ofenUse" @click="getTime(90)">过去90天</div><div class="ofenUse" @click="getTime(180)">过去180天</div><div class="ofenUse" @click="getTime(365)">过去365天</div> --><divv-for="item in buttonData":key="item.id":class="item.id === selectedButton ? 'selected' : 'ofenUse'"@click="handleButtonClick(item)">{{ item.name }}</div></div><div class="slect">条件筛选:<a-select v-model="selectedYear" :key="resetKey" @change="handleChange"><a-select-option v-for="year in yearArr" :key="year" :value="year">{{ year }} 年</a-select-option></a-select><a-selectv-model="selectedSeason"@change="handleChange2":key="resetKey":disabled="!selectedYear"><a-select-optionv-for="season in seasonArr":key="season.value":value="season.value">{{ season.name }}</a-select-option></a-select><a-selectv-model="selectedMonth"@change="handleChange3":key="selectedSeason + selectedYear"><a-select-optionv-for="(month, index) in monthArr":key="month":value="index":disabled="!selectedYear || !selectedSeason">{{ month }}月</a-select-option></a-select></div><div class="slect">时间筛选:<a-range-pickerv-model:value="datea"separator="至"valueFormat="YYYY-MM-DD"@change="dataCheck"placeholder=""><template #suffixIcon><down-outlined /></template></a-range-picker></div></div><div class="immediately" @click="search">立即查询</div></div>
</template><script setup>
import { ref, watch, onMounted, computed, reactive, nextTick } from "vue";
import { DownOutlined } from "@ant-design/icons-vue";
const emit = defineEmits(["update:start-time", "update:end-time"]);
import dayjs from "dayjs";
// const emit = defineEmits(["close"]);
const DataSelectModal = ref(null);
const isModalVisible = ref(false);
const form = reactive({startTime: "",endDate: "",
});
const time = new Date().getFullYear();
const yearArr = ref([]);
const startTime = ref("");
const endTime = ref("");
const selectedMonth = ref("");
const selectedSeason = ref("");
const selectedYear = ref("");import eventBus from "@/mixins/eventBus";
import { message } from "ant-design-vue";const seasonArr = [{value: 1,name: "第一季度",},{value: 2,name: "第二季度",},{value: 3,name: "第三季度",},{value: 4,name: "第四季度",},
];
const monthArr = ref([]);const initializeYears = () => {var i;for (i = 2024; i <= time; i++) {yearArr.value.push(i);}
};
const datea = ref([]);const buttonData = [{ id: 1, name: "总计", time: 0 },{ id: 2, name: "过去24小时", time: 1 },{ id: 3, name: "过去7天", time: 7 },{ id: 4, name: "过去30天", time: 30 },{ id: 5, name: "过去90天", time: 90 },{ id: 6, name: "过去180天", time: 180 },{ id: 7, name: "过去365天", time: 365 },
];
// 当前选中的按钮ID
const selectedButton = ref(0);
const resetKey = ref(0);
const changeButton = ref("");onMounted(() => {nextTick(() => {// selectedButton.value = 1;});initializeYears();// getTime();
});
// 处理按钮点击事件
const handleButtonClick = (date) => {selectedYear.value = null;selectedSeason.value = null;selectedMonth.value = null;datea.value = [];selectedButton.value = date.id;resetKey.value++; // 触发组件重新渲染// const resetKey = selectedYear.value + "_" + selectedSeason.value;nextTick(() => {console.log(" selectedYear.value", selectedYear.value);console.log(" selectedSeason.value", selectedSeason.value);console.log(" selectedMonth.value", selectedMonth.value);});getTime(date.time);changeButton.value = date.name;
};// const date = computed({
//   get() {
//     // if (!form.startTime || !form.endTime)
//     //   return [
//     //     dayjs().subtract(3, "day").format("YYYY-MM-DD HH:mm:ss"),
//     //     dayjs().format("YYYY-MM-DD HH:mm:ss"),
//     //   ];
//     return [
//       dayjs().format("YYYY-MM-DD HH:mm:ss"),
//       dayjs().format("YYYY-MM-DD HH:mm:ss"),
//     ];
//   },
//   set(date) {
//     console.log("date: ", date);
//     selectedButton.value = null;
//     startTime.value = date[0];
//     endTime.value = date[1];
//   },
// });const showModal = () => {isModalVisible.value = true;selectedSeason.value = null;selectedMonth.value = null;datea.value = null;selectedYear.value = null;startTime.value = null;endTime.value = null;// selectedButton.value = 1;changeButton.value = "";
};
const close = () => {isModalVisible.value = false;selectedMonth.value = "";
};const getTime = (data) => {if (data) {startTime.value = dayjs().subtract(data, "day").format("YYYY-MM-DD HH:mm:ss");endTime.value = dayjs().format("YYYY-MM-DD HH:mm:ss");console.log("startDate: ", startTime.value);console.log("endTime: ", endTime.value);} else {startTime.value = null;endTime.value = null;}
};const handleChange = (value) => {console.log("value", value);selectedYear.value = value;selectedSeason.value = null;selectedMonth.value = null;selectedButton.value = null;datea.value = [];updateStartEndTime();changeButton.value = "条件筛选";// console.log("queryParam", queryParam.value.deviceType);
};
const handleChange2 = (value) => {console.log("value", value);selectedSeason.value = value;selectedButton.value = null;selectedMonth.value = null; // 先清空月份monthArr.value = []; // 清空月份数组switch (Number.parseInt(value)) {case 1:monthArr.value = [1, 2, 3];break;case 2:monthArr.value = [4, 5, 6];break;case 3:monthArr.value = [7, 8, 9];break;case 4:monthArr.value = [10, 11, 12];break;}updateStartEndTime();
};const handleChange3 = (value) => {console.log("value", value);selectedMonth.value = value;selectedButton.value = null;updateStartEndTime();// console.log("queryParam", queryParam.value.deviceType);
};const updateStartEndTime = () => {console.log(111);if (selectedYear.value && selectedSeason.value) {// 如果选择了年和季度const seasonStartMonth = monthArr.value[0] - 1;const seasonEndMonth = monthArr.value[2];startTime.value = dayjs(new Date(selectedYear.value, seasonStartMonth, 1)).startOf("month").format("YYYY-MM-DD HH:mm:ss");endTime.value = dayjs(new Date(selectedYear.value, seasonEndMonth, 0)).endOf("month").format("YYYY-MM-DD HH:mm:ss");console.log("startDate: ", startTime.value);console.log("endTime: ", endTime.value);} else if (selectedYear.value &&selectedSeason.value &&selectedMonth.value !== "") {// 如果选择了年、季度和月份// 如果 monthArr.value 是 ['01', '02', '03'] 并且 selectedMonth.value 是 1,那么 month 的值将会是 2。// 如果 monthArr.value 是 [1, 2, 3],并且 selectedMonth.value 是 1,那么 month 的值将会是 2。parseInt(2, 10) 仍然返回 2。const month = parseInt(monthArr.value[selectedMonth.value], 10);startTime.value = dayjs(new Date(selectedYear.value, month - 1, 1)).startOf("month").format("YYYY-MM-DD HH:mm:ss");endTime.value = dayjs(new Date(selectedYear.value, month, 0)).endOf("month").format("YYYY-MM-DD HH:mm:ss");console.log("startDate: ", startTime.value);console.log("endTime: ", endTime.value);} else if (selectedYear.value && selectedSeason.value) {// 如果选择了年和季度const seasonStartMonth = monthArr.value[0] - 1;const seasonEndMonth = monthArr.value[2];startTime.value = dayjs(new Date(selectedYear.value, seasonStartMonth, 1)).startOf("month").format("YYYY-MM-DD HH:mm:ss");endTime.value = dayjs(new Date(selectedYear.value, seasonEndMonth, 0)).endOf("month").format("YYYY-MM-DD HH:mm:ss");console.log("startDate: ", startTime.value);console.log("endTime: ", endTime.value);} else if (selectedYear.value) {// 如果只选择了年startTime.value = dayjs(new Date(selectedYear.value, 0, 1)).startOf("year").format("YYYY-MM-DD HH:mm:ss");endTime.value = dayjs(new Date(selectedYear.value, 11, 31)).endOf("year").format("YYYY-MM-DD HH:mm:ss");console.log("startDate: ", startTime.value);console.log("endTime: ", endTime.value);}
};const search = () => {if (!changeButton.value) {message.error("请选择查询时间范围");returm;} else {emit("update:start-time", startTime.value);emit("update:end-time", endTime.value);emit("changeButton", changeButton.value);console.log("查询时间范围:", startTime.value, endTime.value);close();}
};const dataCheck = (data) => {console.log("Range picker clicked:", data);startTime.value = data[0];endTime.value = data[1];resetKey.value++; // 触发组件重新渲染console.log("startDate: ", startTime.value);console.log("endTime: ", endTime.value);selectedSeason.value = null;selectedMonth.value = null;selectedYear.value = null;selectedButton.value = null;changeButton.value = "时间筛选";// 在这里处理点击事件
};//  onChangeTime (data) {
//     if (data.length != 0) {
//       this.queryParam.startDate = data[0];
//       this.queryParam.endDate = data[1];
//     } else {
//       delete this.queryParam.startDate;
//       delete this.queryParam.endDate;
//     }
//   },defineExpose({//   close,showModal,
});
</script><style lang="scss" scoped>
.DataSelectModal {position: relative;font-size: 14px;width: 800px;height: 296px;color: #ffffff;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);z-index: 999;background: url("@/assets/images/image2/selectbox.png") no-repeat;background-size: 100%;.title {height: 40px;line-height: 40px;padding-left: 20px;font-size: 14px;.closeModals {float: right;width: 24px;height: 24px;margin: 5px;cursor: pointer;}}.warmSelectContent {padding: 20px;.slect {display: flex;align-items: center;margin-bottom: 20px;.ofenUse {font-size: 12px;background: #042931;border-radius: 4px;border: 1px solid #0a8fab;margin-right: 20px;padding: 5px;cursor: pointer;}.selected {font-size: 12px;background: #148aa5;border-radius: 4px;border: 1px solid #0a8fab;margin-right: 20px;padding: 5px;cursor: pointer;}}}.immediately {position: absolute;bottom: 10%;left: 50%;transform: translateX(-50%);width: 104px;height: 44px;line-height: 44px;text-align: center;background: #134451;border-radius: 4px;border: 1px solid #165a6b;cursor: pointer;}:deep(.ant-select-selector) {background: #134451 !important;border: 1px solid #165a6b !important;color: #fff;width: 120px !important;line-height: 35px !important;height: 35px !important;}:deep(.ant-select-selection-item) {line-height: 35px !important;}
}
:deep(.ant-picker-range) {width: 300px !important;
}
</style>

 关于下拉框无法置空

这边的难点是关于下拉框是三级联动同时3种筛选选择其中一种的时候,其他两种都必须置为空。难就难在下拉框无法置空踩的坑。后面发现双向绑定还是无法置空 可以重置他们的key

有几个地方需要理解下

关于十进制的用法

 // 如果 monthArr.value 是 ['01', '02', '03'] 并且 selectedMonth.value 是 1,那么 month 的值将会是 2。// 如果 monthArr.value 是 [1, 2, 3],并且 selectedMonth.value 是 1,那么 month 的值将会是 2。parseInt(2, 10) 仍然返回 2。const month = parseInt(monthArr.value[selectedMonth.value], 10);

 关于一个月的开始和尾巴

 // 创建一个日期对象,表示selectedYear.value年seasonStartMonth月的第一天。startTime.value = dayjs(new Date(selectedYear.value, seasonStartMonth, 1)).startOf("month").format("YYYY-MM-DD HH:mm:ss");// 这里0表示该月的最后一天。endTime.value = dayjs(new Date(selectedYear.value, seasonEndMonth, 0)).endOf("month").format("YYYY-MM-DD HH:mm:ss");

 

http://www.zhongyajixie.com/news/40501.html

相关文章:

  • 营销型网站建设推广广州今日头条新闻最新
  • 哈尔滨 网站建设google关键词优化
  • 定制网站的好处网页开发需要学什么
  • 服装行业网站建设比较好网络推广方式主要有
  • 成都网站建设推进方案凡科网站建站教程
  • 枣庄住房和城乡建设局网站整合营销网络推广
  • 网站设计一般多少钱余姚网站制作公司
  • dw wordpress优化网络搜索引擎
  • wordpress简洁设置济南seo培训
  • web开发就是做网站吗电商运营工作内容
  • 给网站做seo诊断怎么做电商平台
  • 东莞企业免费建站东莞网络推广培训
  • 东莞企石网站建设西地那非片的功效与作用
  • 网站备案号的区别google网页版登录入口
  • 宝鸡做网站市场怎么样网络广告营销案例有哪些
  • 网站开发要会英语吗广东公共广告20120708
  • 淮南网站建设科技有限公司长春网站快速优化排名
  • 给网站公司做网站简述什么是seo
  • 梅州市做试块网站怀柔网站整站优化公司
  • 普通高等学校健康驿站建设指引石家庄最新新闻事件
  • 网站设计需要哪些技能网络营销方式有几种
  • 甘肃网站建设搭建网站需要哪些步骤
  • wordpress宝塔安装环境seo自然搜索优化排名
  • 怎么建电子商务网站成都网站快速优化排名
  • 特产网站建设规划书公司软文
  • 企业官网响应式网站品牌营销案例分析
  • h5网站制作价格东莞做网站推广
  • 东莞网站建设分享seo成人技能培训班有哪些
  • 做网站分层技术google下载安卓版下载
  • 定制型网站建设服务器全球搜索