#134 5#日报

Gabung
yanghao menggabungkan 12 komit dari shuzhihua/qhse_person menjadi shuzhihua/master%! (template.HTML=5 hari lalu)s

+ 16 - 0
src/api/pms/fiveconstructiondailyreport/index.ts

@@ -0,0 +1,16 @@
+import request from '@/config/axios'
+
+export const FiveIotProjectDailyReportApi = {
+  // 获取项目日报分页
+  getIotProjectDailyReportPage: async (params) => {
+    return await request.get({ url: '/pms/iot-five-daily-report/page', params })
+  },
+  // 查看项目日报详情
+  getIotProjectDailyReport: async (id) => {
+    return await request.get({ url: '/pms/iot-five-daily-report/get?id=' + id })
+  },
+  // 填报项目日报
+  updateIotProjectDailyReport: async (data) => {
+    return await request.put({ url: '/pms/iot-five-daily-report/update', data })
+  }
+}

+ 130 - 0
src/views/pms/constructionDailyReport/components/ConstructionDailyReportDrawer.vue

@@ -0,0 +1,130 @@
+<script setup lang="ts">
+import { FiveIotProjectDailyReportApi } from '@/api/pms/fiveconstructiondailyreport'
+import dayjs from 'dayjs'
+import type { FormInstance } from 'element-plus'
+import ConstructionDailyReportFormSection from './ConstructionDailyReportFormSection.vue'
+import {
+  createEmptyConstructionDailyReport,
+  formSections,
+  type ConstructionDailyReportRow
+} from './report-config'
+
+interface Props {
+  visible: boolean
+  loadList: () => void | Promise<void>
+}
+
+const props = defineProps<Props>()
+const emits = defineEmits(['update:visible'])
+
+const formRef = ref<FormInstance>()
+const loading = ref(false)
+const submitLoading = ref(false)
+const drawerMode = ref<'edit' | 'readonly'>('edit')
+const form = ref<ConstructionDailyReportRow>(createEmptyConstructionDailyReport())
+const message = useMessage()
+
+const drawerTitle = computed(() =>
+  drawerMode.value === 'readonly' ? '查看施工日报' : '填报施工日报'
+)
+const disabled = computed(() => drawerMode.value === 'readonly')
+
+function normalizeDetail(detail: Record<string, any> = {}) {
+  const createTime = detail.createTime
+  const constructionEndDate = detail.constructionEndDate
+  return {
+    ...createEmptyConstructionDailyReport(),
+    ...detail,
+    createTime: createTime
+      ? dayjs(createTime).isValid()
+        ? dayjs(createTime).format('YYYY-MM-DD')
+        : createTime
+      : detail.createTime,
+    constructionEndDate: constructionEndDate
+      ? dayjs(constructionEndDate).isValid()
+        ? dayjs(constructionEndDate).format('YYYY-MM-DD')
+        : constructionEndDate
+      : detail.constructionEndDate
+  } as ConstructionDailyReportRow
+}
+
+async function loadDetail(id: number) {
+  loading.value = true
+  try {
+    const detail = await FiveIotProjectDailyReportApi.getIotProjectDailyReport(id)
+    form.value = normalizeDetail(detail)
+  } finally {
+    loading.value = false
+  }
+}
+
+async function handleOpenForm(id: number, type: 'edit' | 'readonly') {
+  drawerMode.value = type
+  emits('update:visible', true)
+  await loadDetail(id)
+  nextTick(() => formRef.value?.clearValidate())
+}
+
+async function handleSubmit() {
+  // console.log('handleSubmit', form.value)
+  // return
+  if (drawerMode.value === 'readonly') {
+    emits('update:visible', false)
+    return
+  }
+
+  submitLoading.value = true
+  try {
+    const payload = { ...form.value } as Record<string, any>
+    await FiveIotProjectDailyReportApi.updateIotProjectDailyReport(payload)
+    message.success('保存成功')
+    emits('update:visible', false)
+    await props.loadList()
+  } finally {
+    submitLoading.value = false
+  }
+}
+
+function handleModelChange(value: ConstructionDailyReportRow) {
+  form.value = value
+}
+
+defineExpose({ handleOpenForm })
+</script>
+
+<template>
+  <el-drawer
+    :model-value="props.visible"
+    size="80%"
+    destroy-on-close
+    header-class="mb-0!"
+    @update:model-value="emits('update:visible', $event)">
+    <template #header>
+      <span class="text-xl font-bold text-[var(--el-text-color-primary)]">{{ drawerTitle }}</span>
+    </template>
+
+    <el-form ref="formRef" :model="form" label-position="top" v-loading="loading">
+      <div class="flex flex-col gap-6">
+        <ConstructionDailyReportFormSection
+          v-for="section in formSections"
+          :key="section.title"
+          :model="form"
+          :section="section"
+          :disabled="disabled"
+          @update:model="handleModelChange" />
+      </div>
+    </el-form>
+
+    <template #footer>
+      <el-button size="default" @click="emits('update:visible', false)">取消</el-button>
+      <el-button
+        size="default"
+        v-if="!disabled"
+        type="primary"
+        :loading="submitLoading"
+        @click="handleSubmit">
+        保存
+      </el-button>
+    </template>
+  </el-drawer>
+</template>

