vue中一周的时间选择多个阶段(手动表格选择)

news/2024/7/8 12:23:30 标签: vue.js, 前端, javascript

 先给大家看一下效果图

 源代码

<template>
	<div style="width: 45%">
		<div style="width: 100%">
			<div class="time">
				<div class="timeleft">星期/时间</div>
				<div class="timeright">
					<div class="timeright_cell">
						<el-row :gutter="0">
							<el-col :span="12">
								<div class="topitem" style="font-size: 12px; font-weight: bold">
									00:00~12:00
								</div>
							</el-col>
							<el-col :span="12">
								<div class="topitem" style="font-size: 12px; font-weight: bold">
									12:00~24:00
								</div>
							</el-col>
						</el-row>
					</div>
					<div class="timeright_cell" style="color: #333333">
						<el-row :gutter="0">
							<el-col
								:span="1"
								v-for="(item, index) in 24"
								:key="item"
								@click="clicktime(index)"
							>
								<div
									class="topitem"
									:style="{ '--bgColor': bgColor }"
									:class="{ is_selected: isTimeSelected(index) }"
								>
									{{ index }}
								</div>
							</el-col>
						</el-row>
					</div>
				</div>
			</div>
			<div class="time">
				<div style="width: 8.8%">
					<div
						class="timelefts"
						:style="{ '--bgColor': bgColor }"
						:class="{ is_selected: isDaySelected(index) }"
						v-for="(dayName, index) in [
							'星期一',
							'星期二',
							'星期三',
							'星期四',
							'星期五',
							'星期六',
							'星期日'
						]"
						:key="dayName"
						@click="clickDay(index)"
					>
						{{ dayName }}
					</div>
				</div>

				<div class="objects" ref="objectsRef" @mousedown="handleMouseDown">
					<!-- 矩形选择框 -->
					<div
						class="mask"
						ref="maskRef"
						v-show="maskPosition.show"
						:style="
							'width:' +
							maskWidth +
							'left:' +
							maskLeft +
							'height:' +
							maskHeight +
							'top:' +
							maskTop
						"
					/>

					<!-- 选择对象内容的目标插槽 -->
					<!-- <slot name="selcetObject" /> -->
					<div class="objects_content">
						<div
							v-for="item in weekData"
							:key="item.id"
							class="select_object"
							:day_index="item.daynum"
							:time_index="item.timenum"
							:object_id="item.id"
							:class="{ is_selected: item.status }"
							:style="{ '--bgColor': bgColor }"
						>
							<!-- {{ item.id }} -->
						</div>
					</div>
				</div>
			</div>
			<!-- 鼠标画矩形选择对象 -->
		</div>
		<div class="box">
			<div>
				<div class="dt">已选择时间段</div>
				<!-- 按钮-->
				<el-button v-for="button in buttons" :key="button.text" :type="button.type" link>
					{{ button.text }}
				</el-button>
			</div>
			<div class="dtime">
				<ul
					v-for="item in weekData
						.filter((t) => t.status == true)
						.reduce(
							(prev, curr) =>
								prev.find((t) => t.daynum == curr.daynum) ? prev : [...prev, curr],
							[]
						)"
				>
					星期{{
						convertSum(item.daynum)
					}}:
					<span class="dts" v-for="item in tList(item.daynum)">
						{{ convertTime(item) }}
						<!--{{ item.timenum - 1 }}:{{ item.id % 2 == 0 ? "30" : "00" }} ~{{ item.timenum - 1 }}:{{ item.id % 1 == 0 ? "30" : "00" }}-->
					</span>
				</ul>
			</div>
		</div>
	</div>
</template>

