设备状态图表-甘特图

news2024/11/28 16:33:29

1.背景:设备状态监控图表,监控不同状态的时间段,可以使用甘特图来展示效果
在这里插入图片描述
鼠标经过时的数据提示框
在这里插入图片描述
在这里插入图片描述
2、代码实现

<template>
  <div
    ref="ganttChartRefs"
    :style="{ height: '6.2rem', width: '100%' }"
    class="bg_screen"
  ></div>
</template>
<script lang="ts" setup>
import { onMounted, ref, watch, nextTick,onBeforeUnmount } from "vue";
import * as echarts from "echarts";
// import { GaugeChart } from "echarts/charts";
import { useDebounceFn, useResizeObserver } from "@vueuse/core";
// echarts.use([GaugeChart]); // 引入仪表盘 看版本 echart5以上不需要引入
const chartInstance = ref<any>(null);
const ganttChartRefs = ref<any>(null);
const myChart = ref<any>(null);
const props = defineProps({
  chartData: {
    type: Array,
    default: () => [],
  },
});
function setChartOptions(data:any) {
  myChart.value = echarts.init(ganttChartRefs.value);
  var types:any = [
    { value: "1", color: "#91cc75", label: '运行'},
    { value: "2", color: "#ccc", label: '停机'},
    { value: "3", color: "#fd666d", label: '故障'},
  ];
  var startDate;
  startDate = new Date(data[0]?.RUNTIME);
  var datatemp = data.map((d:any) => ({  // 数据集处理
    name: types.filter((a:any) => a.value == d.STATUSDESC)[0].label,  // 状态名称
    value: [
      parseInt(d.GROUPID),
      new Date(d.RUNTIME).getTime(),  // 处理成时间辍的格式
      new Date(d.END_TIME).getTime(),
    ],
    itemStyle: {
      normal: {
        color: types.filter((a:any) => a.value == d.STATUSDESC)[0].color, // 状态颜色的绑定
      },
    },
  }));
  var groupedData = datatemp.reduce((acc:any, curr:any) => {
    if (!acc[curr.value[0]]) {
      acc[curr.value[0]] = [];
    }
    acc[curr.value[0]].push(curr);
    return acc;
  }, {});  // 状态值组合成一组 以便后面排序
  var gaps:any = [];
  var startTime_ = new Date(
    startDate.getFullYear(),
    startDate.getMonth(),
    startDate.getDate()
  ).getTime(); // 返回时间戳
  var endTime_ = startTime_ + 24 * 60 * 60 * 1000; // 24小时后的时间
  Object.keys(groupedData).forEach((groupID) => {
    var groupData = groupedData[groupID];
    // 按开始时间排序
    groupData.sort((a:any, b:any) => a.value[1] - b.value[1]);
    var lastEndTime = startTime_;
    for (var i = 0; i < groupData.length; i++) {
      var currentStartTime = groupData[i].value[1];
      var currentEndTime = groupData[i].value[2];

      if (currentStartTime > lastEndTime) {
        gaps.push([parseInt(groupID), lastEndTime, currentStartTime]);
      }

      lastEndTime = Math.max(lastEndTime, currentEndTime);
    }

    // 检查最后一个时间段结束时间与24小时结束时间之间的空隙
    if (lastEndTime < endTime_) {
      gaps.push([parseInt(groupID), lastEndTime, endTime_]);
    }
  });
  function renderItem(params:any, api: any) {
    var categoryIndex = api.value(0);
    var start = api.coord([api.value(1), categoryIndex]);
    var end = api.coord([api.value(2), categoryIndex]);
    var height = api.size([0, 1])[1] * 0.6;
    var rectShape = echarts.graphic.clipRectByRect(
      {
        x: start[0],
        y: start[1] - height / 2,
        width: end[0] - start[0],
        height: height,
      },
      {
        x: params.coordSys.x,
        y: params.coordSys.y,
        width: params.coordSys.width,
        height: params.coordSys.height,
      }
    );

    var shapes;
    shapes = rectShape && {
      type: "rect",
      transition: ["shape"],
      shape: rectShape,
      style: api.style(),
    };
    return shapes;
  }

  const series = [
    {
      type: "custom",
      renderItem: renderItem,
      encode: {
        x: [1, 2],
        y: 0,
      },
      data: datatemp,
    },
    {
      type: "custom",
      renderItem: renderItem,
      z: -1, // 放在最底层
      data: gaps,
    },
  ];
  const option = {
    grid: {
      left: "1%",
      right: "1%",
      top: "1%",
      bottom: 2,
      height: "28%",
      width: "98%",
      containLabel: true,
    },
    tooltip: {
      show: true,
      textStyle: {
        fontSize: 10,
      },
      position: function (point:any, size:any) {
        var mouseX = point[0];
        var mouseY = point[1];
        // 获取容器的宽度和 tooltip 的宽度
        var containerWidth = size.viewSize&&size.viewSize[0];
        var tooltipWidth =  size.contentSize&&size.contentSize[0];

        // 调整 tooltip 的位置
        var offsetX = 10; // x 方向偏移量
        var offsetY = 1; // y 方向偏移量
        // 如果 tooltip 超出容器的右侧,将其显示在鼠标的左侧
        if (mouseX + tooltipWidth + offsetX > containerWidth) {
          // 新的位置坐标
          var newX = mouseX - tooltipWidth - offsetX;
          var newY = mouseY + offsetY;

          // 返回新的位置坐标
          return [newX, newY];
        } else {
          // tooltip 显示在鼠标的下方
          var newX:number = mouseX + offsetX;
          var newY:any = mouseY + offsetY;
          // 返回新的位置坐标
          return [newX, newY];
        }
      },
      formatter: function (params:any) {
        // 参数校验
        if (!Array.isArray(params.value) || params.value.length < 2) {
          return "";
        }
        try {
          const startTime = params.value[1];
          const endTime = params.value[2];
          if (endTime < startTime) {
            return "";
          }
          const duration = endTime - startTime;
          const hours = Math.floor(duration / (1000 * 60 * 60));
          const minutes = Math.floor(
            (duration % (1000 * 60 * 60)) / (1000 * 60)
          );
          const seconds = Math.floor((duration % (1000 * 60)) / 1000);
          // 获取带前导0的小时、分钟和秒
          const formatTimeUnit = (unit:any) =>
            unit < 10 ? "0" + unit : unit.toString();
          const formattedStartTimeHours = formatTimeUnit(
            new Date(startTime).getHours()
          );
          const formattedStartTimeMinutes = formatTimeUnit(
            new Date(startTime).getMinutes()
          );
          const formattedStartTimeSeconds = formatTimeUnit(
            new Date(startTime).getSeconds()
          );
          const formattedEndTimeHours = formatTimeUnit(
            new Date(endTime).getHours()
          );
          const formattedEndTimeMinutes = formatTimeUnit(
            new Date(endTime).getMinutes()
          );
          const formattedEndTimeSeconds = formatTimeUnit(
            new Date(endTime).getSeconds()
          );
          const formattedTimeSeconds = formatTimeUnit(seconds);

          let formattedDuration = `${hours}小时${minutes}分${formattedTimeSeconds}秒`;
         // output 鼠标经过的时候展示的文本
          let output = `${params.marker}${params.name}${
            params.seriesIndex === 1
              ? `空闲时长:`
              : `时长:`
          }${formattedDuration}<br/>`;
          output += `${params.marker}时间区间:${formattedStartTimeHours}:${formattedStartTimeMinutes}:${formattedStartTimeSeconds} - ${formattedEndTimeHours}:${formattedEndTimeMinutes}:${formattedEndTimeSeconds}`;
          return output;
        } catch (error) {
          return ""; // 根据实际情况考虑是否返回错误信息或特定的格式化失败字符串
        }
      },
    },
    dataZoom: [
      {
        type: "inside",
        filterMode: "none",
        showDataShadow: false,
        show: true,
      },
    ],
    xAxis: {
      type: "time",
      min: new Date().getTime() - 24 * 60 * 60 * 1000, // 24小时前
      max: new Date().getTime(), // 当前时间
      axisLabel: {
        formatter: function (value:any) {
          var date = new Date(value);
          var hours = date.getHours();
          var minutes = date.getMinutes();
          var seconds = date.getSeconds();

          // 如果分钟和秒都是0,则只显示小时(例如:00)
          if (minutes === 0 && seconds === 0) {
            return hours === 0
              ? "00:00"
              : echarts.format.formatTime("hh:mm", value);
          }
          // 其他情况显示小时、分钟和秒(例如:01:30:45)
          return echarts.format.formatTime("hh:mm:ss", value);
        },
        // 标签与轴线紧挨在一起
        padding: [0, 0, 0, 0], // 标签的内边距(可根据实际情况调整)
        // rotate: 30, // 旋转角度,避免标签重叠(可选)
      },
      splitNumber: 24,
      splitLine: {
        show: false,
      },
      axisLine: {
        show: false, // 隐藏坐标轴线
      },
      axisTick: {
        show: false, // 隐藏刻度线
      },
    },
    yAxis: [
      {
        yAxisIndex: 0,
        type: "category",
        data: [""],
        axisLine: {
          show: false,
        },
        axisTick: {
          show: false,
        },
        axisLabel: {
          show: false,
        },
      },
    ],
    series: series,
  };
  useResizeObserver(ganttChartRefs.value, resizeChart);
  myChart.value.setOption(option);
}
// 窗口自适应并开启过渡动画
const resize = () => {
  if (chartInstance.value) {
    chartInstance.value.resize({ animation: { duration: 300 } });
  }
};
// 重绘图表函数
const resizeChart = useDebounceFn(() => {
  myChart.value?.resize();
}, 300);
const debouncedResize = useDebounceFn(resize, 500, { maxWait: 800 });
watch(
  () => props.chartData,
  () => {
    nextTick(() => {
      setChartOptions(props.chartData);
    });
  },
  {
    immediate: true,
  }
);
onMounted(() => {
  window.addEventListener("resize", debouncedResize);
});
onBeforeUnmount(() => {
  myChart.value?.dispose();
  myChart.value = null;
  window.removeEventListener("resize", debouncedResize);
});
</script>

