| | |
| | | data: query, |
| | | }); |
| | | } |
| | | // å é¤è®°å½ |
| | | export function ledgerRecordDelete(ids) { |
| | | return request({ |
| | | url: "/measuringInstrumentLedgerRecord/delete", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // æ¥è¯¢ä¿å
»ä»»å¡éä»¶å表 |
| | | export function listMaintenanceTaskFiles(query) { |
| | | return request({ |
| | | url: "/maintenanceTaskFile/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢ä¿å
»ä»»å¡éä»¶ |
| | | export function addMaintenanceTaskFile(data) { |
| | | return request({ |
| | | url: "/maintenanceTaskFile/add", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // å é¤ä¿å
»ä»»å¡éä»¶ |
| | | export function delMaintenanceTaskFile(id) { |
| | | return request({ |
| | | url: "/maintenanceTaskFile/del", |
| | | method: "delete", |
| | | data: Array.isArray(id) ? id : [id], |
| | | }); |
| | | } |
| | |
| | | data, |
| | | }); |
| | | }; |
| | | // æ¥è¯¢è®¾å¤çæ¥ä¿®éé¢-æ¯æ |
| | | export const monthlyAmount = (query) => { |
| | | return request({ |
| | | url: `/device/repair/monthlyAmount`, |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | }; |
| | | // æ¥è¯¢è®¾å¤çæ¥ä¿®éé¢-æ¯å¹´ |
| | | export const yearlyAmount = (query) => { |
| | | return request({ |
| | | url: `/device/repair/yearlyAmount`, |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | }; |
| | |
| | | data: params, |
| | | }); |
| | | }; |
| | | |
| | | // æ¥è¯¢è®¾å¤çæ¥ä¿®éé¢-æ¯æ |
| | | export const monthlyAmount = (query) => { |
| | | return request({ |
| | | url: `/device/maintenance/monthlyAmount`, |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | }; |
| | | // æ¥è¯¢è®¾å¤çæ¥ä¿®éé¢-æ¯å¹´ |
| | | export const yearlyAmount = (query) => { |
| | | return request({ |
| | | url: `/device/maintenance/yearlyAmount`, |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="dialogVisible" |
| | | :title="title" |
| | | :width="width" |
| | | :before-close="handleClose"> |
| | | <div class="file-list-toolbar" |
| | | v-if="showToolbar"> |
| | | <template v-if="useBuiltInUpload"> |
| | | <el-upload v-model:file-list="uploadFileList" |
| | | class="upload-demo" |
| | | :action="uploadAction" |
| | | :headers="uploadHeaders" |
| | | :show-file-list="false" |
| | | :on-success="handleDefaultUploadSuccess" |
| | | :on-error="handleDefaultUploadError"> |
| | | <el-button v-if="showUploadButton" |
| | | type="primary" |
| | | size="small"> |
| | | ä¸ä¼ éä»¶ |
| | | </el-button> |
| | | </el-upload> |
| | | </template> |
| | | <template v-else> |
| | | <el-button v-if="showUploadButton" |
| | | type="primary" |
| | | size="small" |
| | | @click="handleUpload"> |
| | | æ°å¢éä»¶ |
| | | </el-button> |
| | | </template> |
| | | </div> |
| | | <el-table :data="tableData" |
| | | border |
| | | :height="tableHeight"> |
| | | <el-table-column :label="nameColumnLabel" |
| | | :prop="nameColumnProp" |
| | | :min-width="nameColumnMinWidth" |
| | | show-overflow-tooltip /> |
| | | <el-table-column v-if="showActions" |
| | | fixed="right" |
| | | label="æä½" |
| | | :width="actionColumnWidth" |
| | | align="center"> |
| | | <template #default="scope"> |
| | | <el-button v-if="showDownload" |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="handleDownload(scope.row)"> |
| | | ä¸è½½ |
| | | </el-button> |
| | | <el-button v-if="showPreview" |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="handlePreview(scope.row)"> |
| | | é¢è§ |
| | | </el-button> |
| | | <el-button v-if="showDeleteButton" |
| | | link |
| | | type="danger" |
| | | size="small" |
| | | @click="handleDelete(scope.row, scope.$index)"> |
| | | å é¤ |
| | | </el-button> |
| | | <slot name="actions" |
| | | :row="scope.row"></slot> |
| | | </template> |
| | | </el-table-column> |
| | | <slot name="columns"></slot> |
| | | </el-table> |
| | | <pagination v-if="isShowPagination" |
| | | style="margin-bottom: 20px;" |
| | | :total="page.total" |
| | | :page="page.current" |
| | | :limit="page.size" |
| | | @pagination="paginationSearch" |
| | | @change="handleChange" /> |
| | | </el-dialog> |
| | | <filePreview v-if="showPreview" |
| | | ref="filePreviewRef" /> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, getCurrentInstance } from "vue"; |
| | | import pagination from "@/components/Pagination/index.vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import filePreview from "@/components/filePreview/index.vue"; |
| | | import { getToken } from "@/utils/auth"; |
| | | |
| | | const props = defineProps({ |
| | | modelValue: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | title: { |
| | | type: String, |
| | | default: "éä»¶", |
| | | }, |
| | | width: { |
| | | type: String, |
| | | default: "40%", |
| | | }, |
| | | tableHeight: { |
| | | type: String, |
| | | default: "40vh", |
| | | }, |
| | | nameColumnLabel: { |
| | | type: String, |
| | | default: "éä»¶åç§°", |
| | | }, |
| | | nameColumnProp: { |
| | | type: String, |
| | | default: "name", |
| | | }, |
| | | nameColumnMinWidth: { |
| | | type: [String, Number], |
| | | default: 400, |
| | | }, |
| | | actionColumnWidth: { |
| | | type: [String, Number], |
| | | default: 160, |
| | | }, |
| | | showActions: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | showDownload: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | showPreview: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | showUploadButton: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | showDeleteButton: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | urlField: { |
| | | type: String, |
| | | default: "url", |
| | | }, |
| | | downloadMethod: { |
| | | type: Function, |
| | | default: null, |
| | | }, |
| | | previewMethod: { |
| | | type: Function, |
| | | default: null, |
| | | }, |
| | | uploadMethod: { |
| | | type: Function, |
| | | default: null, |
| | | }, |
| | | deleteMethod: { |
| | | type: Function, |
| | | default: null, |
| | | }, |
| | | rulesRegulationsManagementId: { |
| | | type: [String, Number], |
| | | default: "", |
| | | }, |
| | | uploadUrl: { |
| | | type: String, |
| | | default: `${import.meta.env.VITE_APP_BASE_API}/file/upload`, |
| | | }, |
| | | isShowPagination: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | page: { |
| | | type: Object, |
| | | default: () => ({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }), |
| | | }, |
| | | }); |
| | | |
| | | const emit = defineEmits([ |
| | | "update:modelValue", |
| | | "close", |
| | | "download", |
| | | "preview", |
| | | "upload", |
| | | "delete", |
| | | ]); |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | const filePreviewRef = ref(null); |
| | | const uploadFileList = ref([]); |
| | | |
| | | const dialogVisible = computed({ |
| | | get: () => props.modelValue, |
| | | set: val => emit("update:modelValue", val), |
| | | }); |
| | | |
| | | const tableData = ref([]); |
| | | const showToolbar = computed(() => props.showUploadButton); |
| | | const useBuiltInUpload = computed(() => !props.uploadMethod); |
| | | const uploadAction = computed(() => props.uploadUrl); |
| | | const uploadHeaders = computed(() => ({ |
| | | Authorization: `Bearer ${getToken()}`, |
| | | })); |
| | | |
| | | const handleClose = () => { |
| | | emit("close"); |
| | | dialogVisible.value = false; |
| | | }; |
| | | |
| | | const handleDownload = row => { |
| | | if (props.downloadMethod) { |
| | | props.downloadMethod(row); |
| | | } else { |
| | | // é»è®¤ä¸è½½æ¹æ³ |
| | | proxy.$download.name(row[props.urlField]); |
| | | } |
| | | emit("download", row); |
| | | }; |
| | | |
| | | const handlePreview = row => { |
| | | if (props.previewMethod) { |
| | | props.previewMethod(row); |
| | | } else { |
| | | // é»è®¤é¢è§æ¹æ³ |
| | | if (filePreviewRef.value) { |
| | | filePreviewRef.value.open(row[props.urlField]); |
| | | } |
| | | } |
| | | emit("preview", row); |
| | | }; |
| | | const paginationSearch = page => { |
| | | props.page.current = page.page; |
| | | props.page.size = page.limit; |
| | | emit("pagination", page.page, page.limit); |
| | | }; |
| | | |
| | | const open = list => { |
| | | dialogVisible.value = true; |
| | | tableData.value = list || []; |
| | | }; |
| | | |
| | | const handleUpload = async () => { |
| | | if (props.uploadMethod) { |
| | | // 妿æä¾äºèªå®ä¹ä¸ä¼ æ¹æ³ï¼ç±ç¶ç»ä»¶è´è´£æ´æ°å表ï¼éè¿ setListï¼ |
| | | // è¿éä¸åèªå¨æ·»å ï¼é¿å
ä¸ç¶ç»ä»¶ç setList éå¤ |
| | | await props.uploadMethod(); |
| | | } |
| | | emit("upload"); |
| | | }; |
| | | |
| | | const handleDelete = async (row, index) => { |
| | | if (props.deleteMethod) { |
| | | const result = await props.deleteMethod(row, index); |
| | | if (result === false) { |
| | | return; |
| | | } |
| | | // 妿æä¾äº deleteMethodï¼ç±ç¶ç»ä»¶è´è´£å·æ°å表ï¼ä¸å¨è¿éå é¤ |
| | | } else { |
| | | // å¦ææ²¡ææä¾ deleteMethodï¼æå¨ç»ä»¶å
é¨å é¤ |
| | | removeAttachment(index); |
| | | } |
| | | emit("delete", row); |
| | | }; |
| | | |
| | | const addAttachment = item => { |
| | | tableData.value = [...tableData.value, item]; |
| | | }; |
| | | |
| | | const handleDefaultUploadSuccess = async (res, file) => { |
| | | if (res?.code !== 200) { |
| | | ElMessage.error(res?.msg || "æä»¶ä¸ä¼ 失败"); |
| | | return; |
| | | } |
| | | if (!props.rulesRegulationsManagementId) { |
| | | ElMessage.error("缺å°è§ç« å¶åº¦IDï¼æ æ³ä¿åéä»¶"); |
| | | return; |
| | | } |
| | | const fileName = res?.data?.originalName || file?.name; |
| | | const fileUrl = res?.data?.tempPath || res?.data?.url; |
| | | const payload = { |
| | | fileName, |
| | | fileUrl, |
| | | rulesRegulationsManagementId: props.rulesRegulationsManagementId, |
| | | raw: res?.data || {}, |
| | | }; |
| | | emit("upload", payload); |
| | | }; |
| | | |
| | | const handleDefaultUploadError = () => { |
| | | ElMessage.error("æä»¶ä¸ä¼ 失败"); |
| | | }; |
| | | |
| | | const removeAttachment = index => { |
| | | if (index > -1 && index < tableData.value.length) { |
| | | const newList = [...tableData.value]; |
| | | newList.splice(index, 1); |
| | | tableData.value = newList; |
| | | } |
| | | }; |
| | | |
| | | const setList = list => { |
| | | tableData.value = list || []; |
| | | }; |
| | | |
| | | defineExpose({ |
| | | open, |
| | | addAttachment, |
| | | removeAttachment, |
| | | setList, |
| | | handleUpload, |
| | | handleDelete, |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .file-list-toolbar { |
| | | margin-bottom: 8px; |
| | | text-align: right; |
| | | } |
| | | </style> |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | :title="computedTitle" |
| | | :width="width" |
| | | @close="handleClose" |
| | | > |
| | | <slot></slot> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleConfirm">确认</el-button> |
| | | <el-button @click="handleCancel">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed } from 'vue' |
| | | |
| | | const props = defineProps({ |
| | | modelValue: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | title: { |
| | | type: [String, Function], |
| | | default: '' |
| | | }, |
| | | operationType: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | width: { |
| | | type: String, |
| | | default: '70%' |
| | | } |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:modelValue', 'close', 'confirm', 'cancel']) |
| | | |
| | | const dialogVisible = computed({ |
| | | get: () => props.modelValue, |
| | | set: (val) => emit('update:modelValue', val) |
| | | }) |
| | | |
| | | const computedTitle = computed(() => { |
| | | if (typeof props.title === 'function') { |
| | | return props.title(props.operationType) |
| | | } |
| | | return props.title |
| | | }) |
| | | |
| | | const handleClose = () => { |
| | | emit('close') |
| | | } |
| | | |
| | | const handleConfirm = () => { |
| | | emit('confirm') |
| | | } |
| | | |
| | | const handleCancel = () => { |
| | | emit('cancel') |
| | | dialogVisible.value = false |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .dialog-footer { |
| | | text-align: center; |
| | | } |
| | | </style> |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-tabs v-model="activeTab"> |
| | | <el-tab-pane label="æ¥ä¿®" name="repair"> |
| | | <el-form :inline="true" :model="filtersRepair"> |
| | | <el-form-item label="æ¥ç模å¼"> |
| | | <el-radio-group v-model="modeRepair" @change="buildColumnsRepair"> |
| | | <el-radio-button :value="'month'">ææ</el-radio-button> |
| | | <el-radio-button :value="'year'">æå¹´</el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item v-if="modeRepair === 'month' || modeRepair === 'year'" label="年份"> |
| | | <el-date-picker v-model="yearRepair" type="year" value-format="YYYY" format="YYYY" placeholder="è¯·éæ©å¹´ä»½" @change="refreshRepair" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="refreshRepair">æ¥è¯¢</el-button> |
| | | <el-button @click="resetRepair">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <div class="table_list"> |
| | | <PIMTable |
| | | rowKey="deviceId" |
| | | :column="columnsRepair" |
| | | :tableData="tableDataRepair" |
| | | :page="{ current: 1, size: tableDataRepair.length || 10, total: tableDataRepair.length }" |
| | | /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="ä¿å
»" name="maintain"> |
| | | <el-form :inline="true" :model="filtersMaintain"> |
| | | <el-form-item label="æ¥ç模å¼"> |
| | | <el-radio-group v-model="modeMaintain" @change="buildColumnsMaintain"> |
| | | <el-radio-button :value="'month'">ææ</el-radio-button> |
| | | <el-radio-button :value="'year'">æå¹´</el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item v-if="modeMaintain === 'month' || modeMaintain === 'year'" label="年份"> |
| | | <el-date-picker v-model="yearMaintain" type="year" value-format="YYYY" format="YYYY" placeholder="è¯·éæ©å¹´ä»½" @change="refreshMaintain" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="refreshMaintain">æ¥è¯¢</el-button> |
| | | <el-button @click="resetMaintain">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <div class="table_list"> |
| | | <PIMTable |
| | | rowKey="deviceId" |
| | | :column="columnsMaintain" |
| | | :tableData="tableDataMaintain" |
| | | :page="{ current: 1, size: tableDataMaintain.length || 10, total: tableDataMaintain.length }" |
| | | /> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from "vue"; |
| | | import { monthlyAmount, yearlyAmount } from "@/api/equipmentManagement/repair"; |
| | | import { monthlyAmount as monthlyAmountMaintain, yearlyAmount as yearlyAmountMaintain } from "@/api/equipmentManagement/upkeep"; |
| | | |
| | | defineOptions({ name: "é颿±æ»" }); |
| | | |
| | | const activeTab = ref("repair"); |
| | | |
| | | // æ¥ä¿® |
| | | const modeRepair = ref("month"); |
| | | const yearRepair = ref(new Date().getFullYear().toString()); |
| | | const filtersRepair = ref({}); |
| | | const columnsRepair = ref([]); |
| | | const tableDataRepair = ref([]); |
| | | |
| | | const fetchRepairData = async () => { |
| | | try { |
| | | const query = { year: yearRepair.value }; |
| | | const res = modeRepair.value === "month" ? await monthlyAmount(query) : await yearlyAmount(query); |
| | | const list = res?.records || res?.data || res || []; |
| | | tableDataRepair.value = Array.isArray(list) ? list : []; |
| | | } catch (e) { |
| | | tableDataRepair.value = []; |
| | | } |
| | | }; |
| | | |
| | | const buildColumnsRepair = async () => { |
| | | const base = [{ label: "设å¤åç§°", align: "center", prop: "deviceName", width: 180 }]; |
| | | if (modeRepair.value === "month") { |
| | | const monthCols = Array.from({ length: 12 }, (_, i) => ({ |
| | | label: `${i + 1}æ`, |
| | | align: "center", |
| | | prop: `month${i + 1}`, |
| | | })); |
| | | columnsRepair.value = [ |
| | | ...base, |
| | | ...monthCols, |
| | | { label: "æ»è®¡", align: "center", prop: "total" }, |
| | | ]; |
| | | } else { |
| | | columnsRepair.value = [ |
| | | ...base, |
| | | { label: "éé¢", align: "center", prop: "totalRepairPrice" }, |
| | | ]; |
| | | } |
| | | await fetchRepairData(); |
| | | }; |
| | | |
| | | const refreshRepair = async () => { |
| | | await buildColumnsRepair(); |
| | | }; |
| | | |
| | | const resetRepair = () => { |
| | | modeRepair.value = "month"; |
| | | yearRepair.value = new Date().getFullYear().toString(); |
| | | refreshRepair(); |
| | | }; |
| | | |
| | | // ä¿å
» |
| | | const modeMaintain = ref("month"); |
| | | const yearMaintain = ref(new Date().getFullYear().toString()); |
| | | const filtersMaintain = ref({}); |
| | | const columnsMaintain = ref([]); |
| | | const tableDataMaintain = ref([]); |
| | | |
| | | const fetchMaintainData = async () => { |
| | | try { |
| | | const query = { year: yearMaintain.value }; |
| | | const res = modeMaintain.value === "month" ? await monthlyAmountMaintain(query) : await yearlyAmountMaintain(query); |
| | | const list = res?.records || res?.data || res || []; |
| | | tableDataMaintain.value = Array.isArray(list) ? list : []; |
| | | } catch (e) { |
| | | tableDataMaintain.value = []; |
| | | } |
| | | }; |
| | | |
| | | const buildColumnsMaintain = async () => { |
| | | const base = [{ label: "设å¤åç§°", align: "center", prop: "deviceName", width: 180 }]; |
| | | if (modeMaintain.value === "month") { |
| | | const monthCols = Array.from({ length: 12 }, (_, i) => ({ |
| | | label: `${i + 1}æ`, |
| | | align: "center", |
| | | prop: `month${i + 1}`, |
| | | })); |
| | | columnsMaintain.value = [ |
| | | ...base, |
| | | ...monthCols, |
| | | { label: "æ»è®¡", align: "center", prop: "total" }, |
| | | ]; |
| | | } else { |
| | | columnsMaintain.value = [ |
| | | ...base, |
| | | { label: "éé¢", align: "center", prop: "totalRepairPrice" }, |
| | | ]; |
| | | } |
| | | await fetchMaintainData(); |
| | | }; |
| | | |
| | | const refreshMaintain = async () => { |
| | | await buildColumnsMaintain(); |
| | | }; |
| | | |
| | | const resetMaintain = () => { |
| | | modeMaintain.value = "month"; |
| | | yearMaintain.value = new Date().getFullYear().toString(); |
| | | refreshMaintain(); |
| | | }; |
| | | |
| | | buildColumnsRepair(); |
| | | refreshRepair(); |
| | | buildColumnsMaintain(); |
| | | refreshMaintain(); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .table_list { |
| | | margin-top: 10px; |
| | | } |
| | | </style> |
| | |
| | | |
| | | <script setup> |
| | | import {onMounted, ref} from "vue"; |
| | | import {ElMessageBox, ElMessage} from "element-plus"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import CalibrationDia from "@/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue"; |
| | | import {ledgerRecordListPage, ledgerRecordDelete} from "@/api/equipmentManagement/calibration.js"; |
| | | import {ledgerRecordListPage} from "@/api/equipmentManagement/calibration.js"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const userStore = useUserStore() |
| | | |
| | |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | width: 140, |
| | | align: "center", |
| | | fixed: 'right', |
| | | operation: [ |
| | |
| | | clickFun: (row) => { |
| | | openCalibrationDia("edit", row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "å é¤", |
| | | type: "text", |
| | | style: { |
| | | color: "#F56C6C" |
| | | }, |
| | | clickFun: (row) => { |
| | | handleDelete(row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.userId !== userStore.id |
| | | } |
| | | }, |
| | | ], |
| | | }, |
| | |
| | | calibrationDia.value?.openDialog(type, row) |
| | | }) |
| | | } |
| | | |
| | | // å é¤è®°å½ |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤è®¡éå¨å
·ç¼å·ä¸º"${row.code}"çæ£å®è®°å½åï¼`, "å é¤ç¡®è®¤", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | ledgerRecordDelete([row.id]).then(() => { |
| | | ElMessage.success("å 餿å"); |
| | | getList(); |
| | | }).catch(() => { |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶å é¤"); |
| | | }); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | |
| | | <el-dialog title="ç»è®°è®¾å¤ç¼ºé·" v-model="showRegisterDialog" width="50%"> |
| | | <el-form :model="defectForm" :rules="defectRules" ref="defectFormRef" label-width="100px"> |
| | | <el-form-item label="设å¤åç§°" prop="deviceName"> |
| | | <el-select v-model="defectForm.deviceLedgerId" @change="setDeviceModel"> |
| | | <el-select v-model="defectForm.deviceLedgerId" @change="setDeviceModel" filterable> |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | |
| | | <el-form ref="formRef" :model="form" :rules="rules" label-width="120px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设å¤åç§°" prop="taskId"> |
| | | <el-select v-model="form.taskId" @change="setDeviceModel" filterable> |
| | | <el-form-item label="设å¤åç§°" prop="taskIds"> |
| | | <el-select v-model="form.taskIds" @change="setDeviceModel" multiple filterable> |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å·¡æ£äºº" prop="inspector"> |
| | | <el-select v-model="form.inspector" filterable |
| | | default-first-option |
| | | :reserve-keyword="false" placeholder="è¯·éæ©" multiple clearable> |
| | | <el-select v-model="form.inspector" placeholder="è¯·éæ©" multiple clearable> |
| | | <el-option v-for="item in userList" :label="item.nickName" :value="item.userId" :key="item.userId"/> |
| | | </el-select> |
| | | </el-form-item> |
| | |
| | | <el-col :span="12"> |
| | | <el-form-item label="夿³¨" prop="remarks"> |
| | | <el-input v-model="form.remarks" placeholder="请è¾å
¥å¤æ³¨" type="textarea" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»è®°æ¶é´" prop="dateStr"> |
| | | <el-date-picker |
| | | v-model="form.dateStr" |
| | | type="date" |
| | | placeholder="éæ©ç»è®°æ¥æ" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="cancel">åæ¶</el-button> |
| | | <el-button type="primary" @click="submitForm">ä¿å</el-button> |
| | | <el-button @click="cancel">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | |
| | | const deviceOptions = ref([]); |
| | | const data = reactive({ |
| | | form: { |
| | | taskId: undefined, |
| | | taskIds: [], |
| | | taskName: undefined, |
| | | inspector: '', |
| | | inspectorIds: '', |
| | |
| | | frequencyType: '', |
| | | frequencyDetail: '', |
| | | week: '', |
| | | time: '', |
| | | dateStr: '' |
| | | time: '' |
| | | }, |
| | | rules: { |
| | | taskId: [{ required: true, message: "è¯·éæ©è®¾å¤", trigger: "change" },], |
| | | taskIds: [{ required: true, message: "è¯·éæ©è®¾å¤", trigger: "change" },], |
| | | inspector: [{ required: true, message: "请è¾å
¥å·¡æ£äºº", trigger: "blur" },], |
| | | dateStr: [{ required: true, message: "è¯·éæ©ç»è®°æ¶é´", trigger: "change" }] |
| | | } |
| | | }) |
| | | const { form, rules } = toRefs(data) |
| | |
| | | deviceOptions.value = data; |
| | | }; |
| | | |
| | | const setDeviceModel = (id) => { |
| | | const option = deviceOptions.value.find((item) => item.id === id); |
| | | if (option) { |
| | | form.value.taskName = option.deviceName; |
| | | const setDeviceModel = (ids) => { |
| | | if (!ids || ids.length === 0) { |
| | | form.value.taskIds = [] |
| | | form.value.taskName = undefined |
| | | return |
| | | } |
| | | |
| | | const selectedDevices = deviceOptions.value.filter((item) => ids.includes(item.id)) |
| | | if (selectedDevices.length > 0) { |
| | | form.value.taskIds = ids |
| | | form.value.taskName = selectedDevices.map(d => d.deviceName).join(',') |
| | | } |
| | | } |
| | | |
| | |
| | | form.value = {...row} |
| | | form.value.inspector = form.value.inspectorIds.split(',').map(Number) |
| | | |
| | | // 妿æè®¾å¤IDï¼èªå¨è®¾ç½®è®¾å¤ä¿¡æ¯ |
| | | if (form.value.taskId) { |
| | | setDeviceModel(form.value.taskId); |
| | | // 妿æè®¾å¤IDæ°ç»ï¼è½¬æ¢ä¸ºæ°ç»å¹¶è®¾ç½®è®¾å¤ä¿¡æ¯ |
| | | if (row.taskIds) { |
| | | form.value.taskIds = row.taskIds.split(',').map(id => parseInt(id.trim())) |
| | | setDeviceModel(form.value.taskIds) |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | // éç½®è¡¨åæ°æ®ç¡®ä¿è®¾å¤ä¿¡æ¯æ£ç¡®éç½® |
| | | form.value = { |
| | | taskId: undefined, |
| | | taskIds: [], |
| | | taskName: undefined, |
| | | inspector: '', |
| | | inspectorIds: '', |
| | |
| | | form.value.inspectorIds = form.value.inspector.join(',') |
| | | delete form.value.inspector |
| | | |
| | | // å¤ç taskIds å taskName |
| | | if (form.value.taskIds && Array.isArray(form.value.taskIds)) { |
| | | form.value.taskIds = form.value.taskIds.join(',') |
| | | } |
| | | |
| | | if (form.value.frequencyType === 'WEEKLY') { |
| | | let frequencyDetail = '' |
| | | frequencyDetail = form.value.week + ',' + form.value.time |
| | |
| | | |
| | | <!-- ç产å --> |
| | | <div class="form-container"> |
| | | <div class="title">ç产ä¸</div> |
| | | <div class="title">ç产å</div> |
| | | |
| | | <!-- å¾çå表 --> |
| | | <div style="display: flex; flex-wrap: wrap;"> |
| | |
| | | |
| | | <!-- ç产é®é¢ --> |
| | | <div class="form-container"> |
| | | <div class="title">ç产å</div> |
| | | <div class="title">ç产é®é¢</div> |
| | | |
| | | <!-- å¾çå表 --> |
| | | <div style="display: flex; flex-wrap: wrap;"> |
| | |
| | | |
| | | <!-- è§é¢ --> |
| | | <div v-else-if="mediaType === 'video'" style="position: relative;"> |
| | | <Video |
| | | <video |
| | | :src="mediaList[currentMediaIndex]" |
| | | autoplay |
| | | controls |
| | |
| | | <script setup> |
| | | import { ref } from 'vue'; |
| | | import VueEasyLightbox from 'vue-easy-lightbox'; |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | | // æ§å¶å¼¹çªæ¾ç¤º |
| | | const dialogVisitable = ref(false); |
| | |
| | | const currentMediaIndex = ref(0); |
| | | const mediaList = ref([]); // åå¨å½åè¦æ¥ççåªä½å表ï¼å«å¾çåè§é¢å¯¹è±¡ï¼ |
| | | const mediaType = ref('image'); // image | video |
| | | const javaApi = proxy.javaApi; |
| | | |
| | | // å¤ç URLï¼å° Windows è·¯å¾è½¬æ¢ä¸ºå¯è®¿é®ç URL |
| | | function processFileUrl(fileUrl) { |
| | | if (!fileUrl) return ''; |
| | | |
| | | // 妿 URL æ¯ Windows è·¯å¾æ ¼å¼ï¼å
å«åææ ï¼ï¼éè¦è½¬æ¢ |
| | | if (fileUrl && fileUrl.indexOf('\\') > -1) { |
| | | // æ¥æ¾ uploads å
³é®åçä½ç½®ï¼ä»é£éå¼å§æåç¸å¯¹è·¯å¾ |
| | | const uploadsIndex = fileUrl.toLowerCase().indexOf('uploads'); |
| | | if (uploadsIndex > -1) { |
| | | // ä» uploads å¼å§æåè·¯å¾ï¼å¹¶å°åææ æ¿æ¢ä¸ºæ£ææ |
| | | const relativePath = fileUrl.substring(uploadsIndex).replace(/\\/g, '/'); |
| | | fileUrl = '/' + relativePath; |
| | | } else { |
| | | // å¦ææ²¡ææ¾å° uploadsï¼æåæåä¸ä¸ªç®å½åæä»¶å |
| | | const parts = fileUrl.split('\\'); |
| | | const fileName = parts[parts.length - 1]; |
| | | fileUrl = '/uploads/' + fileName; |
| | | } |
| | | } |
| | | |
| | | // ç¡®ä¿ææé http å¼å¤´ç URL 齿¼æ¥ baseUrl |
| | | if (fileUrl && !fileUrl.startsWith('http')) { |
| | | // ç¡®ä¿è·¯å¾ä»¥ / å¼å¤´ |
| | | if (!fileUrl.startsWith('/')) { |
| | | fileUrl = '/' + fileUrl; |
| | | } |
| | | // æ¼æ¥ baseUrl |
| | | fileUrl = javaApi + fileUrl; |
| | | } |
| | | |
| | | return fileUrl; |
| | | } |
| | | |
| | | // å¤çæ¯ä¸ç±»æ°æ®ï¼å离å¾çåè§é¢ |
| | | function processItems(items) { |
| | | const images = []; |
| | | const videos = []; |
| | | |
| | | // æ£æ¥ items æ¯å¦åå¨ä¸ä¸ºæ°ç» |
| | | if (!items || !Array.isArray(items)) { |
| | | return { images, videos }; |
| | | } |
| | | |
| | | items.forEach(item => { |
| | | if (item.contentType?.startsWith('image/')) { |
| | | images.push(item.url); |
| | | } else if (item.contentType?.startsWith('video/')) { |
| | | videos.push(item.url); |
| | | if (!item || !item.url) return; |
| | | |
| | | // å¤çæä»¶ URL |
| | | const fileUrl = processFileUrl(item.url); |
| | | |
| | | // æ ¹æ®æä»¶æ©å±å夿æ¯å¾çè¿æ¯è§é¢ |
| | | const urlLower = fileUrl.toLowerCase(); |
| | | if (urlLower.match(/\.(jpg|jpeg|png|gif|bmp|webp)$/)) { |
| | | images.push(fileUrl); |
| | | } else if (urlLower.match(/\.(mp4|avi|mov|wmv|flv|mkv|webm)$/)) { |
| | | videos.push(fileUrl); |
| | | } else if (item.contentType) { |
| | | // 妿æ contentTypeï¼ä½¿ç¨ contentType 夿 |
| | | if (item.contentType.startsWith('image/')) { |
| | | images.push(fileUrl); |
| | | } else if (item.contentType.startsWith('video/')) { |
| | | videos.push(fileUrl); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | return { images, videos }; |
| | | } |
| | | |
| | | // æå¼å¼¹çªå¹¶å è½½æ°æ® |
| | | const openDialog = async (row) => { |
| | | const { images: beforeImgs, videos: beforeVids } = processItems(row.beforeProduction); |
| | | const { images: afterImgs, videos: afterVids } = processItems(row.afterProduction); |
| | | const { images: issueImgs, videos: issueVids } = processItems(row.productionIssues); |
| | | // ä½¿ç¨æ£ç¡®çåæ®µåï¼commonFileListBefore, commonFileListAfter |
| | | // productionIssues å¯è½ä¸åå¨ï¼ä½¿ç¨ç©ºæ°ç» |
| | | const { images: beforeImgs, videos: beforeVids } = processItems(row.commonFileListBefore || []); |
| | | const { images: afterImgs, videos: afterVids } = processItems(row.commonFileListAfter || []); |
| | | const { images: issueImgs, videos: issueVids } = processItems(row.productionIssues || []); |
| | | |
| | | beforeProductionImgs.value = beforeImgs; |
| | | beforeProductionVideos.value = beforeVids; |
| | |
| | | </el-space> |
| | | </div> |
| | | <div> |
| | | <div> |
| | | <PIMTable :table-loading="tableLoading" |
| | | :table-data="tableData" |
| | | :column="tableColumns" |
| | | @selection-change="handleSelectionChange" |
| | | @pagination="handlePagination" |
| | | :is-selection="true" |
| | | :border="true" |
| | | :table-style="{ width: '100%', height: 'calc(100vh - 23em)' }" |
| | | :page="{ |
| | | current: pageNum, |
| | | size: pageSize, |
| | | total: total, |
| | | layout: 'total, sizes, prev, pager, next, jumper' |
| | | }" |
| | | @pagination="pagination" |
| | | :table-style="{ width: '100%', height: 'calc(100vh - 23em)' }" |
| | | > |
| | | <template #inspector="{ row }"> |
| | | <div class="person-tags"> |
| | |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | <form-dia ref="formDia" @closeDia="handleQuery"></form-dia> |
| | | <view-files ref="viewFiles"></view-files> |
| | |
| | | import { ElMessageBox } from "element-plus"; |
| | | |
| | | // ç»ä»¶å¼å
¥ |
| | | import Pagination from "@/components/Pagination/index.vue"; |
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue"; |
| | | import FormDia from "@/views/equipmentManagement/inspectionManagement/components/formDia.vue"; |
| | | import ViewFiles from "@/views/equipmentManagement/inspectionManagement/components/viewFiles.vue"; |
| | |
| | | prop: "frequencyType", |
| | | label: "颿¬¡", |
| | | minWidth: 150, |
| | | formatData: (cell) => ({ |
| | | formatter: (_, __, val) => ({ |
| | | DAILY: "æ¯æ¥", |
| | | WEEKLY: "æ¯å¨", |
| | | MONTHLY: "æ¯æ", |
| | | QUARTERLY: "å£åº¦" |
| | | }[cell] || "") |
| | | }[val] || "") |
| | | }, |
| | | { |
| | | prop: "frequencyDetail", |
| | |
| | | } |
| | | }, |
| | | { prop: "registrant", label: "ç»è®°äºº", minWidth: 100 }, |
| | | { prop: "dateStr", label: "ç»è®°æ¥æ", minWidth: 100 }, |
| | | { prop: "createTime", label: "ç»è®°æ¥æ", minWidth: 100 }, |
| | | ]); |
| | | |
| | | // æä½åé
ç½® |
| | |
| | | operationsArr.value = ['edit']; |
| | | } else if (value === "task") { |
| | | const operationColumn = getOperationColumn(['viewFile']); |
| | | tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])]; |
| | | const statusColumn = { |
| | | prop: "status", |
| | | label: "ä»»å¡ç¶æ", |
| | | minWidth: 100, |
| | | dataType: "tag", |
| | | formatType: (row) => { |
| | | if (row.status === '已巡æ£') return 'success'; |
| | | return 'warning'; |
| | | } |
| | | }; |
| | | tableColumns.value = [...columns.value, statusColumn, ...(operationColumn ? [operationColumn] : [])]; |
| | | operationsArr.value = ['viewFile']; |
| | | } |
| | | pageNum.value = 1; |
| | |
| | | pageSize.value = 10; |
| | | getList(); |
| | | }; |
| | | const pagination = (obj) => { |
| | | pageNum.value = obj.page; |
| | | pageSize.value = obj.limit; |
| | | // å页å¤ç |
| | | const handlePagination = (val) => { |
| | | pageNum.value = val.page; |
| | | pageSize.value = val.limit; |
| | | getList(); |
| | | }; |
| | | // è·ååè¡¨æ°æ® |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¯ç¨ææ§" prop="enableDepreciation"> |
| | | <el-switch v-model="form.enableDepreciation" :active-value="true" :inactive-value="false" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ°é" prop="number"> |
| | | <el-input-number :min="1" style="width: 100%" |
| | | v-model="form.number" |
| | | disabled |
| | | placeholder="请è¾å
¥æ°é" |
| | | @change="mathNum" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å«ç¨åä»·" prop="taxIncludingPriceUnit"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" |
| | | <el-form-item label="èµäº§åå¼" prop="taxIncludingPriceUnit"> |
| | | <el-input-number :min="0" style="width: 100%" |
| | | :precision="2" |
| | | v-model="form.taxIncludingPriceUnit" |
| | | placeholder="请è¾å
¥å«ç¨åä»·" |
| | | placeholder="请è¾å
¥èµäº§åå¼" |
| | | maxlength="10" |
| | | @change="mathNum" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å«ç¨æ»ä»·" prop="taxIncludingPriceTotal"> |
| | | <el-input |
| | | v-model="form.taxIncludingPriceTotal" |
| | | placeholder="èªå¨çæ" |
| | | type="number" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¨ç(%)" prop="taxRate"> |
| | | <!-- <el-input |
| | | v-model="form.taxRate" |
| | | placeholder="请è¾å
¥ç¨ç" |
| | | type="number" |
| | | > |
| | | <template #append> % </template> |
| | | </el-input> --> |
| | | <el-select |
| | | v-model="form.taxRate" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | @change="mathNum" |
| | | > |
| | | <el-option label="1" :value="1" /> |
| | | <el-option label="6" :value="6" /> |
| | | <el-option label="13" :value="13" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¸å«ç¨æ»ä»·" prop="unTaxIncludingPriceTotal"> |
| | | <el-input |
| | | v-model="form.unTaxIncludingPriceTotal" |
| | | placeholder="èªå¨çæ" |
| | | type="number" |
| | | disabled |
| | | /> |
| | | <el-form-item label="å¯ç¨ææ§" prop="enableDepreciation"> |
| | | <el-switch v-model="form.enableDepreciation" :active-value="true" :inactive-value="false" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <!-- <el-col :span="12"> |
| | |
| | | // import useUserStore from "@/store/modules/user"; |
| | | import { getLedgerById } from "@/api/equipmentManagement/ledger"; |
| | | import dayjs from "dayjs"; |
| | | import { |
| | | calculateTaxIncludeTotalPrice, |
| | | calculateTaxExclusiveTotalPrice, |
| | | } from "@/utils/summarizeTable"; |
| | | import { ElMessage } from "element-plus"; |
| | | import {ref} from "vue"; |
| | | |
| | | defineOptions({ |
| | |
| | | const operationType = ref(''); |
| | | const formRules = { |
| | | deviceName: [{ required: true, trigger: "blur", message: "请è¾å
¥" }], |
| | | deviceModel: [{ required: true, trigger: "blur", message: "请è¾å
¥" }], |
| | | supplierName: [{ required: true, trigger: "blur", message: "请è¾å
¥" }], |
| | | unit: [{ required: true, trigger: "blur", message: "请è¾å
¥" }], |
| | | number: [{ required: true, trigger: "blur", message: "请è¾å
¥" }], |
| | | taxIncludingPriceUnit: [{ required: true, trigger: "blur", message: "请è¾å
¥" }], |
| | | taxRate: [{ required: true, trigger: "change", message: "请è¾å
¥" }], |
| | | planRuntimeTime: [{ required: true, trigger: "change", message: "è¯·éæ©" }], |
| | | deviceModel: [{ trigger: "blur", message: "请è¾å
¥" }], |
| | | supplierName: [{ trigger: "blur", message: "请è¾å
¥" }], |
| | | unit: [{ trigger: "blur", message: "请è¾å
¥" }], |
| | | taxIncludingPriceUnit: [ |
| | | { |
| | | required: true, |
| | | trigger: "blur", |
| | | validator: (rule, value, callback) => { |
| | | if (value === undefined || value === null || value === '') { |
| | | callback(new Error("请è¾å
¥èµäº§åå¼")); |
| | | } else if (typeof value === 'number' && value >= 0) { |
| | | callback(); |
| | | } else { |
| | | callback(new Error("请è¾å
¥ææçèµäº§åå¼")); |
| | | } |
| | | } |
| | | } |
| | | ], |
| | | planRuntimeTime: [{ trigger: "change", message: "è¯·éæ©" }], |
| | | } |
| | | |
| | | const { form, resetForm } = useFormData({ |
| | |
| | | enableDepreciation: false, // æ¯å¦å¯ç¨ææ§ |
| | | unit: undefined, // åä½ |
| | | number: 1, // æ°é |
| | | taxIncludingPriceUnit: undefined, // å«ç¨åä»· |
| | | taxIncludingPriceTotal: undefined, // å«ç¨æ»ä»· |
| | | taxRate: undefined, // ç¨ç |
| | | unTaxIncludingPriceTotal: undefined, // ä¸å«ç¨æ»ä»· |
| | | taxIncludingPriceUnit: undefined, // èµäº§åå¼ |
| | | // createUser: useUserStore().nickName, // å½å
¥äºº |
| | | createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // å½å
¥æ¥æ |
| | | planRuntimeTime: dayjs().format("YYYY-MM-DD"), // å½å
¥æ¥æ |
| | |
| | | form.unit = data.unit; |
| | | form.number = 1; |
| | | form.taxIncludingPriceUnit = data.taxIncludingPriceUnit; |
| | | form.taxIncludingPriceTotal = data.taxIncludingPriceTotal; |
| | | form.taxRate = data.taxRate; |
| | | form.unTaxIncludingPriceTotal = data.unTaxIncludingPriceTotal; |
| | | form.createTime = data.createTime; |
| | | } |
| | | }; |
| | | |
| | | const mathNum = () => { |
| | | if (!form.taxIncludingPriceUnit) { |
| | | ElMessage.error("请è¾å
¥åä»·"); |
| | | return; |
| | | } |
| | | form.taxIncludingPriceTotal = calculateTaxIncludeTotalPrice( |
| | | form.taxIncludingPriceUnit, |
| | | form.number |
| | | ); |
| | | if (form.taxRate) { |
| | | form.unTaxIncludingPriceTotal = calculateTaxExclusiveTotalPrice( |
| | | form.taxIncludingPriceTotal, |
| | | form.taxRate |
| | | ); |
| | | } |
| | | }; |
| | | |
| | | |
| | | // æ¸
é¤è¡¨åæ ¡éªç¶æ |
| | | const clearValidate = () => { |
| | |
| | | <template> |
| | | <el-dialog :title="modalOptions.title" v-model="visible" @close="close" draggable> |
| | | <el-dialog :title="modalOptions.title" v-model="visible" @close="close"> |
| | | <Form ref="formRef"></Form> |
| | | <template #footer> |
| | | <el-button type="primary" @click="sendForm" :loading="loading"> |
| | |
| | | <div></div> |
| | | <div> |
| | | <el-button type="primary" @click="add" icon="Plus"> æ°å¢ </el-button> |
| | | <el-button plain icon="Upload" @click="handleImport">导å
¥</el-button> |
| | | <el-button @click="handleOut" icon="download">导åº</el-button> |
| | | <el-button |
| | | type="danger" |
| | |
| | | </PIMTable> |
| | | </div> |
| | | <Modal ref="modalRef" @success="getTableData"></Modal> |
| | | <el-dialog v-model="qrDialogVisible" title="äºç»´ç " width="300px" draggable> |
| | | <el-dialog v-model="qrDialogVisible" title="äºç»´ç " width="300px"> |
| | | <div style="text-align:center;"> |
| | | <img :src="qrCodeUrl" alt="äºç»´ç " style="width:200px;height:200px;" /> |
| | | <div style="margin-top:6px;font-size:14px;color:#333;">{{ qrRowData?.deviceName }}</div> |
| | | <div style="margin:10px 0;"> |
| | | <el-button type="primary" @click="downloadQRCode">ä¸è½½äºç»´ç å¾ç</el-button> |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | | <!-- ç¨æ·å¯¼å
¥å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | :title="upload.title" |
| | | v-model="upload.open" |
| | | width="400px" |
| | | append-to-body |
| | | > |
| | | <el-upload |
| | | ref="uploadRef" |
| | | :limit="1" |
| | | accept=".xlsx, .xls" |
| | | :headers="upload.headers" |
| | | :action="upload.url + '?updateSupport=' + upload.updateSupport" |
| | | :disabled="upload.isUploading" |
| | | :before-upload="upload.beforeUpload" |
| | | :on-progress="upload.onProgress" |
| | | :on-success="upload.onSuccess" |
| | | :on-error="upload.onError" |
| | | :on-change="upload.onChange" |
| | | :auto-upload="false" |
| | | drag |
| | | > |
| | | <el-icon class="el-icon--upload"><upload-filled /></el-icon> |
| | | <div class="el-upload__text">å°æä»¶æå°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> |
| | | <template #tip> |
| | | <div class="el-upload__tip text-center"> |
| | | <span>ä»
å
许导å
¥xlsãxlsxæ ¼å¼æä»¶ã</span> |
| | | <el-link |
| | | type="primary" |
| | | :underline="false" |
| | | style="font-size: 12px; vertical-align: baseline" |
| | | @click="importTemplate" |
| | | >ä¸è½½æ¨¡æ¿</el-link |
| | | > |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitFileForm">ç¡® å®</el-button> |
| | | <el-button @click="upload.open = false">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | import dayjs from "dayjs"; |
| | | import QRCode from "qrcode"; |
| | | import { ref } from "vue"; |
| | | import { getToken } from "@/utils/auth.js"; |
| | | |
| | | defineOptions({ |
| | | name: "设å¤å°è´¦", |
| | |
| | | prop: "number", |
| | | }, |
| | | { |
| | | label: "å«ç¨åä»·", |
| | | label: "èµäº§åå¼", |
| | | align: "center", |
| | | prop: "taxIncludingPriceUnit", |
| | | }, |
| | | { |
| | | label: "å«ç¨æ»ä»·", |
| | | align: "center", |
| | | prop: "taxIncludingPriceTotal", |
| | | }, |
| | | { |
| | | label: "ç¨ç", |
| | | align: "center", |
| | | prop: "taxRate", |
| | | }, |
| | | { |
| | | label: "ä¸å«ç¨æ»ä»·", |
| | | align: "center", |
| | | prop: "unTaxIncludingPriceTotal", |
| | | }, |
| | | { |
| | | label: "å¯ç¨ææ§", |
| | |
| | | }, |
| | | ] |
| | | ); |
| | | |
| | | const upload = reactive({ |
| | | // æ¯å¦æ¾ç¤ºå¼¹åºå±ï¼å®¢æ·å¯¼å
¥ï¼ |
| | | open: false, |
| | | // å¼¹åºå±æ é¢ï¼å®¢æ·å¯¼å
¥ï¼ |
| | | title: "", |
| | | // æ¯å¦ç¦ç¨ä¸ä¼ |
| | | isUploading: false, |
| | | // 设置ä¸ä¼ ç请æ±å¤´é¨ |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | // ä¸ä¼ çå°å |
| | | url: import.meta.env.VITE_APP_BASE_API + "/device/ledger/import", |
| | | // æä»¶ä¸ä¼ åçåè° |
| | | beforeUpload: (file) => { |
| | | console.log('æä»¶å³å°ä¸ä¼ ', file); |
| | | // å¯ä»¥å¨æ¤å¤åæä»¶ç±»åæå¤§å°æ ¡éª |
| | | const isValid = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.name.endsWith('.xlsx') || file.name.endsWith('.xls'); |
| | | if (!isValid) { |
| | | proxy.$modal.msgError("åªè½ä¸ä¼ Excel æä»¶"); |
| | | } |
| | | return isValid; |
| | | }, |
| | | // æä»¶ç¶ææ¹åæ¶çåè° |
| | | onChange: (file, fileList) => { |
| | | console.log('æä»¶ç¶ææ¹å', file, fileList); |
| | | }, |
| | | // æä»¶ä¸ä¼ æåæ¶çåè° |
| | | onSuccess: (response, file, fileList) => { |
| | | console.log('ä¸ä¼ æå', response, file, fileList); |
| | | upload.isUploading = false; |
| | | if(response.code === 200){ |
| | | proxy.$modal.msgSuccess("æä»¶ä¸ä¼ æå"); |
| | | upload.open = false; |
| | | proxy.$refs["uploadRef"].clearFiles(); |
| | | getTableData(); |
| | | }else if(response.code === 500){ |
| | | proxy.$modal.msgError(response.msg); |
| | | }else{ |
| | | proxy.$modal.msgWarning(response.msg); |
| | | } |
| | | }, |
| | | // æä»¶ä¸ä¼ 失败æ¶çåè° |
| | | onError: (error, file, fileList) => { |
| | | console.error('ä¸ä¼ 失败', error, file, fileList); |
| | | upload.isUploading = false; |
| | | proxy.$modal.msgError("æä»¶ä¸ä¼ 失败"); |
| | | }, |
| | | // æä»¶ä¸ä¼ è¿åº¦åè° |
| | | onProgress: (event, file, fileList) => { |
| | | console.log('ä¸ä¼ ä¸...', event.percent); |
| | | } |
| | | }); |
| | | |
| | | /** æäº¤ä¸ä¼ æä»¶ */ |
| | | const submitFileForm = () => { |
| | | upload.isUploading = true; |
| | | proxy.$refs["uploadRef"].submit(); |
| | | } |
| | | |
| | | /** ä¸è½½æ¨¡æ¿ */ |
| | | const importTemplate = () => { |
| | | proxy.download("/device/ledger/downloadTemplate", {}, "设å¤å°è´¦æ¨¡æ¿.xlsx"); |
| | | } |
| | | |
| | | // å¤éååä»ä¹ |
| | | const handleSelectionChange = (selectionList) => { |
| | |
| | | } |
| | | getTableData(); |
| | | }; |
| | | /** 导å
¥æé®æä½ */ |
| | | const handleImport = () => { |
| | | upload.title = "设å¤å°è´¦å¯¼å
¥"; |
| | | upload.open = true; |
| | | } |
| | | |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | |
| | | }; |
| | | |
| | | const downloadQRCode = () => { |
| | | const name = qrRowData.value?.deviceName || "äºç»´ç "; |
| | | const img = new Image(); |
| | | img.src = qrCodeUrl.value; |
| | | img.onload = () => { |
| | | const padding = 10; |
| | | const qrSize = 200; |
| | | const textHeight = 24; // space for text |
| | | const width = qrSize + padding * 2; |
| | | const height = qrSize + padding * 2 + textHeight; |
| | | const canvas = document.createElement("canvas"); |
| | | canvas.width = width; |
| | | canvas.height = height; |
| | | const ctx = canvas.getContext("2d"); |
| | | // background |
| | | ctx.fillStyle = "#ffffff"; |
| | | ctx.fillRect(0, 0, width, height); |
| | | // draw QR centered |
| | | ctx.drawImage(img, padding, padding, qrSize, qrSize); |
| | | // draw name centered below |
| | | ctx.fillStyle = "#333"; |
| | | ctx.font = "14px Arial"; |
| | | ctx.textAlign = "center"; |
| | | ctx.textBaseline = "middle"; |
| | | const maxTextWidth = width - padding * 2; |
| | | let displayName = name; |
| | | // ellipsis if too long |
| | | while (ctx.measureText(displayName).width > maxTextWidth && displayName.length > 0) { |
| | | displayName = displayName.slice(0, -1); |
| | | } |
| | | if (displayName !== name) displayName = displayName + "â¦"; |
| | | ctx.fillText(displayName, width / 2, qrSize + padding + textHeight / 2); |
| | | |
| | | const dataUrl = canvas.toDataURL("image/png"); |
| | | const a = document.createElement("a"); |
| | | a.href = qrCodeUrl.value; |
| | | a.download = `${qrRowData.value.deviceName || "äºç»´ç "}.png`; |
| | | a.href = dataUrl; |
| | | a.download = `${name}.png`; |
| | | a.click(); |
| | | }; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getTableData(); |
| | |
| | | v-model="dialogFormVisible" |
| | | title="计éå¨å
·" |
| | | width="50%" |
| | | draggable |
| | | @close="closeDia" |
| | | > |
| | | <el-form |
| | |
| | | <el-select |
| | | v-model="form.userId" |
| | | placeholder="è¯·éæ©" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | disabled |
| | | clearable |
| | | > |
| | | <el-option |
| | |
| | | import {getToken} from "@/utils/auth.js"; |
| | | import {ledgerRecordUpdate, ledgerRecordVerifying} from "@/api/equipmentManagement/calibration.js"; |
| | | import {delLedgerFile} from "@/api/salesManagement/salesLedger.js"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | const dialogFormVisible = ref(false); |
| | |
| | | dialogFormVisible.value = false; |
| | | emit('close') |
| | | }; |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); // æä»½ä»0å¼å§ |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| | |
| | | v-model="dialogFormVisible" |
| | | title="计éå¨å
·" |
| | | width="50%" |
| | | draggable |
| | | @close="closeDia" |
| | | > |
| | | <el-form |
| | |
| | | v-model="form.userId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | disabled |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | |
| | | import {afterSalesServiceAdd, afterSalesServiceUpdate} from "@/api/customerService/index.js"; |
| | | import {getToken} from "@/utils/auth.js"; |
| | | import {measuringInstrumentAdd, measuringInstrumentUpdate} from "@/api/equipmentManagement/measurementEquipment.js"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | const dialogFormVisible = ref(false); |
| | |
| | | dialogFormVisible.value = false; |
| | | emit('close') |
| | | }; |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); // æä»½ä»0å¼å§ |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| | |
| | | openCalibrationDia("verifying", row); |
| | | }, |
| | | }, |
| | | // { |
| | | // name: "éä»¶", |
| | | // type: "text", |
| | | // clickFun: (row) => { |
| | | // openFilesFormDia(row); |
| | | // }, |
| | | // }, |
| | | { |
| | | name: "éä»¶", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openFilesFormDia(row); |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | ]); |
| | |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | // æ£æ¥æ¯å¦æä»äººç»´æ¤çæ°æ® |
| | | const unauthorizedData = selectedRows.value.filter(item => item.userId !== userStore.id); |
| | | if (unauthorizedData.length > 0) { |
| | | proxy.$modal.msgWarning("ä¸å¯å é¤ä»äººç»´æ¤çæ°æ®"); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <FormDialog |
| | | v-model="visible" |
| | | title="æ¥ä¿®å®¡æ¹" |
| | | width="800px" |
| | | @confirm="handleSubmit" |
| | | @cancel="handleClose" |
| | | @close="handleClose" |
| | | > |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions-item label="设å¤åç§°"> |
| | | {{ detail.deviceName || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="è§æ ¼åå·"> |
| | | {{ detail.deviceModel || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="æ¥ä¿®æ¥æ"> |
| | | {{ detail.repairTime || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="æ¥ä¿®äºº"> |
| | | {{ detail.repairName || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="审æ¹äºº"> |
| | | {{ detail.auditName || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="å½åç¶æ"> |
| | | {{ statusText(detail.status) }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="æ
éç°è±¡" :span="2"> |
| | | {{ detail.remark || "-" }} |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | <div style="margin-top: 16px"> |
| | | <el-form ref="formRef" :model="form" :rules="rules" label-width="100px"> |
| | | <el-form-item label="审æ¹ç»æ" prop="decision"> |
| | | <el-radio-group v-model="form.decision"> |
| | | <el-radio :value="0">éè¿</el-radio> |
| | | <el-radio :value="3">ä¸éè¿</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="çç£äºº" prop="supervisoryName"> |
| | | <el-input v-model="form.supervisoryName" placeholder="请è¾å
¥çç£äºº" clearable style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { nextTick, ref } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { editRepair, getRepairById } from "@/api/equipmentManagement/repair"; |
| | | |
| | | defineOptions({ |
| | | name: "æ¥ä¿®å®¡æ¹å¼¹çª", |
| | | }); |
| | | |
| | | const emits = defineEmits(["ok"]); |
| | | |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | const id = ref(); |
| | | const detail = ref({}); |
| | | const formRef = ref(); |
| | | const form = ref({ |
| | | decision: undefined, // 0 éè¿ 3 ä¸éè¿ |
| | | supervisoryName: undefined, // çç£äºº |
| | | }); |
| | | |
| | | const rules = { |
| | | decision: [{ required: true, message: "è¯·éæ©å®¡æ¹ç»æ", trigger: "change" }], |
| | | supervisoryName: [{ required: true, message: "è¯·éæ©çç£äºº", trigger: "change" }], |
| | | }; |
| | | |
| | | const statusText = (status) => { |
| | | const map = { |
| | | 0: "å¾
ç»´ä¿®", |
| | | 1: "å®ç»", |
| | | 2: "å¾
å®¡æ ¸", |
| | | 3: "å®¡æ ¸ä¸éè¿", |
| | | }; |
| | | return map[status] ?? "-"; |
| | | }; |
| | | |
| | | const loadDetail = async (repairId) => { |
| | | const { data } = await getRepairById(repairId); |
| | | detail.value = data ?? {}; |
| | | }; |
| | | |
| | | const open = async (repairId) => { |
| | | id.value = repairId; |
| | | visible.value = true; |
| | | await nextTick(); |
| | | await loadDetail(repairId); |
| | | form.value.decision = undefined; |
| | | form.value.supervisoryName = undefined; |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | visible.value = false; |
| | | id.value = undefined; |
| | | detail.value = {}; |
| | | form.value.decision = undefined; |
| | | form.value.supervisoryName = undefined; |
| | | }; |
| | | |
| | | const updateStatus = async (status) => { |
| | | loading.value = true; |
| | | try { |
| | | const { code } = await editRepair({ id: id.value, status, supervisoryName: form.value.supervisoryName }); |
| | | if (code === 200) { |
| | | ElMessage.success("å®¡æ¹æå"); |
| | | emits("ok"); |
| | | handleClose(); |
| | | } |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const handleSubmit = async () => { |
| | | if (detail.value?.status !== 2) { |
| | | ElMessage.warning("ä»
å¾
å®¡æ ¸ç¶æå¯å®¡æ¹"); |
| | | return; |
| | | } |
| | | await formRef.value?.validate(async (valid) => { |
| | | if (!valid) return; |
| | | const isApprove = form.value.decision === 0; |
| | | ElMessageBox.confirm(`确认审æ¹${isApprove ? "éè¿" : "ä¸éè¿"}ï¼`, "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(() => updateStatus(form.value.decision)); |
| | | }); |
| | | }; |
| | | |
| | | defineExpose({ open }); |
| | | </script> |
| | | |
| | | <style scoped></style> |
| | | |
| | |
| | | <template> |
| | | <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr" draggable> |
| | | <MaintainForm ref="maintainFormRef" /> |
| | | <template #footer> |
| | | <el-button type="primary" @click="sendForm" :loading="loading"> |
| | | {{ modalOptions.confirmText }} |
| | | </el-button> |
| | | <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | <FormDialog |
| | | v-model="visible" |
| | | :title="'设å¤ç»´ä¿®'" |
| | | width="500px" |
| | | @confirm="sendForm" |
| | | @cancel="handleCancel" |
| | | @close="handleClose" |
| | | > |
| | | <el-form :model="form" :rules="rules" label-width="110px" ref="formRef"> |
| | | <el-form-item label="维修人" prop="maintenanceName"> |
| | | <el-input v-model="form.maintenanceName" placeholder="请è¾å
¥ç»´ä¿®äºº" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç»´ä¿®ç»æ" prop="maintenanceResult"> |
| | | <el-input v-model="form.maintenanceResult" placeholder="请è¾å
¥ç»´ä¿®ç»æ" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¬æ¬¡ç»´ä¿®éé¢" prop="repairPrice"> |
| | | <el-input-number v-model="form.repairPrice" :min="0" :precision="2" style="width: 100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç»´ä¿®æ¥æ" prop="maintenanceTime"> |
| | | <el-date-picker |
| | | v-model="form.maintenanceTime" |
| | | placeholder="è¯·éæ©ç»´ä¿®æ¥æ" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="datetime" |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { useModal } from "@/hooks/useModal"; |
| | | import MaintainForm from "../Form/MaintainForm.vue"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { addMaintain } from "@/api/equipmentManagement/repair"; |
| | | import useFormData from "@/hooks/useFormData"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import dayjs from "dayjs"; |
| | | import { ElMessage } from "element-plus"; |
| | | |
| | | defineOptions({ |
| | | name: "ç»´ä¿®æ¨¡ææ¡", |
| | | }); |
| | | |
| | | const maintainFormRef = ref(); |
| | | const emits = defineEmits(["ok"]); |
| | | |
| | | const { |
| | | id, |
| | | visible, |
| | | loading, |
| | | openModal, |
| | | modalOptions, |
| | | handleConfirm, |
| | | closeModal, |
| | | } = useModal({ title: "设å¤ç»´ä¿®" }); |
| | | // ä¿åæ¥ä¿®è®°å½çid |
| | | const repairId = ref(); |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | const formRef = ref(); |
| | | |
| | | const userStore = useUserStore(); |
| | | const { form, resetForm } = useFormData({ |
| | | maintenanceName: undefined, // ç»´ä¿®åç§° |
| | | maintenanceResult: undefined, // ç»´ä¿®ç»æ |
| | | maintenanceTime: undefined, // ç»´ä¿®æ¥æ |
| | | repairPrice: undefined, // ç»´ä¿®éé¢ |
| | | status: 0, |
| | | }); |
| | | |
| | | const rules = { |
| | | maintenanceName: [{ required: true, message: "请è¾å
¥ç»´ä¿®äºº", trigger: "blur" }], |
| | | maintenanceResult: [{ required: true, message: "请è¾å
¥ç»´ä¿®ç»æ", trigger: "blur" }], |
| | | repairPrice: [{ required: true, message: "请è¾å
¥æ¬æ¬¡ç»´ä¿®éé¢", trigger: "change" }], |
| | | maintenanceTime: [{ required: true, message: "è¯·éæ©ç»´ä¿®æ¥æ", trigger: "change" }], |
| | | }; |
| | | |
| | | const setForm = (data) => { |
| | | form.maintenanceName = data.maintenanceName ?? userStore.nickName; |
| | | form.maintenanceResult = data.maintenanceResult; |
| | | form.maintenanceTime = |
| | | data.maintenanceTime |
| | | ? dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss") |
| | | : dayjs().format("YYYY-MM-DD HH:mm:ss"); |
| | | form.status = 2; // ç»´ä¿®ååºå®è¿å
¥å¾
å®¡æ ¸ï¼ä¸å¨çé¢å±ç¤ºï¼ |
| | | }; |
| | | |
| | | const sendForm = async () => { |
| | | await formRef.value.validate(async (valid) => { |
| | | if (!valid) return; |
| | | loading.value = true; |
| | | const form = await maintainFormRef.value.getForm(); |
| | | const { code } = await addMaintain({ id: id.value, ...form }); |
| | | try { |
| | | const { code } = await addMaintain({ id: repairId.value, ...form }); |
| | | if (code == 200) { |
| | | ElMessage.success("ç»´ä¿®æå"); |
| | | emits("ok"); |
| | | maintainFormRef.value.resetForm(); |
| | | closeModal(); |
| | | resetForm(); |
| | | visible.value = false; |
| | | } |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }) |
| | | }; |
| | | |
| | | const handleCancel = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const open = async (id, row) => { |
| | | openModal(id); |
| | | repairId.value = id; // ä¿åæ¥ä¿®è®°å½çid |
| | | visible.value = true; |
| | | await nextTick(); |
| | | maintainFormRef.value.setForm(row); |
| | | setForm(row); |
| | | }; |
| | | |
| | | defineExpose({ |
| | |
| | | <template> |
| | | <el-dialog v-model="visible" :title="modalOptions.title" @close="close" draggable> |
| | | <RepairForm ref="repairFormRef" :id="id" /> |
| | | <template #footer> |
| | | <el-button type="primary" @click="sendForm" :loading="loading"> |
| | | {{ modalOptions.confirmText }} |
| | | </el-button> |
| | | <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | <FormDialog |
| | | v-model="visible" |
| | | :title="id ? 'ç¼è¾è®¾å¤æ¥ä¿®' : 'æ°å¢è®¾å¤æ¥ä¿®'" |
| | | width="800px" |
| | | @confirm="sendForm" |
| | | @cancel="handleCancel" |
| | | @close="handleClose" |
| | | > |
| | | <el-form :model="form" :rules="rules" label-width="100px" ref="formRef"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设å¤åç§°"> |
| | | <el-select v-model="form.deviceLedgerId" @change="setDeviceModel" filterable> |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | | :label="item.deviceName" |
| | | :value="item.id" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼åå·"> |
| | | <el-input |
| | | v-model="form.deviceModel" |
| | | placeholder="请è¾å
¥è§æ ¼åå·" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥ä¿®æ¥æ"> |
| | | <el-date-picker |
| | | v-model="form.repairTime" |
| | | placeholder="è¯·éæ©æ¥ä¿®æ¥æ" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | type="date" |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥ä¿®äºº"> |
| | | <el-input v-model="form.repairName" placeholder="请è¾å
¥æ¥ä¿®äºº" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="审æ¹äºº" prop="auditName"> |
| | | <el-select |
| | | v-model="form.auditName" |
| | | placeholder="è¯·éæ©å®¡æ¹äºº" |
| | | filterable |
| | | clearable |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="user in userOptions" |
| | | :key="user.userId" |
| | | :label="user.nickName" |
| | | :value="user.nickName" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row v-if="id"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥ä¿®ç¶æ"> |
| | | <el-select v-model="form.status"> |
| | | <el-option label="å¾
ç»´ä¿®" :value="0"></el-option> |
| | | <el-option label="å®ç»" :value="1"></el-option> |
| | | <el-option label="å¾
å®¡æ ¸" :value="2"></el-option> |
| | | <el-option label="å®¡æ ¸ä¸éè¿" :value="3"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="æ
éç°è±¡"> |
| | | <el-input |
| | | v-model="form.remark" |
| | | :rows="2" |
| | | type="textarea" |
| | | placeholder="请è¾å
¥æ
éç°è±¡" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { useModal } from "@/hooks/useModal"; |
| | | import RepairForm from "../Form/RepairForm.vue"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { |
| | | addRepair, |
| | | editRepair, |
| | | getRepairById, |
| | | } from "@/api/equipmentManagement/repair"; |
| | | import { ElMessage } from "element-plus"; |
| | | import dayjs from "dayjs"; |
| | | import useFormData from "@/hooks/useFormData"; |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { userListNoPageByTenantId } from "@/api/system/user"; |
| | | |
| | | defineOptions({ |
| | | name: "è®¾å¤æ¥ä¿®å¼¹çª", |
| | |
| | | |
| | | const emits = defineEmits(["ok"]); |
| | | |
| | | const repairFormRef = ref(); |
| | | const { |
| | | id, |
| | | visible, |
| | | loading, |
| | | openModal, |
| | | modalOptions, |
| | | handleConfirm, |
| | | closeModal, |
| | | } = useModal({ title: "è®¾å¤æ¥ä¿®" }); |
| | | const id = ref(); |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | const formRef = ref(); |
| | | |
| | | const userStore = useUserStore(); |
| | | const deviceOptions = ref([]); |
| | | const userOptions = ref([]); |
| | | |
| | | const loadDeviceName = async () => { |
| | | const { data } = await getDeviceLedger(); |
| | | deviceOptions.value = data; |
| | | }; |
| | | |
| | | const loadUserOptions = async () => { |
| | | const res = await userListNoPageByTenantId(); |
| | | userOptions.value = res?.data ?? []; |
| | | }; |
| | | |
| | | const { form, resetForm } = useFormData({ |
| | | deviceLedgerId: undefined, // 设å¤Id |
| | | deviceName: undefined, // 设å¤åç§° |
| | | deviceModel: undefined, // è§æ ¼åå· |
| | | repairTime: dayjs().format("YYYY-MM-DD"), // æ¥ä¿®æ¥æï¼é»è®¤å½å¤© |
| | | repairName: userStore.nickName, // æ¥ä¿®äºº |
| | | auditName: undefined, // 审æ¹äºº |
| | | remark: undefined, // æ
éç°è±¡ |
| | | status: 0, // æ¥ä¿®ç¶æ |
| | | }); |
| | | |
| | | const rules = { |
| | | auditName: [ |
| | | { required: true, message: "è¯·éæ©å®¡æ¹äºº", trigger: "change" }, |
| | | ], |
| | | }; |
| | | |
| | | const setDeviceModel = (deviceId) => { |
| | | const option = deviceOptions.value.find((item) => item.id === deviceId); |
| | | form.deviceModel = option.deviceModel; |
| | | }; |
| | | |
| | | const setForm = (data) => { |
| | | form.deviceLedgerId = data.deviceLedgerId; |
| | | form.deviceName = data.deviceName; |
| | | form.deviceModel = data.deviceModel; |
| | | form.repairTime = data.repairTime; |
| | | form.repairName = data.repairName; |
| | | form.auditName = data.auditName; |
| | | form.remark = data.remark; |
| | | form.status = data.status; |
| | | }; |
| | | |
| | | const sendForm = async () => { |
| | | try { |
| | | // å¼å§å è½½ |
| | | await formRef.value?.validate(async (valid) => { |
| | | if (!valid) return; |
| | | loading.value = true; |
| | | // æäº¤è¡¨åå¹¶è·åæ ¡éªç»æ |
| | | const submitStatus = await repairFormRef.value.submitForm(); |
| | | if (!submitStatus) { |
| | | // å¦æè¡¨åéªè¯å¤±è´¥ï¼åæ¶å è½½ç¶æ |
| | | loading.value = false; |
| | | return; |
| | | } |
| | | // è·åè¡¨åæ°æ® |
| | | const form = await repairFormRef.value.getForm(); |
| | | // æ ¹æ®æ¯å¦æIDå³å®æ¯ç¼è¾è¿æ¯æ°å¢ |
| | | try { |
| | | const { code } = id.value |
| | | ? await editRepair({ id: unref(id), ...form }) |
| | | : await addRepair(form); |
| | | if (code === 200) { |
| | | ElMessage.success(`${id ? "ç¼è¾" : "æ°å¢"}æ¥ä¿®æå`); |
| | | if (code == 200) { |
| | | ElMessage.success(`${id.value ? "ç¼è¾" : "æ°å¢"}æ¥ä¿®æå`); |
| | | visible.value = false; |
| | | emits("ok"); |
| | | } |
| | | } catch (error) { |
| | | } finally { |
| | | // æ 论æåè¿æ¯å¤±è´¥ï¼é½åæ¶å è½½ç¶æ |
| | | loading.value = false; |
| | | closeModal(); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const handleCancel = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const openAdd = async () => { |
| | | openModal(); |
| | | id.value = undefined; |
| | | visible.value = true; |
| | | await nextTick(); |
| | | await repairFormRef.value.loadDeviceName(); |
| | | await Promise.all([loadDeviceName(), loadUserOptions()]); |
| | | }; |
| | | |
| | | const openEdit = async (id) => { |
| | | const { data } = await getRepairById(id); |
| | | openModal(id); |
| | | const openEdit = async (editId) => { |
| | | const { data } = await getRepairById(editId); |
| | | id.value = editId; |
| | | visible.value = true; |
| | | await nextTick(); |
| | | await repairFormRef.value.loadDeviceName(); |
| | | await repairFormRef.value.setForm(data); |
| | | }; |
| | | |
| | | const close = () => { |
| | | repairFormRef.value.resetForm(); |
| | | closeModal(); |
| | | await Promise.all([loadDeviceName(), loadUserOptions()]); |
| | | setForm(data); |
| | | }; |
| | | |
| | | defineExpose({ |
| | |
| | | openEdit, |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped></style> |
| | |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥è®¾å¤åç§°" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @change="getTableData" |
| | | /> |
| | | </el-form-item> |
| | |
| | | <el-input |
| | | v-model="filters.deviceModel" |
| | | style="width: 240px" |
| | | placeholder="è¯·éæ©è§æ ¼åå·" |
| | | placeholder="请è¾å
¥è§æ ¼åå·" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @change="getTableData" |
| | | /> |
| | | </el-form-item> |
| | |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥æ
éç°è±¡" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @change="getTableData" |
| | | /> |
| | | </el-form-item> |
| | |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥ç»´ä¿®äºº" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @change="getTableData" |
| | | /> |
| | | </el-form-item> |
| | |
| | | <div class="actions"> |
| | | <el-text class="mx-1" size="large">è®¾å¤æ¥ä¿®</el-text> |
| | | <div> |
| | | <el-button |
| | | type="primary" |
| | | icon="Plus" |
| | | :disabled="multipleList.length !== 1 || multipleList[0]?.status !== 1" |
| | | @click="addMaintain" |
| | | > |
| | | |
| | | æ°å¢ç»´ä¿® |
| | | </el-button> |
| | | <el-button type="success" icon="Van" @click="addRepair"> |
| | | æ°å¢æ¥ä¿® |
| | | </el-button> |
| | |
| | | <el-button |
| | | type="danger" |
| | | icon="Delete" |
| | | :disabled="multipleList.length <= 0" |
| | | @click="delRepairByIds(multipleList)" |
| | | :disabled="multipleList.length <= 0 || hasFinishedStatus" |
| | | @click="delRepairByIds(multipleList.map((item) => item.id))" |
| | | > |
| | | æ¹éå é¤ |
| | | </el-button> |
| | |
| | | @pagination="changePage" |
| | | > |
| | | <template #statusRef="{ row }"> |
| | | <el-tag v-if="row.status === 5" type="danger">维修失败</el-tag> |
| | | <el-tag v-if="row.status === 4" type="danger">ç»´ä¿®æå</el-tag> |
| | | <el-tag v-if="row.status === 3" type="danger">ç»´ä¿®ä¸</el-tag> |
| | | <el-tag v-if="row.status === 2" type="danger">å®¡æ ¸å¤±è´¥</el-tag> |
| | | <el-tag v-if="row.status === 1" type="success">å®¡æ ¸éè¿</el-tag> |
| | | <el-tag v-if="row.status === 0" type="warning">å®¡æ ¸ä¸</el-tag> |
| | | <el-tag v-if="row.status === 0" type="warning">å¾
ç»´ä¿®</el-tag> |
| | | <el-tag v-else-if="row.status === 1" type="success">å®ç»</el-tag> |
| | | <el-tag v-else-if="row.status === 2" type="info">å¾
å®¡æ ¸</el-tag> |
| | | <el-tag v-else-if="row.status === 3" type="danger">å®¡æ ¸ä¸éè¿</el-tag> |
| | | </template> |
| | | <template #operation="{ row }"> |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | icon="editPen" |
| | | link |
| | | :disabled="row.status === 1" |
| | | @click="editRepair(row.id)" |
| | | :disabled="row.status !== 0" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | text |
| | | icon="delete" |
| | | @click="delRepairByIds(row)" |
| | | type="warning" |
| | | link |
| | | :disabled="row.status !== 2" |
| | | @click="openApprove(row.id)" |
| | | > |
| | | å®¡æ¹ |
| | | </el-button> |
| | | <el-button |
| | | type="success" |
| | | link |
| | | :disabled="row.status !== 0" |
| | | @click="addMaintain(row)" |
| | | > |
| | | ç»´ä¿® |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | link |
| | | :disabled="row.status === 1" |
| | | @click="delRepairByIds(row.id)" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | |
| | | </div> |
| | | <RepairModal ref="repairModalRef" @ok="getTableData" /> |
| | | <MaintainModal ref="maintainModalRef" @ok="getTableData" /> |
| | | <ApproveModal ref="approveModalRef" @ok="getTableData"/> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { onMounted, getCurrentInstance, computed } from "vue"; |
| | | import { usePaginationApi } from "@/hooks/usePaginationApi"; |
| | | import { getRepairPage, delRepair } from "@/api/equipmentManagement/repair"; |
| | | import { onMounted, getCurrentInstance } from "vue"; |
| | | import RepairModal from "./Modal/RepairModal.vue"; |
| | | import { ElMessageBox, ElMessage } from "element-plus"; |
| | | import dayjs from "dayjs"; |
| | | import MaintainModal from "./Modal/MaintainModal.vue"; |
| | | import ApproveModal from "./Modal/ApproveModal.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "è®¾å¤æ¥ä¿®", |
| | |
| | | // æ¨¡ææ¡å®ä¾ |
| | | const repairModalRef = ref(); |
| | | const maintainModalRef = ref(); |
| | | const approveModalRef = ref(); |
| | | |
| | | // è¡¨æ ¼å¤éæ¡éä¸é¡¹ |
| | | const multipleList = ref([]); |
| | |
| | | prop: "maintenanceTime", |
| | | formatData: (cell) => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""), |
| | | }, |
| | | { prop: "auditName", label: "å®¡æ ¸äºº", width: 120 }, |
| | | { prop: "supervisoryName", label: "çç£äºº", width: 120 }, |
| | | { |
| | | label: "ç¶æ", |
| | | align: "center", |
| | |
| | | dataType: "slot", |
| | | slot: "operation", |
| | | align: "center", |
| | | width: "200px", |
| | | width: "300px", |
| | | }, |
| | | ] |
| | | ); |
| | |
| | | multipleList.value = selectionList; |
| | | }; |
| | | |
| | | // æ£æ¥éä¸çè®°å½ä¸æ¯å¦æå®ç»ç¶æç |
| | | const hasFinishedStatus = computed(() => { |
| | | return multipleList.value.some(item => item.status === 1) |
| | | }) |
| | | |
| | | // æ°å¢æ¥ä¿® |
| | | const addRepair = () => { |
| | | repairModalRef.value.openAdd(); |
| | |
| | | }; |
| | | |
| | | // æ°å¢ç»´ä¿® |
| | | const addMaintain = () => { |
| | | |
| | | const row = multipleList.value[0]; |
| | | const addMaintain = (row) => { |
| | | maintainModalRef.value.open(row.id, row); |
| | | }; |
| | | |
| | | // å®¡æ¹ |
| | | const openApprove = (id) => { |
| | | approveModalRef.value.open(id); |
| | | }; |
| | | |
| | | const changePage = ({ page, limit }) => { |
| | |
| | | |
| | | // åè¡å é¤ |
| | | const delRepairByIds = async (ids) => { |
| | | let isDel = false |
| | | if(Array.isArray(ids)){ |
| | | ids.forEach((item)=>{ |
| | | if(item.status !== 0){ |
| | | isDel = true |
| | | } |
| | | }) |
| | | }else{ |
| | | if(ids.status !== 0){ |
| | | isDel = true |
| | | } |
| | | } |
| | | // æ£æ¥æ¯å¦æå®ç»ç¶æçè®°å½ |
| | | const idsArray = Array.isArray(ids) ? ids : [ids]; |
| | | const hasFinished = idsArray.some(id => { |
| | | const record = dataList.value.find(item => item.id === id); |
| | | return record && record.status === 1; |
| | | }); |
| | | |
| | | if(isDel){ |
| | | ElMessage.warning("åªè½å é¤å®¡æ ¸ä¸çæ¥ä¿®æ°æ®"); |
| | | return |
| | | if (hasFinished) { |
| | | ElMessage.warning('ä¸è½å é¤ç¶æä¸ºå®ç»çè®°å½'); |
| | | return; |
| | | } |
| | | |
| | | ElMessageBox.confirm("确认å 餿¥ä¿®æ°æ®, æ¤æä½ä¸å¯é?", "è¦å", { |
| | |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(async () => { |
| | | let idsList = "" |
| | | if(Array.isArray(ids)){ |
| | | idsList = multipleList.value.map((item) => item.id); |
| | | console.log(idsList) |
| | | }else{ |
| | | idsList = ids.id |
| | | } |
| | | const { code } = await delRepair(idsList); |
| | | const {code} = await delRepair(ids); |
| | | if (code === 200) { |
| | | ElMessage.success("å 餿å"); |
| | | await getTableData(); |
| | | getTableData(); |
| | | } |
| | | }); |
| | | }; |
| | |
| | | .table_list { |
| | | margin-top: unset; |
| | | } |
| | | |
| | | .actions { |
| | | display: flex; |
| | | justify-content: space-between; |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="table_list"> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="renderTableData" |
| | | style="width: 100%; margin-top: 10px;" |
| | | border |
| | | row-key="id" |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="columns" |
| | | :tableData="renderTableData" |
| | | :tableLoading="loading" |
| | | :page="pagination" |
| | | :isShowPagination="true" |
| | | @pagination="handleSizeChange" |
| | | > |
| | | <el-table-column prop="deviceNameStr" label="设å¤åç§°" width="300"></el-table-column> |
| | | <el-table-column prop="name" label="å¤ä»¶åç§°" width="200"></el-table-column> |
| | | <el-table-column prop="sparePartsNo" label="å¤ä»¶ç¼å·" width="200"></el-table-column> |
| | | <el-table-column prop="status" label="ç¶æ" width="100"> |
| | | <template #default="{ row }"> |
| | | <template #status="{ row }"> |
| | | <el-tag type="success" size="small">{{ row.status }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="price" label="ä»·æ ¼" width="140"></el-table-column> |
| | | <el-table-column prop="description" label="æè¿°" width="150"></el-table-column> |
| | | <el-table-column label="æä½" width="150" fixed="right" align="center"> |
| | | <template #default="{ row }"> |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | @click="() => editCategory(row)" |
| | | :disabled="loading" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | link |
| | | @click="() => deleteCategory(row.id)" |
| | | style="color: #f56c6c;" |
| | | :disabled="loading" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </PIMTable> |
| | | |
| | | <el-dialog title="å类管ç" v-model="dialogVisible" width="60%"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="100px"> |
| | | <el-form-item label="设å¤" prop="deviceLedgerIds"> |
| | |
| | | </el-form-item> |
| | | <el-form-item label="å¤ä»¶ç¼å·" prop="sparePartsNo"> |
| | | <el-input v-model="form.sparePartsNo"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="æ°é" prop="quantity"> |
| | | <el-input type="number" v-model="form.quantity"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="form.status" placeholder="è¯·éæ©ç¶æ"> |
| | |
| | | const queryParams = reactive({ |
| | | name: '' |
| | | }); |
| | | // å页忰 |
| | | const pagination = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0 |
| | | }); |
| | | const columns = ref([ |
| | | { |
| | | label: "设å¤åç§°", |
| | | prop: "deviceNameStr", |
| | | }, |
| | | { |
| | | label: "å¤ä»¶åç§°", |
| | | prop: "name", |
| | | }, |
| | | { |
| | | label: "å¤ä»¶ç¼å·", |
| | | prop: "sparePartsNo", |
| | | }, |
| | | { |
| | | label: "ç¶æ", |
| | | prop: "status", |
| | | slot: "status", |
| | | dataType: "slot", |
| | | }, |
| | | { |
| | | label: "ä»·æ ¼", |
| | | prop: "price", |
| | | }, |
| | | { |
| | | label: "æ°é", |
| | | prop: "quantity", |
| | | }, |
| | | { |
| | | label: "æè¿°", |
| | | prop: "description", |
| | | }, |
| | | { |
| | | label: "æä½", |
| | | prop: "operation", |
| | | width: 150, |
| | | fixed: 'right', |
| | | align: "center", |
| | | dataType: "action", |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | | clickFun: (row) => { |
| | | editCategory(row) |
| | | }, |
| | | }, |
| | | { |
| | | name: "å é¤", |
| | | clickFun: (row) => { |
| | | deleteCategory(row.id) |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | ]); |
| | | // è¡¨åæ°æ® |
| | | const form = reactive({ |
| | | id:'', |
| | |
| | | ], |
| | | sparePartsNo: [ |
| | | { required: true, message: '请è¾å
¥å¤ä»¶ç¼å·', trigger: 'blur' } |
| | | ], |
| | | quantity:[ |
| | | { required: true, message: '请è¾å
¥æ°é', trigger: 'blur' } |
| | | ], |
| | | status: [ |
| | | { required: true, message: 'è¯·éæ©ç¶æ', trigger: 'change' } |
| | |
| | | const fetchListData = async () => { |
| | | loading.value = true; |
| | | try { |
| | | const params = {}; |
| | | const params = { |
| | | current: pagination.current, |
| | | size: pagination.size |
| | | }; |
| | | if (queryParams.name) { |
| | | params.name = queryParams.name; |
| | | } |
| | |
| | | if (res.code === 200) { |
| | | renderTableData.value = res.data.records || []; |
| | | categories.value = res.data.records || []; |
| | | pagination.total = res.data.total || 0; |
| | | } |
| | | } catch (error) { |
| | | loading.value = false; |
| | |
| | | |
| | | // æ¥è¯¢ |
| | | const handleQuery = () => { |
| | | pagination.current = 1; |
| | | fetchListData(); |
| | | } |
| | | |
| | | // éç½®æ¥è¯¢ |
| | | const resetQuery = () => { |
| | | queryParams.name = ''; |
| | | pagination.current = 1; |
| | | fetchListData(); |
| | | } |
| | | |
| | | // å页大尿¹å |
| | | const handleSizeChange = (size) => { |
| | | pagination.size = size; |
| | | pagination.current = 1; |
| | | fetchListData(); |
| | | } |
| | | |
| | | // å½å页æ¹å |
| | | const handleCurrentChange = (current) => { |
| | | pagination.current = current; |
| | | fetchListData(); |
| | | } |
| | | |
| | |
| | | form.status = ''; |
| | | form.description = ''; |
| | | form.deviceLedgerIds = []; |
| | | form.quantity = undefined; |
| | | form.price = null; |
| | | operationType.value = 'add' |
| | | dialogVisible.value = true; |
| | |
| | | margin-top: unset; |
| | | } |
| | | |
| | | .pagination-container { |
| | | margin-top: 20px; |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | padding: 16px 0; |
| | | } |
| | | |
| | | .el-table__header-wrapper th { |
| | | background-color: #f5f7fa; |
| | | font-weight: 600; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <FormDialog |
| | | v-model="visible" |
| | | title="宿¶ä»»å¡å®¡æ¹" |
| | | width="800px" |
| | | @confirm="handleSubmit" |
| | | @cancel="handleClose" |
| | | @close="handleClose" |
| | | > |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions-item label="ä»»å¡åç§°"> |
| | | {{ detail.taskName || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="è§æ ¼åå·"> |
| | | {{ detail.deviceModel || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="颿¬¡"> |
| | | {{ frequencyText(detail.frequencyType) }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="å¼å§æ¥æä¸æ¶é´"> |
| | | {{ detail.frequencyDetail || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="ç»è®°äºº"> |
| | | {{ detail.registrant || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="ç»è®°æ¥æ"> |
| | | {{ detail.registrationDate || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="å½åç¶æ"> |
| | | {{ statusText(detail.status) }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="夿³¨" :span="2"> |
| | | {{ detail.remarks || "-" }} |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | <div style="margin-top: 16px"> |
| | | <el-form ref="formRef" :model="form" :rules="rules" label-width="100px"> |
| | | <el-form-item label="审æ¹ç»æ" prop="decision"> |
| | | <el-radio-group v-model="form.decision"> |
| | | <el-radio label="å®¡æ ¸éè¿">å®¡æ ¸éè¿</el-radio> |
| | | <el-radio label="å®¡æ ¸ä¸éè¿">å®¡æ ¸ä¸éè¿</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="çç£äºº" prop="supervisoryName"> |
| | | <el-input v-model="form.supervisoryName" placeholder="请è¾å
¥çç£äºº" clearable style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { nextTick, ref } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { deviceMaintenanceTaskEdit } from "@/api/equipmentManagement/upkeep"; |
| | | |
| | | defineOptions({ |
| | | name: "宿¶ä»»å¡å®¡æ¹å¼¹çª", |
| | | }); |
| | | |
| | | const emits = defineEmits(["ok"]); |
| | | |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | const detail = ref({}); |
| | | const formRef = ref(); |
| | | const form = ref({ |
| | | decision: undefined, // å®¡æ ¸éè¿ / å®¡æ ¸ä¸éè¿ |
| | | supervisoryName: undefined, // çç£äºº |
| | | }); |
| | | |
| | | const rules = { |
| | | decision: [{ required: true, message: "è¯·éæ©å®¡æ¹ç»æ", trigger: "change" }], |
| | | supervisoryName: [{ required: true, message: "è¯·éæ©çç£äºº", trigger: "change" }], |
| | | }; |
| | | |
| | | const statusText = (status) => status || "-"; |
| | | |
| | | const frequencyText = (type) => { |
| | | const map = { |
| | | DAILY: "æ¯æ¥", |
| | | WEEKLY: "æ¯å¨", |
| | | MONTHLY: "æ¯æ", |
| | | QUARTERLY: "å£åº¦", |
| | | }; |
| | | return map[type] ?? "-"; |
| | | }; |
| | | |
| | | const open = async (row) => { |
| | | detail.value = { ...(row || {}) }; |
| | | visible.value = true; |
| | | await nextTick(); |
| | | form.value.decision = undefined; |
| | | form.value.supervisoryName = undefined; |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | visible.value = false; |
| | | detail.value = {}; |
| | | form.value.decision = undefined; |
| | | form.value.supervisoryName = undefined; |
| | | }; |
| | | |
| | | const updateStatus = async (status) => { |
| | | loading.value = true; |
| | | try { |
| | | const payload = { ...(detail.value || {}), status, supervisoryName: form.value.supervisoryName }; |
| | | const { code } = await deviceMaintenanceTaskEdit(payload); |
| | | if (code === 200) { |
| | | ElMessage.success("å®¡æ¹æå"); |
| | | emits("ok"); |
| | | handleClose(); |
| | | } |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const handleSubmit = async () => { |
| | | if (detail.value?.status === "å®¡æ ¸éè¿") { |
| | | ElMessage.warning("å®¡æ ¸éè¿åä¸å¯å次审æ¹"); |
| | | return; |
| | | } |
| | | await formRef.value?.validate(async (valid) => { |
| | | if (!valid) return; |
| | | const isApprove = form.value.decision === "å®¡æ ¸éè¿"; |
| | | ElMessageBox.confirm( |
| | | `确认审æ¹${isApprove ? "éè¿" : "ä¸éè¿"}ï¼`, |
| | | "æç¤º", |
| | | { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | } |
| | | ).then(() => updateStatus(form.value.decision)); |
| | | }); |
| | | }; |
| | | |
| | | defineExpose({ open }); |
| | | </script> |
| | | |
| | | <style scoped></style> |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <FormDialog |
| | | v-model="visible" |
| | | :title="'设å¤ä¿å
»'" |
| | | width="500px" |
| | | @confirm="sendForm" |
| | | @cancel="handleCancel" |
| | | @close="handleClose" |
| | | > |
| | | <el-form :model="form" :rules="rules" label-width="120px" ref="formRef"> |
| | | <el-form-item label="å®é
ä¿å
»äºº" prop="maintenanceActuallyName"> |
| | | <el-input |
| | | v-model="form.maintenanceActuallyName" |
| | | placeholder="请è¾å
¥å®é
ä¿å
»äºº" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="å®é
ä¿å
»æ¥æ" prop="maintenanceActuallyTime"> |
| | | <el-date-picker |
| | | v-model="form.maintenanceActuallyTime" |
| | | placeholder="è¯·éæ©å®é
ä¿å
»æ¥æ" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="datetime" |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ä¿å
»ç¶æ" prop="status"> |
| | | <el-select v-model="form.status"> |
| | | <el-option label="å¾
ä¿å
»" :value="0"></el-option> |
| | | <el-option label="å®ç»" :value="1"></el-option> |
| | | <el-option label="失败" :value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ä¿å
ȍȾ" prop="maintenanceResult"> |
| | | <el-input |
| | | v-model="form.maintenanceResult" |
| | | placeholder="请è¾å
¥ä¿å
ȍȾ" |
| | | type="text" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¬æ¬¡ä¿å
»éé¢" prop="maintenancePrice"> |
| | | <el-input-number v-model="form.maintenancePrice" :min="0" :precision="2" style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { addMaintenance } from "@/api/equipmentManagement/upkeep"; |
| | | import useFormData from "@/hooks/useFormData"; |
| | | import dayjs from "dayjs"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { ElMessage } from "element-plus"; |
| | | |
| | | defineOptions({ |
| | | name: "ä¿å
»æ¨¡ææ¡", |
| | | }); |
| | | |
| | | const emits = defineEmits(["ok"]); |
| | | |
| | | // ä¿å计åä¿å
»è®°å½çid |
| | | const planId = ref(); |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | const formRef = ref(); |
| | | const userStore = useUserStore(); |
| | | |
| | | const { form, resetForm } = useFormData({ |
| | | maintenanceActuallyName: undefined, // å®é
ä¿å
»äºº |
| | | maintenanceActuallyTime: undefined, // å®é
ä¿å
»æ¥æ |
| | | maintenanceResult: undefined, // ä¿å
ȍȾ |
| | | maintenancePrice: undefined, // ä¿å
»éé¢ |
| | | status: 0, // ä¿å
»ç¶æ |
| | | }); |
| | | |
| | | const rules = { |
| | | maintenanceActuallyName: [ |
| | | { required: true, message: "请è¾å
¥å®é
ä¿å
»äºº", trigger: "blur" }, |
| | | ], |
| | | maintenanceActuallyTime: [ |
| | | { required: true, message: "è¯·éæ©å®é
ä¿å
»æ¥æ", trigger: "change" }, |
| | | ], |
| | | maintenanceResult: [ |
| | | { required: true, message: "请è¾å
¥ä¿å
ȍȾ", trigger: "blur" }, |
| | | ], |
| | | maintenancePrice: [ |
| | | { required: true, message: "请è¾å
¥æ¬æ¬¡ä¿å
»éé¢", trigger: "change" }, |
| | | ], |
| | | }; |
| | | |
| | | const setForm = (data) => { |
| | | form.maintenanceActuallyName = |
| | | data.maintenanceActuallyName ?? userStore.nickName; |
| | | form.maintenanceActuallyTime = |
| | | data.maintenanceActuallyTime |
| | | ? dayjs(data.maintenanceActuallyTime).format("YYYY-MM-DD HH:mm:ss") |
| | | : dayjs().format("YYYY-MM-DD HH:mm:ss"); |
| | | form.maintenanceResult = data.maintenanceResult; |
| | | form.status = 1; // é»è®¤ç¶æä¸ºå®ç» |
| | | }; |
| | | |
| | | /** |
| | | * @desc ä¿åä¿å
» |
| | | */ |
| | | const sendForm = async () => { |
| | | await formRef.value?.validate(async (valid) => { |
| | | if (!valid) return; |
| | | loading.value = true; |
| | | try { |
| | | const { code } = await addMaintenance({ id: planId.value, ...form }); |
| | | if (code == 200) { |
| | | ElMessage.success("ä¿å
»æå"); |
| | | emits("ok"); |
| | | resetForm(); |
| | | visible.value = false; |
| | | } |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const handleCancel = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const open = async (id, row) => { |
| | | planId.value = id; // ä¿å计åä¿å
»è®°å½çid |
| | | visible.value = true; |
| | | await nextTick(); |
| | | setForm(row); |
| | | }; |
| | | |
| | | defineExpose({ |
| | | open, |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped></style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <FormDialog |
| | | v-model="visible" |
| | | :title="id ? 'ç¼è¾è®¾å¤ä¿å
»è®¡å' : 'æ°å¢è®¾å¤ä¿å
»è®¡å'" |
| | | width="500px" |
| | | @confirm="sendForm" |
| | | @cancel="handleCancel" |
| | | @close="handleClose" |
| | | > |
| | | <el-form :model="form" label-width="100px"> |
| | | <el-form-item label="设å¤åç§°"> |
| | | <el-select |
| | | v-model="form.deviceLedgerId" |
| | | @change="setDeviceModel" |
| | | placeholder="è¯·éæ©è®¾å¤" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | > |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | | :label="item.deviceName" |
| | | :value="item.id" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="è§æ ¼åå·"> |
| | | <el-input |
| | | v-model="form.deviceModel" |
| | | placeholder="请è¾å
¥è§æ ¼åå·" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="å½å
¥äºº"> |
| | | <el-select |
| | | v-model="form.createUser" |
| | | placeholder="è¯·éæ©" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.userId" |
| | | :label="item.nickName" |
| | | :value="item.userId" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="id" label="ä¿ä¿®ç¶æ"> |
| | | <el-select v-model="form.status"> |
| | | <el-option label="å¾
ä¿ä¿®" :value="0"></el-option> |
| | | <el-option label="å®ç»" :value="1"></el-option> |
| | | <el-option label="失败" :value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="计åä¿å
»æ¥æ"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.maintenancePlanTime" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="date" |
| | | placeholder="è¯·éæ©è®¡åä¿å
»æ¥ææ¥æ" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { |
| | | addUpkeep, |
| | | editUpkeep, |
| | | getUpkeepById, |
| | | } from "@/api/equipmentManagement/upkeep"; |
| | | import { ElMessage } from "element-plus"; |
| | | import useFormData from "@/hooks/useFormData"; |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | | import { onMounted } from "vue"; |
| | | import dayjs from "dayjs"; |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | |
| | | defineOptions({ |
| | | name: "设å¤ä¿å
»æ°å¢è®¡å", |
| | | }); |
| | | |
| | | const emits = defineEmits(["ok"]); |
| | | |
| | | const id = ref(); |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | |
| | | const deviceOptions = ref([]); |
| | | const loadDeviceName = async () => { |
| | | const { data } = await getDeviceLedger(); |
| | | deviceOptions.value = data; |
| | | }; |
| | | |
| | | const { form, resetForm } = useFormData({ |
| | | deviceLedgerId: undefined, // 设å¤Id |
| | | deviceName: undefined, // 设å¤åç§° |
| | | deviceModel: undefined, // è§æ ¼åå· |
| | | maintenancePlanTime: undefined, // 计åä¿å
»æ¥æ |
| | | createUser: undefined, // å½å
¥äºº |
| | | status: 0, //ä¿ä¿®ç¶æ |
| | | }); |
| | | |
| | | const setDeviceModel = (deviceId) => { |
| | | const option = deviceOptions.value.find((item) => item.id === deviceId); |
| | | form.deviceModel = option.deviceModel; |
| | | }; |
| | | |
| | | /** |
| | | * @desc 设置表åå
容 |
| | | * @param data 设å¤ä¿¡æ¯ |
| | | */ |
| | | const setForm = (data) => { |
| | | form.deviceLedgerId = data.deviceLedgerId; |
| | | form.deviceName = data.deviceName; |
| | | form.deviceModel = data.deviceModel; |
| | | form.createUser = Number(data.createUser); |
| | | form.status = data.status; |
| | | form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format( |
| | | "YYYY-MM-DD HH:mm:ss" |
| | | ); |
| | | }; |
| | | |
| | | // ç¨æ·å表 |
| | | const userList = ref([]); |
| | | |
| | | onMounted(() => { |
| | | loadDeviceName(); |
| | | userListNoPage().then((res) => { |
| | | userList.value = res.data; |
| | | }); |
| | | }); |
| | | |
| | | const openEdit = async (editId) => { |
| | | const { data } = await getUpkeepById(editId); |
| | | id.value = editId; |
| | | visible.value = true; |
| | | await nextTick(); |
| | | setForm(data); |
| | | }; |
| | | |
| | | const sendForm = async () => { |
| | | loading.value = true; |
| | | try { |
| | | const { code } = id.value |
| | | ? await editUpkeep({ id: unref(id), ...form }) |
| | | : await addUpkeep(form); |
| | | if (code == 200) { |
| | | ElMessage.success(`${id.value ? "ç¼è¾" : "æ°å¢"}计åæå`); |
| | | visible.value = false; |
| | | emits("ok"); |
| | | } |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const handleCancel = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const openModal = () => { |
| | | id.value = undefined; |
| | | visible.value = true; |
| | | }; |
| | | |
| | | defineExpose({ |
| | | openModal, |
| | | openEdit, |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped></style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <FormDialog |
| | | v-model="dialogVisitable" |
| | | :title="operationType === 'add' ? 'æ°å¢ä¿å
»ä»»å¡' : 'ç¼è¾ä¿å
»ä»»å¡'" |
| | | width="800px" |
| | | :operation-type="operationType" |
| | | @confirm="submitForm" |
| | | @cancel="cancel" |
| | | @close="cancel" |
| | | > |
| | | <el-form ref="formRef" :model="form" :rules="rules" label-width="120px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设å¤åç§°" prop="taskIds"> |
| | | <el-select v-model="form.taskIds" @change="setDeviceModel" multiple filterable> |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | | :label="item.deviceName" |
| | | :value="item.id" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼åå·"> |
| | | <el-input |
| | | v-model="form.deviceModel" |
| | | placeholder="请è¾å
¥è§æ ¼åå·" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å½å
¥äºº" prop="inspector"> |
| | | <el-select |
| | | v-model="form.inspector" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | | :label="item.nickName" |
| | | :value="item.userId" |
| | | :key="item.userId" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»è®°æ¶é´" prop="registrationDate"> |
| | | <el-date-picker |
| | | v-model="form.registrationDate" |
| | | type="date" |
| | | placeholder="éæ©ç»è®°æ¥æ" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="审æ¹äºº" prop="auditName"> |
| | | <el-select |
| | | v-model="form.auditName" |
| | | filterable |
| | | placeholder="è¯·éæ©å®¡æ¹äºº" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.userId" |
| | | :label="item.nickName" |
| | | :value="item.nickName" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä»»å¡é¢ç" prop="frequencyType"> |
| | | <el-select v-model="form.frequencyType" placeholder="è¯·éæ©" clearable> |
| | | <el-option label="æ¯æ¥" value="DAILY"/> |
| | | <el-option label="æ¯å¨" value="WEEKLY"/> |
| | | <el-option label="æ¯æ" value="MONTHLY"/> |
| | | <el-option label="å£åº¦" value="QUARTERLY"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType"> |
| | | <el-form-item label="æ¥æ" prop="frequencyDetail"> |
| | | <el-time-picker v-model="form.frequencyDetail" placeholder="éæ©æ¶é´" format="HH:mm" |
| | | value-format="HH:mm" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType"> |
| | | <el-form-item label="æ¥æ" prop="frequencyDetail"> |
| | | <el-select v-model="form.week" placeholder="è¯·éæ©" clearable style="width: 50%"> |
| | | <el-option label="å¨ä¸" value="MON"/> |
| | | <el-option label="å¨äº" value="TUE"/> |
| | | <el-option label="å¨ä¸" value="WED"/> |
| | | <el-option label="å¨å" value="THU"/> |
| | | <el-option label="å¨äº" value="FRI"/> |
| | | <el-option label="å¨å
" value="SAT"/> |
| | | <el-option label="卿¥" value="SUN"/> |
| | | </el-select> |
| | | <el-time-picker v-model="form.time" placeholder="éæ©æ¶é´" format="HH:mm" |
| | | value-format="HH:mm" style="width: 50%"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType"> |
| | | <el-form-item label="æ¥æ" prop="frequencyDetail"> |
| | | <el-date-picker |
| | | v-model="form.frequencyDetail" |
| | | type="datetime" |
| | | clearable |
| | | placeholder="éæ©å¼å§æ¥æ" |
| | | format="DD,HH:mm" |
| | | value-format="DD,HH:mm" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType"> |
| | | <el-form-item label="æ¥æ" prop="frequencyDetail"> |
| | | <el-date-picker |
| | | v-model="form.frequencyDetail" |
| | | type="datetime" |
| | | clearable |
| | | placeholder="éæ©å¼å§æ¥æ" |
| | | format="MM,DD,HH:mm" |
| | | value-format="MM,DD,HH:mm" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="夿³¨" prop="remarks"> |
| | | <el-input v-model="form.remarks" placeholder="请è¾å
¥å¤æ³¨" type="textarea" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { reactive, ref, getCurrentInstance, toRefs } from "vue"; |
| | | import {userListNoPageByTenantId} from "@/api/system/user.js"; |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | | import { deviceMaintenanceTaskAdd, deviceMaintenanceTaskEdit } from "@/api/equipmentManagement/upkeep"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits() |
| | | const dialogVisitable = ref(false); |
| | | const operationType = ref('add'); |
| | | const deviceOptions = ref([]); |
| | | const userStore = useUserStore(); |
| | | const data = reactive({ |
| | | form: { |
| | | taskIds: [], |
| | | taskName: undefined, |
| | | // å½å
¥äººï¼åéä¸ä¸ªç¨æ· id |
| | | inspector: undefined, |
| | | auditName: undefined, |
| | | remarks: '', |
| | | frequencyType: '', |
| | | frequencyDetail: '', |
| | | week: '', |
| | | time: '', |
| | | deviceModel: undefined, // è§æ ¼åå· |
| | | registrationDate: '' |
| | | }, |
| | | rules: { |
| | | taskIds: [{ required: true, message: "è¯·éæ©è®¾å¤", trigger: "change" },], |
| | | inspector: [{ required: true, message: "è¯·éæ©å½å
¥äºº", trigger: "blur" },], |
| | | registrationDate: [{ required: true, message: "è¯·éæ©ç»è®°æ¶é´", trigger: "change" }], |
| | | auditName: [{ required: true, message: "è¯·éæ©å®¡æ¹äºº", trigger: "change" }], |
| | | } |
| | | }) |
| | | const { form, rules } = toRefs(data) |
| | | const userList = ref([]) |
| | | |
| | | const loadDeviceName = async () => { |
| | | const { data } = await getDeviceLedger(); |
| | | deviceOptions.value = data; |
| | | }; |
| | | |
| | | // éæ©è®¾å¤æ¶ï¼å填设å¤åç§°(taskName)åè§æ ¼åå·(deviceModel) |
| | | const setDeviceModel = (ids) => { |
| | | if (!ids || ids.length === 0) { |
| | | form.value.taskIds = [] |
| | | form.value.taskName = undefined |
| | | form.value.deviceModel = undefined |
| | | return |
| | | } |
| | | |
| | | const selectedDevices = deviceOptions.value.filter((item) => ids.includes(item.id)) |
| | | if (selectedDevices.length > 0) { |
| | | form.value.taskIds = ids |
| | | form.value.taskName = selectedDevices.map(d => d.deviceName).join(',') |
| | | form.value.deviceModel = selectedDevices.map(d => d.deviceModel || '-').join(',') |
| | | } |
| | | } |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = async (type, row) => { |
| | | dialogVisitable.value = true |
| | | operationType.value = type |
| | | |
| | | // é置表å |
| | | resetForm(); |
| | | |
| | | // å è½½ç¨æ·å表 |
| | | userListNoPageByTenantId().then((res) => { |
| | | userList.value = res.data; |
| | | }); |
| | | |
| | | // å 载设å¤å表 |
| | | await loadDeviceName(); |
| | | |
| | | if (type === 'edit' && row) { |
| | | form.value = { ...row } |
| | | // ç¼è¾æ¶ç¨æ¥å£è¿åç registrantId åæ¾å½å
¥äºº |
| | | if (row.registrantId) { |
| | | form.value.inspector = row.registrantId |
| | | } |
| | | // 妿æè®¾å¤IDæ°ç»ï¼è½¬æ¢ä¸ºæ°ç»å¹¶è®¾ç½®è®¾å¤ä¿¡æ¯ |
| | | if (row.taskIds) { |
| | | form.value.taskIds = row.taskIds.split(',').map(id => parseInt(id.trim())) |
| | | setDeviceModel(form.value.taskIds) |
| | | } |
| | | } else if (type === 'add') { |
| | | // æ°å¢æ¶è®¾ç½®ç»è®°æ¥æä¸ºå½å¤© |
| | | form.value.registrationDate = getCurrentDate(); |
| | | // æ°å¢æ¶è®¾ç½®å½å
¥äººä¸ºå½åç»å½è´¦æ· |
| | | form.value.inspector = userStore.id; |
| | | } |
| | | } |
| | | |
| | | // å
³éå¯¹è¯æ¡ |
| | | const cancel = () => { |
| | | resetForm() |
| | | dialogVisitable.value = false |
| | | emit('closeDia') |
| | | } |
| | | |
| | | // é置表å彿° |
| | | const resetForm = () => { |
| | | if (proxy.$refs.formRef) { |
| | | proxy.$refs.formRef.resetFields() |
| | | } |
| | | // éç½®è¡¨åæ°æ®ç¡®ä¿è®¾å¤ä¿¡æ¯æ£ç¡®éç½® |
| | | form.value = { |
| | | taskIds: [], |
| | | taskName: undefined, |
| | | inspector: undefined, |
| | | auditName: undefined, |
| | | remarks: '', |
| | | frequencyType: '', |
| | | frequencyDetail: '', |
| | | week: '', |
| | | time: '', |
| | | deviceModel: undefined, |
| | | registrationDate: '' |
| | | } |
| | | } |
| | | |
| | | // æäº¤è¡¨å |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate(async valid => { |
| | | if (valid) { |
| | | try { |
| | | const payload = { ...form.value } |
| | | // ä¸åååç«¯ä¼ ä¿å
»äººå段ï¼ä»
ä½¿ç¨æ¥å£è¦æ±ç registrant / registrantId |
| | | // æ ¹æ®éæ©ç"å½å
¥äºº"设置 registrant / registrantId |
| | | if (payload.inspector) { |
| | | const selectedUser = userList.value.find( |
| | | (u) => String(u.userId) === String(payload.inspector) |
| | | ) |
| | | if (selectedUser) { |
| | | payload.registrantId = selectedUser.userId |
| | | payload.registrant = selectedUser.nickName |
| | | } |
| | | } |
| | | delete payload.inspector |
| | | delete payload.inspectorIds |
| | | |
| | | // å¤ç taskIds å taskName |
| | | if (payload.taskIds && Array.isArray(payload.taskIds)) { |
| | | payload.taskIds = payload.taskIds.join(',') |
| | | } |
| | | |
| | | if (payload.frequencyType === 'WEEKLY') { |
| | | let frequencyDetail = '' |
| | | frequencyDetail = payload.week + ',' + payload.time |
| | | payload.frequencyDetail = frequencyDetail |
| | | } |
| | | |
| | | // å½å
¥æ¥æï¼ç´æ¥ä½¿ç¨è¡¨åéç registrationDate åæ®µ |
| | | // ä¸äºé»è®¤ç¶æå段 |
| | | if (payload.status === undefined || payload.status === null || payload.status === '') { |
| | | payload.status = 'å¾
å®¡æ ¸' // é»è®¤ç¶æï¼å¾
å®¡æ ¸ |
| | | } |
| | | payload.active = true |
| | | payload.deleted = 0 |
| | | |
| | | if (operationType.value === 'edit') { |
| | | await deviceMaintenanceTaskEdit(payload) |
| | | } else { |
| | | await deviceMaintenanceTaskAdd(payload) |
| | | } |
| | | cancel() |
| | | proxy.$modal.msgSuccess('æäº¤æå') |
| | | } catch (error) { |
| | | proxy.$modal.msgError('æäº¤å¤±è´¥ï¼è¯·éè¯') |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | defineExpose({ openDialog }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
| | |
| | | </el-form-item> |
| | | <el-form-item label="ä»»å¡ç¶æ"> |
| | | <el-select v-model="scheduledFilters.status" placeholder="è¯·éæ©ä»»å¡ç¶æ" clearable style="width: 200px"> |
| | | <el-option label="å¯ç¨" value="1" /> |
| | | <el-option label="åç¨" value="0" /> |
| | | <el-option label="å¾
å®¡æ ¸" value="å¾
å®¡æ ¸" /> |
| | | <el-option label="å®¡æ ¸éè¿" value="å®¡æ ¸éè¿" /> |
| | | <el-option label="å®¡æ ¸ä¸éè¿" value="å®¡æ ¸ä¸éè¿" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | |
| | | @pagination="changeScheduledPage" |
| | | > |
| | | <template #statusRef="{ row }"> |
| | | <el-tag v-if="row.status === 1" type="success">å¯ç¨</el-tag> |
| | | <el-tag v-if="row.status === 0" type="danger">åç¨</el-tag> |
| | | <el-tag v-if="row.status === 'å¾
å®¡æ ¸'" type="warning">å¾
å®¡æ ¸</el-tag> |
| | | <el-tag v-else-if="row.status === 'å®¡æ ¸éè¿'" type="success">å®¡æ ¸éè¿</el-tag> |
| | | <el-tag v-else-if="row.status === 'å®¡æ ¸ä¸éè¿'" type="danger">å®¡æ ¸ä¸éè¿</el-tag> |
| | | <span v-else>{{ row.status }}</span> |
| | | </template> |
| | | <template #operation="{ row }"> |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | icon="editPen" |
| | | link |
| | | @click="editScheduledTask(row)" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | type="warning" |
| | | link |
| | | :disabled="row.status === 'å®¡æ ¸éè¿'" |
| | | @click="openScheduledApprove(row)" |
| | | > |
| | | å®¡æ¹ |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | text |
| | | icon="delete" |
| | | link |
| | | @click="delScheduledTaskByIds(row.id)" |
| | | > |
| | | å é¤ |
| | |
| | | <div class="actions"> |
| | | <el-text class="mx-1" size="large">ä»»å¡è®°å½</el-text> |
| | | <div> |
| | | <el-button |
| | | type="primary" |
| | | icon="Plus" |
| | | :disabled="multipleList.length !== 1" |
| | | @click="addMaintain" |
| | | > |
| | | æ°å¢ä¿å
» |
| | | </el-button> |
| | | <el-button type="success" icon="Van" @click="addPlan"> |
| | | æ°å¢è®¡å |
| | | </el-button> |
| | | <el-button @click="handleOut"> |
| | | å¯¼åº |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | icon="Delete" |
| | | :disabled="multipleList.length <= 0" |
| | | :disabled="multipleList.length <= 0 || hasFinishedStatus" |
| | | @click="delRepairByIds(multipleList.map((item) => item.id))" |
| | | > |
| | | æ¹éå é¤ |
| | |
| | | <el-tag v-if="row.status === 0" type="warning">å¾
ä¿å
»</el-tag> |
| | | </template> |
| | | <template #operation="{ row }"> |
| | | <el-button |
| | | <!-- è¿ä¸ªåè½è·æ°å¢ä¿å
»åè½ä¸æ¨¡ä¸æ ·ï¼æå¥æä¹ï¼ --> |
| | | <!-- <el-button |
| | | type="primary" |
| | | text |
| | | icon="editPen" |
| | | @click="addMaintain(row)" |
| | | > |
| | | æ°å¢ä¿å
» |
| | | </el-button> --> |
| | | <el-button |
| | | type="primary" |
| | | link |
| | | :disabled="row.status === 1" |
| | | @click="editPlan(row.id)" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | type="success" |
| | | link |
| | | :disabled="row.status === 1" |
| | | @click="addMaintain(row)" |
| | | > |
| | | ä¿å
» |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | text |
| | | icon="delete" |
| | | link |
| | | :disabled="row.status === 1" |
| | | @click="delRepairByIds(row.id)" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | <el-button |
| | | type="primary" |
| | | link |
| | | @click="openFileDialog(row)" |
| | | > |
| | | éä»¶ |
| | | </el-button> |
| | | </template> |
| | | </PIMTable> |
| | |
| | | <PlanModal ref="planModalRef" @ok="getTableData" /> |
| | | <MaintenanceModal ref="maintainModalRef" @ok="getTableData" /> |
| | | <FormDia ref="formDiaRef" @closeDia="getScheduledTableData" /> |
| | | <ApproveModal ref="approveModalRef" @ok="getScheduledTableData" /> |
| | | <FileListDialog |
| | | ref="fileListDialogRef" |
| | | v-model="fileDialogVisible" |
| | | :show-upload-button="true" |
| | | :show-delete-button="true" |
| | | :delete-method="handleAttachmentDelete" |
| | | :name-column-label="'éä»¶åç§°'" |
| | | :rulesRegulationsManagementId="currentMaintenanceTaskId" |
| | | @upload="handleAttachmentUpload" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, reactive, getCurrentInstance, nextTick } from 'vue' |
| | | import { ref, onMounted, reactive, getCurrentInstance, nextTick, computed } from 'vue' |
| | | import { Search } from '@element-plus/icons-vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import PlanModal from './Modal/PlanModal.vue' |
| | | import MaintenanceModal from './Modal/MaintenanceModal.vue' |
| | | import FormDia from './Modal/formDia.vue' |
| | | import PlanModal from './Form/PlanModal.vue' |
| | | import MaintenanceModal from './Form/MaintenanceModal.vue' |
| | | import FormDia from './Form/formDia.vue' |
| | | import ApproveModal from './Form/ApproveModal.vue' |
| | | import FileListDialog from '@/components/Dialog/FileListDialog.vue' |
| | | import { |
| | | getUpkeepPage, |
| | | delUpkeep, |
| | | deviceMaintenanceTaskList, |
| | | deviceMaintenanceTaskDel, |
| | | } from '@/api/equipmentManagement/upkeep' |
| | | import { |
| | | listMaintenanceTaskFiles, |
| | | addMaintenanceTaskFile, |
| | | delMaintenanceTaskFile, |
| | | } from '@/api/equipmentManagement/maintenanceTaskFile' |
| | | import dayjs from 'dayjs' |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | |
| | | const maintainModalRef = ref() |
| | | // 宿¶ä»»å¡å¼¹çªæ§å¶å¨ |
| | | const formDiaRef = ref() |
| | | // ä¿å
»å®¡æ¹å¼¹çª |
| | | const approveModalRef = ref() |
| | | // éä»¶å¼¹çª |
| | | const fileListDialogRef = ref(null) |
| | | const fileDialogVisible = ref(false) |
| | | const currentMaintenanceTaskId = ref(null) |
| | | |
| | | // ä»»å¡è®°å½tabï¼å设å¤ä¿å
»é¡µé¢ï¼ç¸å
³åé |
| | | const filters = reactive({ |
| | |
| | | }, |
| | | { prop: "registrant", label: "ç»è®°äºº", minWidth: 100 }, |
| | | { prop: "registrationDate", label: "ç»è®°æ¥æ", minWidth: 100 }, |
| | | { prop: "auditName", label: "å®¡æ ¸äºº", width: 120 }, |
| | | { prop: "supervisoryName", label: "çç£äºº", width: 120 }, |
| | | { |
| | | label: "ç¶æ", |
| | | align: "center", |
| | | prop: "status", |
| | | dataType: "slot", |
| | | slot: "statusRef", |
| | | }, |
| | | { |
| | | fixed: "right", |
| | | label: "æä½", |
| | |
| | | dataType: "slot", |
| | | slot: "operation", |
| | | align: "center", |
| | | width: "200px", |
| | | width: "350px", |
| | | }, |
| | | ]) |
| | | |
| | |
| | | multipleList.value = selection |
| | | } |
| | | |
| | | // æ£æ¥éä¸çè®°å½ä¸æ¯å¦æå®ç»ç¶æç |
| | | const hasFinishedStatus = computed(() => { |
| | | return multipleList.value.some(item => item.status === 1) |
| | | }) |
| | | |
| | | const changePage = (page) => { |
| | | pagination.value.currentPage = page.page |
| | | pagination.value.pageSize = page.limit |
| | | getTableData() |
| | | } |
| | | |
| | | const addMaintain = () => { |
| | | const row = multipleList.value[0] |
| | | const addMaintain = (row) => { |
| | | maintainModalRef.value.open(row.id, row) |
| | | } |
| | | |
| | | // 宿¶ä»»å¡å®¡æ¹ |
| | | const openScheduledApprove = (row) => { |
| | | approveModalRef.value.open(row) |
| | | } |
| | | |
| | | const addPlan = () => { |
| | |
| | | } |
| | | |
| | | const delRepairByIds = async (ids) => { |
| | | // æ£æ¥æ¯å¦æå®ç»ç¶æçè®°å½ |
| | | const hasFinished = multipleList.value.some(item => item.status === 1) |
| | | if (hasFinished) { |
| | | ElMessage.warning('ä¸è½å é¤ç¶æä¸ºå®ç»çè®°å½') |
| | | return |
| | | } |
| | | |
| | | try { |
| | | await ElMessageBox.confirm('确认å é¤ä¿å
»æ°æ®, æ¤æä½ä¸å¯é?', 'è¦å', { |
| | | confirmButtonText: 'ç¡®å®', |
| | |
| | | getTableData() |
| | | } |
| | | |
| | | // éä»¶ç¸å
³æ¹æ³ |
| | | // æ¥è¯¢éä»¶å表 |
| | | const fetchMaintenanceTaskFiles = async (deviceMaintenanceId) => { |
| | | try { |
| | | const params = { |
| | | current: 1, |
| | | size: 100, |
| | | deviceMaintenanceId, |
| | | rulesRegulationsManagementId:deviceMaintenanceId |
| | | } |
| | | const res = await listMaintenanceTaskFiles(params) |
| | | const records = res?.data?.records || [] |
| | | const mapped = records.map(item => ({ |
| | | id: item.id, |
| | | name: item.fileName || item.name, |
| | | url: item.fileUrl || item.url, |
| | | raw: item, |
| | | })) |
| | | fileListDialogRef.value?.setList(mapped) |
| | | } catch (error) { |
| | | ElMessage.error('è·åéä»¶å表失败') |
| | | } |
| | | } |
| | | |
| | | // æå¼éä»¶å¼¹çª |
| | | const openFileDialog = async (row) => { |
| | | currentMaintenanceTaskId.value = row.id |
| | | fileDialogVisible.value = true |
| | | await fetchMaintenanceTaskFiles(row.id) |
| | | } |
| | | |
| | | // å·æ°éä»¶å表 |
| | | const refreshFileList = async () => { |
| | | if (!currentMaintenanceTaskId.value) return |
| | | await fetchMaintenanceTaskFiles(currentMaintenanceTaskId.value) |
| | | } |
| | | |
| | | // ä¸ä¼ éä»¶ |
| | | const handleAttachmentUpload = async (filePayload) => { |
| | | if (!currentMaintenanceTaskId.value) return |
| | | try { |
| | | const payload = { |
| | | name: filePayload?.fileName || filePayload?.name, |
| | | url: filePayload?.fileUrl || filePayload?.url, |
| | | deviceMaintenanceId: currentMaintenanceTaskId.value, |
| | | } |
| | | await addMaintenanceTaskFile(payload) |
| | | ElMessage.success('æä»¶ä¸ä¼ æå') |
| | | await refreshFileList() |
| | | } catch (error) { |
| | | ElMessage.error('æä»¶ä¸ä¼ 失败') |
| | | } |
| | | } |
| | | |
| | | // å é¤éä»¶ |
| | | const handleAttachmentDelete = async (row) => { |
| | | if (!row?.id) return false |
| | | try { |
| | | await ElMessageBox.confirm('确认å é¤è¯¥éä»¶ï¼', 'æç¤º', { type: 'warning' }) |
| | | } catch { |
| | | return false |
| | | } |
| | | try { |
| | | await delMaintenanceTaskFile(row.id) |
| | | ElMessage.success('å 餿å') |
| | | await refreshFileList() |
| | | return true |
| | | } catch (error) { |
| | | ElMessage.error('å é¤å¤±è´¥') |
| | | return false |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | // æ ¹æ®é»è®¤æ¿æ´»ç Tab è°ç¨å¯¹åºçæ¥è¯¢æ¥å£ |
| | | if (activeTab.value === 'scheduled') { |