<script lang="ts" setup>
import { reactive, toRefs, ref, computed, onMounted, onBeforeMount } from "vue";
//数据格式1:默认0或者1,数据格式2:json字符串(x-(1-7)对应周一到周日), 如timeSet=”{‘1’:‘1,2,3’}”表示周一的0:30-1:00,1:00-1:30,1:30-2:00为播放时间,数据格式3:字符串,xHHmm x为1-7对应周一到周日,HH为小时,mm,00或30  00表示00-30这半小时, 30表示30-00这半小时
// 数据格式2:
// 格式为json字符串,(x-(1-7)对应周一到周日), 如timeSet=”{‘1’:‘1,2,3’}”表示周一的0:30-1:00,1:00-1:30,1:30-2:00为播放时间,
// 数据格式3:
// 格式是字符串,xHHmm     x为1-7对应周一到周日,HH为小时,mm,00或30  00表示00-30这半小时, 30表示30-00这半小时
// 10600,10630,10700,10730,10800,10830,10900,10930,11000,11030,11100,11130,11200,11230,11300,11330,11400,11430,11500,11530,11600,11630,11700,11730,11800,11830,11900,11930,12000,12030,12100,12130,12200,12230,12300,12330,20600,20630,20700,20730,20800,20830,20900,20930,21000,21030,21100,21130,21200,21230,21300
const clientX = ref(0);
const clientY = ref(0);

const props = withDefaults(
	defineProps<{
		datatype?: number; //数据类型
		week?: String; //绑定数组
		objectClassName?: string; // 选择对象的class name,用于定义如何获取对象
		objectIdName?: string; // 选择对象的id name,用于定义如何获取对象的id
		useCtrlSelect?: boolean; // 是否支持按住Ctrl多选
		bgColor?: string; //选中的背景色
	}>(),
	{
		datatype: 1,
		objectClassName: "select_object",
		objectIdName: "object_id",
		bgColor: "#197afb",
		useCtrlSelect: false // 默认支持按住Ctrl多选
	}
);
function findTimeInterval(arr) {
	if (arr.length === 0) return [];

	let intervals = [];
	let startTime = arr[0];
	let endTime = arr[0];

	for (let i = 1; i < arr.length; i++) {
		if (arr[i] === endTime + 1) {
			endTime = arr[i];
		} else {
			intervals.push({ startTime: startTime, endTime: endTime });
			startTime = arr[i];
			endTime = arr[i];
		}
	}
	intervals.push({ startTime: startTime, endTime: endTime });

	return intervals;
}

const convertTime = (items) => {
	let result = "";
	// 	<!--{{ item.timenum - 1 }}:{{ item.id % 2 == 0 ? "30" : "00" }} ~{{ item.timenum - 1 }}:{{ item.id % 1 == 0 ? "30" : "00" }}-->
	let list = items.map((el) => el.id);
	let convertList = findTimeInterval(list);
	console.log("转换后的", convertList);
	if (convertList?.length > 0) {
		convertList.forEach((el) => {
			let start = items.find((item) => el.startTime == item.id);
			let end = items.find((item) => el.endTime == item.id);
			console.log("end", end);
			if (el.startTime == el.endTime) {
				let startStr = `${formatNum(start.timenum - 1)} : ${start.id % 2 == 0 ? "30" : "00"} `;
				let endStr = "";
				if (end.id % 2 != 0) {
					endStr = `${formatNum(end.timenum - 1)} : 30`;
				} else {
					endStr = `${formatNum(end.timenum)} : 00`;
				}
				result += `${startStr} ~ ${endStr}`;
			} else {
				// 不一致 的
				let endStr = "";
				let startStr = `${formatNum(start.timenum - 1)} : ${start.id % 2 == 0 ? "30" : "00"} `;
				// 结束时间存在问题, 单个多半个小时
				if (el.endTime % 2 == 0) {
					endStr = `${formatNum(end.timenum)} : 00`;
				} else {
					endStr = `${formatNum(end.timenum - 1)} : 30`;
				}
				result += `${startStr} ~ ${endStr}`;
			}
		});
	}
	return result;
};

const formatNum = (num) => {
	return num < 10 ? `0${num}` : num;
}

/**
 * 转换星期
 * @param daynum
 */