+ 108 - 0
src/views/pms/constructionDailyReport/components/ConstructionDailyReportFormSection.vue

@@ -0,0 +1,108 @@
+<script setup lang="ts">
+import { getStrDictOptions } from '@/utils/dict'
+import type {
+  ConstructionDailyReportField,
+  ConstructionDailyReportRow,
+  ConstructionDailyReportSection
+} from './report-config'
+
+const props = defineProps<{
+  model: ConstructionDailyReportRow
+  section: ConstructionDailyReportSection
+  disabled: boolean
+}>()
+
+const emits = defineEmits<{
+  (e: 'update:model', value: ConstructionDailyReportRow): void
+}>()
+
+function isNumberField(value: unknown) {
+  return value === null || value === undefined || typeof value === 'number'
+}
+
+function updateField(prop: keyof ConstructionDailyReportRow, value: unknown) {
+  emits('update:model', {
+    ...props.model,
+    [prop]: value
+  })
+}
+
+function getNumberValue(prop: keyof ConstructionDailyReportRow) {
+  const value = props.model[prop]
+  return typeof value === 'number' ? value : undefined
+}
+
+function isFieldDisabled(field: ConstructionDailyReportField) {
+  return props.disabled || !field.editableInEdit
+}
+
+function getDictOptions(field: ConstructionDailyReportField) {
+  return field.dictType ? getStrDictOptions(field.dictType) : []
+}
+</script>
+
+<template>
+  <div class="flex flex-col gap-4">
+    <div class="flex items-center gap-2">
+      <div class="h-5 w-1 rounded-full bg-[var(--el-color-primary)]"></div>
+      <div class="text-lg font-medium text-[var(--el-text-color-primary)]">
+        {{ props.section.title }}
+      </div>
+    </div>
+    <div class="grid grid-cols-2 gap-4">
+      <el-form-item
+        v-for="field in props.section.fields"
+        :key="`${props.section.title}-${String(field.prop)}-${field.label}`"
+        :label="field.label"
+        :prop="field.prop"
+        :class="{ 'col-span-2': field.span === 2 }"
+      >
+        <el-input
+          v-if="field.type === 'textarea'"
+          size="default"
+          :model-value="props.model[field.prop]"
+          type="textarea"
+          :autosize="{ minRows: 3 }"
+          resize="none"
+          :disabled="isFieldDisabled(field)"
+          @update:model-value="updateField(field.prop, $event)"
+        />
+        <el-select
+          v-else-if="field.type === 'select'"
+          size="default"
+          :model-value="props.model[field.prop]"
+          :options="getDictOptions(field)"
+          class="w-full"
+          clearable
+          placeholder="请选择"
+          :disabled="isFieldDisabled(field)"
+          @update:model-value="updateField(field.prop, $event)"
+        />
+        <el-input-number
+          v-else-if="field.type === 'number' || isNumberField(props.model[field.prop])"
+          :model-value="getNumberValue(field.prop)"
+          class="!w-full"
+          :controls="false"
+          :min="0"
+          size="default"
+          :precision="field.precision"
+          :disabled="isFieldDisabled(field)"
+          @update:model-value="updateField(field.prop, $event)"
+        />
+        <el-input
+          v-else
+          size="default"
+          :model-value="props.model[field.prop]"
+          :disabled="isFieldDisabled(field)"
+          @update:model-value="updateField(field.prop, $event)"
+        />
+      </el-form-item>
+    </div>
+  </div>
+</template>
+
+<style scoped>
+:deep(.el-form-item) {
+  margin-bottom: 0;
+}
+</style>