3.数据源:组件传过来 props.chartData
格式如下:如
var data = [{
“GROUPID”: “0”, // 组别 因为考虑到有多种设备情况 若只有一种 默认0就好
“END_TIME”: “2024-08-19 01:23:48”, // 结束时间
“RUNTIME”: “2024-08-19 00:22:56”, // 开始时间
“STATUSDESC”: “1” // 状态值
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:24:01”,
“RUNTIME”: “2024-08-19 15:23:48”,
“STATUSDESC”: “2”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:24:54”,
“RUNTIME”: “2024-08-19 15:24:01”,
“STATUSDESC”: “2”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:25:07”,
“RUNTIME”: “2024-08-19 15:24:54”,
“STATUSDESC”: “2”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:25:58”,
“RUNTIME”: “2024-08-19 15:25:07”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:26:14”,
“RUNTIME”: “2024-08-19 15:25:58”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:27:05”,
“RUNTIME”: “2024-08-19 15:26:14”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:27:16”,
“RUNTIME”: “2024-08-19 15:27:05”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:28:14”,
“RUNTIME”: “2024-08-19 15:27:16”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:28:24”,
“RUNTIME”: “2024-08-19 15:28:14”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:29:16”,
“RUNTIME”: “2024-08-19 15:28:24”,
“STATUSDESC”: “2”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:29:32”,
“RUNTIME”: “2024-08-19 15:29:16”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:30:26”,
“RUNTIME”: “2024-08-19 15:29:32”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:30:35”,
“RUNTIME”: “2024-08-19 15:30:26”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:31:30”,
“RUNTIME”: “2024-08-19 15:30:35”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:31:43”,
“RUNTIME”: “2024-08-19 15:31:30”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:32:36”,
“RUNTIME”: “2024-08-19 15:31:43”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:32:48”,
“RUNTIME”: “2024-08-19 15:32:36”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:33:45”,
“RUNTIME”: “2024-08-19 15:32:48”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:33:54”,
“RUNTIME”: “2024-08-19 15:33:45”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:34:49”,
“RUNTIME”: “2024-08-19 15:33:54”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:35:04”,
“RUNTIME”: “2024-08-19 15:34:49”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:35:55”,
“RUNTIME”: “2024-08-19 15:35:04”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:36:04”,
“RUNTIME”: “2024-08-19 15:35:55”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:36:59”,
“RUNTIME”: “2024-08-19 15:36:04”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:37:12”,
“RUNTIME”: “2024-08-19 15:36:59”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:38:04”,
“RUNTIME”: “2024-08-19 15:37:12”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:38:16”,
“RUNTIME”: “2024-08-19 15:38:04”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:39:12”,
“RUNTIME”: “2024-08-19 15:38:16”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:39:23”,
“RUNTIME”: “2024-08-19 15:39:12”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:40:19”,
“RUNTIME”: “2024-08-19 15:39:23”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:40:32”,
“RUNTIME”: “2024-08-19 15:40:19”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:41:24”,
“RUNTIME”: “2024-08-19 15:40:32”,
“STATUSDESC”: “1”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:41:36”,
“RUNTIME”: “2024-08-19 15:41:24”,
“STATUSDESC”: “3”
},
{
“GROUPID”: “0”,
“END_TIME”: “2024-08-19 15:41:36”,
“RUNTIME”: “2024-08-19 15:47:24”,
“STATUSDESC”: “3”
}]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2060240.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用ai写作软件,一键智能改写文案很简单