const convertSum = (daynum) => {
	switch (daynum) {
		case 1:
			return "一";
		case 2:
			return "二";
		case 3:
			return "三";
		case 4:
			return "四";
		case 5:
			return "五";
		case 6:
			return "六";
		case 7:
			return "日";
	}
};

const tempStr = ref([]);
const tempStrComputed = computed(() => {
	return JSON.stringify(tempStr);
});

const tList = (daynum) => {
	let tArr = [];
	let tItem = [];
	let dayList = weekData.value
		.filter((t) => t.status == true)
		.reduce(
			(prev, curr) => (prev.find((t) => t.daynum == curr.daynum) ? prev : [...prev, curr]),
			[]
		);
	let dayAllDataList = weekData.value.filter((t) => t.daynum == daynum);
	for (let i = 0; i < dayAllDataList.length; i++) {
		let item = dayAllDataList[i];
		if (item.status == false) {
			if (tItem.length > 0) {
				tArr.push(new Array(...tItem));
				tItem.length = 0;
			}
		} else tItem.push(item);
	}
	if (tItem.length > 0) {
		tArr.push(new Array(...tItem));
		tItem.length = 0;
	}
	return tArr;
};

// const tList = computed(() => {
// 	console.log('tList');
// 	let tArr = [];
// 	let tItem = [];
// 	let dayList = weekData.value.filter(t=>t.status==true).reduce((prev, curr) => prev.find(t=>t.daynum == curr.daynum) ? prev : [...prev, curr], [])
// 	let dayAllDataList = weekData.value.filter(t=>t.daynum==2);
//
// 	for (let i = 0; i < dayAllDataList; i++) {
// 		let item = dayAllDataList[i];
// 		if(item.status==false){
// 			if (tItem.length > 0) {
// 				tArr.push(tItem);
// 				tItem.length = 0;
// 			}
// 		}else
// 			tItem.push(item);
// 	}
// 	return tArr;
// })
const hasHandleObjectIds = ref<number[]>([]); //已处理id数组
// 全局计数器
let uniqueId = 1;
// 初始化 weekData
const weekData = ref([] as any);
// 初始化 weekData 中的 hours
onMounted(() => {
	for (let i = 0; i < 7; i++) {
		for (let hour = 0, timenum = 1; hour < 48; hour += 2) {
			weekData.value.push({ id: uniqueId++, status: false, daynum: i + 1, timenum: timenum });
			weekData.value.push({ id: uniqueId++, status: false, daynum: i + 1, timenum: timenum });
			timenum = (timenum % 24) + 1; // 使 timenum 在 1 到 24 之间循环
		}
	}
	if (props.week) {
		datahandle();
	}
});

//初始化处理数据
const datahandle = () => {
	let data: any = props.week === undefined ? [] : props.week;
	if (props.datatype == 1) {
		for (let i = 0; i < data.length; i++) {
			if (Number(data[i]) == 1) {
				weekData.value[i].status = true;
			}
		}
	} else if (props.datatype == 2) {
		let obj: any = JSON.parse(data);
		for (const key in obj) {
			let value = obj[key].split(",");
			for (let i = 0; i < weekData.value.length; i++) {
				const element = weekData.value[i];
				if (element.daynum == key) {
					if (value.includes(String(i))) {
						weekData.value[i].status = true;
					}
				}
			}
		}
	} else if (props.datatype == 3) {
		let array = data.split(",");
		for (let i = 0; i < array.length; i++) {
			const element = array[i];
			const dayNum = Number(element.slice(0, 1));
			const hourNum = Number(element.slice(1, 3).replace(/\b(0+)/gi, ""));
			const timeNum = element.slice(3, 5);
			for (let i = 0; i < weekData.value.length; i++) {
				const element = weekData.value[i];
				if (element.daynum == dayNum && element.timenum == hourNum) {
					if (timeNum == "00") {
						if (i % 2 === 0) {
							weekData.value[i].status = true;
						}
					} else {
						if (i % 2 !== 0) {
							weekData.value[i].status = true;
						}
					}
				}
			}
		}
	}
};

