|
@@ -1,11 +1,20 @@
|
|
|
<template>
|
|
<template>
|
|
|
<el-row :gutter="20">
|
|
<el-row :gutter="20">
|
|
|
- <el-col :class="{'leftcontent': true, 'collapsed': isLeftContentCollapsed}" :span="isLeftContentCollapsed ? 0 : 4" :xs="24">
|
|
|
|
|
|
|
+ <el-col
|
|
|
|
|
+ :class="{ leftcontent: true, collapsed: isLeftContentCollapsed }"
|
|
|
|
|
+ :span="isLeftContentCollapsed ? 0 : 4"
|
|
|
|
|
+ :xs="24"
|
|
|
|
|
+ >
|
|
|
<ContentWrap class="h-1/1">
|
|
<ContentWrap class="h-1/1">
|
|
|
<DeptTree @node-click="handleDeptNodeClick" />
|
|
<DeptTree @node-click="handleDeptNodeClick" />
|
|
|
</ContentWrap>
|
|
</ContentWrap>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
- <el-col class="rightcontent" :span="isLeftContentCollapsed ? 24 : 20" :xs="24" style="position: relative;height: 100vh;">
|
|
|
|
|
|
|
+ <el-col
|
|
|
|
|
+ class="rightcontent"
|
|
|
|
|
+ :span="isLeftContentCollapsed ? 24 : 20"
|
|
|
|
|
+ :xs="24"
|
|
|
|
|
+ style="position: relative; height: 100vh"
|
|
|
|
|
+ >
|
|
|
<div
|
|
<div
|
|
|
class="toggle-button"
|
|
class="toggle-button"
|
|
|
:style="{ left: isLeftContentCollapsed ? '0px' : '-13px' }"
|
|
:style="{ left: isLeftContentCollapsed ? '0px' : '-13px' }"
|
|
@@ -14,7 +23,10 @@
|
|
|
@mouseout="handleMouseOut"
|
|
@mouseout="handleMouseOut"
|
|
|
:title="hoverText"
|
|
:title="hoverText"
|
|
|
>
|
|
>
|
|
|
- <span style="font-size: 5px;" :class="{'triangle': true, 'rotated': isLeftContentCollapsed}"></span>
|
|
|
|
|
|
|
+ <span
|
|
|
|
|
+ style="font-size: 5px"
|
|
|
|
|
+ :class="{ triangle: true, rotated: isLeftContentCollapsed }"
|
|
|
|
|
+ ></span>
|
|
|
</div>
|
|
</div>
|
|
|
<ContentWrap>
|
|
<ContentWrap>
|
|
|
<!-- 搜索工作栏 -->
|
|
<!-- 搜索工作栏 -->
|
|
@@ -61,16 +73,19 @@
|
|
|
/>
|
|
/>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item>
|
|
<el-form-item>
|
|
|
- <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" />
|
|
|
|
|
- {{ t('operationFill.search') }}</el-button>
|
|
|
|
|
- <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> {{ t('operationFill.reset') }}</el-button>
|
|
|
|
|
|
|
+ <el-button @click="handleQuery"
|
|
|
|
|
+ ><Icon icon="ep:search" class="mr-5px" /> {{ t('operationFill.search') }}</el-button
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-button @click="resetQuery"
|
|
|
|
|
+ ><Icon icon="ep:refresh" class="mr-5px" /> {{ t('operationFill.reset') }}</el-button
|
|
|
|
|
+ >
|
|
|
<el-button
|
|
<el-button
|
|
|
type="primary"
|
|
type="primary"
|
|
|
plain
|
|
plain
|
|
|
@click="openForm('create')"
|
|
@click="openForm('create')"
|
|
|
v-hasPermi="['pms:iot-main-work-order:create']"
|
|
v-hasPermi="['pms:iot-main-work-order:create']"
|
|
|
>
|
|
>
|
|
|
- <Icon icon="ep:plus" class="mr-5px" /> {{ t('operationFill.add') }}
|
|
|
|
|
|
|
+ <Icon icon="ep:plus" class="mr-5px" /> {{ t('operationFill.add') }}
|
|
|
</el-button>
|
|
</el-button>
|
|
|
<el-button
|
|
<el-button
|
|
|
type="success"
|
|
type="success"
|
|
@@ -87,38 +102,76 @@
|
|
|
|
|
|
|
|
<!-- 列表 -->
|
|
<!-- 列表 -->
|
|
|
<ContentWrap ref="tableContainerRef" class="table-wrap">
|
|
<ContentWrap ref="tableContainerRef" class="table-wrap">
|
|
|
- <el-table v-loading="loading" :data="list" :stripe="true" style="width: 100%" ref="tableRef">
|
|
|
|
|
- <el-table-column :label="t('iotDevice.serial')" align="center" :width="columnWidths.serial">
|
|
|
|
|
|
|
+ <el-table
|
|
|
|
|
+ v-loading="loading"
|
|
|
|
|
+ :data="list"
|
|
|
|
|
+ :stripe="true"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ ref="tableRef"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ :label="t('iotDevice.serial')"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ :width="columnWidths.serial"
|
|
|
|
|
+ >
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
{{ scope.$index + 1 }}
|
|
{{ scope.$index + 1 }}
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column :label="t('bomList.name')" align="center" prop="name" :width="columnWidths.name"/>
|
|
|
|
|
- <el-table-column :label="t('iotDevice.dept')" align="center" prop="deptName" :width="columnWidths.deptName"/>
|
|
|
|
|
- <el-table-column :label="t('bomList.status')" align="center" prop="result" :width="columnWidths.result">
|
|
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ :label="t('bomList.name')"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ prop="name"
|
|
|
|
|
+ :width="columnWidths.name"
|
|
|
|
|
+ />
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ :label="t('iotDevice.dept')"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ prop="deptName"
|
|
|
|
|
+ :width="columnWidths.deptName"
|
|
|
|
|
+ />
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ :label="t('bomList.status')"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ prop="result"
|
|
|
|
|
+ :width="columnWidths.result"
|
|
|
|
|
+ >
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
<dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT" :value="scope.row.result" />
|
|
<dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT" :value="scope.row.result" />
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column :label="t('bomList.serviceDue')" align="center" :width="columnWidths.serviceDue">
|
|
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ :label="t('bomList.serviceDue')"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ :width="columnWidths.serviceDue"
|
|
|
|
|
+ >
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
- <span :class="getDistanceClass(scope.row.mainDistance)">
|
|
|
|
|
- {{ scope.row.mainDistance }}
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+ <span :class="getDistanceClass(scope.row.mainDistance)">
|
|
|
|
|
+ {{ scope.row.mainDistance }}
|
|
|
|
|
+ </span>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column :label="t('bomList.type')" align="center" prop="type" :width="columnWidths.type">
|
|
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ :label="t('bomList.type')"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ prop="type"
|
|
|
|
|
+ :width="columnWidths.type"
|
|
|
|
|
+ >
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
<dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_TYPE" :value="scope.row.type" />
|
|
<dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_TYPE" :value="scope.row.type" />
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column :label="t('iotMaintain.PersonInCharge')" align="center"
|
|
|
|
|
- prop="responsiblePersonName" :width="columnWidths.responsiblePersonName"/>
|
|
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ :label="t('iotMaintain.PersonInCharge')"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ prop="responsiblePersonName"
|
|
|
|
|
+ :width="columnWidths.responsiblePersonName"
|
|
|
|
|
+ />
|
|
|
<el-table-column
|
|
<el-table-column
|
|
|
:label="t('dict.createTime')"
|
|
:label="t('dict.createTime')"
|
|
|
align="center"
|
|
align="center"
|
|
|
prop="createTime"
|
|
prop="createTime"
|
|
|
- :formatter="dateFormatter"
|
|
|
|
|
|
|
+ :formatter="dateFormatter2"
|
|
|
:width="columnWidths.createTime"
|
|
:width="columnWidths.createTime"
|
|
|
/>
|
|
/>
|
|
|
<el-table-column
|
|
<el-table-column
|
|
@@ -128,13 +181,18 @@
|
|
|
:width="columnWidths.updateTime"
|
|
:width="columnWidths.updateTime"
|
|
|
>
|
|
>
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
- <span v-if="scope.row.result == 2">
|
|
|
|
|
- {{ formatCellDate(scope.row.updateTime) }}
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+ <span v-if="scope.row.result == 2">
|
|
|
|
|
+ {{ formatCellDate(scope.row.updateTime) }}
|
|
|
|
|
+ </span>
|
|
|
<span v-else></span>
|
|
<span v-else></span>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column :label="t('iotMaintain.operation')" align="center" :width="columnWidths.operation" fixed="right">
|
|
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ :label="t('iotMaintain.operation')"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ :width="columnWidths.operation"
|
|
|
|
|
+ fixed="right"
|
|
|
|
|
+ >
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
<el-button
|
|
<el-button
|
|
|
v-if="isNegativeMainDistance(scope.row.mainDistance)"
|
|
v-if="isNegativeMainDistance(scope.row.mainDistance)"
|
|
@@ -160,7 +218,7 @@
|
|
|
@click="detail(scope.row.id)"
|
|
@click="detail(scope.row.id)"
|
|
|
v-hasPermi="['pms:iot-main-work-order:query']"
|
|
v-hasPermi="['pms:iot-main-work-order:query']"
|
|
|
>
|
|
>
|
|
|
- {{ t('operationFill.view') }}
|
|
|
|
|
|
|
+ {{ t('operationFill.view') }}
|
|
|
</el-button>
|
|
</el-button>
|
|
|
<el-button
|
|
<el-button
|
|
|
link
|
|
link
|
|
@@ -169,7 +227,7 @@
|
|
|
v-hasPermi="['pms:iot-main-work-order:back']"
|
|
v-hasPermi="['pms:iot-main-work-order:back']"
|
|
|
v-if="scope.row.result === 2 && scope.row.status === 0"
|
|
v-if="scope.row.result === 2 && scope.row.status === 0"
|
|
|
>
|
|
>
|
|
|
- {{ t('workOrderMaterial.back') }}
|
|
|
|
|
|
|
+ {{ t('workOrderMaterial.back') }}
|
|
|
</el-button>
|
|
</el-button>
|
|
|
<el-button
|
|
<el-button
|
|
|
link
|
|
link
|
|
@@ -177,9 +235,13 @@
|
|
|
class="warning-btn"
|
|
class="warning-btn"
|
|
|
@click="openModifyForm('modify', scope.row.id)"
|
|
@click="openModifyForm('modify', scope.row.id)"
|
|
|
v-hasPermi="['pms:iot-main-work-order:update']"
|
|
v-hasPermi="['pms:iot-main-work-order:update']"
|
|
|
- v-if="scope.row.result === 2 && scope.row.status === 1 && currentUserId?.toString() === scope.row.responsiblePerson"
|
|
|
|
|
|
|
+ v-if="
|
|
|
|
|
+ scope.row.result === 2 &&
|
|
|
|
|
+ scope.row.status === 1 &&
|
|
|
|
|
+ currentUserId?.toString() === scope.row.responsiblePerson
|
|
|
|
|
+ "
|
|
|
>
|
|
>
|
|
|
- {{ t('modelTemplate.update') }}
|
|
|
|
|
|
|
+ {{ t('modelTemplate.update') }}
|
|
|
</el-button>
|
|
</el-button>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
@@ -204,8 +266,12 @@
|
|
|
width="500px"
|
|
width="500px"
|
|
|
:close-on-click-modal="false"
|
|
:close-on-click-modal="false"
|
|
|
>
|
|
>
|
|
|
- <el-form :model="delayReasonForm" label-width="0px" :rules="delayReasonRules"
|
|
|
|
|
- ref="delayReasonFormRef">
|
|
|
|
|
|
|
+ <el-form
|
|
|
|
|
+ :model="delayReasonForm"
|
|
|
|
|
+ label-width="0px"
|
|
|
|
|
+ :rules="delayReasonRules"
|
|
|
|
|
+ ref="delayReasonFormRef"
|
|
|
|
|
+ >
|
|
|
<el-form-item label=" " prop="delayReason" class="required-item" label-width="16px">
|
|
<el-form-item label=" " prop="delayReason" class="required-item" label-width="16px">
|
|
|
<el-input
|
|
<el-input
|
|
|
v-model="delayReasonForm.delayReason"
|
|
v-model="delayReasonForm.delayReason"
|
|
@@ -226,17 +292,16 @@
|
|
|
</el-button>
|
|
</el-button>
|
|
|
</template>
|
|
</template>
|
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
-
|
|
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import { dateFormatter } from '@/utils/formatTime'
|
|
|
|
|
|
|
+import { dateFormatter2 } from '@/utils/formatTime'
|
|
|
import download from '@/utils/download'
|
|
import download from '@/utils/download'
|
|
|
import { IotMainWorkOrderApi, IotMainWorkOrderVO } from '@/api/pms/iotmainworkorder'
|
|
import { IotMainWorkOrderApi, IotMainWorkOrderVO } from '@/api/pms/iotmainworkorder'
|
|
|
import IotMainWorkOrderForm from './IotMainWorkOrderForm.vue'
|
|
import IotMainWorkOrderForm from './IotMainWorkOrderForm.vue'
|
|
|
-import {DICT_TYPE, getStrDictOptions} from "@/utils/dict";
|
|
|
|
|
-import DeptTree from "@/views/system/user/DeptTree.vue";
|
|
|
|
|
-import { useUserStore } from "@/store/modules/user";
|
|
|
|
|
|
|
+import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
|
|
|
|
|
+import DeptTree from '@/views/system/user/DeptTree.vue'
|
|
|
|
|
+import { useUserStore } from '@/store/modules/user'
|
|
|
const { push } = useRouter() // 路由跳转
|
|
const { push } = useRouter() // 路由跳转
|
|
|
|
|
|
|
|
/** 保养工单 列表 */
|
|
/** 保养工单 列表 */
|
|
@@ -246,12 +311,12 @@ defineOptions({ name: 'IotMainWorkOrder' })
|
|
|
const delayReasonFormRef = ref<InstanceType<typeof ElForm>>()
|
|
const delayReasonFormRef = ref<InstanceType<typeof ElForm>>()
|
|
|
|
|
|
|
|
// 定义响应式变量存储当前登录人ID
|
|
// 定义响应式变量存储当前登录人ID
|
|
|
-const currentUserId = ref<number | undefined>(undefined);
|
|
|
|
|
|
|
+const currentUserId = ref<number | undefined>(undefined)
|
|
|
|
|
|
|
|
const message = useMessage() // 消息弹窗
|
|
const message = useMessage() // 消息弹窗
|
|
|
const { t } = useI18n() // 国际化
|
|
const { t } = useI18n() // 国际化
|
|
|
const tableRef = ref() // 表格引用
|
|
const tableRef = ref() // 表格引用
|
|
|
-const isLeftContentCollapsed = ref(false);
|
|
|
|
|
|
|
+const isLeftContentCollapsed = ref(false)
|
|
|
// 表格容器引用 用于获取容器宽度
|
|
// 表格容器引用 用于获取容器宽度
|
|
|
const tableContainerRef = ref()
|
|
const tableContainerRef = ref()
|
|
|
const loading = ref(true) // 列表的加载中
|
|
const loading = ref(true) // 列表的加载中
|
|
@@ -279,16 +344,20 @@ const queryParams = reactive({
|
|
|
status: undefined,
|
|
status: undefined,
|
|
|
processInstanceId: undefined,
|
|
processInstanceId: undefined,
|
|
|
auditStatus: undefined,
|
|
auditStatus: undefined,
|
|
|
- createTime: [],
|
|
|
|
|
|
|
+ createTime: []
|
|
|
})
|
|
})
|
|
|
const queryFormRef = ref() // 搜索的表单
|
|
const queryFormRef = ref() // 搜索的表单
|
|
|
const exportLoading = ref(false) // 导出的加载中
|
|
const exportLoading = ref(false) // 导出的加载中
|
|
|
-const hoverText = ref('');
|
|
|
|
|
|
|
+const hoverText = ref('')
|
|
|
|
|
|
|
|
// 定义表单验证规则
|
|
// 定义表单验证规则
|
|
|
const delayReasonRules = {
|
|
const delayReasonRules = {
|
|
|
delayReason: [
|
|
delayReason: [
|
|
|
- { required: true, message: t('workOrderMaterial.inputDelayReason') || '请输入延时原因', trigger: 'blur' }
|
|
|
|
|
|
|
+ {
|
|
|
|
|
+ required: true,
|
|
|
|
|
+ message: t('workOrderMaterial.inputDelayReason') || '请输入延时原因',
|
|
|
|
|
+ trigger: 'blur'
|
|
|
|
|
+ }
|
|
|
]
|
|
]
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -308,20 +377,20 @@ const columnWidths = ref({
|
|
|
|
|
|
|
|
// 计算文本宽度
|
|
// 计算文本宽度
|
|
|
const getTextWidth = (text: string, fontSize = 14) => {
|
|
const getTextWidth = (text: string, fontSize = 14) => {
|
|
|
- const span = document.createElement('span');
|
|
|
|
|
- span.style.visibility = 'hidden';
|
|
|
|
|
- span.style.position = 'absolute';
|
|
|
|
|
- span.style.whiteSpace = 'nowrap';
|
|
|
|
|
- span.style.fontSize = `${fontSize}px`;
|
|
|
|
|
- span.style.fontFamily = 'inherit';
|
|
|
|
|
- span.innerText = text;
|
|
|
|
|
|
|
+ const span = document.createElement('span')
|
|
|
|
|
+ span.style.visibility = 'hidden'
|
|
|
|
|
+ span.style.position = 'absolute'
|
|
|
|
|
+ span.style.whiteSpace = 'nowrap'
|
|
|
|
|
+ span.style.fontSize = `${fontSize}px`
|
|
|
|
|
+ span.style.fontFamily = 'inherit'
|
|
|
|
|
+ span.innerText = text
|
|
|
|
|
|
|
|
- document.body.appendChild(span);
|
|
|
|
|
- const width = span.offsetWidth;
|
|
|
|
|
- document.body.removeChild(span);
|
|
|
|
|
|
|
+ document.body.appendChild(span)
|
|
|
|
|
+ const width = span.offsetWidth
|
|
|
|
|
+ document.body.removeChild(span)
|
|
|
|
|
|
|
|
- return width;
|
|
|
|
|
-};
|
|
|
|
|
|
|
+ return width
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
/** 延保原因相关状态 */
|
|
/** 延保原因相关状态 */
|
|
|
const delayReasonDialogVisible = ref(false)
|
|
const delayReasonDialogVisible = ref(false)
|
|
@@ -400,87 +469,106 @@ const handleDeptNodeClick = async (row) => {
|
|
|
|
|
|
|
|
// 计算列宽度
|
|
// 计算列宽度
|
|
|
const calculateColumnWidths = () => {
|
|
const calculateColumnWidths = () => {
|
|
|
- const MIN_WIDTH = 80; // 最小列宽
|
|
|
|
|
- const PADDING = 25; // 列内边距
|
|
|
|
|
- const FLEXIBLE_COLUMN = 'name'; // 可伸缩列
|
|
|
|
|
|
|
+ const MIN_WIDTH = 80 // 最小列宽
|
|
|
|
|
+ const PADDING = 25 // 列内边距
|
|
|
|
|
+ const FLEXIBLE_COLUMN = 'name' // 可伸缩列
|
|
|
|
|
|
|
|
// 确保表格容器存在
|
|
// 确保表格容器存在
|
|
|
- if (!tableContainerRef.value?.$el) return;
|
|
|
|
|
|
|
+ if (!tableContainerRef.value?.$el) return
|
|
|
|
|
|
|
|
- const container = tableContainerRef.value.$el;
|
|
|
|
|
- const containerWidth = container.clientWidth;
|
|
|
|
|
|
|
+ const container = tableContainerRef.value.$el
|
|
|
|
|
+ const containerWidth = container.clientWidth
|
|
|
|
|
|
|
|
// 1. 计算所有列的最小宽度
|
|
// 1. 计算所有列的最小宽度
|
|
|
- const minWidths: Record<string, number> = {};
|
|
|
|
|
- let totalMinWidth = 0;
|
|
|
|
|
|
|
+ const minWidths: Record<string, number> = {}
|
|
|
|
|
+ let totalMinWidth = 0
|
|
|
|
|
|
|
|
// 计算列最小宽度的函数
|
|
// 计算列最小宽度的函数
|
|
|
const calculateColumnMinWidth = (key: string, label: string, getValue: Function) => {
|
|
const calculateColumnMinWidth = (key: string, label: string, getValue: Function) => {
|
|
|
- const headerWidth = getTextWidth(label) * 1.2;
|
|
|
|
|
- let contentMaxWidth = 0;
|
|
|
|
|
|
|
+ const headerWidth = getTextWidth(label) * 1.2
|
|
|
|
|
+ let contentMaxWidth = 0
|
|
|
|
|
|
|
|
// 计算内容最大宽度
|
|
// 计算内容最大宽度
|
|
|
list.value.forEach((row, index) => {
|
|
list.value.forEach((row, index) => {
|
|
|
- const text = String(getValue ? getValue(row, index) : (row[key] || ''));
|
|
|
|
|
- const textWidth = getTextWidth(text);
|
|
|
|
|
- if (textWidth > contentMaxWidth) contentMaxWidth = textWidth;
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ const text = String(getValue ? getValue(row, index) : row[key] || '')
|
|
|
|
|
+ const textWidth = getTextWidth(text)
|
|
|
|
|
+ if (textWidth > contentMaxWidth) contentMaxWidth = textWidth
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- const minWidth = Math.max(headerWidth, contentMaxWidth, MIN_WIDTH) + PADDING;
|
|
|
|
|
- minWidths[key] = minWidth;
|
|
|
|
|
- totalMinWidth += minWidth;
|
|
|
|
|
- return minWidth;
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ const minWidth = Math.max(headerWidth, contentMaxWidth, MIN_WIDTH) + PADDING
|
|
|
|
|
+ minWidths[key] = minWidth
|
|
|
|
|
+ totalMinWidth += minWidth
|
|
|
|
|
+ return minWidth
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// 计算各列最小宽度
|
|
// 计算各列最小宽度
|
|
|
- calculateColumnMinWidth('serial', t('iotDevice.serial'), (row: any, index: number) => `${index + 1}`);
|
|
|
|
|
- const nameMinWidth = calculateColumnMinWidth('name', t('bomList.name'), (row: any) => row.name);
|
|
|
|
|
- calculateColumnMinWidth('deptName', t('iotDevice.dept'), (row: any) => row.deptName);
|
|
|
|
|
|
|
+ calculateColumnMinWidth(
|
|
|
|
|
+ 'serial',
|
|
|
|
|
+ t('iotDevice.serial'),
|
|
|
|
|
+ (row: any, index: number) => `${index + 1}`
|
|
|
|
|
+ )
|
|
|
|
|
+ const nameMinWidth = calculateColumnMinWidth('name', t('bomList.name'), (row: any) => row.name)
|
|
|
|
|
+ calculateColumnMinWidth('deptName', t('iotDevice.dept'), (row: any) => row.deptName)
|
|
|
calculateColumnMinWidth('result', t('bomList.status'), (row: any) => {
|
|
calculateColumnMinWidth('result', t('bomList.status'), (row: any) => {
|
|
|
- const dict = getStrDictOptions(DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT)
|
|
|
|
|
- .find(d => d.value === row.result);
|
|
|
|
|
- return dict ? dict.label : '';
|
|
|
|
|
- });
|
|
|
|
|
- calculateColumnMinWidth('serviceDue', t('bomList.serviceDue'), (row: any) => row.mainDistance || '');
|
|
|
|
|
|
|
+ const dict = getStrDictOptions(DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT).find(
|
|
|
|
|
+ (d) => d.value === row.result
|
|
|
|
|
+ )
|
|
|
|
|
+ return dict ? dict.label : ''
|
|
|
|
|
+ })
|
|
|
|
|
+ calculateColumnMinWidth(
|
|
|
|
|
+ 'serviceDue',
|
|
|
|
|
+ t('bomList.serviceDue'),
|
|
|
|
|
+ (row: any) => row.mainDistance || ''
|
|
|
|
|
+ )
|
|
|
calculateColumnMinWidth('type', t('bomList.type'), (row: any) => {
|
|
calculateColumnMinWidth('type', t('bomList.type'), (row: any) => {
|
|
|
- const dict = getStrDictOptions(DICT_TYPE.PMS_MAIN_WORK_ORDER_TYPE)
|
|
|
|
|
- .find(d => d.value === row.type);
|
|
|
|
|
- return dict ? dict.label : '';
|
|
|
|
|
- });
|
|
|
|
|
- calculateColumnMinWidth('responsiblePersonName', t('iotMaintain.PersonInCharge'), (row: any) => row.responsiblePersonName);
|
|
|
|
|
- calculateColumnMinWidth('createTime', t('dict.createTime'), (row: any) => dateFormatter(null, null, row.createTime));
|
|
|
|
|
- calculateColumnMinWidth('updateTime', t('dict.fillTime'), (row: any) => row.result == 2 ? formatCellDate(row.updateTime) : '');
|
|
|
|
|
|
|
+ const dict = getStrDictOptions(DICT_TYPE.PMS_MAIN_WORK_ORDER_TYPE).find(
|
|
|
|
|
+ (d) => d.value === row.type
|
|
|
|
|
+ )
|
|
|
|
|
+ return dict ? dict.label : ''
|
|
|
|
|
+ })
|
|
|
|
|
+ calculateColumnMinWidth(
|
|
|
|
|
+ 'responsiblePersonName',
|
|
|
|
|
+ t('iotMaintain.PersonInCharge'),
|
|
|
|
|
+ (row: any) => row.responsiblePersonName
|
|
|
|
|
+ )
|
|
|
|
|
+ calculateColumnMinWidth('createTime', t('dict.createTime'), (row: any) =>
|
|
|
|
|
+ dateFormatter(null, null, row.createTime)
|
|
|
|
|
+ )
|
|
|
|
|
+ calculateColumnMinWidth('updateTime', t('dict.fillTime'), (row: any) =>
|
|
|
|
|
+ row.result == 2 ? formatCellDate(row.updateTime) : ''
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
// 操作列固定宽度
|
|
// 操作列固定宽度
|
|
|
- minWidths.operation = 160;
|
|
|
|
|
- totalMinWidth += 160;
|
|
|
|
|
|
|
+ minWidths.operation = 160
|
|
|
|
|
+ totalMinWidth += 160
|
|
|
|
|
|
|
|
// 2. 计算可伸缩列最终宽度
|
|
// 2. 计算可伸缩列最终宽度
|
|
|
- const newWidths: Record<string, string> = {};
|
|
|
|
|
- const availableWidth = containerWidth - 17; // 减去滚动条宽度
|
|
|
|
|
|
|
+ const newWidths: Record<string, string> = {}
|
|
|
|
|
+ const availableWidth = containerWidth - 17 // 减去滚动条宽度
|
|
|
|
|
|
|
|
// 应用最小宽度到所有列
|
|
// 应用最小宽度到所有列
|
|
|
- Object.keys(minWidths).forEach(key => {
|
|
|
|
|
- newWidths[key] = `${minWidths[key]}px`;
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ Object.keys(minWidths).forEach((key) => {
|
|
|
|
|
+ newWidths[key] = `${minWidths[key]}px`
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
// 计算可伸缩列需要的宽度
|
|
// 计算可伸缩列需要的宽度
|
|
|
if (totalMinWidth < availableWidth) {
|
|
if (totalMinWidth < availableWidth) {
|
|
|
// 有剩余空间:分配给可伸缩列
|
|
// 有剩余空间:分配给可伸缩列
|
|
|
- newWidths[FLEXIBLE_COLUMN] = `${minWidths[FLEXIBLE_COLUMN] + (availableWidth - totalMinWidth)}px`;
|
|
|
|
|
|
|
+ newWidths[FLEXIBLE_COLUMN] =
|
|
|
|
|
+ `${minWidths[FLEXIBLE_COLUMN] + (availableWidth - totalMinWidth)}px`
|
|
|
} else {
|
|
} else {
|
|
|
// 空间不足:确保可伸缩列至少显示内容
|
|
// 空间不足:确保可伸缩列至少显示内容
|
|
|
- newWidths[FLEXIBLE_COLUMN] = `${nameMinWidth}px`;
|
|
|
|
|
|
|
+ newWidths[FLEXIBLE_COLUMN] = `${nameMinWidth}px`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 3. 更新列宽配置
|
|
// 3. 更新列宽配置
|
|
|
- columnWidths.value = newWidths;
|
|
|
|
|
|
|
+ columnWidths.value = newWidths
|
|
|
|
|
|
|
|
// 4. 触发表格重新布局
|
|
// 4. 触发表格重新布局
|
|
|
nextTick(() => {
|
|
nextTick(() => {
|
|
|
- tableRef.value?.doLayout();
|
|
|
|
|
- });
|
|
|
|
|
-};
|
|
|
|
|
|
|
+ tableRef.value?.doLayout()
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
/** 查询列表 */
|
|
/** 查询列表 */
|
|
|
const getList = async () => {
|
|
const getList = async () => {
|
|
@@ -502,8 +590,8 @@ const getList = async () => {
|
|
|
|
|
|
|
|
// 日期格式化辅助函数
|
|
// 日期格式化辅助函数
|
|
|
const formatCellDate = (dateString: string | null) => {
|
|
const formatCellDate = (dateString: string | null) => {
|
|
|
- if (!dateString) return '';
|
|
|
|
|
- return dateFormatter(null, null, dateString);
|
|
|
|
|
|
|
+ if (!dateString) return ''
|
|
|
|
|
+ return dateFormatter(null, null, dateString)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** 搜索按钮操作 */
|
|
/** 搜索按钮操作 */
|
|
@@ -531,7 +619,7 @@ const handleBack = async (id: number) => {
|
|
|
// 调用接口提交退回请求
|
|
// 调用接口提交退回请求
|
|
|
await IotMainWorkOrderApi.updateIotMainWorkOrder({
|
|
await IotMainWorkOrderApi.updateIotMainWorkOrder({
|
|
|
id: id,
|
|
id: id,
|
|
|
- backFlag: '1' // 退回标识参数
|
|
|
|
|
|
|
+ backFlag: '1' // 退回标识参数
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
message.success(t('common.success') || '退回成功')
|
|
message.success(t('common.success') || '退回成功')
|
|
@@ -562,58 +650,56 @@ const resultOptions = computed(() => [
|
|
|
])
|
|
])
|
|
|
|
|
|
|
|
const getDistanceClass = (distance: number | string | null) => {
|
|
const getDistanceClass = (distance: number | string | null) => {
|
|
|
- if (distance === null || distance === undefined) return '';
|
|
|
|
|
|
|
+ if (distance === null || distance === undefined) return ''
|
|
|
|
|
|
|
|
// 如果是数字类型,直接处理
|
|
// 如果是数字类型,直接处理
|
|
|
if (typeof distance === 'number') {
|
|
if (typeof distance === 'number') {
|
|
|
- return distance < 0 ? 'negative-distance' :
|
|
|
|
|
- distance > 0 ? 'positive-distance' : '';
|
|
|
|
|
|
|
+ return distance < 0 ? 'negative-distance' : distance > 0 ? 'positive-distance' : ''
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 如果是字符串,提取数字部分
|
|
// 如果是字符串,提取数字部分
|
|
|
if (typeof distance === 'string') {
|
|
if (typeof distance === 'string') {
|
|
|
// 使用正则提取数字部分(包括负号、小数点和科学计数法)
|
|
// 使用正则提取数字部分(包括负号、小数点和科学计数法)
|
|
|
- const numericPart = distance.match(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/)?.[0];
|
|
|
|
|
|
|
+ const numericPart = distance.match(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/)?.[0]
|
|
|
|
|
|
|
|
// 如果提取到数字部分,转换为数值
|
|
// 如果提取到数字部分,转换为数值
|
|
|
if (numericPart) {
|
|
if (numericPart) {
|
|
|
- const num = parseFloat(numericPart);
|
|
|
|
|
- return num < 0 ? 'negative-distance' :
|
|
|
|
|
- num > 0 ? 'positive-distance' : '';
|
|
|
|
|
|
|
+ const num = parseFloat(numericPart)
|
|
|
|
|
+ return num < 0 ? 'negative-distance' : num > 0 ? 'positive-distance' : ''
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return '';
|
|
|
|
|
-};
|
|
|
|
|
|
|
+ return ''
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
const toggleLeftContent = () => {
|
|
const toggleLeftContent = () => {
|
|
|
- isLeftContentCollapsed.value = !isLeftContentCollapsed.value;
|
|
|
|
|
-};
|
|
|
|
|
|
|
+ isLeftContentCollapsed.value = !isLeftContentCollapsed.value
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
const handleMouseOver = () => {
|
|
const handleMouseOver = () => {
|
|
|
- hoverText.value = isLeftContentCollapsed.value ? '展开' : '收起';
|
|
|
|
|
-};
|
|
|
|
|
|
|
+ hoverText.value = isLeftContentCollapsed.value ? '展开' : '收起'
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
const handleMouseOut = () => {
|
|
const handleMouseOut = () => {
|
|
|
- hoverText.value = '';
|
|
|
|
|
-};
|
|
|
|
|
|
|
+ hoverText.value = ''
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
/** 添加/修改操作 */
|
|
/** 添加/修改操作 */
|
|
|
const formRef = ref()
|
|
const formRef = ref()
|
|
|
const openForm = (type: string, id?: number) => {
|
|
const openForm = (type: string, id?: number) => {
|
|
|
// 修改
|
|
// 修改
|
|
|
if (typeof id === 'number') {
|
|
if (typeof id === 'number') {
|
|
|
- push({ name: 'IotMainWorkOrderOptimize', params: {id } })
|
|
|
|
|
|
|
+ push({ name: 'IotMainWorkOrderOptimize', params: { id } })
|
|
|
return
|
|
return
|
|
|
} else {
|
|
} else {
|
|
|
- push({ name: 'IotMainWorkOrderAdd', params:{} })
|
|
|
|
|
|
|
+ push({ name: 'IotMainWorkOrderAdd', params: {} })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const openModifyForm = (type: string, id?: number) => {
|
|
const openModifyForm = (type: string, id?: number) => {
|
|
|
// 修改
|
|
// 修改
|
|
|
if (typeof id === 'number') {
|
|
if (typeof id === 'number') {
|
|
|
- push({ name: 'IotMainWorkOrderModify', params: {id } })
|
|
|
|
|
|
|
+ push({ name: 'IotMainWorkOrderModify', params: { id } })
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -632,7 +718,7 @@ const handleDelete = async (id: number) => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const detail = (id?: number) => {
|
|
const detail = (id?: number) => {
|
|
|
- push({ name: 'IotMainWorkOrderDetail', params:{id} })
|
|
|
|
|
|
|
+ push({ name: 'IotMainWorkOrderDetail', params: { id } })
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** 导出按钮操作 */
|
|
/** 导出按钮操作 */
|
|
@@ -651,58 +737,60 @@ const handleExport = async () => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 声明 ResizeObserver 实例
|
|
// 声明 ResizeObserver 实例
|
|
|
-let resizeObserver: ResizeObserver | null = null;
|
|
|
|
|
|
|
+let resizeObserver: ResizeObserver | null = null
|
|
|
|
|
|
|
|
/** 初始化 **/
|
|
/** 初始化 **/
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
// 获取当前登录人的id 与 保养工单创建人id 匹配修改退回工单 的权限
|
|
// 获取当前登录人的id 与 保养工单创建人id 匹配修改退回工单 的权限
|
|
|
const userId = useUserStore().getUser.id
|
|
const userId = useUserStore().getUser.id
|
|
|
- currentUserId.value = userId;
|
|
|
|
|
|
|
+ currentUserId.value = userId
|
|
|
|
|
|
|
|
getList()
|
|
getList()
|
|
|
- window.addEventListener('resize', calculateColumnWidths);
|
|
|
|
|
|
|
+ window.addEventListener('resize', calculateColumnWidths)
|
|
|
// 创建 ResizeObserver 监听表格容器尺寸变化
|
|
// 创建 ResizeObserver 监听表格容器尺寸变化
|
|
|
if (tableContainerRef.value?.$el) {
|
|
if (tableContainerRef.value?.$el) {
|
|
|
resizeObserver = new ResizeObserver(() => {
|
|
resizeObserver = new ResizeObserver(() => {
|
|
|
// 使用防抖避免频繁触发
|
|
// 使用防抖避免频繁触发
|
|
|
- clearTimeout(window.resizeTimer);
|
|
|
|
|
|
|
+ clearTimeout(window.resizeTimer)
|
|
|
window.resizeTimer = setTimeout(() => {
|
|
window.resizeTimer = setTimeout(() => {
|
|
|
- calculateColumnWidths();
|
|
|
|
|
- }, 100);
|
|
|
|
|
- });
|
|
|
|
|
- resizeObserver.observe(tableContainerRef.value.$el);
|
|
|
|
|
|
|
+ calculateColumnWidths()
|
|
|
|
|
+ }, 100)
|
|
|
|
|
+ })
|
|
|
|
|
+ resizeObserver.observe(tableContainerRef.value.$el)
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
onUnmounted(() => {
|
|
|
- window.removeEventListener('resize', calculateColumnWidths);
|
|
|
|
|
|
|
+ window.removeEventListener('resize', calculateColumnWidths)
|
|
|
|
|
|
|
|
// 清除 ResizeObserver
|
|
// 清除 ResizeObserver
|
|
|
if (resizeObserver && tableContainerRef.value?.$el) {
|
|
if (resizeObserver && tableContainerRef.value?.$el) {
|
|
|
- resizeObserver.unobserve(tableContainerRef.value.$el);
|
|
|
|
|
- resizeObserver = null;
|
|
|
|
|
|
|
+ resizeObserver.unobserve(tableContainerRef.value.$el)
|
|
|
|
|
+ resizeObserver = null
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 清除定时器
|
|
// 清除定时器
|
|
|
if (window.resizeTimer) {
|
|
if (window.resizeTimer) {
|
|
|
- clearTimeout(window.resizeTimer);
|
|
|
|
|
|
|
+ clearTimeout(window.resizeTimer)
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
// 监听列表数据变化重新计算列宽
|
|
// 监听列表数据变化重新计算列宽
|
|
|
-watch(list, () => {
|
|
|
|
|
- nextTick(calculateColumnWidths)
|
|
|
|
|
-}, { deep: true })
|
|
|
|
|
|
|
+watch(
|
|
|
|
|
+ list,
|
|
|
|
|
+ () => {
|
|
|
|
|
+ nextTick(calculateColumnWidths)
|
|
|
|
|
+ },
|
|
|
|
|
+ { deep: true }
|
|
|
|
|
+)
|
|
|
|
|
|
|
|
// 监听左侧菜单状态变化(展开/收起)
|
|
// 监听左侧菜单状态变化(展开/收起)
|
|
|
watch(isLeftContentCollapsed, () => {
|
|
watch(isLeftContentCollapsed, () => {
|
|
|
// 添加延迟以确保 DOM 更新完成
|
|
// 添加延迟以确保 DOM 更新完成
|
|
|
- setTimeout(calculateColumnWidths, 50);
|
|
|
|
|
|
|
+ setTimeout(calculateColumnWidths, 50)
|
|
|
})
|
|
})
|
|
|
-
|
|
|
|
|
</script>
|
|
</script>
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
-
|
|
|
|
|
.leftcontent {
|
|
.leftcontent {
|
|
|
transition: width 0.3s ease;
|
|
transition: width 0.3s ease;
|
|
|
position: relative;
|
|
position: relative;
|
|
@@ -715,7 +803,7 @@ watch(isLeftContentCollapsed, () => {
|
|
|
|
|
|
|
|
/* 正数样式 - 淡绿色 */
|
|
/* 正数样式 - 淡绿色 */
|
|
|
.positive-distance {
|
|
.positive-distance {
|
|
|
- color: #67c23a; /* element-plus 成功色 */
|
|
|
|
|
|
|
+ color: #67c23a; /* element-plus 成功色 */
|
|
|
background-color: rgba(103, 194, 58, 0.1); /* 10% 透明度的淡绿色背景 */
|
|
background-color: rgba(103, 194, 58, 0.1); /* 10% 透明度的淡绿色背景 */
|
|
|
padding: 2px 8px;
|
|
padding: 2px 8px;
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
@@ -724,7 +812,7 @@ watch(isLeftContentCollapsed, () => {
|
|
|
|
|
|
|
|
/* 负数样式 - 淡红色 */
|
|
/* 负数样式 - 淡红色 */
|
|
|
.negative-distance {
|
|
.negative-distance {
|
|
|
- color: #f56c6c; /* element-plus 危险色 */
|
|
|
|
|
|
|
+ color: #f56c6c; /* element-plus 危险色 */
|
|
|
background-color: rgba(245, 108, 108, 0.1); /* 10% 透明度的淡红色背景 */
|
|
background-color: rgba(245, 108, 108, 0.1); /* 10% 透明度的淡红色背景 */
|
|
|
padding: 2px 8px;
|
|
padding: 2px 8px;
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
@@ -776,7 +864,7 @@ watch(isLeftContentCollapsed, () => {
|
|
|
.toggle-button {
|
|
.toggle-button {
|
|
|
position: absolute;
|
|
position: absolute;
|
|
|
top: 44%;
|
|
top: 44%;
|
|
|
- transform: translate(-65%,-50%);
|
|
|
|
|
|
|
+ transform: translate(-65%, -50%);
|
|
|
width: 12px;
|
|
width: 12px;
|
|
|
height: 40px;
|
|
height: 40px;
|
|
|
background-color: #f0f0f0;
|
|
background-color: #f0f0f0;
|