| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- <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>
|