const isDaySelected = computed(() => {
	return (index) => {
		if (weekData.value && weekData.value.length > 0) {
			return weekData.value
				.filter((t) => t.daynum === index + 1)
				.every((item) => item.status === true);
		}
		return false;
	};
});

const isTimeSelected = computed(() => {
	return (index) => {
		if (weekData.value && weekData.value.length > 0) {
			return weekData.value
				.filter((t) => t.timenum === index + 1)
				.every((item) => item.status === true);
		}
		return false;
	};
});

const objectsRef = ref();
const maskRef = ref();
const emits = defineEmits(["update:week"]);
const state = reactive({
	maskPosition: {
		show: false,
		startX: 0,
		startY: 0,
		endX: 0,
		endY: 0
	}, // 矩形框位置
	isPressCtrlKey: false // 是否按下了Ctrl键
});
const { maskPosition, isPressCtrlKey } = toRefs(state);

// 若支持按住Ctrl多选,监听Ctrl事件
if (props.useCtrlSelect) {
	// 释放
	document.addEventListener("keyup", (event) => {
		if (event.keyCode === 17) {
			isPressCtrlKey.value = false;
		}
	});
	// 按下
	document.addEventListener("keydown", (event) => {
		if (event.keyCode === 17) {
			isPressCtrlKey.value = true;
		}
	});
}
//点击星期天数的事件
const clickDay = (index) => {
	// var weekData: Array<any> = [];
	// weekData = weekData === undefined ? [] : weekData;
	// const hours = weekData[index].hours;
	// const allIn = hasHandleObjectIds.value.every(item => weekData.includes(item));
	const arr = weekData.value.filter((t) => t.daynum == index + 1);
	const allIn = arr.every((item) => item.status === true);
	if (allIn) {
		arr.forEach((e) => {
			e.status = false;
			hasHandleObjectIds.value.splice(
				hasHandleObjectIds.value.findIndex((t) => t == e.id),
				1
			);
		});
	} else {
		arr.forEach((e) => {
			e.status = true;
			hasHandleObjectIds.value.push(e.id);
		});
	}
	emits("update:week", handlerdata());
};

// 点击时间点数
const clicktime = (index) => {
	const arr = weekData.value.filter((t) => t.timenum == index + 1);
	const allIn = arr.every((item) => item.status === true);
	if (allIn) {
		arr.forEach((e) => {
			e.status = false;
			hasHandleObjectIds.value.splice(
				hasHandleObjectIds.value.findIndex((t) => t == e.id),
				1
			);
		});
	} else {
		arr.forEach((e) => {
			e.status = true;
			hasHandleObjectIds.value.push(e.id);
		});
	}
	emits("update:week", handlerdata());
};
/** 鼠标按下 */
const handleMouseDown = (event) => {
	//点下时清空已处理数组
	hasHandleObjectIds.value.length = 0;
	var id = Number(event.target.getAttribute(props.objectIdName));
	// var weekData: Array<any> = [];
	// weekData = weekData === undefined ? [] : weekData;
	// const hourItem = weekData.flatMap(day => day.hours).find(item => item.id === id);
	const index = weekData.value.findIndex((t) => t.id == id);
	if (index > -1) {
		weekData.value[index].status = !weekData.value[index].status;
	}
	if (!hasHandleObjectIds.value.includes(id)) {
		hasHandleObjectIds.value.push(id);
	} else {
		hasHandleObjectIds.value.splice(
			hasHandleObjectIds.value.findIndex((t) => t == id),
			1
		);
	}
	// 展示矩形框,通过坐标位置来画出矩形
	maskPosition.value.show = true;
	maskPosition.value.startX = event.clientX;
	maskPosition.value.startY = event.clientY;
	maskPosition.value.endX = event.clientX;
	maskPosition.value.endY = event.clientY;
	// 监听鼠标移动事件和抬起离开事件
	objectsRef.value.addEventListener("mousemove", handleMouseMove);
	objectsRef.value.addEventListener("mouseup", handleMouseUp);
};

