hejianhao
2026-01-19 426dc2e52c8f72ff399391ed0108ca1370876f16
feat(路由): 添加分项隐患数页面路由和样式调整

feat(组件): 新增分项隐患数页面功能实现
style(组件): 统一调整多个页面的日期选择器分隔符样式
refactor(表格): 优化customTable组件行背景色实现方式
2个文件已添加
11个文件已修改
441 ■■■■■ 已修改文件
screen/src/assets/img/home/Shape.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/components/customTable.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/router/index.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/accidentCase/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/equipmentList/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/hiddenDanger/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/home/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/majorRisk/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/personnelOnDuty/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/planOfAudit/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/projectList/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/subentry/index.vue 385 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/workList/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Shape.png
screen/src/components/customTable.vue
@@ -66,13 +66,22 @@
    color: #ffffff;
    font-family: "Source Han Sans CN Medium";
  }
  tr {
    background-color: transparent;
  }
  .oneRow {
    background-color: #02004d !important;
    height: 50px;
    td {
      background-color: #02004d !important;
    }
  }
  .twoRow {
    background: rgba(14, 95, 255, .2) !important;
    height: 50px;
    td {
      background: rgba(14, 95, 255, 0.2) !important;
    }
  }
}
</style>
screen/src/router/index.js
@@ -95,6 +95,13 @@
    meta: {
      title: '人员在岗信息'
    }
  },
  {
    path: '/subentry',
    component: () => import('../view/subentry/index.vue'),
    meta: {
      title: '分项隐患数'
    }
  }
]
screen/src/view/accidentCase/index.vue
@@ -287,6 +287,10 @@
    display: none;
  }
  ::v-deep .el-range-separator {
    display: none;
  }
  ::v-deep .el-input__inner {
    background: transparent;
    border: none;
screen/src/view/equipmentList/index.vue
@@ -391,6 +391,10 @@
    display: none;
  }
  ::v-deep .el-range-separator {
    display: none;
  }
  ::v-deep .el-input__inner {
    background: transparent;
    border: none;
screen/src/view/hiddenDanger/index.vue
@@ -602,6 +602,10 @@
    display: none;
  }
  ::v-deep .el-range-separator {
    display: none;
  }
  ::v-deep .el-input__inner {
    background: transparent;
    border: none;
screen/src/view/home/index.vue
@@ -930,6 +930,10 @@
      display: none;
    }
  ::v-deep .el-range-separator {
    display: none;
  }
    ::v-deep .el-input__inner {
      background: transparent;
      border: none;
screen/src/view/majorRisk/index.vue
@@ -288,6 +288,10 @@
    display: none;
  }
  ::v-deep .el-range-separator {
    display: none;
  }
  ::v-deep .el-input__inner {
    background: transparent;
    border: none;
screen/src/view/personnelOnDuty/index.vue
@@ -382,6 +382,10 @@
    display: none;
  }
  ::v-deep .el-range-separator {
    display: none;
  }
  ::v-deep .el-input__inner {
    background: transparent;
    border: none;
screen/src/view/planOfAudit/index.vue
@@ -406,6 +406,10 @@
    display: none;
  }
  ::v-deep .el-range-separator {
    display: none;
  }
  ::v-deep .el-input__inner {
    background: transparent;
    border: none;
screen/src/view/projectList/index.vue
@@ -444,6 +444,10 @@
    display: none;
  }
  ::v-deep .el-range-separator {
    display: none;
  }
  ::v-deep .el-input__inner {
    background: transparent;
    border: none;
screen/src/view/subentry/index.vue
New file
@@ -0,0 +1,385 @@
<template>
  <div>
    <HeaderBox :title="projectName" />
    <div class="pt--35 px--20 pb--54">
      <!-- 返回 -->
      <div @click="backFun" class="flex a-center cursor-pointer">
        <img
          src="../../assets/img/back.png"
          class="w--22 h--20 shrink0 mr--13"
        />
        <div class="c-fff lh--22 fs--22 SHSBold">分项隐患数</div>
      </div>
      <!-- 搜索 -->
      <div class="flex a-center j-between mt--24 mb--20">
        <div class="flex a-center gap--16">
          <div class="flex a-center searchTabs">
            <div
              @click="handleTabClick(item)"
              v-for="item in searchTabs"
              :key="item"
              :class="{ activeTabs: item === activeTabs }"
            >
              {{ item }}
            </div>
          </div>
          <div
            @click="handleClick(2)"
            class="flex a-center j-between px--20 w--300 h--40 relative bgcolor1 picker"
          >
            <el-date-picker
              v-model="monthrange"
              ref="monthrangeRef"
              type="monthrange"
              placeholder=""
              :disabled="activeTabs != '自定义'"
            >
            </el-date-picker>
            <div class="absolute w100 h100 flex a-center c-fff fs--14 SHS">
              <div class="flex a-center flex1 shrink0 gap--13">
                <img
                  src="../../assets/img/home/Shape@2x (6).png"
                  class="w--13 h--13 shrink0"
                />
                <div style="width: calc(100% - 20px)" v-if="dateTxt1">
                  {{ dateTxt1 }}
                </div>
                <div v-else>请选择日期</div>
              </div>
              <div class="flex a-center flex1 shrink0 gap--13">
                <img
                  src="../../assets/img/home/Shape@2x (6).png"
                  class="w--13 h--13 shrink0"
                />
                <div style="width: calc(100% - 20px)" v-if="dateTxt2">
                  {{ dateTxt2 }}
                </div>
                <div v-else>请选择日期</div>
              </div>
            </div>
          </div>
          <div
            class="flex a-center j-between w--300 pl--20 h--40 relative bgcolor1 searchBox"
          >
            <el-select
              filterable
              v-model="projectId"
              placeholder="请输入搜索内容"
              class="flex1"
            >
              <el-option
                v-for="item in [1, 2]"
                :key="item"
                :label="item"
                :value="item"
              >
              </el-option>
            </el-select>
            <div class="btn SHSR">搜索</div>
          </div>
        </div>
        <div
          @click="formVisible = true"
          class="flex a-center j-center w--150 h--40 cursor-pointer br--4 bgcolor88"
        >
          <img
            src="../../assets/img/home/Shape.png"
            class="w--12 h--12 shrink0 mr--9"
          />
          <div class="fs--14 lh--14 c-fff SHSR">分析图表</div>
        </div>
      </div>
      <!-- 表格 -->
      <CustomTable
        :data="[
          { projectName: '文明施工' },
          { projectName: '文明施工' },
          { projectName: '文明施工' },
        ]"
        height="800"
        style="border: 2px solid #3d7fff"
      >
        <el-table-column label="隐患类型" prop="projectName" />
        <el-table-column
          v-for="(item, index) in tableHeader"
          :key="index"
          :label="item.label"
          :prop="item.prop"
        />
      </CustomTable>
      <CustomPagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[100, 200, 300, 400]"
        :page-size="10"
        :total="400"
      />
    </div>
  </div>