+ 89 - 0
src/views/pms/constructionDailyReport/components/ConstructionDailyReportTable.vue

@@ -0,0 +1,89 @@
+<script setup lang="ts">
+import { useTableComponents } from '@/components/ZmTable/useTableComponents'
+import dayjs from 'dayjs'
+import type { ConstructionDailyReportRow } from './report-config'
+import { tableColumns } from './report-config'
+
+const props = withDefaults(
+  defineProps<{
+    list: ConstructionDailyReportRow[]
+    loading: boolean
+    total: number
+    pageNo: number
+    pageSize: number
+  }>(),
+  {
+    list: () => [],
+    loading: false,
+    total: 0,
+    pageNo: 1,
+    pageSize: 10
+  }
+)
+
+const emits = defineEmits<{
+  (e: 'size-change', value: number): void
+  (e: 'current-change', value: number): void
+}>()
+
+const { ZmTable, ZmTableColumn } = useTableComponents<ConstructionDailyReportRow>()
+
+function formatCellValue(row: ConstructionDailyReportRow, prop: keyof ConstructionDailyReportRow) {
+  const value = row[prop]
+  if (prop === 'createTime' || prop === 'constructionStartDate' || prop === 'constructionEndDate') {
+    if (!value) return '-'
+    return dayjs(value).isValid() ? dayjs(value).format('YYYY-MM-DD') : value
+  }
+  return value === null || value === undefined || value === '' ? '-' : value
+}
+</script>
+
+<template>
+  <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg flex flex-col p-4 overflow-hidden">
+    <div class="flex-1 relative">
+      <el-auto-resizer class="absolute">
+        <template #default="{ width, height }">
+          <ZmTable
+            :data="props.list"
+            :loading="props.loading"
+            :width="width"
+            :height="height"
+            :max-height="height"
+            show-border>
+            <ZmTableColumn type="index" label="序号" :width="60" fixed="left" />
+            <ZmTableColumn
+              v-for="column in tableColumns"
+              :key="`${String(column.prop)}-${column.label}`"
+              :prop="column.prop"
+              :label="column.label"
+              :width="column.width"
+              :min-width="column.minWidth"
+              :fixed="column.fixed"
+              show-overflow-tooltip
+              cover-formatter
+              :real-value="
+                (row: ConstructionDailyReportRow) => formatCellValue(row, column.prop)
+              " />
+            <ZmTableColumn label="操作" :width="120" fixed="right" action>
+              <template #default="{ row }">
+                <slot name="action" :row="row"></slot>
+              </template>
+            </ZmTableColumn>
+          </ZmTable>
+        </template>
+      </el-auto-resizer>
+    </div>
+    <div class="h-8 mt-2 flex items-center justify-end">
+      <el-pagination
+        v-show="props.total > 0"
+        :current-page="props.pageNo"
+        :page-size="props.pageSize"
+        :background="true"
+        :page-sizes="[10, 20, 30, 50, 100]"
+        :total="props.total"
+        layout="total, sizes, prev, pager, next, jumper"
+        @size-change="emits('size-change', $event)"
+        @current-change="emits('current-change', $event)" />
+    </div>
+  </div>
+</template>

+ 191 - 0
src/views/pms/constructionDailyReport/components/report-config.ts

