Newer
Older
smart-metering-front / src / views / business / bench / bench.vue
<!-- 工作台 -->
<script lang="ts" setup name="BusinessBench">
import { getCurrentInstance, ref } from 'vue'
import type { Ref } from 'vue'
import type { pieDataI } from '@/components/Echart/echart-interface'
import { getSampleMonitorList } from '@/api/business/bench/bench'
// 每个展示块高度
const blockHeight = ref(300)
const blockWidth = ref(400)
const { proxy } = getCurrentInstance() as any
// 样品监控表头
const sampleMonitorData = ref([])
// 样品监控表头
const sampleMonitorHead = [
  { text: '样品名称', value: 'sampleName', width: '80' },
  { text: '当前检测实验室', value: 'currentSegment', width: '125' },
  { text: '下一检测实验室', value: 'nextSegment', width: '130' },
  { text: '进度', value: 'progressData', width: '140' },
]
// 我的检测表头
const myTestsHead = [
  { text: '样品名称', value: 'equipmentName', width: '80' },
  { text: '委托方名称', value: 'usePersonName', width: '100' },
  { text: '检测状态', value: 'lastTime', width: '80' },
]
// 我的检测表格数据
const myTestsData = ref([
  {
    equipmentName: '样品名称',
    usePersonName: '委托方名称',
    lastTime: '检测状态',
  },
  {
    equipmentName: '样品名称',
    usePersonName: '委托方名称',
    lastTime: '检测状态',
  },
  {
    equipmentName: '样品名称',
    usePersonName: '委托方名称',
    lastTime: '检测状态',
  },
  {
    equipmentName: '样品名称',
    usePersonName: '委托方名称',
    lastTime: '检测状态',
  },
  {
    equipmentName: '样品名称',
    usePersonName: '委托方名称',
    lastTime: '检测状态',
  },
])
// 进度条添加后缀 %
const format = (percentage: number) => (percentage === 100 ? 'Full' : `${percentage}%`)
// 证书报告表头
const credentialsHead = [
  { text: '名称', value: 'equipmentName', width: '100' },
  { text: '检定员', value: 'usePersonName' },
  { text: '状态', value: 'lastTime' },
  { text: '进度', value: 'schedule', width: '140' },
]
// 证书报告表格数据
const credentialsData = ref([
  {
    equipmentName: '样品名称',
    usePersonName: '检定员',
    lastTime: '编制中',
    schedule: 30,
  },
  {
    equipmentName: '样品名称',
    usePersonName: '检定员',
    lastTime: '审批中',
    schedule: 20,
  },
  {
    equipmentName: '样品名称',
    usePersonName: '检定员',
    lastTime: '可打印',
    schedule: 60,
  },
  {
    equipmentName: '样品名称',
    usePersonName: '检定员',
    lastTime: '编制中',
    schedule: 70,
  },
  {
    equipmentName: '样品名称',
    usePersonName: '检定员',
    lastTime: '编制中',
    schedule: 10,
  },
])
// 实时工作统计表头
const realTimeWorkStatisticsHead = [
  { text: '实验室名称', value: 'equipmentName', width: '100' },
  { text: '今日检完样品', value: 'usePersonName', width: '120' },
  { text: '今日出具证书数', value: 'lastTime', width: '140' },
  { text: '进度', value: 'schedule', width: '140' },
]
// 实时工作统计表格数据
const realTimeWorkStatisticsData = ref([
  {
    equipmentName: '实验室名称',
    usePersonName: '今日检完样品',
    lastTime: '今日出具证书数',
    schedule: 12,
  },
  {
    equipmentName: '实验室名称',
    usePersonName: '今日检完样品',
    lastTime: '今日出具证书数',
    schedule: 25,
  },
  {
    equipmentName: '实验室名称',
    usePersonName: '今日检完样品',
    lastTime: '今日出具证书数',
    schedule: 99,
  },
  {
    equipmentName: '实验室名称',
    usePersonName: '今日检完样品',
    lastTime: '今日出具证书数',
    schedule: 44,
  },
])
// 我的检测饼图数据
const myTestsPieList: Ref<pieDataI[]> = ref([])
// 我的测试饼图
const myTestsPieTitle = ref(0)
// 饼图--图例配置项
const picLegend = ref({
  show: false,
  orient: 'vertical',
  right: '20%',
  top: 'center',
  icon: 'circle',
  itemWidth: 12,
  itemHeight: 12,
  itemStyle: {
    fontSize: 18,
  },
})
// 渲染饼图
setTimeout(() => {
  myTestsPieList.value = [
    { name: '176-50%  待检测', value: 1 },
    { name: '176-25%  检测中', value: 20 },
    { name: '176-25%  检测完', value: 20 },
  ]
  myTestsPieTitle.value = 41
}, 1)
// 按钮跳转数据
const buttonTypes = ref([
  { id: '1', text: '证书打印', url: '/schedule/certPrintList' },
  { id: '2', text: '环境记录单', url: '/lab/environmentalList' },
  { id: '3', text: '原始记录', url: '/lab/primitiveLogList' },
  { id: '4', text: '现场检测申请', url: '/fieldTest/approve' },
  { id: '5', text: '分包项目登记', url: '/subpackage/itemApply' },
  { id: '6', text: '分包方档案', url: '/subpackage/archives' },
])
// 当前进行中样品状态数据
const statusData = ref([
  { name: '待收入', number: '256' },
  { name: '待分发', number: '167' },
  { name: '检测中', number: '135' },
  { name: '成编制报告', number: '135' },
])
const router = useRouter()

