|
@@ -1,305 +1,56 @@
|
|
|
-<template>
|
|
|
|
|
- <el-row :gutter="20">
|
|
|
|
|
- <DeptTree @node-click="handleDeptNodeClick" v-model:collapsed="isLeftContentCollapsed" />
|
|
|
|
|
- <el-col :xs="24" :span="isLeftContentCollapsed ? 24 : 20">
|
|
|
|
|
- <ContentWrap>
|
|
|
|
|
- <!-- 搜索工作栏 -->
|
|
|
|
|
- <el-form
|
|
|
|
|
- class="-mb-15px"
|
|
|
|
|
- :model="queryParams"
|
|
|
|
|
- ref="queryFormRef"
|
|
|
|
|
- :inline="true"
|
|
|
|
|
- label-width="68px"
|
|
|
|
|
- >
|
|
|
|
|
- <el-form-item :label="t('bomList.name')" prop="name">
|
|
|
|
|
- <el-input
|
|
|
|
|
- v-model="queryParams.name"
|
|
|
|
|
- :placeholder="t('bomList.nHolder')"
|
|
|
|
|
- clearable
|
|
|
|
|
- @keyup.enter="handleQuery"
|
|
|
|
|
- class="!w-240px"
|
|
|
|
|
- />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- <el-form-item :label="t('bomList.status')" prop="result">
|
|
|
|
|
- <el-select
|
|
|
|
|
- v-model="queryParams.result"
|
|
|
|
|
- :placeholder="t('bomList.status')"
|
|
|
|
|
- clearable
|
|
|
|
|
- class="!w-240px"
|
|
|
|
|
- >
|
|
|
|
|
- <el-option
|
|
|
|
|
- v-for="dict in resultOptions"
|
|
|
|
|
- :key="dict.value"
|
|
|
|
|
- :label="dict.label"
|
|
|
|
|
- :value="dict.value"
|
|
|
|
|
- />
|
|
|
|
|
- </el-select>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- <el-form-item :label="t('common.createTime')" prop="createTime" label-width="100px">
|
|
|
|
|
- <el-date-picker
|
|
|
|
|
- v-model="queryParams.createTime"
|
|
|
|
|
- value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
|
- type="daterange"
|
|
|
|
|
- :start-placeholder="t('operationFill.start')"
|
|
|
|
|
- :end-placeholder="t('operationFill.end')"
|
|
|
|
|
- :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
|
|
|
|
- class="!w-220px"
|
|
|
|
|
- />
|
|
|
|
|
- </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
|
|
|
|
|
- type="primary"
|
|
|
|
|
- plain
|
|
|
|
|
- @click="openForm('create')"
|
|
|
|
|
- v-hasPermi="['pms:iot-main-work-order:create']"
|
|
|
|
|
- >
|
|
|
|
|
- <Icon icon="ep:plus" class="mr-5px" /> {{ t('operationFill.add') }}
|
|
|
|
|
- </el-button>
|
|
|
|
|
- <el-button
|
|
|
|
|
- type="success"
|
|
|
|
|
- plain
|
|
|
|
|
- @click="handleExport"
|
|
|
|
|
- :loading="exportLoading"
|
|
|
|
|
- v-hasPermi="['pms:iot-main-work-order:export']"
|
|
|
|
|
- >
|
|
|
|
|
- <Icon icon="ep:download" class="mr-5px" /> 导出
|
|
|
|
|
- </el-button>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-form>
|
|
|
|
|
- </ContentWrap>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 列表 -->
|
|
|
|
|
- <ContentWrap ref="tableContainerRef" class="table-wrap">
|
|
|
|
|
- <el-table
|
|
|
|
|
- v-loading="loading"
|
|
|
|
|
- :data="list"
|
|
|
|
|
- :stripe="true"
|
|
|
|
|
- style="width: 100%"
|
|
|
|
|
- ref="tableRef"
|
|
|
|
|
- height="calc(85vh - 175px)"
|
|
|
|
|
- >
|
|
|
|
|
- <el-table-column
|
|
|
|
|
- :label="t('iotDevice.serial')"
|
|
|
|
|
- align="center"
|
|
|
|
|
- :width="columnWidths.serial"
|
|
|
|
|
- fixed="left"
|
|
|
|
|
- >
|
|
|
|
|
- <template #default="scope">
|
|
|
|
|
- {{ scope.$index + 1 }}
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-table-column>
|
|
|
|
|
- <el-table-column
|
|
|
|
|
- :label="t('bomList.name')"
|
|
|
|
|
- align="center"
|
|
|
|
|
- prop="name"
|
|
|
|
|
- :width="columnWidths.name"
|
|
|
|
|
- fixed="left"
|
|
|
|
|
- />
|
|
|
|
|
- <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">
|
|
|
|
|
- <dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT" :value="scope.row.result" />
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-table-column>
|
|
|
|
|
- <el-table-column
|
|
|
|
|
- :label="t('bomList.serviceDue')"
|
|
|
|
|
- align="center"
|
|
|
|
|
- :width="columnWidths.serviceDue"
|
|
|
|
|
- >
|
|
|
|
|
- <template #default="scope">
|
|
|
|
|
- <span :class="getDistanceClass(scope.row.mainDistance)">
|
|
|
|
|
- {{ scope.row.mainDistance }}
|
|
|
|
|
- </span>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-table-column>
|
|
|
|
|
- <el-table-column
|
|
|
|
|
- :label="t('bomList.type')"
|
|
|
|
|
- align="center"
|
|
|
|
|
- prop="type"
|
|
|
|
|
- :width="columnWidths.type"
|
|
|
|
|
- >
|
|
|
|
|
- <template #default="scope">
|
|
|
|
|
- <dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_TYPE" :value="scope.row.type" />
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-table-column>
|
|
|
|
|
- <el-table-column
|
|
|
|
|
- :label="t('iotMaintain.PersonInCharge')"
|
|
|
|
|
- align="center"
|
|
|
|
|
- prop="responsiblePersonName"
|
|
|
|
|
- :width="columnWidths.responsiblePersonName"
|
|
|
|
|
- />
|
|
|
|
|
- <el-table-column
|
|
|
|
|
- :label="t('dict.createTime')"
|
|
|
|
|
- align="center"
|
|
|
|
|
- prop="createTime"
|
|
|
|
|
- :formatter="dateFormatter2"
|
|
|
|
|
- :width="columnWidths.createTime"
|
|
|
|
|
- />
|
|
|
|
|
- <el-table-column
|
|
|
|
|
- :label="t('dict.fillTime')"
|
|
|
|
|
- align="center"
|
|
|
|
|
- prop="updateTime"
|
|
|
|
|
- :width="columnWidths.updateTime"
|
|
|
|
|
- >
|
|
|
|
|
- <template #default="scope">
|
|
|
|
|
- <span v-if="scope.row.result == 2">
|
|
|
|
|
- {{ formatCellDate(scope.row.updateTime) }}
|
|
|
|
|
- </span>
|
|
|
|
|
- <span v-else></span>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-table-column>
|
|
|
|
|
- <el-table-column
|
|
|
|
|
- :label="t('iotMaintain.operation')"
|
|
|
|
|
- align="center"
|
|
|
|
|
- :width="columnWidths.operation"
|
|
|
|
|
- fixed="right"
|
|
|
|
|
- >
|
|
|
|
|
- <template #default="scope">
|
|
|
|
|
- <el-button
|
|
|
|
|
- v-if="isNegativeMainDistance(scope.row.mainDistance)"
|
|
|
|
|
- link
|
|
|
|
|
- :type="getDelayReasonButtonType(scope.row.delayReason)"
|
|
|
|
|
- @click="openDelayReasonDialog(scope.row)"
|
|
|
|
|
- v-hasPermi="['pms:iot-main-work-order:update']"
|
|
|
|
|
- >
|
|
|
|
|
- {{ t('mainPlan.delayed') || '延时' }}
|
|
|
|
|
- </el-button>
|
|
|
|
|
- <el-button
|
|
|
|
|
- link
|
|
|
|
|
- type="primary"
|
|
|
|
|
- @click="openForm('update', scope.row.id)"
|
|
|
|
|
- v-hasPermi="['pms:iot-main-work-order:update']"
|
|
|
|
|
- v-if="scope.row.result === 1"
|
|
|
|
|
- >
|
|
|
|
|
- {{ t('operationFill.fill') }}
|
|
|
|
|
- </el-button>
|
|
|
|
|
- <el-button
|
|
|
|
|
- link
|
|
|
|
|
- type="primary"
|
|
|
|
|
- @click="detail(scope.row.id)"
|
|
|
|
|
- v-hasPermi="['pms:iot-main-work-order:query']"
|
|
|
|
|
- >
|
|
|
|
|
- {{ t('operationFill.view') }}
|
|
|
|
|
- </el-button>
|
|
|
|
|
- <el-button
|
|
|
|
|
- link
|
|
|
|
|
- type="danger"
|
|
|
|
|
- @click="handleBack(scope.row.id)"
|
|
|
|
|
- v-hasPermi="['pms:iot-main-work-order:back']"
|
|
|
|
|
- v-if="scope.row.result === 2 && scope.row.status === 0"
|
|
|
|
|
- >
|
|
|
|
|
- {{ t('workOrderMaterial.back') }}
|
|
|
|
|
- </el-button>
|
|
|
|
|
- <el-button
|
|
|
|
|
- link
|
|
|
|
|
- type="warning"
|
|
|
|
|
- class="warning-btn"
|
|
|
|
|
- @click="openModifyForm('modify', scope.row.id)"
|
|
|
|
|
- v-hasPermi="['pms:iot-main-work-order:update']"
|
|
|
|
|
- v-if="
|
|
|
|
|
- scope.row.result === 2 &&
|
|
|
|
|
- scope.row.status === 1 &&
|
|
|
|
|
- currentUserId?.toString() === scope.row.responsiblePerson
|
|
|
|
|
- "
|
|
|
|
|
- >
|
|
|
|
|
- {{ t('modelTemplate.update') }}
|
|
|
|
|
- </el-button>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-table-column>
|
|
|
|
|
- </el-table>
|
|
|
|
|
- <!-- 分页 -->
|
|
|
|
|
- <Pagination
|
|
|
|
|
- :total="total"
|
|
|
|
|
- v-model:page="queryParams.pageNo"
|
|
|
|
|
- v-model:limit="queryParams.pageSize"
|
|
|
|
|
- @pagination="getList"
|
|
|
|
|
- />
|
|
|
|
|
- </ContentWrap>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
- <!-- 表单弹窗:添加/修改 -->
|
|
|
|
|
- <IotMainWorkOrderForm ref="formRef" @success="getList" />
|
|
|
|
|
-
|
|
|
|
|
- <!-- 延保原因弹窗 -->
|
|
|
|
|
- <el-dialog
|
|
|
|
|
- v-model="delayReasonDialogVisible"
|
|
|
|
|
- :title="t('workOrderMaterial.delayReason') || '延时原因'"
|
|
|
|
|
- width="500px"
|
|
|
|
|
- :close-on-click-modal="false"
|
|
|
|
|
- >
|
|
|
|
|
- <el-form
|
|
|
|
|
- :model="delayReasonForm"
|
|
|
|
|
- label-width="0px"
|
|
|
|
|
- :rules="delayReasonRules"
|
|
|
|
|
- ref="delayReasonFormRef"
|
|
|
|
|
- >
|
|
|
|
|
- <el-form-item label=" " prop="delayReason" class="required-item" label-width="16px">
|
|
|
|
|
- <el-input
|
|
|
|
|
- v-model="delayReasonForm.delayReason"
|
|
|
|
|
- type="textarea"
|
|
|
|
|
- :rows="4"
|
|
|
|
|
- :placeholder="t('workOrderMaterial.inputDelayReason') || '请输入延时原因'"
|
|
|
|
|
- maxlength="500"
|
|
|
|
|
- show-word-limit
|
|
|
|
|
- />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-form>
|
|
|
|
|
- <template #footer>
|
|
|
|
|
- <el-button @click="delayReasonDialogVisible = false">
|
|
|
|
|
- {{ t('common.cancel') || '取消' }}
|
|
|
|
|
- </el-button>
|
|
|
|
|
- <el-button type="primary" @click="saveDelayReason" :loading="saveDelayReasonLoading">
|
|
|
|
|
- {{ t('common.save') || '保存' }}
|
|
|
|
|
- </el-button>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-dialog>
|
|
|
|
|
-</template>
|
|
|
|
|
-
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
|
|
|
|
|
-import download from '@/utils/download'
|
|
|
|
|
|
|
+import { useTableComponents } from '@/components/ZmTable/useTableComponents'
|
|
|
import { IotMainWorkOrderApi, IotMainWorkOrderVO } from '@/api/pms/iotmainworkorder'
|
|
import { IotMainWorkOrderApi, IotMainWorkOrderVO } from '@/api/pms/iotmainworkorder'
|
|
|
-import IotMainWorkOrderForm from './IotMainWorkOrderForm.vue'
|
|
|
|
|
-import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
|
|
|
|
|
-import DeptTree from '@/views/system/user/DeptTree2.vue'
|
|
|
|
|
import { useUserStore } from '@/store/modules/user'
|
|
import { useUserStore } from '@/store/modules/user'
|
|
|
-const { push } = useRouter() // 路由跳转
|
|
|
|
|
|
|
+import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
|
|
|
|
|
+import download from '@/utils/download'
|
|
|
|
|
+import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
|
|
|
|
|
+import type { FormInstance } from 'element-plus'
|
|
|
|
|
|
|
|
-/** 保养工单 列表 */
|
|
|
|
|
defineOptions({ name: 'IotMainWorkOrder' })
|
|
defineOptions({ name: 'IotMainWorkOrder' })
|
|
|
|
|
|
|
|
-// 表单引用
|
|
|
|
|
-const delayReasonFormRef = ref<InstanceType<typeof ElForm>>()
|
|
|
|
|
-
|
|
|
|
|
-// 定义响应式变量存储当前登录人ID
|
|
|
|
|
-const currentUserId = ref<number | undefined>(undefined)
|
|
|
|
|
-
|
|
|
|
|
-const message = useMessage() // 消息弹窗
|
|
|
|
|
-const { t } = useI18n() // 国际化
|
|
|
|
|
-const tableRef = ref() // 表格引用
|
|
|
|
|
-const isLeftContentCollapsed = ref(false)
|
|
|
|
|
-// 表格容器引用 用于获取容器宽度
|
|
|
|
|
-const tableContainerRef = ref()
|
|
|
|
|
-const loading = ref(true) // 列表的加载中
|
|
|
|
|
-const list = ref<IotMainWorkOrderVO[]>([]) // 列表的数据
|
|
|
|
|
-const total = ref(0) // 列表的总页数
|
|
|
|
|
-const queryParams = reactive({
|
|
|
|
|
|
|
+type MainWorkOrderRow = IotMainWorkOrderVO & {
|
|
|
|
|
+ mainDistance?: string | number | null
|
|
|
|
|
+ updateTime?: string | null
|
|
|
|
|
+ createTime?: string | null
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface QueryParams extends PageParam {
|
|
|
|
|
+ planId?: number
|
|
|
|
|
+ planSerialNumber?: string
|
|
|
|
|
+ deptId?: number
|
|
|
|
|
+ orderNumber?: string
|
|
|
|
|
+ name?: string
|
|
|
|
|
+ type?: number
|
|
|
|
|
+ responsiblePerson?: string
|
|
|
|
|
+ responsiblePersonName?: string
|
|
|
|
|
+ cost?: number
|
|
|
|
|
+ result?: string | number
|
|
|
|
|
+ otherCost?: number
|
|
|
|
|
+ laborCost?: number
|
|
|
|
|
+ outsourcingFlag?: number
|
|
|
|
|
+ actualStartTime?: string[]
|
|
|
|
|
+ actualEndTime?: string[]
|
|
|
|
|
+ remark?: string
|
|
|
|
|
+ status?: number
|
|
|
|
|
+ processInstanceId?: string
|
|
|
|
|
+ auditStatus?: number
|
|
|
|
|
+ createTime?: string[]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type DelayReasonButtonType = 'success' | 'warning'
|
|
|
|
|
+
|
|
|
|
|
+const message = useMessage()
|
|
|
|
|
+const { t } = useI18n()
|
|
|
|
|
+const { push } = useRouter()
|
|
|
|
|
+const { ZmTable, ZmTableColumn } = useTableComponents<MainWorkOrderRow>()
|
|
|
|
|
+
|
|
|
|
|
+const userStore = useUserStore()
|
|
|
|
|
+const rootDeptId = 156
|
|
|
|
|
+const deptId = userStore.getUser.deptId || rootDeptId
|
|
|
|
|
+const currentUserId = ref<number | undefined>(userStore.getUser.id)
|
|
|
|
|
+
|
|
|
|
|
+const initQuery: QueryParams = {
|
|
|
pageNo: 1,
|
|
pageNo: 1,
|
|
|
pageSize: 10,
|
|
pageSize: 10,
|
|
|
planId: undefined,
|
|
planId: undefined,
|
|
@@ -322,12 +73,24 @@ const queryParams = reactive({
|
|
|
processInstanceId: undefined,
|
|
processInstanceId: undefined,
|
|
|
auditStatus: undefined,
|
|
auditStatus: undefined,
|
|
|
createTime: []
|
|
createTime: []
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const queryParams = reactive<QueryParams>({ ...initQuery })
|
|
|
|
|
+const queryFormRef = ref()
|
|
|
|
|
+const loading = ref(false)
|
|
|
|
|
+const exportLoading = ref(false)
|
|
|
|
|
+const list = ref<MainWorkOrderRow[]>([])
|
|
|
|
|
+const total = ref(0)
|
|
|
|
|
+
|
|
|
|
|
+const delayReasonDialogVisible = ref(false)
|
|
|
|
|
+const saveDelayReasonLoading = ref(false)
|
|
|
|
|
+const delayReasonFormRef = ref<FormInstance>()
|
|
|
|
|
+const delayReasonForm = reactive({
|
|
|
|
|
+ id: undefined as number | undefined,
|
|
|
|
|
+ delayReason: ''
|
|
|
})
|
|
})
|
|
|
-const queryFormRef = ref() // 搜索的表单
|
|
|
|
|
-const exportLoading = ref(false) // 导出的加载中
|
|
|
|
|
|
|
|
|
|
-// 定义表单验证规则
|
|
|
|
|
-const delayReasonRules = {
|
|
|
|
|
|
|
+const delayReasonRules = computed(() => ({
|
|
|
delayReason: [
|
|
delayReason: [
|
|
|
{
|
|
{
|
|
|
required: true,
|
|
required: true,
|
|
@@ -335,73 +98,96 @@ const delayReasonRules = {
|
|
|
trigger: 'blur'
|
|
trigger: 'blur'
|
|
|
}
|
|
}
|
|
|
]
|
|
]
|
|
|
|
|
+}))
|
|
|
|
|
+
|
|
|
|
|
+const resultOptions = computed(() => [
|
|
|
|
|
+ {
|
|
|
|
|
+ label: t('operationFill.all'),
|
|
|
|
|
+ value: '0'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: t('mainPlan.delayed'),
|
|
|
|
|
+ value: '3'
|
|
|
|
|
+ },
|
|
|
|
|
+ ...getStrDictOptions(DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT)
|
|
|
|
|
+])
|
|
|
|
|
+
|
|
|
|
|
+const getList = async () => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data = await IotMainWorkOrderApi.sortedMainWorkOrderPage(queryParams)
|
|
|
|
|
+ list.value = data.list
|
|
|
|
|
+ total.value = data.total
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 列宽度配置
|
|
|
|
|
-const columnWidths = ref({
|
|
|
|
|
- serial: '80px',
|
|
|
|
|
- name: '200px',
|
|
|
|
|
- deptName: '150px',
|
|
|
|
|
- result: '120px',
|
|
|
|
|
- serviceDue: '150px',
|
|
|
|
|
- type: '120px',
|
|
|
|
|
- responsiblePersonName: '150px',
|
|
|
|
|
- createTime: '180px',
|
|
|
|
|
- updateTime: '180px',
|
|
|
|
|
- operation: '150px'
|
|
|
|
|
-})
|
|
|
|
|
|
|
+const handleQuery = () => {
|
|
|
|
|
+ queryParams.pageNo = 1
|
|
|
|
|
+ getList()
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-// 计算文本宽度
|
|
|
|
|
-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 resetQuery = () => {
|
|
|
|
|
+ Object.assign(queryParams, { ...initQuery })
|
|
|
|
|
+ queryFormRef.value?.resetFields()
|
|
|
|
|
+ handleQuery()
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- document.body.appendChild(span)
|
|
|
|
|
- const width = span.offsetWidth
|
|
|
|
|
- document.body.removeChild(span)
|
|
|
|
|
|
|
+const handleSizeChange = (val: number) => {
|
|
|
|
|
+ queryParams.pageSize = val
|
|
|
|
|
+ handleQuery()
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- return width
|
|
|
|
|
|
|
+const handleCurrentChange = (val: number) => {
|
|
|
|
|
+ queryParams.pageNo = val
|
|
|
|
|
+ getList()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/** 延保原因相关状态 */
|
|
|
|
|
-const delayReasonDialogVisible = ref(false)
|
|
|
|
|
-const saveDelayReasonLoading = ref(false)
|
|
|
|
|
-const delayReasonForm = reactive({
|
|
|
|
|
- id: undefined as number | undefined,
|
|
|
|
|
- delayReason: ''
|
|
|
|
|
-})
|
|
|
|
|
|
|
+const handleDeptNodeClick = async (row: Tree) => {
|
|
|
|
|
+ queryParams.deptId = row.id
|
|
|
|
|
+ queryParams.pageNo = 1
|
|
|
|
|
+ await getList()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const formatCellDate = (dateString?: string | null) => {
|
|
|
|
|
+ if (!dateString) return ''
|
|
|
|
|
+ return dateFormatter(null, null, dateString)
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-/** 判断mainDistance是否为负值 */
|
|
|
|
|
-const isNegativeMainDistance = (mainDistance: string | null): boolean => {
|
|
|
|
|
- if (!mainDistance) return false
|
|
|
|
|
|
|
+const parseDistanceNumber = (distance: number | string | null | undefined) => {
|
|
|
|
|
+ if (distance === null || distance === undefined || distance === '') return undefined
|
|
|
|
|
+ if (typeof distance === 'number') return distance
|
|
|
|
|
+ const numericPart = distance.match(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/)?.[0]
|
|
|
|
|
+ return numericPart ? Number(numericPart) : undefined
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- // 使用正则提取数字部分(包括负号、小数点和科学计数法)
|
|
|
|
|
- const numericPart = mainDistance.match(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/)?.[0]
|
|
|
|
|
|
|
+const isNegativeMainDistance = (mainDistance: number | string | null | undefined) => {
|
|
|
|
|
+ const value = parseDistanceNumber(mainDistance)
|
|
|
|
|
+ return value !== undefined && value < 0
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- if (numericPart) {
|
|
|
|
|
- const num = parseFloat(numericPart)
|
|
|
|
|
- return num < 0
|
|
|
|
|
- }
|
|
|
|
|
|
|
+const getDistanceClass = (distance: number | string | null | undefined) => {
|
|
|
|
|
+ const value = parseDistanceNumber(distance)
|
|
|
|
|
+ if (value === undefined || value === 0) return ''
|
|
|
|
|
+ return value < 0 ? 'negative-distance' : 'positive-distance'
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- return false
|
|
|
|
|
|
|
+const getDelayReasonButtonType = (
|
|
|
|
|
+ delayReason: string | null | undefined
|
|
|
|
|
+): DelayReasonButtonType => {
|
|
|
|
|
+ return delayReason ? 'success' : 'warning'
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/** 打开延保原因弹窗 */
|
|
|
|
|
-const openDelayReasonDialog = (row: IotMainWorkOrderVO) => {
|
|
|
|
|
|
|
+const openDelayReasonDialog = (row: MainWorkOrderRow) => {
|
|
|
delayReasonForm.id = row.id
|
|
delayReasonForm.id = row.id
|
|
|
delayReasonForm.delayReason = row.delayReason || ''
|
|
delayReasonForm.delayReason = row.delayReason || ''
|
|
|
delayReasonDialogVisible.value = true
|
|
delayReasonDialogVisible.value = true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/** 保存延保原因 */
|
|
|
|
|
const saveDelayReason = async () => {
|
|
const saveDelayReason = async () => {
|
|
|
- // 表单验证
|
|
|
|
|
if (!delayReasonFormRef.value) return
|
|
if (!delayReasonFormRef.value) return
|
|
|
|
|
+
|
|
|
const valid = await delayReasonFormRef.value.validate()
|
|
const valid = await delayReasonFormRef.value.validate()
|
|
|
if (!valid) return
|
|
if (!valid) return
|
|
|
|
|
|
|
@@ -410,18 +196,14 @@ const saveDelayReason = async () => {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ saveDelayReasonLoading.value = true
|
|
|
try {
|
|
try {
|
|
|
- saveDelayReasonLoading.value = true
|
|
|
|
|
- // 调用更新接口,只传递id和delayReason字段
|
|
|
|
|
await IotMainWorkOrderApi.updateIotMainWorkOrder({
|
|
await IotMainWorkOrderApi.updateIotMainWorkOrder({
|
|
|
id: delayReasonForm.id,
|
|
id: delayReasonForm.id,
|
|
|
delayReason: delayReasonForm.delayReason
|
|
delayReason: delayReasonForm.delayReason
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
|
|
+ } as IotMainWorkOrderVO)
|
|
|
message.success(t('common.success') || '保存成功')
|
|
message.success(t('common.success') || '保存成功')
|
|
|
delayReasonDialogVisible.value = false
|
|
delayReasonDialogVisible.value = false
|
|
|
-
|
|
|
|
|
- // 刷新列表数据
|
|
|
|
|
await getList()
|
|
await getList()
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('保存延保原因失败:', error)
|
|
console.error('保存延保原因失败:', error)
|
|
@@ -431,405 +213,463 @@ const saveDelayReason = async () => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/** 根据delayReason是否有值返回按钮类型 */
|
|
|
|
|
-const getDelayReasonButtonType = (delayReason: string | null | undefined): string => {
|
|
|
|
|
- // 如果delayReason有值(不为null、undefined且不是空字符串),返回success,否则返回warning
|
|
|
|
|
- return delayReason ? 'success' : 'warning'
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/** 处理部门被点击 */
|
|
|
|
|
-const handleDeptNodeClick = async (row) => {
|
|
|
|
|
- queryParams.deptId = row.id
|
|
|
|
|
- await getList()
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// 计算列宽度
|
|
|
|
|
-const calculateColumnWidths = () => {
|
|
|
|
|
- const MIN_WIDTH = 80 // 最小列宽
|
|
|
|
|
- const PADDING = 25 // 列内边距
|
|
|
|
|
- const FLEXIBLE_COLUMN = 'name' // 可伸缩列
|
|
|
|
|
-
|
|
|
|
|
- // 确保表格容器存在
|
|
|
|
|
- if (!tableContainerRef.value?.$el) return
|
|
|
|
|
-
|
|
|
|
|
- const container = tableContainerRef.value.$el
|
|
|
|
|
- const containerWidth = container.clientWidth
|
|
|
|
|
-
|
|
|
|
|
- // 1. 计算所有列的最小宽度
|
|
|
|
|
- const minWidths: Record<string, number> = {}
|
|
|
|
|
- let totalMinWidth = 0
|
|
|
|
|
-
|
|
|
|
|
- // 计算列最小宽度的函数
|
|
|
|
|
- const calculateColumnMinWidth = (key: string, label: string, getValue: Function) => {
|
|
|
|
|
- const headerWidth = getTextWidth(label) * 1.2
|
|
|
|
|
- let contentMaxWidth = 0
|
|
|
|
|
-
|
|
|
|
|
- // 计算内容最大宽度
|
|
|
|
|
- list.value.forEach((row, index) => {
|
|
|
|
|
- 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
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 计算各列最小宽度
|
|
|
|
|
- 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) => {
|
|
|
|
|
- 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) => {
|
|
|
|
|
- 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
|
|
|
|
|
-
|
|
|
|
|
- // 2. 计算可伸缩列最终宽度
|
|
|
|
|
- const newWidths: Record<string, string> = {}
|
|
|
|
|
- const availableWidth = containerWidth - 17 // 减去滚动条宽度
|
|
|
|
|
-
|
|
|
|
|
- // 应用最小宽度到所有列
|
|
|
|
|
- Object.keys(minWidths).forEach((key) => {
|
|
|
|
|
- newWidths[key] = `${minWidths[key]}px`
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- // 计算可伸缩列需要的宽度
|
|
|
|
|
- if (totalMinWidth < availableWidth) {
|
|
|
|
|
- // 有剩余空间:分配给可伸缩列
|
|
|
|
|
- newWidths[FLEXIBLE_COLUMN] =
|
|
|
|
|
- `${minWidths[FLEXIBLE_COLUMN] + (availableWidth - totalMinWidth)}px`
|
|
|
|
|
- } else {
|
|
|
|
|
- // 空间不足:确保可伸缩列至少显示内容
|
|
|
|
|
- newWidths[FLEXIBLE_COLUMN] = `${nameMinWidth}px`
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 3. 更新列宽配置
|
|
|
|
|
- columnWidths.value = newWidths
|
|
|
|
|
-
|
|
|
|
|
- // 4. 触发表格重新布局
|
|
|
|
|
- nextTick(() => {
|
|
|
|
|
- tableRef.value?.doLayout()
|
|
|
|
|
- })
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/** 查询列表 */
|
|
|
|
|
-const getList = async () => {
|
|
|
|
|
- loading.value = true
|
|
|
|
|
- try {
|
|
|
|
|
- const data = await IotMainWorkOrderApi.sortedMainWorkOrderPage(queryParams)
|
|
|
|
|
- list.value = data.list
|
|
|
|
|
- total.value = data.total
|
|
|
|
|
-
|
|
|
|
|
- // 数据加载后计算列宽
|
|
|
|
|
- nextTick(() => {
|
|
|
|
|
- calculateColumnWidths()
|
|
|
|
|
- window.dispatchEvent(new Event('resize'))
|
|
|
|
|
- })
|
|
|
|
|
- } finally {
|
|
|
|
|
- loading.value = false
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// 日期格式化辅助函数
|
|
|
|
|
-const formatCellDate = (dateString: string | null) => {
|
|
|
|
|
- if (!dateString) return ''
|
|
|
|
|
- return dateFormatter(null, null, dateString)
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/** 搜索按钮操作 */
|
|
|
|
|
-const handleQuery = () => {
|
|
|
|
|
- queryParams.pageNo = 1
|
|
|
|
|
- getList()
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/** 重置按钮操作 */
|
|
|
|
|
-const resetQuery = () => {
|
|
|
|
|
- queryFormRef.value.resetFields()
|
|
|
|
|
- handleQuery()
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/** 处理退回操作 */
|
|
|
|
|
const handleBack = async (id: number) => {
|
|
const handleBack = async (id: number) => {
|
|
|
try {
|
|
try {
|
|
|
- // 弹出确认提示框
|
|
|
|
|
- await message.confirm('退回到提交人修改?', t('common.confirmTitle') || '确认', {
|
|
|
|
|
- confirmButtonText: t('common.ok') || '确定',
|
|
|
|
|
- cancelButtonText: t('common.cancel') || '取消',
|
|
|
|
|
- type: 'warning'
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- // 调用接口提交退回请求
|
|
|
|
|
|
|
+ await message.confirm(
|
|
|
|
|
+ '退回到提交人修改?',
|
|
|
|
|
+ t('common.confirmTitle') || '确认',
|
|
|
|
|
+ t('common.ok') || '确定',
|
|
|
|
|
+ t('common.cancel') || '取消'
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
await IotMainWorkOrderApi.updateIotMainWorkOrder({
|
|
await IotMainWorkOrderApi.updateIotMainWorkOrder({
|
|
|
- id: id,
|
|
|
|
|
- backFlag: '1' // 退回标识参数
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ id,
|
|
|
|
|
+ backFlag: '1'
|
|
|
|
|
+ } as unknown as IotMainWorkOrderVO)
|
|
|
|
|
|
|
|
message.success(t('common.success') || '退回成功')
|
|
message.success(t('common.success') || '退回成功')
|
|
|
- // 刷新列表数据
|
|
|
|
|
await getList()
|
|
await getList()
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
- // 如果是用户取消操作,不显示任何提示信息
|
|
|
|
|
- if (error?.toString().includes('cancel') || error?.toString().includes('取消')) {
|
|
|
|
|
- return // 静默返回,不显示任何提示
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (error?.toString().includes('cancel') || error?.toString().includes('取消')) return
|
|
|
|
|
|
|
|
console.error('退回操作失败:', error)
|
|
console.error('退回操作失败:', error)
|
|
|
message.error(t('sys.api.operationFailed') || '退回失败')
|
|
message.error(t('sys.api.operationFailed') || '退回失败')
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 保养状态 下拉列表 添加数据字典外的选项
|
|
|
|
|
-const resultOptions = computed(() => [
|
|
|
|
|
- {
|
|
|
|
|
- label: t('operationFill.all'),
|
|
|
|
|
- value: '0' // 空值会触发 clearable 效果
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: t('mainPlan.delayed'),
|
|
|
|
|
- value: '3' // 空值会触发 clearable 效果
|
|
|
|
|
- },
|
|
|
|
|
- ...getStrDictOptions(DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT)
|
|
|
|
|
-])
|
|
|
|
|
-
|
|
|
|
|
-const getDistanceClass = (distance: number | string | null) => {
|
|
|
|
|
- if (distance === null || distance === undefined) return ''
|
|
|
|
|
-
|
|
|
|
|
- // 如果是数字类型,直接处理
|
|
|
|
|
- if (typeof distance === 'number') {
|
|
|
|
|
- return distance < 0 ? 'negative-distance' : distance > 0 ? 'positive-distance' : ''
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 如果是字符串,提取数字部分
|
|
|
|
|
- if (typeof distance === 'string') {
|
|
|
|
|
- // 使用正则提取数字部分(包括负号、小数点和科学计数法)
|
|
|
|
|
- const numericPart = distance.match(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/)?.[0]
|
|
|
|
|
-
|
|
|
|
|
- // 如果提取到数字部分,转换为数值
|
|
|
|
|
- if (numericPart) {
|
|
|
|
|
- const num = parseFloat(numericPart)
|
|
|
|
|
- return num < 0 ? 'negative-distance' : num > 0 ? 'positive-distance' : ''
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return ''
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/** 添加/修改操作 */
|
|
|
|
|
-const formRef = ref()
|
|
|
|
|
-const openForm = (type: string, id?: number) => {
|
|
|
|
|
- // 修改
|
|
|
|
|
- if (typeof id === 'number') {
|
|
|
|
|
|
|
+const openForm = (type: 'create' | 'update', id?: number) => {
|
|
|
|
|
+ if (type === 'update' && typeof id === 'number') {
|
|
|
push({ name: 'IotMainWorkOrderOptimize', params: { id } })
|
|
push({ name: 'IotMainWorkOrderOptimize', params: { id } })
|
|
|
return
|
|
return
|
|
|
- } else {
|
|
|
|
|
- push({ name: 'IotMainWorkOrderAdd', params: {} })
|
|
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ push({ name: 'IotMainWorkOrderAdd', params: {} })
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const openModifyForm = (type: string, id?: number) => {
|
|
|
|
|
- // 修改
|
|
|
|
|
- if (typeof id === 'number') {
|
|
|
|
|
|
|
+const openModifyForm = (type: 'modify', id?: number) => {
|
|
|
|
|
+ if (type === 'modify' && typeof id === 'number') {
|
|
|
push({ name: 'IotMainWorkOrderModify', params: { id } })
|
|
push({ name: 'IotMainWorkOrderModify', params: { id } })
|
|
|
- return
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/** 删除按钮操作 */
|
|
|
|
|
-const handleDelete = async (id: number) => {
|
|
|
|
|
- try {
|
|
|
|
|
- // 删除的二次确认
|
|
|
|
|
- await message.delConfirm()
|
|
|
|
|
- // 发起删除
|
|
|
|
|
- await IotMainWorkOrderApi.deleteIotMainWorkOrder(id)
|
|
|
|
|
- message.success(t('common.delSuccess'))
|
|
|
|
|
- // 刷新列表
|
|
|
|
|
- await getList()
|
|
|
|
|
- } catch {}
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
const detail = (id?: number) => {
|
|
const detail = (id?: number) => {
|
|
|
push({ name: 'IotMainWorkOrderDetail', params: { id } })
|
|
push({ name: 'IotMainWorkOrderDetail', params: { id } })
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/** 导出按钮操作 */
|
|
|
|
|
const handleExport = async () => {
|
|
const handleExport = async () => {
|
|
|
|
|
+ exportLoading.value = true
|
|
|
try {
|
|
try {
|
|
|
- exportLoading.value = true
|
|
|
|
|
const data = await IotMainWorkOrderApi.exportIotMainWorkOrderIndex(queryParams)
|
|
const data = await IotMainWorkOrderApi.exportIotMainWorkOrderIndex(queryParams)
|
|
|
download.excel(data, '保养工单.xls')
|
|
download.excel(data, '保养工单.xls')
|
|
|
- } catch {
|
|
|
|
|
} finally {
|
|
} finally {
|
|
|
exportLoading.value = false
|
|
exportLoading.value = false
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 声明 ResizeObserver 实例
|
|
|
|
|
-let resizeObserver: ResizeObserver | null = null
|
|
|
|
|
-
|
|
|
|
|
-/** 初始化 **/
|
|
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
- // 获取当前登录人的id 与 保养工单创建人id 匹配修改退回工单 的权限
|
|
|
|
|
- const userId = useUserStore().getUser.id
|
|
|
|
|
- currentUserId.value = userId
|
|
|
|
|
-
|
|
|
|
|
getList()
|
|
getList()
|
|
|
- window.addEventListener('resize', calculateColumnWidths)
|
|
|
|
|
- // 创建 ResizeObserver 监听表格容器尺寸变化
|
|
|
|
|
- if (tableContainerRef.value?.$el) {
|
|
|
|
|
- resizeObserver = new ResizeObserver(() => {
|
|
|
|
|
- // 使用防抖避免频繁触发
|
|
|
|
|
- clearTimeout(window.resizeTimer)
|
|
|
|
|
- window.resizeTimer = setTimeout(() => {
|
|
|
|
|
- calculateColumnWidths()
|
|
|
|
|
- }, 100)
|
|
|
|
|
- })
|
|
|
|
|
- resizeObserver.observe(tableContainerRef.value.$el)
|
|
|
|
|
- }
|
|
|
|
|
})
|
|
})
|
|
|
|
|
+</script>
|
|
|
|
|
|
|
|
-onUnmounted(() => {
|
|
|
|
|
- window.removeEventListener('resize', calculateColumnWidths)
|
|
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="main-work-order-page grid grid-cols-[auto_1fr] grid-rows-[auto_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
|
|
|
|
|
+ >
|
|
|
|
|
+ <DeptTreeSelect
|
|
|
|
|
+ :top-id="rootDeptId"
|
|
|
|
|
+ :deptId="deptId"
|
|
|
|
|
+ v-model="queryParams.deptId"
|
|
|
|
|
+ :init-select="false"
|
|
|
|
|
+ :show-title="false"
|
|
|
|
|
+ request-api="getSimpleDeptList"
|
|
|
|
|
+ class="main-work-order-tree row-span-2"
|
|
|
|
|
+ @node-click="handleDeptNodeClick"
|
|
|
|
|
+ />
|
|
|
|
|
|
|
|
- // 清除 ResizeObserver
|
|
|
|
|
- if (resizeObserver && tableContainerRef.value?.$el) {
|
|
|
|
|
- resizeObserver.unobserve(tableContainerRef.value.$el)
|
|
|
|
|
- resizeObserver = null
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ <el-form
|
|
|
|
|
+ ref="queryFormRef"
|
|
|
|
|
+ :model="queryParams"
|
|
|
|
|
+ size="default"
|
|
|
|
|
+ label-width="68px"
|
|
|
|
|
+ class="main-work-order-query bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-6 py-3 min-w-0"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="query-row">
|
|
|
|
|
+ <el-form-item :label="t('bomList.name')" prop="name">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="queryParams.name"
|
|
|
|
|
+ :placeholder="t('bomList.nHolder')"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ class="query-control"
|
|
|
|
|
+ @keyup.enter="handleQuery"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="t('bomList.status')" prop="result">
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="queryParams.result"
|
|
|
|
|
+ :placeholder="t('bomList.status')"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ class="query-control query-control--small"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="dict in resultOptions"
|
|
|
|
|
+ :key="dict.value"
|
|
|
|
|
+ :label="dict.label"
|
|
|
|
|
+ :value="dict.value"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="t('common.createTime')" prop="createTime" label-width="100px">
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-model="queryParams.createTime"
|
|
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
|
+ type="daterange"
|
|
|
|
|
+ :start-placeholder="t('operationFill.start')"
|
|
|
|
|
+ :end-placeholder="t('operationFill.end')"
|
|
|
|
|
+ :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
|
|
|
|
+ class="query-control query-control--date"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item class="query-actions">
|
|
|
|
|
+ <el-button type="primary" @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
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ plain
|
|
|
|
|
+ @click="openForm('create')"
|
|
|
|
|
+ v-hasPermi="['pms:iot-main-work-order:create']"
|
|
|
|
|
+ >
|
|
|
|
|
+ <Icon icon="ep:plus" class="mr-5px" />{{ t('operationFill.add') }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ type="success"
|
|
|
|
|
+ plain
|
|
|
|
|
+ :loading="exportLoading"
|
|
|
|
|
+ @click="handleExport"
|
|
|
|
|
+ v-hasPermi="['pms:iot-main-work-order:export']"
|
|
|
|
|
+ >
|
|
|
|
|
+ <Icon icon="ep:download" class="mr-5px" />导出
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
|
|
|
- // 清除定时器
|
|
|
|
|
- if (window.resizeTimer) {
|
|
|
|
|
- clearTimeout(window.resizeTimer)
|
|
|
|
|
- }
|
|
|
|
|
-})
|
|
|
|
|
|
|
+ <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg flex flex-col p-4 min-w-0 min-h-0">
|
|
|
|
|
+ <div class="flex-1 relative min-h-0">
|
|
|
|
|
+ <el-auto-resizer class="absolute">
|
|
|
|
|
+ <template #default="{ width, height }">
|
|
|
|
|
+ <ZmTable
|
|
|
|
|
+ :data="list"
|
|
|
|
|
+ :loading="loading"
|
|
|
|
|
+ :width="width"
|
|
|
|
|
+ :height="height"
|
|
|
|
|
+ :max-height="height"
|
|
|
|
|
+ show-border
|
|
|
|
|
+ >
|
|
|
|
|
+ <ZmTableColumn
|
|
|
|
|
+ type="index"
|
|
|
|
|
+ :label="t('iotDevice.serial')"
|
|
|
|
|
+ :width="70"
|
|
|
|
|
+ fixed="left"
|
|
|
|
|
+ hide-in-column-settings
|
|
|
|
|
+ />
|
|
|
|
|
+ <ZmTableColumn prop="name" :label="t('bomList.name')" fixed="left" min-width="300" />
|
|
|
|
|
+ <ZmTableColumn prop="deptName" :label="t('iotDevice.dept')" min-width="150" />
|
|
|
|
|
+ <ZmTableColumn prop="result" :label="t('bomList.status')" width="120">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT" :value="row.result" />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </ZmTableColumn>
|
|
|
|
|
+ <ZmTableColumn :label="t('bomList.serviceDue')" min-width="150">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <span :class="getDistanceClass(row.mainDistance)">
|
|
|
|
|
+ {{ row.mainDistance }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </ZmTableColumn>
|
|
|
|
|
+ <ZmTableColumn prop="type" :label="t('bomList.type')" width="120">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_TYPE" :value="row.type" />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </ZmTableColumn>
|
|
|
|
|
+ <ZmTableColumn
|
|
|
|
|
+ prop="responsiblePersonName"
|
|
|
|
|
+ :label="t('iotMaintain.PersonInCharge')"
|
|
|
|
|
+ min-width="150"
|
|
|
|
|
+ />
|
|
|
|
|
+ <ZmTableColumn
|
|
|
|
|
+ prop="createTime"
|
|
|
|
|
+ :label="t('dict.createTime')"
|
|
|
|
|
+ :formatter="dateFormatter2"
|
|
|
|
|
+ width="180"
|
|
|
|
|
+ />
|
|
|
|
|
+ <ZmTableColumn prop="updateTime" :label="t('dict.fillTime')" width="180">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <span v-if="row.result == 2">{{ formatCellDate(row.updateTime) }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </ZmTableColumn>
|
|
|
|
|
+ <ZmTableColumn :label="t('iotMaintain.operation')" width="140" fixed="right" action>
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ v-if="isNegativeMainDistance(row.mainDistance)"
|
|
|
|
|
+ link
|
|
|
|
|
+ :type="getDelayReasonButtonType(row.delayReason)"
|
|
|
|
|
+ @click="openDelayReasonDialog(row)"
|
|
|
|
|
+ v-hasPermi="['pms:iot-main-work-order:update']"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ t('mainPlan.delayed') || '延时' }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ v-if="row.result === 1"
|
|
|
|
|
+ link
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ @click="openForm('update', row.id)"
|
|
|
|
|
+ v-hasPermi="['pms:iot-main-work-order:update']"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ t('operationFill.fill') }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ link
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ @click="detail(row.id)"
|
|
|
|
|
+ v-hasPermi="['pms:iot-main-work-order:query']"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ t('operationFill.view') }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ v-if="row.result === 2 && row.status === 0"
|
|
|
|
|
+ link
|
|
|
|
|
+ type="danger"
|
|
|
|
|
+ @click="handleBack(row.id)"
|
|
|
|
|
+ v-hasPermi="['pms:iot-main-work-order:back']"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ t('workOrderMaterial.back') }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ v-if="
|
|
|
|
|
+ row.result === 2 &&
|
|
|
|
|
+ row.status === 1 &&
|
|
|
|
|
+ currentUserId?.toString() === row.responsiblePerson
|
|
|
|
|
+ "
|
|
|
|
|
+ link
|
|
|
|
|
+ type="warning"
|
|
|
|
|
+ class="warning-btn"
|
|
|
|
|
+ @click="openModifyForm('modify', row.id)"
|
|
|
|
|
+ v-hasPermi="['pms:iot-main-work-order:update']"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ t('modelTemplate.update') }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </ZmTableColumn>
|
|
|
|
|
+ </ZmTable>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-auto-resizer>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="h-8 mt-2 flex items-center justify-end">
|
|
|
|
|
+ <el-pagination
|
|
|
|
|
+ v-show="total > 0"
|
|
|
|
|
+ size="default"
|
|
|
|
|
+ :current-page="queryParams.pageNo"
|
|
|
|
|
+ :page-size="queryParams.pageSize"
|
|
|
|
|
+ :background="true"
|
|
|
|
|
+ :page-sizes="[10, 20, 30, 50, 100]"
|
|
|
|
|
+ :total="total"
|
|
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
|
|
+ @size-change="handleSizeChange"
|
|
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
-// 监听列表数据变化重新计算列宽
|
|
|
|
|
-watch(
|
|
|
|
|
- list,
|
|
|
|
|
- () => {
|
|
|
|
|
- nextTick(calculateColumnWidths)
|
|
|
|
|
- },
|
|
|
|
|
- { deep: true }
|
|
|
|
|
-)
|
|
|
|
|
|
|
+ <el-dialog
|
|
|
|
|
+ v-model="delayReasonDialogVisible"
|
|
|
|
|
+ :title="t('workOrderMaterial.delayReason') || '延时原因'"
|
|
|
|
|
+ width="500px"
|
|
|
|
|
+ :close-on-click-modal="false"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-form
|
|
|
|
|
+ ref="delayReasonFormRef"
|
|
|
|
|
+ :model="delayReasonForm"
|
|
|
|
|
+ :rules="delayReasonRules"
|
|
|
|
|
+ label-width="0px"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-form-item label=" " prop="delayReason" class="required-item" label-width="16px">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="delayReasonForm.delayReason"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ :rows="4"
|
|
|
|
|
+ :placeholder="t('workOrderMaterial.inputDelayReason') || '请输入延时原因'"
|
|
|
|
|
+ maxlength="500"
|
|
|
|
|
+ show-word-limit
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <el-button @click="delayReasonDialogVisible = false">
|
|
|
|
|
+ {{ t('common.cancel') || '取消' }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button type="primary" :loading="saveDelayReasonLoading" @click="saveDelayReason">
|
|
|
|
|
+ {{ t('common.save') || '保存' }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+</template>
|
|
|
|
|
|
|
|
-// 监听左侧菜单状态变化(展开/收起)
|
|
|
|
|
-watch(isLeftContentCollapsed, () => {
|
|
|
|
|
- // 添加延迟以确保 DOM 更新完成
|
|
|
|
|
- setTimeout(calculateColumnWidths, 50)
|
|
|
|
|
-})
|
|
|
|
|
-</script>
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
-.leftcontent {
|
|
|
|
|
- transition: width 0.3s ease;
|
|
|
|
|
- position: relative;
|
|
|
|
|
|
|
+.main-work-order-query {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ gap: 12px 24px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.query-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex: 1 1 auto;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 12px 24px;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.query-actions {
|
|
|
|
|
+ flex: 0 0 auto;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.query-actions :deep(.el-form-item__content) {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 8px 10px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.query-actions :deep(.el-button) {
|
|
|
|
|
+ margin-left: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.query-control {
|
|
|
|
|
+ width: 220px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.query-control--small {
|
|
|
|
|
+ width: 160px;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.leftcontent.collapsed {
|
|
|
|
|
- overflow: visible;
|
|
|
|
|
|
|
+.query-control--date {
|
|
|
|
|
+ width: 240px;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 正数样式 - 淡绿色 */
|
|
|
|
|
.positive-distance {
|
|
.positive-distance {
|
|
|
- color: #67c23a; /* element-plus 成功色 */
|
|
|
|
|
- background-color: rgba(103, 194, 58, 0.1); /* 10% 透明度的淡绿色背景 */
|
|
|
|
|
|
|
+ display: inline-block;
|
|
|
padding: 2px 8px;
|
|
padding: 2px 8px;
|
|
|
|
|
+ color: #67c23a;
|
|
|
|
|
+ background-color: rgb(103 194 58 / 10%);
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
|
- display: inline-block;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 负数样式 - 淡红色 */
|
|
|
|
|
.negative-distance {
|
|
.negative-distance {
|
|
|
- color: #f56c6c; /* element-plus 危险色 */
|
|
|
|
|
- background-color: rgba(245, 108, 108, 0.1); /* 10% 透明度的淡红色背景 */
|
|
|
|
|
|
|
+ display: inline-block;
|
|
|
padding: 2px 8px;
|
|
padding: 2px 8px;
|
|
|
|
|
+ color: #f56c6c;
|
|
|
|
|
+ background-color: rgb(245 108 108 / 10%);
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
|
- display: inline-block;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.table-wrap {
|
|
|
|
|
- overflow-x: auto; /* 允许水平滚动 */
|
|
|
|
|
|
|
+:deep(.required-item .el-form-item__label::before) {
|
|
|
|
|
+ margin-right: 2px;
|
|
|
|
|
+ color: #ff4d4f;
|
|
|
|
|
+ content: '*';
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 确保所有内容不换行 */
|
|
|
|
|
-:deep(.el-table) {
|
|
|
|
|
- min-width: 100% !important;
|
|
|
|
|
- width: auto !important;
|
|
|
|
|
|
|
+:deep(.required-item .el-form-item__label) {
|
|
|
|
|
+ padding-right: 0 !important;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 表头和单元格内容不换行 */
|
|
|
|
|
-:deep(.el-table__header .el-table__cell .cell),
|
|
|
|
|
-:deep(.el-table__body .el-table__cell .cell) {
|
|
|
|
|
- white-space: nowrap !important;
|
|
|
|
|
- overflow: visible !important;
|
|
|
|
|
- text-overflow: clip !important;
|
|
|
|
|
|
|
+:deep(.el-form-item) {
|
|
|
|
|
+ margin-bottom: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 防止表头内容换行 */
|
|
|
|
|
-:deep(.el-table__header-wrapper) .el-table__cell > .cell {
|
|
|
|
|
- white-space: nowrap;
|
|
|
|
|
|
|
+@media (width >= 2200px) {
|
|
|
|
|
+ .main-work-order-query,
|
|
|
|
|
+ .query-row {
|
|
|
|
|
+ flex-wrap: nowrap;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 确保表格行不换行 */
|
|
|
|
|
-:deep(.el-table__row) {
|
|
|
|
|
- white-space: nowrap;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+@media (width <= 1500px) {
|
|
|
|
|
+ .main-work-order-query,
|
|
|
|
|
+ .query-row {
|
|
|
|
|
+ gap: 12px 18px;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-/* 表头特别处理 */
|
|
|
|
|
-:deep(.el-table__header) {
|
|
|
|
|
- .cell {
|
|
|
|
|
- display: inline-block;
|
|
|
|
|
- white-space: nowrap;
|
|
|
|
|
- width: auto !important;
|
|
|
|
|
|
|
+ .query-control {
|
|
|
|
|
+ width: 200px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .query-control--small {
|
|
|
|
|
+ width: 150px;
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
-/* 表格使用100%宽度 */
|
|
|
|
|
-:deep(.el-table__inner-wrapper) {
|
|
|
|
|
- width: 100% !important;
|
|
|
|
|
|
|
+ .query-control--date {
|
|
|
|
|
+ width: 220px;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 延时原因 必填星号样式 */
|
|
|
|
|
-:deep(.required-item .el-form-item__label:before) {
|
|
|
|
|
- content: '*';
|
|
|
|
|
- color: #ff4d4f;
|
|
|
|
|
- margin-right: 2px;
|
|
|
|
|
|
|
+@media (width <= 1200px) {
|
|
|
|
|
+ .main-work-order-page {
|
|
|
|
|
+ grid-template-columns: minmax(0, 1fr);
|
|
|
|
|
+ grid-template-rows: auto auto minmax(480px, 1fr);
|
|
|
|
|
+ height: auto;
|
|
|
|
|
+ min-height: calc(
|
|
|
|
|
+ 100vh - 20px - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height)
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.main-work-order-tree) {
|
|
|
|
|
+ grid-row: auto !important;
|
|
|
|
|
+ width: 100% !important;
|
|
|
|
|
+ height: 320px !important;
|
|
|
|
|
+ min-width: 0 !important;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .query-actions {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 调整标签区域样式 */
|
|
|
|
|
-:deep(.required-item .el-form-item__label) {
|
|
|
|
|
- padding-right: 0 !important;
|
|
|
|
|
|
|
+@media (width <= 768px) {
|
|
|
|
|
+ .main-work-order-query {
|
|
|
|
|
+ padding: 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .query-row,
|
|
|
|
|
+ .query-row :deep(.el-form-item),
|
|
|
|
|
+ .query-actions {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .query-control,
|
|
|
|
|
+ .query-control--small,
|
|
|
|
|
+ .query-control--date {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .query-actions :deep(.el-form-item__content) {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .query-actions :deep(.el-button) {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ margin-left: 0;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|