|
@@ -0,0 +1,300 @@
|
|
|
|
|
+<script lang="ts" setup>
|
|
|
|
|
+import { IotRdDailyReportApi } from '@/api/pms/iotrddailyreport'
|
|
|
|
|
+import dayjs from 'dayjs'
|
|
|
|
|
+import type { Ref } from 'vue'
|
|
|
|
|
+
|
|
|
|
|
+interface RdProductionBriefRow {
|
|
|
|
|
+ id?: number
|
|
|
|
|
+ projectName?: string
|
|
|
|
|
+ deptName?: string
|
|
|
|
|
+ rdStatusLabel?: string
|
|
|
|
|
+ taskName?: string
|
|
|
|
|
+ techniqueNames?: string
|
|
|
|
|
+ deviceNames?: string
|
|
|
|
|
+ cumulativeWorkingLayers?: number | null
|
|
|
|
|
+ cumulativeWorkingWell?: number | null
|
|
|
|
|
+ constructionBrief?: string
|
|
|
|
|
+ projectSort?: number | null
|
|
|
|
|
+ teamSort?: number | null
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface SpanMethodProps {
|
|
|
|
|
+ rowIndex: number
|
|
|
|
|
+ columnIndex: number
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const TABLE_HEIGHT = 220
|
|
|
|
|
+const RD_DEPT_ID = 163
|
|
|
|
|
+const DEFAULT_DATE = dayjs().subtract(1, 'day').format('YYYY-MM-DD')
|
|
|
|
|
+
|
|
|
|
|
+const props = withDefaults(
|
|
|
|
|
+ defineProps<{
|
|
|
|
|
+ pageMode?: 'compact' | 'full'
|
|
|
|
|
+ }>(),
|
|
|
|
|
+ {
|
|
|
|
|
+ pageMode: 'compact'
|
|
|
|
|
+ }
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+const selectedDate = ref(DEFAULT_DATE)
|
|
|
|
|
+const loading = ref(false)
|
|
|
|
|
+const list = ref<RdProductionBriefRow[]>([])
|
|
|
|
|
+const kbScale = inject<Ref<number>>('rdKbScale', ref(1))
|
|
|
|
|
+const tableHeight = computed<number | string>(() =>
|
|
|
|
|
+ props.pageMode === 'full' ? '100%' : Math.round(TABLE_HEIGHT * kbScale.value)
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+const tableData = computed(() => {
|
|
|
|
|
+ return [...list.value].sort((a, b) => {
|
|
|
|
|
+ const projectSort = Number(a.projectSort ?? 9999) - Number(b.projectSort ?? 9999)
|
|
|
|
|
+ if (projectSort !== 0) return projectSort
|
|
|
|
|
+
|
|
|
|
|
+ return Number(a.teamSort ?? 9999) - Number(b.teamSort ?? 9999)
|
|
|
|
|
+ })
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const projectSpanMap = computed(() =>
|
|
|
|
|
+ createSpanMap(tableData.value, (row) => row.projectName || '-')
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+function normalizeList(res: any): RdProductionBriefRow[] {
|
|
|
|
|
+ if (Array.isArray(res?.list)) return res.list
|
|
|
|
|
+ return []
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function createSpanMap(
|
|
|
|
|
+ rows: RdProductionBriefRow[],
|
|
|
|
|
+ getKey: (row: RdProductionBriefRow) => string
|
|
|
|
|
+) {
|
|
|
|
|
+ const spanMap: number[] = []
|
|
|
|
|
+
|
|
|
|
|
+ rows.forEach((row, index) => {
|
|
|
|
|
+ const key = getKey(row)
|
|
|
|
|
+
|
|
|
|
|
+ if (index > 0 && getKey(rows[index - 1]) === key) {
|
|
|
|
|
+ spanMap[index] = 0
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let span = 1
|
|
|
|
|
+ for (let nextIndex = index + 1; nextIndex < rows.length; nextIndex++) {
|
|
|
|
|
+ if (getKey(rows[nextIndex]) !== key) break
|
|
|
|
|
+ span += 1
|
|
|
|
|
+ }
|
|
|
|
|
+ spanMap[index] = span
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ return spanMap
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function tableSpanMethod({ rowIndex, columnIndex }: SpanMethodProps) {
|
|
|
|
|
+ if (columnIndex !== 0) {
|
|
|
|
|
+ return {
|
|
|
|
|
+ rowspan: 1,
|
|
|
|
|
+ colspan: 1
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const rowspan = projectSpanMap.value[rowIndex]
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ rowspan,
|
|
|
|
|
+ colspan: rowspan > 0 ? 1 : 0
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function getCreateTimeRange() {
|
|
|
|
|
+ const date = selectedDate.value || DEFAULT_DATE
|
|
|
|
|
+
|
|
|
|
|
+ return [
|
|
|
|
|
+ dayjs(date).startOf('day').format('YYYY-MM-DD HH:mm:ss'),
|
|
|
|
|
+ dayjs(date).endOf('day').format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
|
+ ]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function formatText(value?: string | number | null) {
|
|
|
|
|
+ return value === null || value === undefined || value === '' ? '-' : value
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function handleDateChange() {
|
|
|
|
|
+ getList()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+async function getList() {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await IotRdDailyReportApi.getIotRdDailyReportPage({
|
|
|
|
|
+ deptId: RD_DEPT_ID,
|
|
|
|
|
+ createTime: getCreateTimeRange()
|
|
|
|
|
+ })
|
|
|
|
|
+ list.value = normalizeList(res)
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取瑞都生产日报失败:', error)
|
|
|
|
|
+ list.value = []
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ getList()
|
|
|
|
|
+})
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="panel device-list-panel production-brief-panel w-full flex flex-col"
|
|
|
|
|
+ :class="{ 'production-brief-panel--full': props.pageMode === 'full' }">
|
|
|
|
|
+ <div class="panel-title flex items-center justify-between">
|
|
|
|
|
+ <div class="kb-panel-title-text flex items-center">
|
|
|
|
|
+ <div class="icon-decorator">
|
|
|
|
|
+ <span></span>
|
|
|
|
|
+ <span></span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ 生产日报
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="production-brief-panel__picker">
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-model="selectedDate"
|
|
|
|
|
+ value-format="YYYY-MM-DD"
|
|
|
|
|
+ type="date"
|
|
|
|
|
+ placeholder="选择日期"
|
|
|
|
|
+ :clearable="false"
|
|
|
|
|
+ class="production-brief-panel__picker-input"
|
|
|
|
|
+ @change="handleDateChange" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="device-list-panel__body flex-1 min-h-0">
|
|
|
|
|
+ <el-table
|
|
|
|
|
+ v-loading="loading"
|
|
|
|
|
+ :data="tableData"
|
|
|
|
|
+ :height="tableHeight"
|
|
|
|
|
+ :span-method="tableSpanMethod"
|
|
|
|
|
+ class="device-list-table production-brief-table"
|
|
|
|
|
+ :class="{ 'production-brief-table--full': props.pageMode === 'full' }">
|
|
|
|
|
+ <el-table-column prop="projectName" label="项目" min-width="150" align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ formatText(row.projectName) }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="deptName" label="队伍" min-width="110" align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ formatText(row.deptName) }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="rdStatusLabel" label="状态" min-width="90" align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ formatText(row.rdStatusLabel) }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="taskName" label="井号" min-width="120" align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ formatText(row.taskName) }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="techniqueNames" label="工艺" min-width="130" align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ formatText(row.techniqueNames) }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="deviceNames" label="使用设备" min-width="170" align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ formatText(row.deviceNames) }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ prop="cumulativeWorkingLayers"
|
|
|
|
|
+ label="压裂层数"
|
|
|
|
|
+ min-width="100"
|
|
|
|
|
+ align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ formatText(row.cumulativeWorkingLayers) }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ prop="cumulativeWorkingWell"
|
|
|
|
|
+ label="连油井数"
|
|
|
|
|
+ min-width="100"
|
|
|
|
|
+ align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ formatText(row.cumulativeWorkingWell) }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="constructionBrief" label="施工简要" min-width="220" align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ formatText(row.constructionBrief) }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+
|
|
|
|
|
+ <template #empty>
|
|
|
|
|
+ <div class="h-full min-h-[220px] flex items-center justify-center">
|
|
|
|
|
+ <el-empty description="暂无数据" :image-size="72" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
|
+@import url('@/styles/kb.scss');
|
|
|
|
|
+
|
|
|
|
|
+.device-list-panel.production-brief-panel--full {
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ margin-top: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.production-brief-panel__picker {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ width: calc(120px * var(--kb-scale, 1));
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.production-brief-panel__picker-input {
|
|
|
|
|
+ width: calc(120px * var(--kb-scale, 1)) !important;
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-input__wrapper) {
|
|
|
|
|
+ min-height: calc(28px * var(--kb-scale, 1));
|
|
|
|
|
+ padding: 0 calc(10px * var(--kb-scale, 1));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-input__inner) {
|
|
|
|
|
+ font-size: calc(12px * var(--kb-scale, 1));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-input__prefix-inner),
|
|
|
|
|
+ :deep(.el-input__suffix-inner) {
|
|
|
|
|
+ font-size: calc(14px * var(--kb-scale, 1));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.production-brief-table {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-table__header-wrapper th.el-table__cell) {
|
|
|
|
|
+ font-size: calc(16px * var(--kb-scale, 1));
|
|
|
|
|
+ line-height: 1.2;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-table__body td.el-table__cell) {
|
|
|
|
|
+ padding: calc(7px * var(--kb-scale, 1)) 0;
|
|
|
|
|
+ font-size: calc(14px * var(--kb-scale, 1));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.production-brief-table--full {
|
|
|
|
|
+ :deep(.el-scrollbar__view) {
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-table__body) {
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-table__body tbody) {
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|