@@ -0,0 +1,191 @@
+import { DICT_TYPE } from '@/utils/dict'
+
+export interface ConstructionDailyReportRow {
+  id?: number
+  deptId?: number
+  projectId?: number
+  taskId?: number
+  status?: number
+  auditStatus?: number
+  createTime?: number | string
+  deptName?: string
+  projectName?: string
+  location?: string
+  mainDeviceNum?: number | null
+  wellName?: string
+  wokDeviceNum?: number | null
+  fiveStatusLabel?: string
+  dailyWorkingLayers?: number | null
+  dailySandVolume?: number | null
+  dailyLiquidVolume?: number | null
+  jingshu?: number | null
+  cengshu?: number | null
+  dailyFuel?: number | null
+  nonProductionTime?: number | null
+  nptReason?: string
+  singleWellWorkload?: number | string | null
+  productionStatus?: string
+  planWorkingLayers?: number | null
+  weather?: string
+  temperature?: string
+  deviceNames?: string
+  customer?: string
+  reportName?: string
+  constructionEndDate?: string | number
+  constructionStartDate?: string | number
+  monthWorkingLayers?: number | null
+  monthWorkingWells?: number | null
+  fiveStatus?: string
+}
+
+export interface ConstructionDailyReportQuery {
+  pageNo: number
+  pageSize: number
+  deptId?: number
+  projectName?: string
+  wellName?: string
+  createTime?: string[]
+}
+
+export interface ConstructionDailyReportField {
+  prop: keyof ConstructionDailyReportRow
+  label: string
+  type?: 'text' | 'number' | 'textarea' | 'select'
+  span?: 1 | 2
+  precision?: number
+  editableInEdit?: boolean
+  dictType?: string
+}
+
+export interface ConstructionDailyReportSection {
+  title: string
+  fields: ConstructionDailyReportField[]
+}
+
+export const tableColumns: Array<{
+  prop: keyof ConstructionDailyReportRow
+  label: string
+  width?: number
+  minWidth?: number
+  fixed?: 'left' | 'right'
+}> = [
+  { prop: 'reportName', label: '日报名称', minWidth: 180, fixed: 'left' },
+  { prop: 'createTime', label: '创建(施工)日期', width: 120 },
+  { prop: 'constructionEndDate', label: '施工结束日期', width: 120 },
+  { prop: 'projectName', label: '项目', minWidth: 160, fixed: 'left' },
+  { prop: 'location', label: '施工区域', minWidth: 140 },
+  { prop: 'deptName', label: '队伍', minWidth: 140 },
+  { prop: 'mainDeviceNum', label: '主设备(泵车)数量', width: 130 },
+  { prop: 'wellName', label: '生产任务', minWidth: 140 },
+  { prop: 'wokDeviceNum', label: '作业泵车数量', width: 120 },
+  { prop: 'fiveStatusLabel', label: '队伍状态', minWidth: 120 },
+  { prop: 'dailyWorkingLayers', label: '当日主压层数', width: 120 },
+  { prop: 'dailySandVolume', label: '当日加砂量(吨)', width: 130 },
+  { prop: 'dailyLiquidVolume', label: '当日注液量(m3)', width: 130 },
+  { prop: 'monthWorkingWells', label: '当月作业井数', width: 120 },
+  { prop: 'monthWorkingLayers', label: '当月作业层数', width: 120 },
+  { prop: 'dailyFuel', label: '当日油耗(L)', width: 110 },
+  { prop: 'nonProductionTime', label: '当日非生产时间', width: 130 },
+  { prop: 'nptReason', label: '造成非生产时间原因', minWidth: 180 },
+  { prop: 'singleWellWorkload', label: '单井工作量', width: 120 },
+  { prop: 'productionStatus', label: '施工动态', minWidth: 180 },
+  { prop: 'planWorkingLayers', label: '本月计划层数', width: 120 },
+  { prop: 'weather', label: '天气', width: 100 },
+  { prop: 'temperature', label: '气温', width: 100 },
+  { prop: 'deviceNames', label: '设备名称', minWidth: 180 },
+  { prop: 'customer', label: '合同甲方', minWidth: 140 }
+]
+
+export const formSections: ConstructionDailyReportSection[] = [
+  {
+    title: '基础信息',
+    fields: [
+      { prop: 'reportName', label: '日报名称' },
+      { prop: 'projectName', label: '项目' },
+      { prop: 'location', label: '施工区域' },
+      { prop: 'deptName', label: '队伍' },
+      { prop: 'wellName', label: '生产任务' },
+      { prop: 'customer', label: '合同甲方' },
+      { prop: 'deviceNames', label: '设备名称', span: 2 }
+    ]
+  },
+  {
+    title: '生产数据',
+    fields: [
+      { prop: 'mainDeviceNum', label: '主设备数量', type: 'number' },
+      { prop: 'wokDeviceNum', label: '作业泵车数量', type: 'number' },
+      {
+        prop: 'fiveStatus',
+        label: '队伍状态',
+        type: 'select',
+        editableInEdit: true,
+        dictType: DICT_TYPE.PMS_PROJECT_RD_STATUS
+      },
+      {
+        prop: 'dailyWorkingLayers',
+        label: '当日主压层数',
+        type: 'number',
+        editableInEdit: true
+      },
+      {
+        prop: 'dailySandVolume',
+        label: '当日加砂量(吨)',
+        type: 'number',
+        editableInEdit: true
+      },
+      {
+        prop: 'dailyLiquidVolume',
+        label: '当日注液量(m³)',
+        type: 'number',
+        editableInEdit: true
+      },
+      { prop: 'monthWorkingWells', label: '当月作业井数', type: 'number' },
+      { prop: 'monthWorkingLayers', label: '当月作业层数', type: 'number' },
+      {
+        prop: 'dailyFuel',
+        label: '当日油耗(L)',
+        type: 'number',
+        editableInEdit: true
+      },
+      {
+        prop: 'nonProductionTime',
+        label: '当日非生产时间',
+        type: 'number',
+        editableInEdit: true
+      },
+      { prop: 'singleWellWorkload', label: '单井工作量' },
+      { prop: 'planWorkingLayers', label: '本月计划层数', type: 'number' }
+    ]
+  },
+  {
+    title: '现场说明',
+    fields: [
+      {
+        prop: 'nptReason',
+        label: '造成非生产时间原因',
+        type: 'textarea',
+        span: 2,
+        editableInEdit: true
+      },
+      { prop: 'productionStatus', label: '施工动态', type: 'textarea', span: 2 },
+      { prop: 'weather', label: '天气' },
+      { prop: 'temperature', label: '气温(℃)' }
+    ]
+  }
+]
+
+export function createEmptyConstructionDailyReport(): ConstructionDailyReportRow {
+  return {
+    mainDeviceNum: null,
+    wokDeviceNum: null,
+    dailyWorkingLayers: null,
+    dailySandVolume: null,
+    dailyLiquidVolume: null,
+    jingshu: null,
+    cengshu: null,
+    dailyFuel: null,
+    nonProductionTime: null,
+    singleWellWorkload: null,
+    planWorkingLayers: null
+  }
+}