</template>
<script>
import HeaderBox from "../header/index.vue";
import moment from "moment";
export default {
  components: { HeaderBox },
  props: {},
  data() {
    return {
      monthrange: null,
      projectId: null,
      projectName: null,
      searchTabs: ["本年", "上一年", "自定义"],
      activeTabs: "本年",
      dateTxt1: "",
      dateTxt2: "",
      currentPage: 1,
      tableHeader: [
        {
          label: "2025年1月",
          prop: "one",
        },
      ],
    };
  },
  computed: {},
  watch: {
    monthrange: {
      handler(newVal, oldVal) {
        if (newVal && newVal.length === 2) {
          this.dateTxt1 = moment(newVal[0]).format("YYYY年MM月");
          this.dateTxt2 = moment(newVal[1]).format("YYYY年MM月");
          this.generateTableHeader(newVal[0], newVal[1]);
        } else {
          this.dateTxt1 = "";
          this.dateTxt2 = "";
          this.tableHeader = [];
        }
      },
      immediate: true,
    },
  },
  created() {
    this.projectId = this.$route.query.projectId;
    this.projectName = this.$route.query.projectName;
    if (this.activeTabs !== "自定义") {
      this.updateByActiveTab();
    }
  },
  mounted() {},
  methods: {
    handleSizeChange(val) {
      console.log(`每页 ${val} 条`);
    },
    handleCurrentChange(val) {
      console.log(`当前页: ${val}`);
    },
    handleClick(type) {
      this.$refs.monthrangeRef.focus();
    },
    handleTabClick(item) {
      this.activeTabs = item;
      this.updateByActiveTab();
    },
    updateByActiveTab() {
      const currentYear = moment().year();
      if (this.activeTabs === "本年") {
        const start = moment().year(currentYear).month(0).startOf("month").toDate();
        const end = moment().year(currentYear).month(11).startOf("month").toDate();
        this.monthrange = [start, end];
      } else if (this.activeTabs === "上一年") {
        const lastYear = currentYear - 1;
        const start = moment().year(lastYear).month(0).startOf("month").toDate();
        const end = moment().year(lastYear).month(11).startOf("month").toDate();
        this.monthrange = [start, end];
      }
    },
    generateTableHeader(startDate, endDate) {
      const start = moment(startDate).startOf("month");
      const end = moment(endDate).startOf("month");
      const list = [];
      const current = start.clone();
      while (current.isSameOrBefore(end, "month")) {
        list.push({
          label: current.format("YYYY年M月"),
          prop: current.format("YYYYMM"),
        });
        current.add(1, "month");
      }
      this.tableHeader = list;
    },
    backFun() {
      this.$router.go(-1);
    },
  },
};
</script>
<style scoped lang="less">
::v-deep .el-table {
  .el-table__body-wrapper {
    .el-table__body {
      .el-table__row {
        td:first-child {
          background-color: rgba(0, 112, 255, 0.4) !important;
        }
      }
    }
  }
}
.color1 {
  color: rgba(255, 255, 255, 0.9);
}
.bgcolor1 {
  background: rgba(2, 0, 77, 0.8);
  box-shadow: inset 0px 0px 34px 0px rgba(17, 40, 255, 0.66);
  border: 2px solid #0d53b7;
}
.bgColor2 {
  background: rgba(24, 69, 135, 0.9);
}
.bgColor3 {
  background: rgba(67, 221, 189, 1) !important;
}
.bgColor4 {
  background: rgba(67, 221, 189, 0.6) !important;
}
.bgColor5 {
  background: rgba(67, 221, 189, 0.4) !important;
}
.bgcolor6 {
  background: linear-gradient(270deg, #64aef0 0%, #4b70ec 100%);
}
.bgcolor7 {
  background: linear-gradient(270deg, #3dabea 0%, #28a5ec 100%);
}
.bgcolor8 {
  background: rgba(24, 83, 200, 0.2);
}
.bgcolor88 {
  background: linear-gradient(270deg, #09b9ff 0%, #4d68ff 100%);
}
.tagItem {
  flex-shrink: 0;
  line-height: 30px;
  padding: 0 12px;
  color: #fff;
  background: rgba(24, 83, 200, 0.2);
}
.searchTabs {
  background: rgba(2, 0, 77, 0.8);
  box-shadow: inset 0px 0px 34px 0px rgba(17, 40, 255, 0.66);
  font-size: 12px;
  color: rgba(255, 255, 255, 0.8);
  font-family: "Source Han Sans CN Normal";
  text-align: center;
  flex-shrink: 0;
  div {
    padding: 2px;
    width: 76px;
    cursor: pointer;
    line-height: 34px;
    border: 1px solid #0d53b7;
    &:hover {
      background: #017be7;
      color: #ffffff;
    }
  }
  .activeTabs {
    background: #017be7;
    color: #ffffff;
  }
}
.picker {
  ::v-deep .el-input__icon {
    display: none;
  }
  ::v-deep .el-range-separator {
    display: none;
  }
  ::v-deep .el-input__inner {
    background: transparent;
    border: none;
    color: transparent;
  }
  ::v-deep .el-range-input {
    background: transparent;
    border: none;
    color: transparent;
  }
}
.searchBox {
  ::v-deep .el-input__inner {
    background: transparent;
    border: none;
    color: #fff;
    padding: 0;
  }
  ::v-deep .el-input__suffix {
    display: none;
  }
  .btn {
    position: absolute;
    top: -2px;
    right: -2px;
    background: linear-gradient(
      90deg,
      #3467d0 0%,
      #0d226a 50.35%,
      #376fe0 100%
    );
    height: 38px;
    display: flex;
    align-items: center;
    font-size: 14px;
    color: #ffffff;
    padding: 0 26px;
    border: 1px solid #307ad9;
    box-sizing: border-box;
    cursor: pointer;
  }
}
.btnColor {
  color: #00ebfc;
}
::v-deep .el-descriptions {
  .el-descriptions__body {
    background-color: transparent;
    .el-descriptions-item__container {
      color: #ffffff;
      font-family: "Source Han Sans CN Regular";
    }
  }
}
</style>
screen/src/view/workList/index.vue
@@ -458,6 +458,10 @@
    display: none;
  }
  ::v-deep .el-range-separator {
    display: none;
  }
  ::v-deep .el-input__inner {
    background: transparent;
    border: none;