diff --git a/src/api/equipment-management/inspection-items.js b/src/api/equipment-management/inspection-items.js index 05102a12..4cd75259 100644 --- a/src/api/equipment-management/inspection-items.js +++ b/src/api/equipment-management/inspection-items.js @@ -27,3 +27,20 @@ export function deleteItem (data) { export function batchDeleteItems (data) { return request({ url: BASE + 'batch_delete', method: 'delete', data: params('device_management_device_check_device_check_items_batch_delete', data) }) } + +export function getImportTemplate (data) { + return request({ + url: BASE + 'get_import_template', + method: 'post', + responseType: 'blob', + data: params('device_management_device_check_device_check_items_get_import_template', data) + }) +} + +export function importData (data) { + return request({ + url: BASE + 'import_data_create', + method: 'post', + data: params('device_management_device_check_device_check_items_import_data_create', data) + }) +} diff --git a/src/api/equipment-management/inspection-logs.js b/src/api/equipment-management/inspection-logs.js index aeb50414..dcbef4b7 100644 --- a/src/api/equipment-management/inspection-logs.js +++ b/src/api/equipment-management/inspection-logs.js @@ -8,6 +8,14 @@ export function getList (data) { return request({ url: BASE + 'list', method: 'get', params: params('device_management_device_check_device_check_items_log_list', data) }) } +export function getDetails (data) { + return request({ url: BASE + 'details', method: 'get', params: params('device_management_device_check_device_check_items_log_details', data) }) +} + +export function getDetailsList (data) { + return request({ url: BASE + 'details_list', method: 'get', params: params('device_management_device_check_device_check_items_log_details_list', data) }) +} + export function createExportTask (data) { return request({ url: BASE + 'export', method: 'post', data: params('device_management_device_check_device_check_items_log_export', data) }) } diff --git a/src/api/equipment-management/inspection-records.js b/src/api/equipment-management/inspection-records.js index d29f9dc4..e80af9d5 100644 --- a/src/api/equipment-management/inspection-records.js +++ b/src/api/equipment-management/inspection-records.js @@ -13,5 +13,5 @@ export function createItem (data) { } export function editItem (data) { - return request({ url: BASE + 'create_record', method: 'put', data: params('device_management_device_check_device_check_create_record', data) }) + return request({ url: BASE + 'edit_record', method: 'post', data: params('device_management_device_check_device_check_edit_record', data) }) } diff --git a/src/locales/en.json b/src/locales/en.json index 9ead54ca..2b41b0bd 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1073,15 +1073,30 @@ "file_column_missing": "Import file is missing column: {title}", "file_format_error": "Please upload an xls or xlsx file", "import": "Import", - "import_template_name": "Consumables Category Import Template", + "import_template_name": "Inspection Item Import Template", "import_tip": "The uploaded file must be xlsx/xls and follow the template.", - "import_title": "Consumables Category Data Import", + "import_title": "Inspection Item Data Import", "length_1_100": "Length must be 1 to 100 characters", "please_import_data": "Please import data first", "please_select_data": "Please select data first", "select_file": "Select File", "sort": "No.", - "update_time": "Updated Time" + "update_time": "Updated Time", + "device_category": "Device Category", + "please_select_device_category": "Please select device category", + "check_method": "Inspection Method", + "enter_check_method": "Enter inspection method", + "unit": "Inspection Unit", + "enter_unit": "Enter inspection unit", + "frequentness": "Frequency", + "enter_frequentness": "Enter frequency", + "example": "Example", + "enter_example": "Enter example", + "enabled": "Enabled", + "disabled": "Disabled", + "please_select_status": "Please select status", + "import_file": "Import File", + "duplicate_import_name": "Inspection item name {name} is duplicated. Remove duplicates and upload again." }, "inspection_records": { "search": "Search", @@ -1222,7 +1237,24 @@ "standard_service_life": "Standard Service Life", "update_time": "Updated Time", "warning_life_not_greater_than_standard": "Warning life cannot be greater than standard life", - "warning_service_life": "Warning Service Life" + "warning_service_life": "Warning Service Life", + "add_inspection_record": "Add Inspection Log", + "last_inspection_time": "Last Inspection Time", + "last_inspection_result": "Last Inspection Result", + "last_item_total": "Last Item Total", + "last_ng_total": "Last NG Total", + "last_ng_rate": "Last NG Rate (%)", + "implementation_people": "Implementer", + "enter_implementation_people": "Enter implementer", + "class_please": "Shift", + "please_select_class_please": "Please select shift", + "day_shift": "Day", + "night_shift": "Night", + "check_method": "Inspection Method", + "unit": "Inspection Unit", + "inspection_value": "Inspection Value", + "enter_inspection_value": "Enter inspection value", + "inspection_items_empty": "No inspection items. Please configure them first." }, "inspection_logs": { "search": "Search", @@ -1335,7 +1367,29 @@ "replace_reason": "Replacement Reason", "enter_replace_reason": "Enter replacement reason", "replace_duration": "Replacement Duration", - "enter_replace_duration": "Enter replacement duration" + "enter_replace_duration": "Enter replacement duration", + "device_category": "Device Category", + "please_select_device_category": "Please select device category", + "start_time": "Start Time", + "end_time": "End Time", + "create_download_task_success": "Download task created successfully", + "details": "Details", + "details_title": "Inspection Log Details", + "close": "Close", + "sort": "No.", + "check_method": "Inspection Method", + "unit": "Inspection Unit", + "frequentness": "Frequency", + "example": "Example", + "inspection_value": "Inspection Value", + "class_please": "Shift", + "implementation_people": "Implementer", + "operator": "Operator", + "item_total": "Item Total", + "item_ng_number": "NG Total", + "item_ng_rate": "NG Rate (%)", + "please_enter_export_device_code": "Enter device code before exporting", + "please_select_export_time": "Select inspection time range before exporting" } }, "maintenance_management": { @@ -5206,8 +5260,7 @@ "sampling_time": "Sampling Time", "sample_value": "Sample Value" } - } - , + }, "scada_manage": { "basic_configuration": { "scada_configure": { @@ -5549,7 +5602,8 @@ "stop_device": "Stop Device" } } - }}, + } + }, "__MENU_TEMP_BEGIN__": "===== 以下为临时菜单翻译,后续统一删除 =====", "设备类型": "Device Type", "首页": "Home", diff --git a/src/locales/zh-chs.json b/src/locales/zh-chs.json index c1d73660..a2955079 100644 --- a/src/locales/zh-chs.json +++ b/src/locales/zh-chs.json @@ -1073,15 +1073,30 @@ "file_column_missing": "导入文件缺少列:{title}", "file_format_error": "请上传 xls 或 xlsx 文件", "import": "导入", - "import_template_name": "损耗品类别导入模板", + "import_template_name": "设备点检项目管理导入模板", "import_tip": "上传的文件后缀必须是 xlsx/xls,且需要按模板填写", - "import_title": "损耗品类别数据导入", + "import_title": "设备点检项目数据导入", "length_1_100": "长度在 1 到 100 个字符", "please_import_data": "请先导入数据", "please_select_data": "请先选择数据", "select_file": "选择文件", "sort": "序号", - "update_time": "更新时间" + "update_time": "更新时间", + "device_category": "设备类别", + "please_select_device_category": "请选择设备类别", + "check_method": "点检方法", + "enter_check_method": "请输入点检方法", + "unit": "点检单位", + "enter_unit": "请输入点检单位", + "frequentness": "频度", + "enter_frequentness": "请输入频度", + "example": "例", + "enter_example": "请输入例", + "enabled": "启用", + "disabled": "禁用", + "please_select_status": "请选择状态", + "import_file": "数据导入表格", + "duplicate_import_name": "【{name}】项目名称存在重复值,请去掉重复值并重新上传" }, "inspection_records": { "search": "查询", @@ -1222,7 +1237,24 @@ "standard_service_life": "标准使用寿命", "update_time": "更新时间", "warning_life_not_greater_than_standard": "预警使用寿命不能大于标准使用寿命", - "warning_service_life": "预警使用寿命" + "warning_service_life": "预警使用寿命", + "add_inspection_record": "新增点检日志", + "last_inspection_time": "上一次点检时间", + "last_inspection_result": "上一次点检结果", + "last_item_total": "上一次点检项目总数", + "last_ng_total": "上一次点检NG总数", + "last_ng_rate": "上一次点检NG率(%)", + "implementation_people": "实施人", + "enter_implementation_people": "请填写实施人", + "class_please": "班别", + "please_select_class_please": "请选择班别", + "day_shift": "早", + "night_shift": "夜", + "check_method": "点检方法", + "unit": "点检单位", + "inspection_value": "点检值", + "enter_inspection_value": "请输入点检值", + "inspection_items_empty": "设备点检项目为空,请先配置" }, "inspection_logs": { "search": "查询", @@ -1335,7 +1367,29 @@ "replace_reason": "更换原因", "enter_replace_reason": "请输入更换原因", "replace_duration": "更换耗时", - "enter_replace_duration": "请输入更换耗时" + "enter_replace_duration": "请输入更换耗时", + "device_category": "设备类别", + "please_select_device_category": "请选择设备类别", + "start_time": "开始时间", + "end_time": "结束时间", + "create_download_task_success": "创建下载任务成功", + "details": "详情", + "details_title": "点检日志详情", + "close": "关闭", + "sort": "序号", + "check_method": "点检方法", + "unit": "点检单位", + "frequentness": "频度", + "example": "例", + "inspection_value": "点检值", + "class_please": "班别", + "implementation_people": "实施人", + "operator": "操作人", + "item_total": "项目总数", + "item_ng_number": "NG总数", + "item_ng_rate": "NG率(%)", + "please_enter_export_device_code": "请输入设备编码后再导出", + "please_select_export_time": "请选择点检时间范围后再导出" } }, "maintenance_management": { @@ -5206,8 +5260,7 @@ "sampling_time": "采样时间", "sample_value": "样本值" } - } - , + }, "scada_manage": { "basic_configuration": { "scada_configure": { @@ -5549,7 +5602,8 @@ "stop_device": "停止设备" } } - }}, + } + }, "__MENU_TEMP_BEGIN__": "===== 以下为临时菜单翻译,后续统一删除 =====", "设备类型": "设备类型", "首页": "首页", diff --git a/src/views/equipment-management/inspection-management/inspection-items/index.vue b/src/views/equipment-management/inspection-management/inspection-items/index.vue index dc863cc1..191c38d9 100644 --- a/src/views/equipment-management/inspection-management/inspection-items/index.vue +++ b/src/views/equipment-management/inspection-management/inspection-items/index.vue @@ -2,15 +2,26 @@ @@ -58,7 +106,21 @@ import { i18nMixin } from '@/composables/useI18n' import { confirmMixin } from '@/composables/useConfirmHandle' import PageTable from '@/components/page-table' import PageDialogForm from '@/components/page-dialog-form' -import { getList, createItem, editItem, deleteItem } from '@/api/equipment-management/inspection-items' +import { downloadRename, readExcel } from '@/utils/file' +import { getEquipmentCategoryALL } from '@/api/equipment-management/equipment-category' +import { getList, createItem, editItem, deleteItem, batchDeleteItems, getImportTemplate, importData } from '@/api/equipment-management/inspection-items' + +function readPageData (res) { + const data = res && res.data !== undefined ? res.data : res + if (Array.isArray(data)) return { list: data, total: data.length } + if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) } + if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) } + return { list: [], total: 0 } +} + +function toOptions (list) { + return (Array.isArray(list) ? list : []).map(item => ({ label: item.name || item.label, value: item.id || item.value, raw: item })) +} export default { name: 'equipment-management-inspection-items', @@ -70,108 +132,77 @@ export default { submitting: false, tableData: [], selectedRows: [], + deviceCategoryOptions: [], + search: { device_category_id: '', name: '', check_method: '', standard: '', unit: '', create_time: [] }, + pagination: { current: 1, size: 10, total: 0 }, dialogVisible: false, dialogTitle: '', - editId: '', handleType: 'create', - search: { - keyword: '' - }, - pagination: { current: 1, size: 10, total: 0 }, - formData: { - device_check_item_code: '', - device_check_item_name: '', - device_id: '', - cycle: '', - standard: '', - remark: '' - }, - rules: { - device_check_item_code: [{ required: true, message: this.key('enter_inspection_item_code'), trigger: 'blur' }], - device_check_item_name: [{ required: true, message: this.key('enter_inspection_item_name'), trigger: 'blur' }] - }, + editId: '', + formData: this.emptyForm(), + importVisible: false, + importDeviceCategoryId: '', + importFileList: [], + importRows: [], + importLoading: false, + importTableLoading: false, columns: [], toolbarButtons: [], rowButtons: [], - formCols: [ + rules: { + name: [ + { required: true, message: this.key('enter_inspection_item_name'), trigger: 'blur' }, + { min: 1, max: 100, message: this.key('length_1_100'), trigger: 'blur' } + ], + device_category_id: [{ required: true, message: this.key('please_select_device_category'), trigger: 'change' }], + status: [{ required: true, message: this.key('please_select_status'), trigger: 'change' }] + } + } + }, + computed: { + formCols () { + return [ [ - { - type: 'input', - prop: 'device_check_item_code', - label: this.key('inspection_item_code'), - placeholder: this.key('enter_inspection_item_code'), - clearable: true, - style: { width: '90%' } - } + { type: 'input', prop: 'name', label: this.key('inspection_item_name'), placeholder: this.key('enter_inspection_item_name'), style: { width: '100%' } }, + { type: 'select', prop: 'device_category_id', label: this.key('device_category'), placeholder: this.key('please_select_device_category'), options: this.deviceCategoryOptions, style: { width: '100%' } } ], [ - { - type: 'input', - prop: 'device_check_item_name', - label: this.key('inspection_item_name'), - placeholder: this.key('enter_inspection_item_name'), - clearable: true, - style: { width: '90%' } - } + { type: 'select', prop: 'status', label: this.key('status'), placeholder: this.key('please_select_status'), options: [{ label: this.$t(this.key('enabled')), value: 1 }, { label: this.$t(this.key('disabled')), value: 0 }], style: { width: '100%' } }, + { type: 'input', prop: 'standard', label: this.key('standard'), placeholder: this.key('enter_standard'), style: { width: '100%' } } ], [ - { - type: 'input', - prop: 'device_id', - label: this.key('device_id'), - placeholder: this.key('enter_device_id'), - clearable: true, - style: { width: '90%' } - } + { type: 'input', prop: 'check_method', label: this.key('check_method'), placeholder: this.key('enter_check_method'), style: { width: '100%' } }, + { type: 'input', prop: 'unit', label: this.key('unit'), placeholder: this.key('enter_unit'), style: { width: '100%' } } ], [ - { - type: 'input', - prop: 'cycle', - label: this.key('cycle'), - placeholder: this.key('enter_cycle'), - clearable: true, - style: { width: '90%' } - } + { type: 'input', prop: 'frequentness', label: this.key('frequentness'), placeholder: this.key('enter_frequentness'), style: { width: '100%' } }, + { type: 'input', prop: 'example', label: this.key('example'), placeholder: this.key('enter_example'), style: { width: '100%' } } ], - [ - { - type: 'input', - prop: 'standard', - label: this.key('standard'), - placeholder: this.key('enter_standard'), - clearable: true, - style: { width: '90%' } - } - ], - [ - { - type: 'input', - prop: 'remark', - label: this.key('remark'), - placeholder: this.key('enter_remark'), - inputType: 'textarea', - autosize: { minRows: 2, maxRows: 6 }, - clearable: true, - style: { width: '90%' } - } - ] + [{ type: 'input', prop: 'remark', label: this.key('remark'), placeholder: this.key('enter_remark'), inputType: 'textarea', autosize: { minRows: 2, maxRows: 6 }, style: { width: '100%' } }] ] } }, created () { this.columns = useTableColumns([ - { prop: 'device_check_item_code', label: this.key('inspection_item_code'), minWidth: 140 }, - { prop: 'device_check_item_name', label: this.key('inspection_item_name'), minWidth: 140 }, - { prop: 'device_name', label: this.key('device_name'), minWidth: 140 }, - { prop: 'cycle', label: this.key('cycle'), minWidth: 140 }, - { prop: 'standard', label: this.key('standard'), minWidth: 140 }, - { prop: 'remark', label: this.key('remark'), minWidth: 140 }, + { prop: 'sort', label: this.key('sort'), width: 80 }, + { prop: 'name', label: this.key('inspection_item_name'), minWidth: 150 }, + { prop: 'device_category_name', label: this.key('device_category'), minWidth: 140 }, + { prop: 'status', label: this.key('status'), slot: 'status', width: 100 }, + { prop: 'standard', label: this.key('standard'), minWidth: 140, showOverflowTooltip: true }, + { prop: 'check_method', label: this.key('check_method'), minWidth: 140, showOverflowTooltip: true }, + { prop: 'unit', label: this.key('unit'), minWidth: 100 }, + { prop: 'frequentness', label: this.key('frequentness'), minWidth: 110 }, + { prop: 'example', label: this.key('example'), minWidth: 110 }, + { prop: 'remark', label: this.key('remark'), minWidth: 140, showOverflowTooltip: true }, + { prop: 'create_time', label: this.key('create_time'), minWidth: 160 }, + { prop: 'update_time', label: this.key('update_time'), minWidth: 160 }, { prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' } ]) const btns = useTableButtons({ toolbar: [ - { key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_check/device_check_items/create', onClick: this.openAdd } + { key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_check/device_check_items/create', onClick: this.openAdd }, + { key: 'batch_delete', label: this.key('batch_delete'), icon: 'el-icon-delete', type: 'danger', auth: '/device_management/device_check/device_check_items/batch-delete', needSelection: true, disabledTip: this.key('please_select_data'), onClick: this.handleBatchDelete }, + { key: 'import', label: this.key('import'), icon: 'el-icon-upload2', type: 'success', auth: '/device_management/device_check/device_check_items/import', onClick: this.openImport } ], row: [ { key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_check/device_check_items/edit', onClick: this.openEdit }, @@ -180,23 +211,29 @@ export default { }, this.$permission) this.toolbarButtons = btns.toolbarButtons this.rowButtons = btns.rowButtons + this.loadDeviceCategories() this.fetchData() }, methods: { - normalizeResponse (res) { - const data = res && res.data !== undefined ? res.data : res - if (Array.isArray(data)) return { list: data, total: data.length } - if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) } - if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) } - return { list: [], total: 0 } + emptyForm () { + return { name: '', device_category_id: '', status: 1, standard: '', check_method: '', unit: '', frequentness: '', example: '', remark: '' } + }, + async loadDeviceCategories () { + const res = await getEquipmentCategoryALL({}) + this.deviceCategoryOptions = toOptions((res && res.data) || res) + }, + buildSearchParams () { + const params = { ...this.search } + if (!Array.isArray(params.create_time) || !params.create_time.length) delete params.create_time + return params }, async fetchData () { this.loading = true try { - const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size }) - const data = this.normalizeResponse(res) - this.tableData = data.list - this.pagination.total = data.total + const res = await getList({ ...this.buildSearchParams(), page_no: this.pagination.current, page_size: this.pagination.size }) + const page = readPageData(res) + this.tableData = page.list + this.pagination.total = page.total } finally { this.loading = false } @@ -206,9 +243,7 @@ export default { this.fetchData() }, onReset () { - this.search = { - keyword: '' - } + this.search = { device_category_id: '', name: '', check_method: '', standard: '', unit: '', create_time: [] } this.pagination.current = 1 this.fetchData() }, @@ -217,39 +252,29 @@ export default { this.pagination.size = page.size this.fetchData() }, - onSelect (rows) { - this.selectedRows = rows - }, resetForm () { - this.formData = { - device_check_item_code: '', - device_check_item_name: '', - device_id: '', - cycle: '', - standard: '', - remark: '' - } + this.formData = this.emptyForm() this.editId = '' }, openAdd () { this.handleType = 'create' this.dialogTitle = this.key('add_title') - this.$nextTick(() => { - this.$refs.dialogForm && this.$refs.dialogForm.reset() - this.resetForm() - this.dialogVisible = true - }) + this.resetForm() + this.dialogVisible = true }, openEdit (row) { this.handleType = 'edit' this.dialogTitle = this.key('edit_title') this.editId = row.id this.formData = { - device_check_item_code: row.device_check_item_code || '', - device_check_item_name: row.device_check_item_name || '', - device_id: row.device_id || '', - cycle: row.cycle || '', + name: row.name || '', + device_category_id: row.device_category_id || '', + status: Number(row.status), standard: row.standard || '', + check_method: row.check_method || '', + unit: row.unit || '', + frequentness: row.frequentness || '', + example: row.example || '', remark: row.remark || '' } this.dialogVisible = true @@ -266,17 +291,102 @@ export default { this.submitting = false } }, - onDialogClose () { - this.resetForm() - }, async handleDelete (row) { const cancelled = await this.$confirmAction( - { message: this.key('confirm_delete'), title: this.key('tip') }, + { message: this.key('confirm_delete'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteItem({ id: [row.id] }) ) - if (cancelled) return + if (!cancelled) { + this.$message.success(this.$t(this.key('operation_success'))) + this.fetchData() + } + }, + async handleBatchDelete () { + if (!this.selectedRows.length) { + this.$message.warning(this.$t(this.key('please_select_data'))) + return + } + const ids = this.selectedRows.map(item => item.id) + const cancelled = await this.$confirmAction( + { message: this.key('confirm_batch_delete'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, + () => batchDeleteItems({ id: ids }) + ) + if (!cancelled) { + this.$message.success(this.$t(this.key('operation_success'))) + this.fetchData() + } + }, + openImport () { + this.importDeviceCategoryId = '' + this.importFileList = [] + this.importRows = [] + this.importVisible = true + }, + async downloadTemplate () { + this.importLoading = true + try { + const res = await getImportTemplate({}) + downloadRename(res, 'xlsx', this.$t(this.key('import_template_name'))) + } finally { + this.importLoading = false + } + }, + async onImportFileChange (file) { + if (!file || !/\.(xls|xlsx)$/i.test(file.name)) { + this.$message.error(this.$t(this.key('file_format_error'))) + return + } + this.importFileList = [file] + this.importTableLoading = true + try { + const rows = await readExcel(file.raw) + const headers = ['inspection_item_name', 'status', 'standard', 'check_method', 'unit', 'frequentness', 'example', 'remark'].map(item => this.$t(this.key(item))) + const first = rows[0] || {} + for (const title of headers) { + if (!Object.prototype.hasOwnProperty.call(first, title)) { + this.$message.error(this.$t(this.key('file_column_missing'), { title })) + this.importRows = [] + return + } + } + const names = new Set() + const normalized = [] + for (const row of rows) { + const name = row[headers[0]] + if (names.has(name)) { + this.$message.error(this.$t(this.key('duplicate_import_name'), { name })) + this.importRows = [] + return + } + names.add(name) + normalized.push({ + name, + status: row[headers[1]], + standard: row[headers[2]], + check_method: row[headers[3]], + unit: row[headers[4]], + frequentness: row[headers[5]], + example: row[headers[6]], + remark: row[headers[7]] + }) + } + this.importRows = normalized + } finally { + this.importTableLoading = false + } + }, + async submitImport () { + if (!this.importDeviceCategoryId) { + this.$message.warning(this.$t(this.key('please_select_device_category'))) + return + } + if (!this.importRows.length) { + this.$message.warning(this.$t(this.key('please_import_data'))) + return + } + await importData({ device_category_id: this.importDeviceCategoryId, import_data: JSON.stringify(this.importRows) }) this.$message.success(this.$t(this.key('operation_success'))) - this.pagination.current = Math.min(this.pagination.current, Math.ceil((this.pagination.total - 1) / this.pagination.size) || 1) + this.importVisible = false this.fetchData() } } @@ -285,5 +395,6 @@ export default { diff --git a/src/views/equipment-management/inspection-management/inspection-logs/index.vue b/src/views/equipment-management/inspection-management/inspection-logs/index.vue index 9b070fd7..5c5bb164 100644 --- a/src/views/equipment-management/inspection-management/inspection-logs/index.vue +++ b/src/views/equipment-management/inspection-management/inspection-logs/index.vue @@ -2,15 +2,20 @@ @@ -41,7 +74,27 @@ import { useTableButtons } from '@/composables/useTableButtons' import { i18nMixin } from '@/composables/useI18n' import { confirmMixin } from '@/composables/useConfirmHandle' import PageTable from '@/components/page-table' -import { getList, createExportTask } from '@/api/equipment-management/inspection-logs' +import { getEquipmentCategoryALL } from '@/api/equipment-management/equipment-category' +import { getList, getDetails, createExportTask } from '@/api/equipment-management/inspection-logs' + +function readPageData (res) { + const data = res && res.data !== undefined ? res.data : res + if (Array.isArray(data)) return { list: data, total: data.length } + if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) } + if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) } + return { list: [], total: 0 } +} + +function readList (res) { + const data = res && res.data !== undefined ? res.data : res + if (Array.isArray(data)) return data + if (data && Array.isArray(data.data)) return data.data + return [] +} + +function toOptions (list) { + return (Array.isArray(list) ? list : []).map(item => ({ label: item.name || item.label, value: item.id || item.value, raw: item })) +} export default { name: 'equipment-management-inspection-logs', @@ -50,63 +103,62 @@ export default { data () { return { loading: false, - submitting: false, + detailsLoading: false, tableData: [], - selectedRows: [], - dialogVisible: false, - dialogTitle: '', - editId: '', - handleType: 'create', - search: { - keyword: '' - }, + detailsData: [], + detailsVisible: false, + deviceCategoryOptions: [], + search: { device_category_id: '', device_code: '', device_name: '', create_time: [] }, pagination: { current: 1, size: 10, total: 0 }, - formData: { - - }, - rules: {}, columns: [], toolbarButtons: [], - rowButtons: [], - formCols: [] + rowButtons: [] } }, created () { this.columns = useTableColumns([ - { prop: 'device_code', label: this.key('device_code'), minWidth: 140 }, - { prop: 'device_name', label: this.key('device_name'), minWidth: 140 }, - { prop: 'check_item_name', label: this.key('inspection_item'), minWidth: 140 }, - { prop: 'check_result', label: this.key('inspection_result'), minWidth: 140 }, - { prop: 'check_user', label: this.key('inspection_user'), minWidth: 140 }, - { prop: 'check_time', label: this.key('inspection_time'), minWidth: 140 } - ]) + { prop: 'device_code', label: this.key('device_code'), minWidth: 140, fixed: 'left' }, + { prop: 'device_name', label: this.key('device_name'), minWidth: 150, fixed: 'left' }, + { prop: 'device_category_name', label: this.key('device_category'), minWidth: 140 }, + { prop: 'result', label: this.key('inspection_result'), slot: 'result', width: 120 }, + { prop: 'item_total', label: this.key('item_total'), minWidth: 120 }, + { prop: 'item_ng_number', label: this.key('item_ng_number'), minWidth: 120 }, + { prop: 'item_ng_rate', label: this.key('item_ng_rate'), minWidth: 130 }, + { prop: 'username', label: this.key('operator'), minWidth: 120 }, + { prop: 'remark', label: this.key('remark'), minWidth: 140, showOverflowTooltip: true }, + { prop: 'create_time', label: this.key('inspection_time'), minWidth: 160 }, + { prop: '_actions', label: this.key('operation'), width: 120, fixed: 'right' } + ], { selectionWidth: 0 }) const btns = useTableButtons({ toolbar: [ - { key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_check/device_check_items_log/export', onClick: this.handleExport } + { key: 'export', label: this.key('export'), icon: 'el-icon-download', type: 'primary', auth: '/device_management/device_check/device_check_items_log/export', onClick: this.handleExport } ], row: [ - + { key: 'details', label: this.key('details'), icon: 'el-icon-view', auth: '/device_management/device_check/device_check_items_log/details', onClick: this.openDetails } ] }, this.$permission) this.toolbarButtons = btns.toolbarButtons this.rowButtons = btns.rowButtons + this.loadDeviceCategories() this.fetchData() }, methods: { - normalizeResponse (res) { - const data = res && res.data !== undefined ? res.data : res - if (Array.isArray(data)) return { list: data, total: data.length } - if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) } - if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) } - return { list: [], total: 0 } + async loadDeviceCategories () { + const res = await getEquipmentCategoryALL({}) + this.deviceCategoryOptions = toOptions((res && res.data) || res) + }, + buildSearchParams () { + const params = { ...this.search } + if (!Array.isArray(params.create_time) || !params.create_time.length) delete params.create_time + return params }, async fetchData () { this.loading = true try { - const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size }) - const data = this.normalizeResponse(res) - this.tableData = data.list - this.pagination.total = data.total + const res = await getList({ ...this.buildSearchParams(), page_no: this.pagination.current, page_size: this.pagination.size }) + const page = readPageData(res) + this.tableData = page.list + this.pagination.total = page.total } finally { this.loading = false } @@ -116,9 +168,7 @@ export default { this.fetchData() }, onReset () { - this.search = { - keyword: '' - } + this.search = { device_category_id: '', device_code: '', device_name: '', create_time: [] } this.pagination.current = 1 this.fetchData() }, @@ -127,22 +177,30 @@ export default { this.pagination.size = page.size this.fetchData() }, - onSelect (rows) { - this.selectedRows = rows - }, - resetForm () { - this.formData = { - + async openDetails (row) { + this.detailsVisible = true + this.detailsLoading = true + try { + const res = await getDetails({ device_check_items_log_id: row.id }) + this.detailsData = readList(res) + } finally { + this.detailsLoading = false } - this.editId = '' }, async handleExport () { + if (!this.search.device_code) { + this.$message.warning(this.$t(this.key('please_enter_export_device_code'))) + return + } + if (!Array.isArray(this.search.create_time) || this.search.create_time.length !== 2) { + this.$message.warning(this.$t(this.key('please_select_export_time'))) + return + } const cancelled = await this.$confirmAction( - { message: this.key('confirm_export'), title: this.key('tip') }, - () => createExportTask({ ...this.search }) + { message: this.key('confirm_export'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, + () => createExportTask(this.buildSearchParams()) ) - if (cancelled) return - this.$message.success(this.$t(this.key('operation_success'))) + if (!cancelled) this.$message.success(this.$t(this.key('create_download_task_success'))) } } } diff --git a/src/views/equipment-management/inspection-management/inspection-records/index.vue b/src/views/equipment-management/inspection-management/inspection-records/index.vue index c63bc72d..4802551c 100644 --- a/src/views/equipment-management/inspection-management/inspection-records/index.vue +++ b/src/views/equipment-management/inspection-management/inspection-records/index.vue @@ -2,15 +2,17 @@ @@ -55,136 +89,97 @@ import { useTableColumns } from '@/composables/useTableColumns' import { useTableButtons } from '@/composables/useTableButtons' import { i18nMixin } from '@/composables/useI18n' -import { confirmMixin } from '@/composables/useConfirmHandle' import PageTable from '@/components/page-table' -import PageDialogForm from '@/components/page-dialog-form' -import { getList, createItem, editItem } from '@/api/equipment-management/inspection-records' +import { getEquipmentCategoryALL } from '@/api/equipment-management/equipment-category' +import { getList, createItem } from '@/api/equipment-management/inspection-records' +import { getAll as getInspectionItemsAll } from '@/api/equipment-management/inspection-items' + +function readPageData (res) { + const data = res && res.data !== undefined ? res.data : res + if (Array.isArray(data)) return { list: data, total: data.length } + if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) } + if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) } + return { list: [], total: 0 } +} + +function readList (res) { + const data = res && res.data !== undefined ? res.data : res + if (Array.isArray(data)) return data + if (data && Array.isArray(data.data)) return data.data + return [] +} + +function toOptions (list) { + return (Array.isArray(list) ? list : []).map(item => ({ label: item.name || item.label, value: item.id || item.value, raw: item })) +} export default { name: 'equipment-management-inspection-records', - components: { PageTable, PageDialogForm }, - mixins: [i18nMixin('page.equipment_management.inspection_management.inspection_records'), confirmMixin], + components: { PageTable }, + mixins: [i18nMixin('page.equipment_management.inspection_management.inspection_records')], data () { return { loading: false, submitting: false, + itemsLoading: false, tableData: [], - selectedRows: [], - dialogVisible: false, - dialogTitle: '', - editId: '', - handleType: 'create', - search: { - keyword: '' - }, + deviceCategoryOptions: [], + search: { device_category_id: '', device_code: '', device_name: '' }, pagination: { current: 1, size: 10, total: 0 }, - formData: { - device_id: '', - check_status: '', - check_user: '', - check_time: '', - remark: '' - }, - rules: { - device_id: [{ required: true, message: this.key('enter_device_id'), trigger: 'blur' }], - check_status: [{ required: true, message: this.key('enter_inspection_status'), trigger: 'blur' }] - }, + dialogVisible: false, + currentDevice: null, + recordForm: { implementation_people: '', class_please: '' }, + itemSearch: { name: '' }, + inspectionItems: [], columns: [], toolbarButtons: [], rowButtons: [], - formCols: [ - [ - { - type: 'input', - prop: 'device_id', - label: this.key('device_id'), - placeholder: this.key('enter_device_id'), - clearable: true, - style: { width: '90%' } - } - ], - [ - { - type: 'input', - prop: 'check_status', - label: this.key('inspection_status'), - placeholder: this.key('enter_inspection_status'), - clearable: true, - style: { width: '90%' } - } - ], - [ - { - type: 'input', - prop: 'check_user', - label: this.key('inspection_user'), - placeholder: this.key('enter_inspection_user'), - clearable: true, - style: { width: '90%' } - } - ], - [ - { - type: 'input', - prop: 'check_time', - label: this.key('inspection_time'), - placeholder: this.key('enter_inspection_time'), - clearable: true, - style: { width: '90%' } - } - ], - [ - { - type: 'input', - prop: 'remark', - label: this.key('remark'), - placeholder: this.key('enter_remark'), - inputType: 'textarea', - autosize: { minRows: 2, maxRows: 6 }, - clearable: true, - style: { width: '90%' } - } - ] - ] + recordRules: { + implementation_people: [{ required: true, message: this.$t(this.key('enter_implementation_people')), trigger: 'blur' }], + class_please: [{ required: true, message: this.$t(this.key('please_select_class_please')), trigger: 'change' }] + } + } + }, + computed: { + dialogTitleText () { + const name = this.currentDevice ? `${this.currentDevice.device_code || ''} ${this.currentDevice.device_name || ''}`.trim() : '' + return `${this.$t(this.key('add_inspection_record'))}${name ? ` - ${name}` : ''}` } }, created () { this.columns = useTableColumns([ - { prop: 'device_code', label: this.key('device_code'), minWidth: 140 }, - { prop: 'device_name', label: this.key('device_name'), minWidth: 140 }, - { prop: 'check_status', label: this.key('inspection_status'), minWidth: 140 }, - { prop: 'check_user', label: this.key('inspection_user'), minWidth: 140 }, - { prop: 'check_time', label: this.key('inspection_time'), minWidth: 140 }, - { prop: 'remark', label: this.key('remark'), minWidth: 140 }, - { prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' } - ]) + { prop: 'device_code', label: this.key('device_code'), minWidth: 140, fixed: 'left' }, + { prop: 'device_name', label: this.key('device_name'), minWidth: 150, fixed: 'left' }, + { prop: 'device_category_name', label: this.key('device_category'), minWidth: 140 }, + { prop: 'check_time', label: this.key('last_inspection_time'), minWidth: 160 }, + { prop: 'check_result', label: this.key('last_inspection_result'), slot: 'check_result', minWidth: 140 }, + { prop: 'item_total', label: this.key('last_item_total'), minWidth: 150 }, + { prop: 'item_ng_number', label: this.key('last_ng_total'), minWidth: 150 }, + { prop: 'item_ng_rate', label: this.key('last_ng_rate'), minWidth: 150 }, + { prop: '_actions', label: this.key('operation'), width: 150, fixed: 'right' } + ], { selectionWidth: 0 }) const btns = useTableButtons({ - toolbar: [ - { key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_check/device_check_record/create', onClick: this.openAdd } - ], row: [ - { key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_check/device_check_record/edit', onClick: this.openEdit } + { key: 'create', label: this.key('add_inspection_record'), icon: 'el-icon-plus', auth: '/device_management/device_check/device_check_record/create', onClick: this.openCreate } ] }, this.$permission) this.toolbarButtons = btns.toolbarButtons this.rowButtons = btns.rowButtons + this.loadDeviceCategories() this.fetchData() }, methods: { - normalizeResponse (res) { - const data = res && res.data !== undefined ? res.data : res - if (Array.isArray(data)) return { list: data, total: data.length } - if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) } - if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) } - return { list: [], total: 0 } + async loadDeviceCategories () { + const res = await getEquipmentCategoryALL({}) + this.deviceCategoryOptions = toOptions((res && res.data) || res) }, async fetchData () { this.loading = true try { const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size }) - const data = this.normalizeResponse(res) - this.tableData = data.list - this.pagination.total = data.total + const page = readPageData(res) + this.tableData = page.list + this.pagination.total = page.total } finally { this.loading = false } @@ -194,9 +189,7 @@ export default { this.fetchData() }, onReset () { - this.search = { - keyword: '' - } + this.search = { device_category_id: '', device_code: '', device_name: '' } this.pagination.current = 1 this.fetchData() }, @@ -205,55 +198,63 @@ export default { this.pagination.size = page.size this.fetchData() }, - onSelect (rows) { - this.selectedRows = rows - }, - resetForm () { - this.formData = { - device_id: '', - check_status: '', - check_user: '', - check_time: '', - remark: '' - } - this.editId = '' - }, - openAdd () { - this.handleType = 'create' - this.dialogTitle = this.key('add_title') - this.$nextTick(() => { - this.$refs.dialogForm && this.$refs.dialogForm.reset() - this.resetForm() - this.dialogVisible = true - }) - }, - openEdit (row) { - this.handleType = 'edit' - this.dialogTitle = this.key('edit_title') - this.editId = row.id - this.formData = { - device_id: row.device_id || '', - check_status: row.check_status || '', - check_user: row.check_user || '', - check_time: row.check_time || '', - remark: row.remark || '' - } + openCreate (row) { + this.currentDevice = row this.dialogVisible = true + this.resetDialog(false) + this.loadInspectionItems() }, - async onDialogSubmit () { - this.submitting = true + resetDialog (clearDevice = true) { + this.recordForm = { implementation_people: '', class_please: '' } + this.itemSearch = { name: '' } + this.inspectionItems = [] + if (clearDevice) this.currentDevice = null + }, + resetItemSearch () { + this.itemSearch = { name: '' } + this.loadInspectionItems() + }, + async loadInspectionItems () { + if (!this.currentDevice || !this.currentDevice.device_category_id) return + this.itemsLoading = true try { - if (this.handleType === 'create') await createItem(this.formData) - else await editItem({ ...this.formData, id: this.editId }) - this.$message.success(this.$t(this.key('operation_success'))) - this.dialogVisible = false - this.fetchData() + const res = await getInspectionItemsAll({ + device_category_id: this.currentDevice.device_category_id, + name: this.itemSearch.name + }) + this.inspectionItems = readList(res).map(item => ({ + ...item, + val: '', + result: 'OK' + })) } finally { - this.submitting = false + this.itemsLoading = false } }, - onDialogClose () { - this.resetForm() + submitRecord () { + this.$refs.recordForm.validate(async valid => { + if (!valid) return + if (!this.inspectionItems.length) { + this.$message.warning(this.$t(this.key('inspection_items_empty'))) + return + } + this.submitting = true + try { + await createItem({ + deviceCheckItemsData: JSON.stringify(this.inspectionItems), + device_category_id: this.currentDevice.device_category_id, + device_code: this.currentDevice.device_code, + class_please: this.recordForm.class_please, + implementation_people: this.recordForm.implementation_people, + status: 1 + }) + this.$message.success(this.$t(this.key('operation_success'))) + this.dialogVisible = false + this.fetchData() + } finally { + this.submitting = false + } + }) } } }