/** 鼠标移动 */
const handleMouseMove = (event) => {
	if (clientX.value !== event.clientX || clientY.value !== event.clientY) {
		clientX.value = event.clientX;
		clientY.value = event.clientY;
		maskPosition.value.endX = event.clientX;
		maskPosition.value.endY = event.clientY;
		// var weekData: Array<any> = [];
		// weekData = props.weekData === undefined ? [] : props.weekData;
		const selectedObjects = objectsRef.value.querySelectorAll(`.${props.objectClassName}`);
		// 获取鼠标画出的矩形框位置
		const rectanglePosition = maskRef.value.getClientRects()[0];
		var rectangleSelObjects: Array<number> = []; //矩形框内的id数组
		selectedObjects.forEach((item) => {
			const objectPosition = item.getClientRects()[0];
			// 这里获取的id的方式定义于父组件的objectIdName
			if (compareObjectPosition(objectPosition, rectanglePosition)) {
				let id = item.getAttribute(props.objectIdName);
				rectangleSelObjects.push(Number(id));
			}
		});
		let handle = (id: number) => {
			const index = weekData.value.findIndex((t) => t.id == id);
			if (index > -1) weekData.value[index].status = !weekData.value[index].status;
			// let index = tempSelectObjectIds.findIndex(t => t == id);
		};
		// 处理存在于 hasHandleObjectIds 中但不在 rectangleSelObjects 中的元素
		for (let i = hasHandleObjectIds.value.length - 1; i >= 0; i--) {
			const id = hasHandleObjectIds.value[i];
			if (!rectangleSelObjects.includes(id)) {
				handle(id);
				hasHandleObjectIds.value.splice(i, 1);
			}
		}

		// 处理存在于 rectangleSelObjects 中但不在 hasHandleObjectIds 中的元素
		for (const id of rectangleSelObjects) {
			if (!hasHandleObjectIds.value.includes(id)) {
				handle(id);
				hasHandleObjectIds.value.push(id);
			}
		}
		// emits("update:weekData", weekData);
		// emits("update:selectObjectIds", tempSelectObjectIds);
	}
};

/** 鼠标抬起离开 */
const handleMouseUp = () => {
	// 移除鼠标监听事件
	objectsRef.value.removeEventListener("mousemove", handleMouseMove);
	objectsRef.value.removeEventListener("mouseup", handleMouseUp);
	maskPosition.value.show = false;
	handleResetMaskPosition();
	emits("update:week", handlerdata());
};

const handlerdata = () => {
	let arr = weekData.value;
	tempStr.value.push(Date.now() + "");
	if (props.datatype == 1) {
		let array = [] as any;
		for (let i = 0; i < arr.length; i++) {
			const element = arr[i];
			if (element.status) {
				array.push(1);
			} else {
				array.push(0);
			}
		}
		return array.join("");
	}
	if (props.datatype == 2) {
		let obj = {};
		for (let i = 0; i < arr.length; i++) {
			const element = arr[i];
			if (element.status) {
				if (obj[element.daynum]) {
					obj[element.daynum].push(i);
				} else {
					obj[element.daynum] = [i];
				}
			}
		}
		for (let key in obj) {
			if (Array.isArray(obj[key])) {
				obj[key] = obj[key].join(","); // 使用逗号连接数组中的元素
			}
		}
		// console.log(JSON.stringify(obj));
		return JSON.stringify(obj);
	}
	if (props.datatype == 3) {
		let array = [] as any;
		for (let i = 0; i < arr.length; i++) {
			const element = arr[i];
			if (element.status) {
				let day = String(element.daynum);
				let time = element.timenum < 10 ? "0" + element.timenum : String(element.timenum);
				let finalStr;
				if (i % 2 === 0) {
					finalStr = day + time + "00";
				} else {
					finalStr = day + time + "30";
				}
				array.push(finalStr);
			}
		}
		return array.toString();
	}
	// return arr.filter(item => item.status == true);
};
/**
 * 判断对象坐标是否在鼠标画出的矩形框坐标位置内
 * @param objectPosition 对象坐标位置
 * @param rectanglePosition 鼠标画出的矩形框坐标位置
 */
