|
@@ -0,0 +1,207 @@
|
|
|
|
+<template>
|
|
|
|
+ <Dialog v-model="dialogVisible"
|
|
|
|
+ :title="t('monitor.details')"
|
|
|
|
+ style="width: 1000px; max-height: 800px" @close="handleClose" >
|
|
|
|
+
|
|
|
|
+ <ContentWrap>
|
|
|
|
+ <el-form
|
|
|
|
+ class="-mb-15px"
|
|
|
|
+ :model="queryParams"
|
|
|
|
+ ref="queryFormRef"
|
|
|
|
+ :inline="true"
|
|
|
|
+ label-width="68px"
|
|
|
|
+ >
|
|
|
|
+ <el-form-item :label="t('profile.user.username')" prop="username" style="margin-left: 28px">
|
|
|
|
+ <el-input
|
|
|
|
+ v-model="queryParams.username"
|
|
|
|
+ :placeholder="t('profile.rules.username')"
|
|
|
|
+ clearable
|
|
|
|
+ @keyup.enter="handleQuery"
|
|
|
|
+ class="!w-200px"
|
|
|
|
+ />
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item :label="t('profile.user.nickname')" prop="nickname">
|
|
|
|
+ <el-input
|
|
|
|
+ v-model="queryParams.nickname"
|
|
|
|
+ :placeholder="t('profile.rules.nickname')"
|
|
|
|
+ clearable
|
|
|
|
+ @keyup.enter="handleQuery"
|
|
|
|
+ class="!w-200px"
|
|
|
|
+ />
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item>
|
|
|
|
+ <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" />
|
|
|
|
+ {{ t('workOrderMaterial.search') }}</el-button>
|
|
|
|
+ <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" />
|
|
|
|
+ {{ t('workOrderMaterial.reset') }}</el-button>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-form>
|
|
|
|
+ </ContentWrap>
|
|
|
|
+
|
|
|
|
+ <ContentWrap>
|
|
|
|
+ <el-table
|
|
|
|
+ v-loading="loading"
|
|
|
|
+ :data="list"
|
|
|
|
+ :stripe="true"
|
|
|
|
+ :show-overflow-tooltip="true"
|
|
|
|
+ >
|
|
|
|
+ <el-table-column :label="t('profile.user.username')" align="center" prop="username" />
|
|
|
|
+ <el-table-column :label="t('profile.user.nickname')" align="center" prop="nickname" />
|
|
|
|
+ <el-table-column :label="t('profile.user.dept')" align="center" prop="deptName" />
|
|
|
|
+ <el-table-column :label="t('profile.user.mobile')" align="center" prop="mobile" />
|
|
|
|
+ <el-table-column
|
|
|
|
+ :label="t('common.createTime')"
|
|
|
|
+ align="center"
|
|
|
|
+ prop="createTime"
|
|
|
|
+ :formatter="dateFormatter"
|
|
|
|
+ width="180"
|
|
|
|
+ />
|
|
|
|
+ </el-table>
|
|
|
|
+
|
|
|
|
+ <Pagination
|
|
|
|
+ :total="total"
|
|
|
|
+ v-model:page="queryParams.pageNo"
|
|
|
|
+ v-model:limit="queryParams.pageSize"
|
|
|
|
+ @pagination="getRoleUserList"
|
|
|
|
+ />
|
|
|
|
+ </ContentWrap>
|
|
|
|
+ </Dialog>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script setup lang="ts">
|
|
|
|
+import { DictDataVO } from '@/api/system/dict/dict.data'
|
|
|
|
+import dayjs from 'dayjs'
|
|
|
|
+import { IotMaintenanceBomApi, IotMaintenanceBomVO } from '@/api/pms/iotmaintenancebom'
|
|
|
|
+import {propTypes} from "@/utils/propTypes";
|
|
|
|
+import * as UserApi from '@/api/system/user'
|
|
|
|
+import {dateFormatter} from "@/utils/formatTime";
|
|
|
|
+
|
|
|
|
+const { t } = useI18n() // 国际化
|
|
|
|
+const emit = defineEmits(['close']) // 定义 success 事件,用于操作成功后的回调
|
|
|
|
+const dialogVisible = ref(false) // 弹窗的是否展示
|
|
|
|
+const loading = ref(true) // 列表的加载中
|
|
|
|
+const queryFormRef = ref() // 搜索的表单
|
|
|
|
+const list = ref([]) // 列表的数据
|
|
|
|
+const total = ref(0) // 列表的总页数
|
|
|
|
+const queryParams = reactive({
|
|
|
|
+ pageNo: 1,
|
|
|
|
+ pageSize: 10,
|
|
|
|
+ roleId: undefined,
|
|
|
|
+ username: undefined,
|
|
|
|
+ nickname: undefined
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+const props = defineProps({
|
|
|
|
+ flag: propTypes.oneOfType<string | string[]>([String, Array<String>]).isRequired,
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+const selectedRow = ref(null)
|
|
|
|
+
|
|
|
|
+// 处理单选逻辑
|
|
|
|
+const selectRow = (row) => {
|
|
|
|
+ selectedRow.value = selectedRow.value?.id === row.id ? null : row
|
|
|
|
+ emit('choose', row)
|
|
|
|
+ dialogVisible.value = false
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const open = async (roleId?: number) => {
|
|
|
|
+ await nextTick() // 确保DOM更新完成
|
|
|
|
+ queryParams.roleId = roleId
|
|
|
|
+ // 加载指定角色的用户列表
|
|
|
|
+ await getRoleUserList()
|
|
|
|
+ dialogVisible.value = true
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
|
|
|
+
|
|
|
|
+const getRoleUserList = async () => {
|
|
|
|
+ loading.value = true
|
|
|
|
+ try {
|
|
|
|
+ const data = await UserApi.getUserPage(queryParams)
|
|
|
|
+ list.value = data.list
|
|
|
|
+ total.value = data.total
|
|
|
|
+ } finally {
|
|
|
|
+ loading.value = false
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const handleClose = () => {
|
|
|
|
+ // 重置状态避免多个弹窗出现
|
|
|
|
+ dialogVisible.value = false
|
|
|
|
+ loading.value = false
|
|
|
|
+ list.value = []
|
|
|
|
+
|
|
|
|
+ // 通知父组件弹窗已关闭
|
|
|
|
+ emit('close')
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 计算 距离下次保养运行时长 H
|
|
|
|
+const calculateTimePeriod = (item: IotMaintenanceBomVO) => {
|
|
|
|
+ if (item.runningTimeRule === 0) {
|
|
|
|
+ const next = Number(item.nextRunningTime) || 0;
|
|
|
|
+ const totalRun = Number(item.totalRunTime) || 0;
|
|
|
|
+ const lastRun = Number(item.lastRunningTime) || 0;
|
|
|
|
+ const result = next - (totalRun - lastRun);
|
|
|
|
+ return Number(result.toFixed(2));
|
|
|
|
+ }
|
|
|
|
+ return typeof item.timePeriod === 'number'
|
|
|
|
+ ? Number(item.timePeriod.toFixed(2))
|
|
|
|
+ : item.timePeriod;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+// 计算 距离下次保养公里数 KM
|
|
|
|
+const calculateKiloPeriod = (item: IotMaintenanceBomVO) => {
|
|
|
|
+ if (item.mileageRule === 0) {
|
|
|
|
+ const next = Number(item.nextRunningKilometers) || 0;
|
|
|
|
+ const totalRun = Number(item.totalMileage) || 0;
|
|
|
|
+ const lastRun = Number(item.lastRunningKilometers) || 0;
|
|
|
|
+ const result = next - (totalRun - lastRun);
|
|
|
|
+ return Number(result.toFixed(2));
|
|
|
|
+ }
|
|
|
|
+ return typeof item.kilometerCycle === 'number'
|
|
|
|
+ ? Number(item.kilometerCycle.toFixed(2))
|
|
|
|
+ : item.kilometerCycle;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+// 计算下次保养日期
|
|
|
|
+const calculateNextNaturalDate = (item: IotMaintenanceBomVO): string => {
|
|
|
|
+ if (item.naturalDateRule !== 0 || !item.lastNaturalDate || !item.nextNaturalDate) {
|
|
|
|
+ return '-'
|
|
|
|
+ }
|
|
|
|
+ return dayjs(item.lastNaturalDate).add(item.nextNaturalDate, 'day').format('YYYY-MM-DD')
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 新增计算属性:控制时间相关列的显示
|
|
|
|
+const showTimeColumns = computed(() => {
|
|
|
|
+ return list.value.some(item => item.runningTimeRule === 0);
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+// 新增计算属性:控制里程相关列的显示
|
|
|
|
+const showMileageColumns = computed(() => {
|
|
|
|
+ return list.value.some(item => item.mileageRule === 0);
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+/** 搜索按钮操作 */
|
|
|
|
+const handleQuery = () => {
|
|
|
|
+ queryParams.pageNo = 1
|
|
|
|
+ getRoleUserList()
|
|
|
|
+}
|
|
|
|
+const choose = (row: DictDataVO) => {
|
|
|
|
+ emit('choose', row)
|
|
|
|
+ dialogVisible.value = false
|
|
|
|
+}
|
|
|
|
+/** 重置按钮操作 */
|
|
|
|
+const resetQuery = () => {
|
|
|
|
+ queryFormRef.value.resetFields()
|
|
|
|
+ handleQuery()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+</script>
|
|
|
|
+<style lang="scss">
|
|
|
|
+.no-label-radio .el-radio__label {
|
|
|
|
+ display: none;
|
|
|
|
+}
|
|
|
|
+.no-label-radio .el-radio__inner {
|
|
|
|
+ margin-right: 0;
|
|
|
|
+}
|
|
|
|
+</style>
|