|
@@ -0,0 +1,363 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <Dialog :title="dialogTitle" v-model="dialogVisible" width="50%">
|
|
|
|
|
+ <el-form
|
|
|
|
|
+ ref="formRef"
|
|
|
|
|
+ :model="formData"
|
|
|
|
|
+ :rules="formRules"
|
|
|
|
|
+ label-width="120px"
|
|
|
|
|
+ v-loading="formLoading">
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="关联设备" prop="deviceId">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.deviceName"
|
|
|
|
|
+ disabled
|
|
|
|
|
+ placeholder="请选择关联设备"
|
|
|
|
|
+ style="width: 100%">
|
|
|
|
|
+ <template #append>
|
|
|
|
|
+ <el-link @click="selectDevice" :underline="false">选择</el-link>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="证书编号" prop="certNo">
|
|
|
|
|
+ <el-input v-model="formData.certNo" placeholder="请输入证书编号" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="检测单位" prop="certOrg">
|
|
|
|
|
+ <el-input v-model="formData.certOrg" placeholder="请输入检测单位" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="检测日期" prop="certTime">
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-model="formData.certTime"
|
|
|
|
|
+ type="date"
|
|
|
|
|
+ value-format="x"
|
|
|
|
|
+ placeholder="请选择检测日期"
|
|
|
|
|
+ style="width: 100%" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="有效期至" prop="certExpire">
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-model="formData.certExpire"
|
|
|
|
|
+ type="date"
|
|
|
|
|
+ value-format="x"
|
|
|
|
|
+ placeholder="请选择有效期至"
|
|
|
|
|
+ style="width: 100%" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="部门" prop="deptId">
|
|
|
|
|
+ <el-tree-select
|
|
|
|
|
+ v-model="formData.deptId"
|
|
|
|
|
+ :data="deptList"
|
|
|
|
|
+ :props="defaultProps"
|
|
|
|
|
+ node-key="id"
|
|
|
|
|
+ filterable
|
|
|
|
|
+ :check-strictly="false"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ placeholder="请选择部门"
|
|
|
|
|
+ style="width: 100%" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="24">
|
|
|
|
|
+ <el-form-item label="附件" prop="file">
|
|
|
|
|
+ <UploadFile
|
|
|
|
|
+ v-model="formData.file"
|
|
|
|
|
+ :file-type="['doc', 'docx', 'pdf', 'jpg', 'png', 'jpeg', 'xls', 'xlsx']"
|
|
|
|
|
+ :limit="3"
|
|
|
|
|
+ :file-size="100"
|
|
|
|
|
+ class="min-w-80px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="24">
|
|
|
|
|
+ <el-form-item label="备注" prop="remark">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.remark"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ :rows="3"
|
|
|
|
|
+ placeholder="请输入备注" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
|
|
|
|
+ <el-button @click="dialogVisible = false">取 消</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </Dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <Dialog title="选择设备" v-model="deviceDialogVisible" width="70%">
|
|
|
|
|
+ <ContentWrap>
|
|
|
|
|
+ <el-form class="-mb-15px" :model="deviceQueryParams" :inline="true">
|
|
|
|
|
+ <el-form-item label="设备名称" prop="deviceName">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="deviceQueryParams.deviceName"
|
|
|
|
|
+ placeholder="请输入设备名称"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @keyup.enter="handleDeviceQuery"
|
|
|
|
|
+ class="!w-200px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="设备编码" prop="deviceCode">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="deviceQueryParams.deviceCode"
|
|
|
|
|
+ placeholder="请输入设备编码"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @keyup.enter="handleDeviceQuery"
|
|
|
|
|
+ class="!w-200px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item>
|
|
|
|
|
+ <el-button @click="handleDeviceQuery">
|
|
|
|
|
+ <Icon icon="ep:search" class="mr-5px" /> {{ t('devicePerson.search') }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button @click="resetDeviceQuery">
|
|
|
|
|
+ <Icon icon="ep:refresh" class="mr-5px" /> {{ t('devicePerson.reset') }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </ContentWrap>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="pb-10">
|
|
|
|
|
+ <zm-table
|
|
|
|
|
+ :loading="deviceLoading"
|
|
|
|
|
+ :data="deviceList"
|
|
|
|
|
+ :stripe="true"
|
|
|
|
|
+ :show-overflow-tooltip="true">
|
|
|
|
|
+ <zm-table-column width="50" align="center">
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ <el-radio
|
|
|
|
|
+ :model-value="selectedDeviceId"
|
|
|
|
|
+ :label="scope.row.id"
|
|
|
|
|
+ @change="handleDeviceRadioChange(scope.row)">
|
|
|
|
|
+
|
|
|
|
|
+ </el-radio>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </zm-table-column>
|
|
|
|
|
+ <zm-table-column :label="t('monitor.serial')" width="70" align="center">
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ {{ scope.$index + 1 }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </zm-table-column>
|
|
|
|
|
+ <zm-table-column label="设备编码" align="center" prop="deviceCode" min-width="140" />
|
|
|
|
|
+ <zm-table-column label="设备名称" align="center" prop="deviceName" min-width="160" />
|
|
|
|
|
+ <zm-table-column label="所在部门" align="center" prop="deptName" min-width="140" />
|
|
|
|
|
+ <zm-table-column label="设备状态" align="center" prop="deviceStatusName" min-width="120" />
|
|
|
|
|
+ <zm-table-column label="位置" align="center" prop="location" min-width="140" />
|
|
|
|
|
+ <zm-table-column label="备注" align="center" prop="remark" min-width="160" />
|
|
|
|
|
+ </zm-table>
|
|
|
|
|
+
|
|
|
|
|
+ <Pagination
|
|
|
|
|
+ :total="deviceTotal"
|
|
|
|
|
+ v-model:page="deviceQueryParams.pageNo"
|
|
|
|
|
+ v-model:limit="deviceQueryParams.pageSize"
|
|
|
|
|
+ @pagination="getDeviceList" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <el-button @click="confirmSelectDevice" type="primary">确 定</el-button>
|
|
|
|
|
+ <el-button @click="closeDeviceDialog">取 消</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </Dialog>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import { InspectDeviceCertApi } from '@/api/pms/qhse/index'
|
|
|
|
|
+import { IotDeviceApi } from '@/api/pms/device'
|
|
|
|
|
+import { defaultProps, handleTree } from '@/utils/tree'
|
|
|
|
|
+import { onMounted, reactive, ref } from 'vue'
|
|
|
|
|
+import * as DeptApi from '@/api/system/dept'
|
|
|
|
|
+import { useUserStore } from '@/store/modules/user'
|
|
|
|
|
+defineOptions({ name: 'QHSEDeviceCertForm' })
|
|
|
|
|
+
|
|
|
|
|
+const { t } = useI18n()
|
|
|
|
|
+const message = useMessage()
|
|
|
|
|
+const userStore = useUserStore()
|
|
|
|
|
+const dialogVisible = ref(false)
|
|
|
|
|
+const dialogTitle = ref('')
|
|
|
|
|
+const formLoading = ref(false)
|
|
|
|
|
+const formType = ref('')
|
|
|
|
|
+const formRef = ref()
|
|
|
|
|
+const deptList = ref<Tree[]>([])
|
|
|
|
|
+
|
|
|
|
|
+const createDefaultFormData = () => ({
|
|
|
|
|
+ id: undefined,
|
|
|
|
|
+ deviceId: undefined,
|
|
|
|
|
+ deviceName: '',
|
|
|
|
|
+ deptId: undefined,
|
|
|
|
|
+ certNo: '',
|
|
|
|
|
+ certOrg: '',
|
|
|
|
|
+ certTime: undefined,
|
|
|
|
|
+ certExpire: undefined,
|
|
|
|
|
+ file: '',
|
|
|
|
|
+ remark: ''
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const formData = ref(createDefaultFormData())
|
|
|
|
|
+
|
|
|
|
|
+const formRules = reactive({
|
|
|
|
|
+ deviceId: [{ required: true, message: '关联设备不能为空', trigger: 'blur' }],
|
|
|
|
|
+ certNo: [{ required: true, message: '证书编号不能为空', trigger: 'blur' }],
|
|
|
|
|
+ certOrg: [{ required: true, message: '检测单位不能为空', trigger: 'blur' }],
|
|
|
|
|
+ certTime: [{ required: true, message: '检测日期不能为空', trigger: 'blur' }],
|
|
|
|
|
+ certExpire: [{ required: true, message: '有效期不能为空', trigger: 'blur' }],
|
|
|
|
|
+ file: [{ required: true, message: '请上传附件', trigger: 'blur' }],
|
|
|
|
|
+ deptId: [{ required: true, message: '所在部门不能为空', trigger: 'blur' }]
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const emit = defineEmits(['success'])
|
|
|
|
|
+
|
|
|
|
|
+const resetForm = () => {
|
|
|
|
|
+ formData.value = createDefaultFormData()
|
|
|
|
|
+ formRef.value?.resetFields()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const open = async (type: string, id?: number) => {
|
|
|
|
|
+ dialogVisible.value = true
|
|
|
|
|
+ dialogTitle.value = t('action.' + type)
|
|
|
|
|
+ formType.value = type
|
|
|
|
|
+ resetForm()
|
|
|
|
|
+ formData.value.deptId = userStore.getUser.deptId
|
|
|
|
|
+ if (id) {
|
|
|
|
|
+ formLoading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await InspectDeviceCertApi.getInspectDeviceCert(id)
|
|
|
|
|
+ formData.value = {
|
|
|
|
|
+ ...createDefaultFormData(),
|
|
|
|
|
+ ...res,
|
|
|
|
|
+ certTime: res.certTime ? Number(res.certTime) : undefined,
|
|
|
|
|
+ certExpire: res.certExpire ? Number(res.certExpire) : undefined
|
|
|
|
|
+ }
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ formLoading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+defineExpose({ open })
|
|
|
|
|
+
|
|
|
|
|
+const submitForm = async () => {
|
|
|
|
|
+ await formRef.value.validate()
|
|
|
|
|
+ formLoading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data = { ...formData.value } as any
|
|
|
|
|
+ if (data.file instanceof Array) {
|
|
|
|
|
+ data.file = data.file.join(',')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (formType.value === 'create') {
|
|
|
|
|
+ await InspectDeviceCertApi.createInspectDeviceCert(data)
|
|
|
|
|
+ message.success(t('common.createSuccess'))
|
|
|
|
|
+ } else {
|
|
|
|
|
+ await InspectDeviceCertApi.updateInspectDeviceCert(data)
|
|
|
|
|
+ message.success(t('common.updateSuccess'))
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ dialogVisible.value = false
|
|
|
|
|
+ emit('success')
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ formLoading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const deviceDialogVisible = ref(false)
|
|
|
|
|
+const deviceLoading = ref(false)
|
|
|
|
|
+const deviceList = ref<any[]>([])
|
|
|
|
|
+const deviceTotal = ref(0)
|
|
|
|
|
+const selectedDeviceId = ref<number | undefined>(undefined)
|
|
|
|
|
+const selectedDevice = ref<any>(null)
|
|
|
|
|
+
|
|
|
|
|
+const deviceQueryParams = reactive({
|
|
|
|
|
+ pageNo: 1,
|
|
|
|
|
+ pageSize: 10,
|
|
|
|
|
+ deviceName: undefined as string | undefined,
|
|
|
|
|
+ deviceCode: undefined as string | undefined
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const getDeviceList = async () => {
|
|
|
|
|
+ deviceLoading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data = await IotDeviceApi.getIotDevicePage(deviceQueryParams)
|
|
|
|
|
+ deviceList.value = data.list
|
|
|
|
|
+ deviceTotal.value = data.total
|
|
|
|
|
+
|
|
|
|
|
+ if (selectedDeviceId.value) {
|
|
|
|
|
+ selectedDevice.value =
|
|
|
|
|
+ deviceList.value.find((item) => item.id === selectedDeviceId.value) || selectedDevice.value
|
|
|
|
|
+ }
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ deviceLoading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleDeviceQuery = () => {
|
|
|
|
|
+ deviceQueryParams.pageNo = 1
|
|
|
|
|
+ getDeviceList()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const resetDeviceQuery = () => {
|
|
|
|
|
+ deviceQueryParams.deviceName = undefined
|
|
|
|
|
+ deviceQueryParams.deviceCode = undefined
|
|
|
|
|
+ handleDeviceQuery()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleDeviceRadioChange = (row: any) => {
|
|
|
|
|
+ selectedDeviceId.value = row.id
|
|
|
|
|
+ selectedDevice.value = row
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const selectDevice = () => {
|
|
|
|
|
+ deviceDialogVisible.value = true
|
|
|
|
|
+ selectedDeviceId.value = formData.value.deviceId as number | undefined
|
|
|
|
|
+ selectedDevice.value =
|
|
|
|
|
+ selectedDeviceId.value && formData.value.deviceName
|
|
|
|
|
+ ? {
|
|
|
|
|
+ id: formData.value.deviceId,
|
|
|
|
|
+ deviceName: formData.value.deviceName,
|
|
|
|
|
+ deptId: formData.value.deptId
|
|
|
|
|
+ }
|
|
|
|
|
+ : null
|
|
|
|
|
+ getDeviceList()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const closeDeviceDialog = () => {
|
|
|
|
|
+ deviceDialogVisible.value = false
|
|
|
|
|
+ selectedDeviceId.value = undefined
|
|
|
|
|
+ selectedDevice.value = null
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const confirmSelectDevice = () => {
|
|
|
|
|
+ if (!selectedDevice.value) {
|
|
|
|
|
+ message.warning('请先选择一个设备')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ formData.value.deviceId = selectedDevice.value.id
|
|
|
|
|
+ formData.value.deviceName = selectedDevice.value.deviceName
|
|
|
|
|
+ formData.value.deptId = selectedDevice.value.deptId
|
|
|
|
|
+ closeDeviceDialog()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onMounted(async () => {
|
|
|
|
|
+ deptList.value = handleTree(await DeptApi.getSimpleDeptList())
|
|
|
|
|
+})
|
|
|
|
|
+</script>
|