const compareObjectPosition = (objectPosition, rectanglePosition) => {
	const maxX = Math.max(
		objectPosition.x + objectPosition.width,
		rectanglePosition.x + rectanglePosition.width
	);
	const maxY = Math.max(
		objectPosition.y + objectPosition.height,
		rectanglePosition.y + rectanglePosition.height
	);
	const minX = Math.min(objectPosition.x, rectanglePosition.x);
	const minY = Math.min(objectPosition.y, rectanglePosition.y);
	return (
		maxX - minX <= objectPosition.width + rectanglePosition.width &&
		maxY - minY <= objectPosition.height + rectanglePosition.height
	);
};

/** 重置鼠标位置 */
const handleResetMaskPosition = () => {
	maskPosition.value.startX = 0;
	maskPosition.value.startY = 0;
	maskPosition.value.endX = 0;
	maskPosition.value.endY = 0;
};

/** 通过鼠标位置实时计算矩形框大小 */
const maskWidth = computed(() => {
	return `${Math.abs(maskPosition.value.endX - maskPosition.value.startX)}px;`;
});
const maskHeight = computed(() => {
	return `${Math.abs(maskPosition.value.endY - maskPosition.value.startY)}px;`;
});
const maskLeft = computed(() => {
	return `${Math.min(maskPosition.value.startX, maskPosition.value.endX)}px;`;
});
const maskTop = computed(() => {
	return `${Math.min(maskPosition.value.startY, maskPosition.value.endY)}px;`;
});

const buttons = [{ type: "primary", text: "清空选择" }] as const;
</script>

<style scoped lang="scss">
.dtime {
	line-height: 22px;
	margin-top: 10px;
	padding: 5px;
	color: #6c757d;
	font-size: 12px;
	transform: translateY(-20px);
}

.dt {
	line-height: 22px;
	padding: 4px;
	color: #6c757d;
	font-size: 13px;
	display: inline-block;
}

.dts {
	color: #000000;
	font-size: 12px;
	padding: 15px;
}

.box {
	width: 100%;
	border-left: #909399 1px solid;
	border-bottom: #909399 1px solid;
	border-right: #909399 1px solid;
}

.el-button {
	justify-content: flex-end;
	margin-left: 90%;
	display: inline-block;
	line-height: 22px;
	transform: translateY(-28px);
}

.time {
	width: 100%;
	display: flex;
	align-items: center;
	font-size: 10px;
	color: #222222;
	// border: #999 1px solid;
	.timeleft {
		width: 8.75%;
		height: 45.8px;
		display: flex;
		align-items: center;
		justify-content: center;
		background: #f5f7fa;
		border-bottom: #999 1px solid;
		border-top: #999 1px solid;
		border-left: #999 1px solid;
		box-sizing: border-box;
		font-size: 10px;
	}

	.timeright {
		height: 44.9px;
		background: #f5f7fa;
		width: 100%;
		border-right: #999 1px solid;
		box-sizing: border-box;
		border-top: #999 1px solid;
		font-size: 10px;

		.timeright_cell {
			border-bottom: #999 1px solid;
			box-sizing: border-box;

			.topitem {
				height: 21.5px;
				display: flex;
				align-items: center;
				justify-content: center;
				border-left: #999 1px solid;
				text-align: center;
				box-sizing: border-box;
			}
		}
	}

	.timelefts {
		height: 40px;
		display: flex;
		align-items: center;
		justify-content: center;
		background: #f5f7fa;
		border-bottom: #999 1px solid;
		border-left: #999 1px solid;
		border-right: #999 1px solid;
		box-sizing: border-box;
	}

	.is_selected {
		background: var(--bgColor);
		color: #fff;
	}

	.objects {
		height: 100%;
		width: 100%;
		// overflow-y: auto;

		.mask {
			position: fixed;
			background: #409eff;
			opacity: 0;
			z-index: 100;
		}

		.objects_content {
			user-select: none;
			display: flex;
			flex-wrap: wrap;

			div {
				display: flex;
				align-items: center;
				justify-content: center;
				width: 2.083%;
				height: 40px;
				box-sizing: border-box;
				border-bottom: #999 1px solid;
				border-right: #999 1px solid;
			}
		}
	}
}
</style>

 

 