在当今快节奏的时代&#xff0c;科技的发展日新月异&#xff0c;人工智能&#xff08;AI&#xff09;已经逐渐融入到我们生活的各个方面。其中&#xff0c;AI写作工具的出现为文案创作带来了极大的便利&#xff0c;让一键智能改写文案变得简单而高效。 AI写作工具利用先进的算法…

项目技巧1

目录 创建项目工程的技巧 示例&#xff1a;创建父工程 第一步&#xff1a;初始化maven项目 第二步&#xff1a;使用标签 抽取依赖的资源版本号&#xff0c;方便后续调整 第三步&#xff1a;配置父工程锁定的版本&#xff0c;使用 该标签的作用&#xff1a;锁定资源的版本号&…

初探Raft算法

在分布式系统有一个经典的CAP理论&#xff0c;C&#xff1a;一致性&#xff0c;即集群中所有节点都应该是一致的。A&#xff1a;可用性&#xff0c;集群一直处于可用状态。P&#xff1a;分区容错性&#xff1a;即复制所有数据到集群的所有节点&#xff0c;保证即使出现网络分区…

TQRFSOC开发板47DR,LMK04832更新配置

在利用RFSOC开发板进行项目开发时&#xff0c;面对多样化的时钟需求&#xff0c;巧妙地配置LMK04832时钟管理芯片以输出精确的时钟信号显得尤为重要。本期内容将讲解如何通过ZYNQ更新LMK04832的配置&#xff0c;以满足您的特定时钟需求。 每次配置成功后&#xff0c;配置文件都…