+ 187 - 0
src/views/pms/constructionDailyReport/index.vue

@@ -0,0 +1,187 @@
+<script setup lang="ts">
+import { FiveIotProjectDailyReportApi } from '@/api/pms/fiveconstructiondailyreport'
+import { useUserStore } from '@/store/modules/user'
+import { rangeShortcuts } from '@/utils/formatTime'
+import { useDebounceFn } from '@vueuse/core'
+import ConstructionDailyReportDrawer from './components/ConstructionDailyReportDrawer.vue'
+import ConstructionDailyReportTable from './components/ConstructionDailyReportTable.vue'
+import type {
+  ConstructionDailyReportQuery,
+  ConstructionDailyReportRow
+} from './components/report-config'
+
+defineOptions({ name: 'ConstructionDailyReport' })
+
+const userStore = useUserStore()
+const deptId = userStore.getUser.deptId
+
+const initQuery: ConstructionDailyReportQuery = {
+  pageNo: 1,
+  pageSize: 10,
+  deptId
+}
+
+const query = ref<ConstructionDailyReportQuery>({ ...initQuery })
+const list = ref<ConstructionDailyReportRow[]>([])
+const total = ref(0)
+const loading = ref(false)
+const visible = ref(false)
+const formRef = ref<InstanceType<typeof ConstructionDailyReportDrawer>>()
+const route = useRoute()
+
+const loadList = useDebounceFn(async () => {
+  loading.value = true
+  try {
+    const data = await FiveIotProjectDailyReportApi.getIotProjectDailyReportPage(query.value as any)
+    list.value = data.list ?? []
+    total.value = data.total ?? 0
+  } finally {
+    loading.value = false
+  }
+}, 200)
+
+function handleQuery(setPage = true) {
+  if (setPage) {
+    query.value.pageNo = 1
+  }
+  loadList()
+}
+
+function resetQuery() {
+  query.value = { ...initQuery }
+  handleQuery()
+}
+
+function handleSizeChange(value: number) {
+  query.value.pageSize = value
+  handleQuery()
+}
+
+function handleCurrentChange(value: number) {
+  query.value.pageNo = value
+  loadList()
+}
+
+function handleOpenForm(id: number, type: 'edit' | 'readonly') {
+  formRef.value?.handleOpenForm(id, type)
+}
+
+watch(
+  [
+    () => query.value.deptId,
+    () => query.value.projectName,
+    () => query.value.wellName,
+    () => query.value.createTime
+  ],
+  () => handleQuery(),
+  { immediate: true }
+)
+
+onMounted(() => {
+  if (route.query.id) {
+    handleOpenForm(Number(route.query.id), 'edit')
+  }
+})
+</script>
+
+<template>
+  <div
+    class="grid grid-cols-[auto_1fr] grid-rows-[62px_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
+  >
+    <DeptTreeSelect
+      v-model="query.deptId"
+      :top-id="158"
+      :deptId="deptId"
+      :show-title="false"
+      class="row-span-2"
+    />
+    <el-form
+      size="default"
+      class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between"
+    >
+      <div class="flex items-center gap-8">
+        <el-form-item label="项目">
+          <el-input
+            v-model="query.projectName"
+            placeholder="请输入项目名称"
+            clearable
+            @keyup.enter="handleQuery()"
+            class="!w-240px"
+          />
+        </el-form-item>
+        <el-form-item label="生产任务">
+          <el-input
+            v-model="query.wellName"
+            placeholder="请输入生产任务"
+            clearable
+            @keyup.enter="handleQuery()"
+            class="!w-240px"
+          />
+        </el-form-item>
+        <el-form-item label="创建时间">
+          <el-date-picker
+            v-model="query.createTime"
+            value-format="YYYY-MM-DD HH:mm:ss"
+            type="daterange"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            :shortcuts="rangeShortcuts"
+            :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
+            class="!w-260px"
+          />
+        </el-form-item>
+      </div>
+      <el-form-item>
+        <el-button type="primary" @click="handleQuery()">
+          <Icon icon="ep:search" class="mr-5px" /> 搜索
+        </el-button>
+        <el-button @click="resetQuery">
+          <Icon icon="ep:refresh" class="mr-5px" /> 重置
+        </el-button>
+      </el-form-item>
+    </el-form>
+
+    <ConstructionDailyReportTable
+      :list="list"
+      :loading="loading"
+      :total="total"
+      :page-no="query.pageNo"
+      :page-size="query.pageSize"
+      @size-change="handleSizeChange"
+      @current-change="handleCurrentChange"
+    >
+      <template #action="{ row }">
+        <el-button
+          v-if="row.status === 0"
+          link
+          type="primary"
+          @click="handleOpenForm(row.id!, 'edit')"
+          v-hasPermi="['pms:iot-five-daily-report:update']"
+        >
+          填报
+        </el-button>
+        <el-button
+          v-else-if="row.status === 1"
+          link
+          type="success"
+          @click="handleOpenForm(row.id!, 'readonly')"
+          v-hasPermi="['pms:iot-five-daily-report:query']"
+        >
+          查看
+        </el-button>
+      </template>
+    </ConstructionDailyReportTable>
+  </div>
+
+  <ConstructionDailyReportDrawer
+    ref="formRef"
+    v-model:visible="visible"
+    :load-list="loadList"
+  />
+</template>
+
+<style scoped>
+:deep(.el-form-item) {
+  margin-bottom: 0;
+}
+</style>