http://www.niftyadmin.cn/n/5537228.html

相关文章

HTMLCSS(入门)

HTML <html> <head><title>第一个页面</title></head><body>键盘敲烂&#xff0c;工资过万</body> </html> <!DOCTYPE>文档类型声明&#xff0c;告诉浏览器使用哪种HTML版本显示网页 <!DOCTYPE html>当前页面采取…

JavaScript基础-函数(完整版)

文章目录 函数基本使用函数提升函数参数arguments对象&#xff08;了解&#xff09;剩余参数(重点)展开运算符(...) 逻辑中断函数参数-默认参数函数返回值-return作用域(scope)全局作用域局部作用域变量的访问原则垃圾回收机制闭包 匿名函数函数表达式立即执行函数 箭头函数箭头…

springboot封装请求参数json的源码解析

源码位置&#xff1a; org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver#readWithMessageConverters(org.springframework.http.HttpInputMessage, org.springframework.core.MethodParameter, java.lang.reflect.Type…

相机、镜头基础知识及硬件选型介绍

工业相机基础知识 1.相机Binning(图像读出模式)功能:将相邻的几个像素合并成一个像素,其优点如下:1)可提高信噪比至sqr(mn)倍;2)可提高帧速至mn倍;3)可提高像素响应度。 2.相机芯片中定义1英寸=16mm,不等于25.4mm 3.相机的作用及基本成像过程:通过光电反应将光…

2024攻防演练:亚信安全新一代WAF,关键时刻守护先锋

实网攻防 网络安全如同一面坚固的盾牌&#xff0c;保护着我们的信息资产免受无孔不入的威胁。而其中&#xff0c;WAF就像网络安全的守门员&#xff0c;关键时刻挺身而出&#xff0c;为您的企业筑起一道坚实的防线。 攻防不对等 防守方实时应答压力山大 在攻防对抗中&#xf…

B+树的元素检索过程

B树的检索方式主要是通过从根节点开始逐层向下搜索&#xff0c;直到找到目标数据或确定目标数据不存在为止。具体的检索过程如下&#xff1a; 从根节点开始&#xff1a; 初始时&#xff0c;从B树的根节点开始查找。 节点内部的查找&#xff1a; 在每个非叶子节点中&#xff0c…

SQLyog脚本无限试用重置脚本

文章目录 引言脚本(win)必要操作、说明 引言 SQLyog 需要po jie&#xff0c;但是网上的没看到很好使的&#xff0c;直接下的官方。能处理14天试用也是很ok的。 脚本(win) echo offREM SQLyog注册表key&#xff0c;可能跟你的不一样&#xff0c;如果不一样&#xff0c;请替换…

一本超简单能用Python实现办公自动化的神书!让我轻松摆脱办公烦恼!

《超简单&#xff1a;用Python让Excel飞起来》 这本书旨在通过Python与Excel的“强强联手”&#xff0c;为办公人员提供一套高效的数据处理方案。书中还介绍了如何在Excel中调用Python代码&#xff0c;进一步拓宽了办公自动化的应用范围。 全书共9章。第1~3章主要讲解Python编…