// 点击按钮组
const handleClickButton = (id: string) => {
  const index = buttonTypes.value.findIndex(item => item.id === id)
  if (index !== -1 && buttonTypes.value[index].url) {
    router.push(buttonTypes.value[index].url)
  }
}
const benchDivHeight = ref()
function calcBlockSize() {
  // 计算工作台区域高度 - 顶部-面包屑-边距
  const bodyHeight = document.body.clientHeight - 60 - 50 - 20
  blockHeight.value = bodyHeight > 610 ? (bodyHeight - 10) / 2 : 300
  blockWidth.value = (document.body.clientWidth - 180 - 20 - 20) / 3
  console.log(blockHeight.value, blockWidth.value - 20)
  benchDivHeight.value = blockHeight.value - 60
}

// ---------------------------------------获取数据------------------------------------
// 样品监控
const fetchSampleMonitorList = () => {
  getSampleMonitorList().then((res) => {
    sampleMonitorData.value = res.data.rows.map((item: { progress: string; progressData: number }) => {
      if (item.progress.includes('%')) {
        item.progressData = Number(item.progress.slice(0, item.progress.indexOf('%')))
      }
      console.log('进度', typeof item.progressData, item.progressData)

      return item
    })
  })
}

onMounted(() => {
  calcBlockSize()
  fetchSampleMonitorList() // 样品监控
})
</script>