电路笔记(PCB):JLC PCB布局和走线基础教程笔记

对立创EDA 四层板PCB设计保姆级教程的笔记看完才发现是个虚假的教程&#xff0c;除了没教四层板咋画其它教了&#xff08;中间的两层全是GND的作用&#xff09; PCB布局 转换原理图 使用USB模块&#xff08;3.0集线器&#xff09;中的原理图。设计- - -》更新/转换原理图到P…

CSP内容安全策略

目录 CSP内容安全策略 一、引入 二、CSP内容安全策略 1、通过 HTTP 响应头信息的 Content-Security-Policy 的字段 2、通过网页的 meta 标签 3、在security的read.php页面&#xff0c;增加以下响应头 4、report-uri安全报告 5、其他安全配置 6、Web服务器全局配置 三…

机器学习:逻辑回归处理手写数字的识别

1、获取数据, 图像分割该数据有50行100列&#xff0c;每个数字占据20*20个像素点&#xff0c;可以进行切分,划分出训练集和测试集。 import numpy as np import pandas as pd import cv2 imgcv2.imread("digits.png")#读取文件 graycv2.cvtColor(img,cv2.COLOR_BGR2G…

8月20日

思维导图 面试题整理&#xff1a; 数据结构中顺序表和链表的区别? 顺序表&#xff1a; 1、存储方式&#xff1a;顺序表是一系列连续的内存空间&#xff0c;每个元素的地址可以通过索引计算出&#xff1b; 2、访问速度&#xff1a;由于不需要遍历查找&#xff0c;访问速度较…

一路坎坷-Mac下安装Python3、环境变量配置、安装jupyter notebook

遇到很多问题最终解决--Mac下安装Python3、环境变量配置、安装jupyter notebook 下载-安装python打开Mac终端-安装Jupyter给python3配置环境变量给jupyter配置环境变量配置遇到的问题 首先说一下我是先下载python3.8-然后安装&#xff1b;再在苹果电脑的终端下载Jupyter的&…