+ 2 - 2
src/views/pms/device/CheckCertificate.vue

@@ -27,7 +27,7 @@
                 :value="dict.value" />
                 :value="dict.value" />
             </el-select>
             </el-select>
           </el-form-item>
           </el-form-item>
-          <el-form-item label="证书编号" prop="certNo">
+          <el-form-item label="序列号" prop="certNo">
             <el-input
             <el-input
               v-model="queryParams.certNo"
               v-model="queryParams.certNo"
               placeholder="请输入证书编号"
               placeholder="请输入证书编号"
@@ -103,7 +103,7 @@
               <dict-tag :type="DICT_TYPE.QHSE_DEVICE_CERT_TYPE" :value="scope.row.certType" />
               <dict-tag :type="DICT_TYPE.QHSE_DEVICE_CERT_TYPE" :value="scope.row.certType" />
             </template>
             </template>
           </zm-table-column>
           </zm-table-column>
-          <zm-table-column label="证书编号" align="center" prop="certNo" />
+          <zm-table-column label="序列号" align="center" prop="certNo" />
           <zm-table-column label="检测日期" align="center" prop="certTime" width="140">
           <zm-table-column label="检测日期" align="center" prop="certTime" width="140">
             <template #default="scope">
             <template #default="scope">
               <span class="iot-md-date">{{ formatDateCorrectly(scope.row.certTime) }}</span>
               <span class="iot-md-date">{{ formatDateCorrectly(scope.row.certTime) }}</span>