<template>
  <app-container>
    <el-row :gutter="10">
      <el-col :span="8">
        <bench-col
          icon="icon-file"
          title="样品监控"
          :height="blockHeight"
        >
          <el-table
            :data="sampleMonitorData"
            :height="blockHeight - 60"
            style="width: 100%; height: 100%;"
            stripe
            header-row-class-name="bench-table-header"
            row-class-name="bench-table-row"
            class="bench-table"
          >
            <el-table-column
              v-for="item in sampleMonitorHead"
              :key="item.value"
              :prop="item.value"
              align="center"
              :label="item.text"
              show-overflow-tooltip
              :width="item.width"
            >
              <template v-if="item.value === 'progressData'" #default="scope">
                <el-progress :stroke-width="5" :percentage="scope.row.progressData" />
              </template>
            </el-table-column>
          </el-table>
        </bench-col>
      </el-col>
      <el-col :span="8">
        <bench-col icon="icon-line" title="我的检测" :height="blockHeight" path-url="/lab/myMeasureList">
          <div class="my-tests">
            <div style="width: 60%;">
              <el-table
                :data="myTestsData"
                :height="blockHeight - 60"
                style="width: 100%; height: 100%;"
                stripe
                header-row-class-name="bench-table-header"
                row-class-name="bench-table-row"
                class="bench-table"
              >
                <el-table-column
                  v-for="item in myTestsHead"
                  :key="item.value"
                  :prop="item.value"
                  align="center"
                  :label="item.text"
                  :width="item.width"
                />
              </el-table>
            </div>
            <div style="width: 40%;">
              <pie-chart
                :data="myTestsPieList"
                :radius="['50%', '70%']"
                :colors="['#3d7eff', '#caddff', '#1d9cce', '#1D9CAF']"
                right="0%"
                :legend="picLegend"
                :width="`${blockWidth - 225}px`"
                :label-formatter="`${myTestsPieTitle}`"
              />
            </div>
          </div>
        </bench-col>
      </el-col>
      <el-col :span="8">
        <bench-col :height="blockHeight">
          <div
            :height="blockHeight - 60"
            style="width: 100%; height: 100%;
            padding: 32px 0;
            display: flex;flex-wrap: wrap;
            justify-content: center;
            align-items: center;"
          >
            <div
              v-for="(item, index) of buttonTypes"
              :key="index"
              class="right-top-box"
              @click="handleClickButton(item.id)"
            >
              {{ item.text }}
            </div>
          </div>
        </bench-col>

        <!-- <div
          v-for="item of buttonTypes"
          :key="item.text"
          class="right-top-box"
        >
          <span>
            {{ item.text }}
          </span>
        </div> -->
      </el-col>
    </el-row>
    <div style="margin-top: 10px;" />
    <el-row :gutter="10">
      <el-col :span="8">
        <bench-col
          icon="icon-book"
          title="证书报告"
          path-url="/lab/reportOnCredentialsApproval"
          :style="{ height: blockHeight }"
          :height="blockHeight"
        >
          <el-table
            :data="credentialsData"
            :height="blockHeight - 60"
            style="width: 100%; height: 100%;"
            stripe
            header-row-class-name="bench-table-header"
            row-class-name="bench-table-row"
            class="bench-table"
          >
            <el-table-column
              v-for="item in credentialsHead"
              :key="item.value"
              :prop="item.value"
              align="center"
              :label="item.text"
              :width="item.width"
            >
              <template v-if="item.value === 'schedule'" #default="scope">
                <el-progress :stroke-width="5" :percentage="scope.row.schedule" />
              </template>
            </el-table-column>
          </el-table>
        </bench-col>
      </el-col>
      <el-col :span="8">
        <bench-col
          icon="icon-book"
          title="实时工作统计"
          :style="{ height: blockHeight }"
          :height="blockHeight"
        >
          <el-table
            :data="realTimeWorkStatisticsData"
            :height="blockHeight - 60"
            style="width: 100%; height: 100%;"
            stripe
            header-row-class-name="bench-table-header"
            row-class-name="bench-table-row"
            class="bench-table"
          >
            <el-table-column
              v-for="item in realTimeWorkStatisticsHead"
              :key="item.value"
              :prop="item.value"
              align="center"
              :label="item.text"
              :width="item.width"
            >
              <template v-if="item.value === 'schedule'" #default="scope">
                <el-progress :stroke-width="5" :percentage="scope.row.schedule" />
              </template>
            </el-table-column>
          </el-table>
        </bench-col>
      </el-col>
      <el-col :span="8" :style="{ height: blockHeight }" :height="blockHeight">
        <bench-col
          title="当前进行中样品状态" icon="icon-book" :height="blockHeight - 60"
          style="width: 100%; height: 100%;"
        >
          <div class="status-box">
            <div v-for="(item, index) in statusData" :key="index" class="status-box-item">
              <div>
                {{ item.number }}
              </div>
              <div style="font-size: 12px;">
                {{ item.name }}
              </div>
              <div class="status-box-bgc" />
            </div>
          </div>
        </bench-col>
      </el-col>
    </el-row>
  </app-container>
</template>

<style lang="scss" scoped>
.bench-div {
  display: flex;
  flex-direction: column;
  // height: var(#{"--global:benchDivHeight"});
  height: v-bind("blockHeight");
  // height: 400px;
}

.my-tests {
  display: flex;
  justify-content: space-between;
}

.personnel-status {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 10%;

  .personnel-progress {
    width: 70%;
    height: 60%;
    display: flex;
    flex-direction: column;
  }
}

.status-box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-around;
  height: 100%;

  .status-box-item {
    width: 40%;
    height: 8vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-around;
    text-align: center;

    .status-box-bgc {
      width: 50%;
      height: 5vh;
      background: url("../../../assets/images/bench/sampie-status.png") no-repeat center / cover;
    }
  }
}

.right-top-box {
  width: calc(33% - 20px);
  height: 20%;
  padding: 10px;
  margin: 5px;
  border-radius: 5px;
  white-space: nowrap;
  // text-align: center;
  // font-size: 14px;
  color: #fff;
  cursor: pointer;
  background-color: #3d7eff;
  display: flex;
  justify-content: center;
  align-items: center;

  &:hover {
    background-color: #286ffd;
  }
}
</style>

<style lang="scss">
.bench-table {
  .el-table__header-wrapper {
    border-radius: 8px;
  }
}

.bench-table-header {
  th {
    font-weight: normal;
    font-size: 14px;
  }
}

.bench-table-row {
  border-radius: 8px;
}
</style>