【JAVA CORE_API】Day18 网络编程、线程、在线聊天室v1.0

C/S&#xff1a;客户端/服务器端&#xff0c;所有网络应用都是基于客户端服务器端进行的&#xff0c;Java写的是服务端&#xff0c;客户端是一个软件&#xff0c;服务端也是一个软件&#xff0c;两个软件之间交互&#xff1b;&#xff08;只能连接对应的服务器&#xff09; B/…

使用 Arch Linux 几个月有感 | 为什么我选择 Arch Linux ,Arch 的优缺点有什么 | 一些Linux发行版推荐

&#xff08;终端是 Yakuake &#xff0c;KDE 自带&#xff09; 一点碎碎念&#xff0c;可以跳过不看 几年前从 CentOS 接触的 Linux &#xff0c;试图搭建一个KMS服务器 但是失败了 &#xff0c;后来装过 Ubuntu Debian deepin Kali Kubuntu Manjaro&#xff0c;踩一路坑最后…

线性数据结构的基本概念(数组,链表,栈,队列)

数组 数组由相同类型的元素组成&#xff0c;使用一块连续的内存来存储。 数组的特点是&#xff1a; 1.利用索引进行访问 2.容量固定 3.使用一块连续的内存来存储 各种操作的时间复杂度&#xff1a; 查找/修改&#xff1a;O&#xff08;1&#xff09;//访问特定位置的元素 插入…

day07_算法训练

案例零&#xff1a;整数反转&#xff08;大整数算法&#xff09; 给你一个 32 位的有符号整数 x &#xff0c;返回将 x 中的数字部分反转后的结果。 暂时不用考虑数据太大的问题&#xff0c;把本题的核心思路写出来即可 比如&#xff1a; ​ 输入&#xff1a;x 123 ​ 输出…

一分钟带你了解叉车!

一、叉车的概念 叉车是指对整件托盘货物或大件桶装进行装卸、堆垛和短距离运输作业的各种搬运车辆。叉车是实现整件货物和散装物料机械化装卸、堆垛和短途运输的高效率工作车辆。 叉车常用于仓储大型物件的运输、车站、码头、机场、仓库、工地、货厂和工矿企业&#xff0c;是…

【案例47】enq: TX - row lock contention事件导致制单卡死

问题现象 制单时&#xff0c;选择公司就会卡住不动&#xff0c;其他节点正常。 问题分析 通过nmc排查&#xff0c;发现后台有很多制单线程卡住&#xff0c;时间较久&#xff0c;并且当前的事件都是在数据库执行sql层面。并且每条线程的卡住语句都为update语句&#xff0c;怀…

Openstack 与 Ceph集群搭建(中): Ceph部署

文章目录 一、部署前说明1. ceph 版本选择依据2. ceph网络要求3. 硬件要求 二、部署架构三、部署过程1. 通用步骤2. 部署管理节点创建账号安装Cephadm运行bootstrap 3. 登录Ceph web4. 将其他节点加入集群同步ceph key安装ceph CLI命令行添加主机节点到集群添加OSD节点将监控节…

[数据集][目标检测]机械常用工具检测数据集VOC+YOLO格式4713张8类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4713 标注数量(xml文件个数)&#xff1a;4713 标注数量(txt文件个数)&#xff1a;4713 标注…

配置typora上传图片到Chevereto图床

目录 一、下载安装PicGo二、配置PicGo三、配置Typora 一、下载安装PicGo PicGo下载地址点击进入 进入官网后点击下载&#xff0c;会跳转到GitHub,如图,选择对应的操作系统版本下载 下载完成后单击安装&#xff08;本文已windows系统为例&#xff09; 二、配置PicGo 点击插件设…

华为OD机试 - 密码输入检测 字符串

只在本地跑过&#xff0c;不确保一定对 #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h>#define setbit(value,bit) (value value |(1<<bit))int main(void) {char buf[201];char out[201];int i 0;int to…

UploadLabs靶场环境

目录 UploadLabs靶场环境 第十八题 第十九题 第二十一题 UploadLabs靶场环境 .php .php. . 第五&#xff0c;十关访问的时候空格必须要使用 %20代替 第七题在linux服务器上的话&#xff0c;文件名如果末尾只存在空格并不会自动删除&#xff0c;还会保留&#xff0c;但是这…