迁移设备损耗品管理功能
This commit is contained in:
@@ -27,3 +27,16 @@ export function deleteItem (data) {
|
|||||||
export function createExportTask (data) {
|
export function createExportTask (data) {
|
||||||
return request({ url: BASE + 'data_export_task', method: 'post', data: params('device_management_device_consumables_device_consumables_category_data_export_task', data) })
|
return request({ url: BASE + 'data_export_task', method: 'post', data: params('device_management_device_consumables_device_consumables_category_data_export_task', data) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getImportTemplate (data) {
|
||||||
|
return request({
|
||||||
|
url: BASE + 'get_import_template',
|
||||||
|
method: 'post',
|
||||||
|
responseType: 'blob',
|
||||||
|
data: params('device_management_device_consumables_device_consumables_category_get_import_template', data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function importData (data) {
|
||||||
|
return request({ url: BASE + 'data_import', method: 'post', data: params('device_management_device_consumables_device_consumables_category_data_import', data) })
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,3 +27,16 @@ export function deleteItem (data) {
|
|||||||
export function createExportTask (data) {
|
export function createExportTask (data) {
|
||||||
return request({ url: BASE + 'data_export_task', method: 'post', data: params('device_management_device_consumables_device_consumables_items_data_export_task', data) })
|
return request({ url: BASE + 'data_export_task', method: 'post', data: params('device_management_device_consumables_device_consumables_items_data_export_task', data) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getImportTemplate (data) {
|
||||||
|
return request({
|
||||||
|
url: BASE + 'get_import_template',
|
||||||
|
method: 'post',
|
||||||
|
responseType: 'blob',
|
||||||
|
data: params('device_management_device_consumables_device_consumables_items_get_import_template', data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function importData (data) {
|
||||||
|
return request({ url: BASE + 'data_import', method: 'post', data: params('device_management_device_consumables_device_consumables_items_data_import', data) })
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,3 +27,16 @@ export function deleteItem (data) {
|
|||||||
export function createExportTask (data) {
|
export function createExportTask (data) {
|
||||||
return request({ url: BASE + 'data_export_task', method: 'post', data: params('device_management_device_consumables_device_consumables_lifetime_management_data_export_task', data) })
|
return request({ url: BASE + 'data_export_task', method: 'post', data: params('device_management_device_consumables_device_consumables_lifetime_management_data_export_task', data) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getImportTemplate (data) {
|
||||||
|
return request({
|
||||||
|
url: BASE + 'get_import_template',
|
||||||
|
method: 'post',
|
||||||
|
responseType: 'blob',
|
||||||
|
data: params('device_management_device_consumables_device_consumables_lifetime_management_get_import_template', data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function importData (data) {
|
||||||
|
return request({ url: BASE + 'data_import', method: 'post', data: params('device_management_device_consumables_device_consumables_lifetime_management_data_import', data) })
|
||||||
|
}
|
||||||
|
|||||||
@@ -74,6 +74,33 @@
|
|||||||
@focus="handleFieldEvent(col, 'focus', $event)"
|
@focus="handleFieldEvent(col, 'focus', $event)"
|
||||||
@blur="handleFieldEvent(col, 'blur', $event)"
|
@blur="handleFieldEvent(col, 'blur', $event)"
|
||||||
/>
|
/>
|
||||||
|
<el-input-number
|
||||||
|
v-else-if="col.type === 'input-number'"
|
||||||
|
v-model="formData[col.prop]"
|
||||||
|
:min="col.min"
|
||||||
|
:max="col.max"
|
||||||
|
:step="col.step || 1"
|
||||||
|
:precision="col.precision"
|
||||||
|
:controls-position="col.controlsPosition"
|
||||||
|
:disabled="!!col.disabled"
|
||||||
|
:style="col.style"
|
||||||
|
@change="handleFieldEvent(col, 'change', $event)"
|
||||||
|
@focus="handleFieldEvent(col, 'focus', $event)"
|
||||||
|
@blur="handleFieldEvent(col, 'blur', $event)"
|
||||||
|
/>
|
||||||
|
<el-date-picker
|
||||||
|
v-else-if="col.type === 'date-picker'"
|
||||||
|
v-model="formData[col.prop]"
|
||||||
|
:type="col.dateType || 'datetime'"
|
||||||
|
:placeholder="$t(col.placeholder)"
|
||||||
|
:value-format="col.valueFormat || 'yyyy-MM-dd HH:mm:ss'"
|
||||||
|
:format="col.format"
|
||||||
|
:clearable="col.clearable !== false"
|
||||||
|
:disabled="!!col.disabled"
|
||||||
|
:style="col.style"
|
||||||
|
@change="handleFieldEvent(col, 'change', $event)"
|
||||||
|
@focus="handleFieldEvent(col, 'focus', $event)"
|
||||||
|
/>
|
||||||
<!-- ===== 下拉选择类型 ===== -->
|
<!-- ===== 下拉选择类型 ===== -->
|
||||||
<!--
|
<!--
|
||||||
select:
|
select:
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
:icon="btn.icon"
|
:icon="btn.icon"
|
||||||
:style="btn.cssStyle"
|
:style="btn.cssStyle"
|
||||||
:disabled="btn.needSelection && !selectedCount"
|
:disabled="btn.needSelection && !selectedCount"
|
||||||
|
:title="getToolbarDisabledTip(btn)"
|
||||||
@click="btn.onClick"
|
@click="btn.onClick"
|
||||||
>
|
>
|
||||||
{{ $t(btn.label) }}
|
{{ $t(btn.label) }}
|
||||||
@@ -449,6 +450,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getToolbarDisabledTip (btn) {
|
||||||
|
if (!btn || !btn.needSelection || this.selectedCount) return ''
|
||||||
|
return btn.disabledTip ? this.$t(btn.disabledTip) : ''
|
||||||
|
},
|
||||||
|
|
||||||
/* ============ 分页事件 ============ */
|
/* ============ 分页事件 ============ */
|
||||||
|
|
||||||
onSizeChange (size) {
|
onSizeChange (size) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export function useTableButtons (options = {}, permissionCheck) {
|
|||||||
auth: btn.auth,
|
auth: btn.auth,
|
||||||
cssStyle: btn.cssStyle || {},
|
cssStyle: btn.cssStyle || {},
|
||||||
needSelection: !!btn.needSelection,
|
needSelection: !!btn.needSelection,
|
||||||
|
disabledTip: btn.disabledTip,
|
||||||
onClick: btn.onClick,
|
onClick: btn.onClick,
|
||||||
hasPermission: btn.auth ? check(btn.auth) : true
|
hasPermission: btn.auth ? check(btn.auth) : true
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -1063,7 +1063,25 @@
|
|||||||
"replace_reason": "Replacement Reason",
|
"replace_reason": "Replacement Reason",
|
||||||
"enter_replace_reason": "Enter replacement reason",
|
"enter_replace_reason": "Enter replacement reason",
|
||||||
"replace_duration": "Replacement Duration",
|
"replace_duration": "Replacement Duration",
|
||||||
"enter_replace_duration": "Enter replacement duration"
|
"enter_replace_duration": "Enter replacement duration",
|
||||||
|
"batch_delete": "Batch Delete",
|
||||||
|
"confirm_batch_delete": "Delete selected records?",
|
||||||
|
"create_download_task_success": "Download task created successfully",
|
||||||
|
"download_template": "Download Template",
|
||||||
|
"start_time": "Start Time",
|
||||||
|
"end_time": "End Time",
|
||||||
|
"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_tip": "The uploaded file must be xlsx/xls and follow the template.",
|
||||||
|
"import_title": "Consumables Category 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"
|
||||||
},
|
},
|
||||||
"inspection_records": {
|
"inspection_records": {
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
@@ -1176,7 +1194,35 @@
|
|||||||
"replace_reason": "Replacement Reason",
|
"replace_reason": "Replacement Reason",
|
||||||
"enter_replace_reason": "Enter replacement reason",
|
"enter_replace_reason": "Enter replacement reason",
|
||||||
"replace_duration": "Replacement Duration",
|
"replace_duration": "Replacement Duration",
|
||||||
"enter_replace_duration": "Enter replacement duration"
|
"enter_replace_duration": "Enter replacement duration",
|
||||||
|
"batch_delete": "Batch Delete",
|
||||||
|
"confirm_batch_delete": "Delete selected records?",
|
||||||
|
"create_download_task_success": "Download task created successfully",
|
||||||
|
"device_category": "Device Category",
|
||||||
|
"device_consumables_category_name": "Consumables Category Name",
|
||||||
|
"download_template": "Download Template",
|
||||||
|
"start_time": "Start Time",
|
||||||
|
"end_time": "End Time",
|
||||||
|
"enter_standard_service_life": "Enter standard service life",
|
||||||
|
"enter_warning_service_life": "Enter warning service life",
|
||||||
|
"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 Items Import Template",
|
||||||
|
"import_tip": "The uploaded file must be xlsx/xls and follow the template.",
|
||||||
|
"import_title": "Consumables Items Data Import",
|
||||||
|
"please_import_data": "Please import data first",
|
||||||
|
"please_select_consumables_category": "Please select consumables category",
|
||||||
|
"please_select_data": "Please select data first",
|
||||||
|
"please_select_device_category": "Please select device category",
|
||||||
|
"please_select_service_life_unit": "Please select service life unit",
|
||||||
|
"select_file": "Select File",
|
||||||
|
"service_life_unit": "Service Life Unit",
|
||||||
|
"sort": "No.",
|
||||||
|
"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"
|
||||||
},
|
},
|
||||||
"inspection_logs": {
|
"inspection_logs": {
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
@@ -1404,7 +1450,49 @@
|
|||||||
"replace_reason": "Replacement Reason",
|
"replace_reason": "Replacement Reason",
|
||||||
"enter_replace_reason": "Enter replacement reason",
|
"enter_replace_reason": "Enter replacement reason",
|
||||||
"replace_duration": "Replacement Duration",
|
"replace_duration": "Replacement Duration",
|
||||||
"enter_replace_duration": "Enter replacement duration"
|
"enter_replace_duration": "Enter replacement duration",
|
||||||
|
"batch_delete": "Batch Delete",
|
||||||
|
"confirm_batch_delete": "Delete selected records?",
|
||||||
|
"consumable_category": "Consumables Category",
|
||||||
|
"consumable_code": "Consumables Code",
|
||||||
|
"consumable_name": "Consumables Name",
|
||||||
|
"consumable_required": "Please select consumables item",
|
||||||
|
"create_download_task_success": "Download task created successfully",
|
||||||
|
"declare_lifetime": "Declare Lifetime",
|
||||||
|
"device_consumables_item": "Consumables Item",
|
||||||
|
"device_required": "Please select device",
|
||||||
|
"download_template": "Download Template",
|
||||||
|
"start_time": "Start Time",
|
||||||
|
"end_time": "End Time",
|
||||||
|
"exceed_standard_life": "Exceeded standard life",
|
||||||
|
"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 Lifecycle Import Template",
|
||||||
|
"import_tip": "The uploaded file must be xlsx/xls and follow the template.",
|
||||||
|
"import_title": "Consumables Lifecycle Data Import",
|
||||||
|
"input_replace_duration": "Enter replacement duration",
|
||||||
|
"input_replace_time": "Select replacement time",
|
||||||
|
"input_replace_user": "Enter replacement user",
|
||||||
|
"input_used_life": "Enter used life",
|
||||||
|
"near_standard_life": "Near standard life",
|
||||||
|
"normal": "Normal",
|
||||||
|
"please_import_data": "Please import data first",
|
||||||
|
"please_select_data": "Please select data first",
|
||||||
|
"related_device": "Related Device",
|
||||||
|
"replace": "Replace",
|
||||||
|
"replace_reason_abnormal": "Abnormal Damage",
|
||||||
|
"replace_reason_exceed": "Overdue Life",
|
||||||
|
"replace_reason_normal": "Normal Wear",
|
||||||
|
"replace_reason_required": "Please select replacement reason",
|
||||||
|
"select_consumable": "Select consumables item",
|
||||||
|
"select_device": "Select device",
|
||||||
|
"select_file": "Select File",
|
||||||
|
"select_replace_reason": "Select replacement reason",
|
||||||
|
"sort": "No.",
|
||||||
|
"standard_service_life": "Standard Service Life",
|
||||||
|
"update_time": "Updated Time",
|
||||||
|
"warning_service_life": "Warning Service Life"
|
||||||
},
|
},
|
||||||
"maintenance_details": {
|
"maintenance_details": {
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
@@ -1630,7 +1718,24 @@
|
|||||||
"replace_reason": "Replacement Reason",
|
"replace_reason": "Replacement Reason",
|
||||||
"enter_replace_reason": "Enter replacement reason",
|
"enter_replace_reason": "Enter replacement reason",
|
||||||
"replace_duration": "Replacement Duration",
|
"replace_duration": "Replacement Duration",
|
||||||
"enter_replace_duration": "Enter replacement duration"
|
"enter_replace_duration": "Enter replacement duration",
|
||||||
|
"abnormal_damage": "Abnormal Damage",
|
||||||
|
"create_download_task_success": "Download task created successfully",
|
||||||
|
"device_consumables_category_name": "Consumables Category Name",
|
||||||
|
"device_consumables_item_code": "Consumables Code",
|
||||||
|
"device_consumables_item_name": "Consumables Name",
|
||||||
|
"start_time": "Start Time",
|
||||||
|
"end_time": "End Time",
|
||||||
|
"enter_replacement_time": "Enter replacement duration",
|
||||||
|
"id": "ID",
|
||||||
|
"normal_wear": "Normal Wear",
|
||||||
|
"overdue_life": "Overdue Life",
|
||||||
|
"please_select_device_name": "Please select device",
|
||||||
|
"related_device": "Related Device",
|
||||||
|
"replace_lifetime": "Replacement Life",
|
||||||
|
"replacement_time": "Replacement Duration",
|
||||||
|
"standard_service_life": "Standard Service Life",
|
||||||
|
"warning_service_life": "Warning Service Life"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"repair_management": {
|
"repair_management": {
|
||||||
@@ -1973,7 +2078,25 @@
|
|||||||
"replace_reason": "Replacement Reason",
|
"replace_reason": "Replacement Reason",
|
||||||
"enter_replace_reason": "Enter replacement reason",
|
"enter_replace_reason": "Enter replacement reason",
|
||||||
"replace_duration": "Replacement Duration",
|
"replace_duration": "Replacement Duration",
|
||||||
"enter_replace_duration": "Enter replacement duration"
|
"enter_replace_duration": "Enter replacement duration",
|
||||||
|
"batch_delete": "Batch Delete",
|
||||||
|
"confirm_batch_delete": "Delete selected records?",
|
||||||
|
"create_download_task_success": "Download task created successfully",
|
||||||
|
"download_template": "Download Template",
|
||||||
|
"start_time": "Start Time",
|
||||||
|
"end_time": "End Time",
|
||||||
|
"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_tip": "The uploaded file must be xlsx/xls and follow the template.",
|
||||||
|
"import_title": "Consumables Category 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"
|
||||||
},
|
},
|
||||||
"consumables_items": {
|
"consumables_items": {
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
@@ -2086,7 +2209,35 @@
|
|||||||
"replace_reason": "Replacement Reason",
|
"replace_reason": "Replacement Reason",
|
||||||
"enter_replace_reason": "Enter replacement reason",
|
"enter_replace_reason": "Enter replacement reason",
|
||||||
"replace_duration": "Replacement Duration",
|
"replace_duration": "Replacement Duration",
|
||||||
"enter_replace_duration": "Enter replacement duration"
|
"enter_replace_duration": "Enter replacement duration",
|
||||||
|
"batch_delete": "Batch Delete",
|
||||||
|
"confirm_batch_delete": "Delete selected records?",
|
||||||
|
"create_download_task_success": "Download task created successfully",
|
||||||
|
"device_category": "Device Category",
|
||||||
|
"device_consumables_category_name": "Consumables Category Name",
|
||||||
|
"download_template": "Download Template",
|
||||||
|
"start_time": "Start Time",
|
||||||
|
"end_time": "End Time",
|
||||||
|
"enter_standard_service_life": "Enter standard service life",
|
||||||
|
"enter_warning_service_life": "Enter warning service life",
|
||||||
|
"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 Items Import Template",
|
||||||
|
"import_tip": "The uploaded file must be xlsx/xls and follow the template.",
|
||||||
|
"import_title": "Consumables Items Data Import",
|
||||||
|
"please_import_data": "Please import data first",
|
||||||
|
"please_select_consumables_category": "Please select consumables category",
|
||||||
|
"please_select_data": "Please select data first",
|
||||||
|
"please_select_device_category": "Please select device category",
|
||||||
|
"please_select_service_life_unit": "Please select service life unit",
|
||||||
|
"select_file": "Select File",
|
||||||
|
"service_life_unit": "Service Life Unit",
|
||||||
|
"sort": "No.",
|
||||||
|
"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"
|
||||||
},
|
},
|
||||||
"consumables_lifecycle": {
|
"consumables_lifecycle": {
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
@@ -2199,7 +2350,49 @@
|
|||||||
"replace_reason": "Replacement Reason",
|
"replace_reason": "Replacement Reason",
|
||||||
"enter_replace_reason": "Enter replacement reason",
|
"enter_replace_reason": "Enter replacement reason",
|
||||||
"replace_duration": "Replacement Duration",
|
"replace_duration": "Replacement Duration",
|
||||||
"enter_replace_duration": "Enter replacement duration"
|
"enter_replace_duration": "Enter replacement duration",
|
||||||
|
"batch_delete": "Batch Delete",
|
||||||
|
"confirm_batch_delete": "Delete selected records?",
|
||||||
|
"consumable_category": "Consumables Category",
|
||||||
|
"consumable_code": "Consumables Code",
|
||||||
|
"consumable_name": "Consumables Name",
|
||||||
|
"consumable_required": "Please select consumables item",
|
||||||
|
"create_download_task_success": "Download task created successfully",
|
||||||
|
"declare_lifetime": "Declare Lifetime",
|
||||||
|
"device_consumables_item": "Consumables Item",
|
||||||
|
"device_required": "Please select device",
|
||||||
|
"download_template": "Download Template",
|
||||||
|
"start_time": "Start Time",
|
||||||
|
"end_time": "End Time",
|
||||||
|
"exceed_standard_life": "Exceeded standard life",
|
||||||
|
"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 Lifecycle Import Template",
|
||||||
|
"import_tip": "The uploaded file must be xlsx/xls and follow the template.",
|
||||||
|
"import_title": "Consumables Lifecycle Data Import",
|
||||||
|
"input_replace_duration": "Enter replacement duration",
|
||||||
|
"input_replace_time": "Select replacement time",
|
||||||
|
"input_replace_user": "Enter replacement user",
|
||||||
|
"input_used_life": "Enter used life",
|
||||||
|
"near_standard_life": "Near standard life",
|
||||||
|
"normal": "Normal",
|
||||||
|
"please_import_data": "Please import data first",
|
||||||
|
"please_select_data": "Please select data first",
|
||||||
|
"related_device": "Related Device",
|
||||||
|
"replace": "Replace",
|
||||||
|
"replace_reason_abnormal": "Abnormal Damage",
|
||||||
|
"replace_reason_exceed": "Overdue Life",
|
||||||
|
"replace_reason_normal": "Normal Wear",
|
||||||
|
"replace_reason_required": "Please select replacement reason",
|
||||||
|
"select_consumable": "Select consumables item",
|
||||||
|
"select_device": "Select device",
|
||||||
|
"select_file": "Select File",
|
||||||
|
"select_replace_reason": "Select replacement reason",
|
||||||
|
"sort": "No.",
|
||||||
|
"standard_service_life": "Standard Service Life",
|
||||||
|
"update_time": "Updated Time",
|
||||||
|
"warning_service_life": "Warning Service Life"
|
||||||
},
|
},
|
||||||
"replacement_logs": {
|
"replacement_logs": {
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
@@ -2312,7 +2505,24 @@
|
|||||||
"replace_reason": "Replacement Reason",
|
"replace_reason": "Replacement Reason",
|
||||||
"enter_replace_reason": "Enter replacement reason",
|
"enter_replace_reason": "Enter replacement reason",
|
||||||
"replace_duration": "Replacement Duration",
|
"replace_duration": "Replacement Duration",
|
||||||
"enter_replace_duration": "Enter replacement duration"
|
"enter_replace_duration": "Enter replacement duration",
|
||||||
|
"abnormal_damage": "Abnormal Damage",
|
||||||
|
"create_download_task_success": "Download task created successfully",
|
||||||
|
"device_consumables_category_name": "Consumables Category Name",
|
||||||
|
"device_consumables_item_code": "Consumables Code",
|
||||||
|
"device_consumables_item_name": "Consumables Name",
|
||||||
|
"start_time": "Start Time",
|
||||||
|
"end_time": "End Time",
|
||||||
|
"enter_replacement_time": "Enter replacement duration",
|
||||||
|
"id": "ID",
|
||||||
|
"normal_wear": "Normal Wear",
|
||||||
|
"overdue_life": "Overdue Life",
|
||||||
|
"please_select_device_name": "Please select device",
|
||||||
|
"related_device": "Related Device",
|
||||||
|
"replace_lifetime": "Replacement Life",
|
||||||
|
"replacement_time": "Replacement Duration",
|
||||||
|
"standard_service_life": "Standard Service Life",
|
||||||
|
"warning_service_life": "Warning Service Life"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1063,7 +1063,25 @@
|
|||||||
"replace_reason": "更换原因",
|
"replace_reason": "更换原因",
|
||||||
"enter_replace_reason": "请输入更换原因",
|
"enter_replace_reason": "请输入更换原因",
|
||||||
"replace_duration": "更换耗时",
|
"replace_duration": "更换耗时",
|
||||||
"enter_replace_duration": "请输入更换耗时"
|
"enter_replace_duration": "请输入更换耗时",
|
||||||
|
"batch_delete": "批量删除",
|
||||||
|
"confirm_batch_delete": "确定要删除所选数据吗?",
|
||||||
|
"create_download_task_success": "创建下载任务成功",
|
||||||
|
"download_template": "下载模板",
|
||||||
|
"start_time": "开始时间",
|
||||||
|
"end_time": "结束时间",
|
||||||
|
"file_column_missing": "导入文件缺少列:{title}",
|
||||||
|
"file_format_error": "请上传 xls 或 xlsx 文件",
|
||||||
|
"import": "导入",
|
||||||
|
"import_template_name": "损耗品类别导入模板",
|
||||||
|
"import_tip": "上传的文件后缀必须是 xlsx/xls,且需要按模板填写",
|
||||||
|
"import_title": "损耗品类别数据导入",
|
||||||
|
"length_1_100": "长度在 1 到 100 个字符",
|
||||||
|
"please_import_data": "请先导入数据",
|
||||||
|
"please_select_data": "请先选择数据",
|
||||||
|
"select_file": "选择文件",
|
||||||
|
"sort": "序号",
|
||||||
|
"update_time": "更新时间"
|
||||||
},
|
},
|
||||||
"inspection_records": {
|
"inspection_records": {
|
||||||
"search": "查询",
|
"search": "查询",
|
||||||
@@ -1176,7 +1194,35 @@
|
|||||||
"replace_reason": "更换原因",
|
"replace_reason": "更换原因",
|
||||||
"enter_replace_reason": "请输入更换原因",
|
"enter_replace_reason": "请输入更换原因",
|
||||||
"replace_duration": "更换耗时",
|
"replace_duration": "更换耗时",
|
||||||
"enter_replace_duration": "请输入更换耗时"
|
"enter_replace_duration": "请输入更换耗时",
|
||||||
|
"batch_delete": "批量删除",
|
||||||
|
"confirm_batch_delete": "确定要删除所选数据吗?",
|
||||||
|
"create_download_task_success": "创建下载任务成功",
|
||||||
|
"device_category": "设备类别",
|
||||||
|
"device_consumables_category_name": "设备损耗品类别名称",
|
||||||
|
"download_template": "下载模板",
|
||||||
|
"start_time": "开始时间",
|
||||||
|
"end_time": "结束时间",
|
||||||
|
"enter_standard_service_life": "请输入标准使用寿命",
|
||||||
|
"enter_warning_service_life": "请输入预警使用寿命",
|
||||||
|
"file_column_missing": "导入文件缺少列:{title}",
|
||||||
|
"file_format_error": "请上传 xls 或 xlsx 文件",
|
||||||
|
"import": "导入",
|
||||||
|
"import_template_name": "损耗品项目导入模板",
|
||||||
|
"import_tip": "上传的文件后缀必须是 xlsx/xls,且需要按模板填写",
|
||||||
|
"import_title": "损耗品项目数据导入",
|
||||||
|
"please_import_data": "请先导入数据",
|
||||||
|
"please_select_consumables_category": "请选择损耗品类别",
|
||||||
|
"please_select_data": "请先选择数据",
|
||||||
|
"please_select_device_category": "请选择设备类别",
|
||||||
|
"please_select_service_life_unit": "请选择寿命单位",
|
||||||
|
"select_file": "选择文件",
|
||||||
|
"service_life_unit": "寿命单位",
|
||||||
|
"sort": "序号",
|
||||||
|
"standard_service_life": "标准使用寿命",
|
||||||
|
"update_time": "更新时间",
|
||||||
|
"warning_life_not_greater_than_standard": "预警使用寿命不能大于标准使用寿命",
|
||||||
|
"warning_service_life": "预警使用寿命"
|
||||||
},
|
},
|
||||||
"inspection_logs": {
|
"inspection_logs": {
|
||||||
"search": "查询",
|
"search": "查询",
|
||||||
@@ -1404,7 +1450,49 @@
|
|||||||
"replace_reason": "更换原因",
|
"replace_reason": "更换原因",
|
||||||
"enter_replace_reason": "请输入更换原因",
|
"enter_replace_reason": "请输入更换原因",
|
||||||
"replace_duration": "更换耗时",
|
"replace_duration": "更换耗时",
|
||||||
"enter_replace_duration": "请输入更换耗时"
|
"enter_replace_duration": "请输入更换耗时",
|
||||||
|
"batch_delete": "批量删除",
|
||||||
|
"confirm_batch_delete": "确定要删除所选数据吗?",
|
||||||
|
"consumable_category": "损耗品类别",
|
||||||
|
"consumable_code": "损耗品项编码",
|
||||||
|
"consumable_name": "损耗品项名称",
|
||||||
|
"consumable_required": "请选择损耗品项",
|
||||||
|
"create_download_task_success": "创建下载任务成功",
|
||||||
|
"declare_lifetime": "申报寿命",
|
||||||
|
"device_consumables_item": "损耗品项",
|
||||||
|
"device_required": "请选择设备",
|
||||||
|
"download_template": "下载模板",
|
||||||
|
"start_time": "开始时间",
|
||||||
|
"end_time": "结束时间",
|
||||||
|
"exceed_standard_life": "超标准寿命",
|
||||||
|
"file_column_missing": "导入文件缺少列:{title}",
|
||||||
|
"file_format_error": "请上传 xls 或 xlsx 文件",
|
||||||
|
"import": "导入",
|
||||||
|
"import_template_name": "损耗品寿命导入模板",
|
||||||
|
"import_tip": "上传的文件后缀必须是 xlsx/xls,且需要按模板填写",
|
||||||
|
"import_title": "损耗品寿命数据导入",
|
||||||
|
"input_replace_duration": "请输入更换耗时",
|
||||||
|
"input_replace_time": "请选择更换时间",
|
||||||
|
"input_replace_user": "请输入更换人员",
|
||||||
|
"input_used_life": "请输入已使用寿命",
|
||||||
|
"near_standard_life": "接近标准寿命",
|
||||||
|
"normal": "正常",
|
||||||
|
"please_import_data": "请先导入数据",
|
||||||
|
"please_select_data": "请先选择数据",
|
||||||
|
"related_device": "所属设备",
|
||||||
|
"replace": "更换",
|
||||||
|
"replace_reason_abnormal": "异常损坏",
|
||||||
|
"replace_reason_exceed": "超标准寿命",
|
||||||
|
"replace_reason_normal": "正常损耗",
|
||||||
|
"replace_reason_required": "请选择更换原因",
|
||||||
|
"select_consumable": "请选择损耗品项",
|
||||||
|
"select_device": "请选择设备",
|
||||||
|
"select_file": "选择文件",
|
||||||
|
"select_replace_reason": "请选择更换原因",
|
||||||
|
"sort": "序号",
|
||||||
|
"standard_service_life": "标准使用寿命",
|
||||||
|
"update_time": "更新时间",
|
||||||
|
"warning_service_life": "预警使用寿命"
|
||||||
},
|
},
|
||||||
"maintenance_details": {
|
"maintenance_details": {
|
||||||
"search": "查询",
|
"search": "查询",
|
||||||
@@ -1630,7 +1718,24 @@
|
|||||||
"replace_reason": "更换原因",
|
"replace_reason": "更换原因",
|
||||||
"enter_replace_reason": "请输入更换原因",
|
"enter_replace_reason": "请输入更换原因",
|
||||||
"replace_duration": "更换耗时",
|
"replace_duration": "更换耗时",
|
||||||
"enter_replace_duration": "请输入更换耗时"
|
"enter_replace_duration": "请输入更换耗时",
|
||||||
|
"abnormal_damage": "异常损坏",
|
||||||
|
"create_download_task_success": "创建下载任务成功",
|
||||||
|
"device_consumables_category_name": "损耗品类别",
|
||||||
|
"device_consumables_item_code": "损耗品项编码",
|
||||||
|
"device_consumables_item_name": "损耗品项名称",
|
||||||
|
"start_time": "开始时间",
|
||||||
|
"end_time": "结束时间",
|
||||||
|
"enter_replacement_time": "请输入更换耗时",
|
||||||
|
"id": "序号",
|
||||||
|
"normal_wear": "正常损耗",
|
||||||
|
"overdue_life": "超标准寿命",
|
||||||
|
"please_select_device_name": "请选择设备名称",
|
||||||
|
"related_device": "所属设备",
|
||||||
|
"replace_lifetime": "更换时寿命",
|
||||||
|
"replacement_time": "更换耗时",
|
||||||
|
"standard_service_life": "标准使用寿命",
|
||||||
|
"warning_service_life": "预警使用寿命"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"repair_management": {
|
"repair_management": {
|
||||||
@@ -1973,7 +2078,25 @@
|
|||||||
"replace_reason": "更换原因",
|
"replace_reason": "更换原因",
|
||||||
"enter_replace_reason": "请输入更换原因",
|
"enter_replace_reason": "请输入更换原因",
|
||||||
"replace_duration": "更换耗时",
|
"replace_duration": "更换耗时",
|
||||||
"enter_replace_duration": "请输入更换耗时"
|
"enter_replace_duration": "请输入更换耗时",
|
||||||
|
"batch_delete": "批量删除",
|
||||||
|
"confirm_batch_delete": "确定要删除所选数据吗?",
|
||||||
|
"create_download_task_success": "创建下载任务成功",
|
||||||
|
"download_template": "下载模板",
|
||||||
|
"start_time": "开始时间",
|
||||||
|
"end_time": "结束时间",
|
||||||
|
"file_column_missing": "导入文件缺少列:{title}",
|
||||||
|
"file_format_error": "请上传 xls 或 xlsx 文件",
|
||||||
|
"import": "导入",
|
||||||
|
"import_template_name": "损耗品类别导入模板",
|
||||||
|
"import_tip": "上传的文件后缀必须是 xlsx/xls,且需要按模板填写",
|
||||||
|
"import_title": "损耗品类别数据导入",
|
||||||
|
"length_1_100": "长度在 1 到 100 个字符",
|
||||||
|
"please_import_data": "请先导入数据",
|
||||||
|
"please_select_data": "请先选择数据",
|
||||||
|
"select_file": "选择文件",
|
||||||
|
"sort": "序号",
|
||||||
|
"update_time": "更新时间"
|
||||||
},
|
},
|
||||||
"consumables_items": {
|
"consumables_items": {
|
||||||
"search": "查询",
|
"search": "查询",
|
||||||
@@ -2086,7 +2209,35 @@
|
|||||||
"replace_reason": "更换原因",
|
"replace_reason": "更换原因",
|
||||||
"enter_replace_reason": "请输入更换原因",
|
"enter_replace_reason": "请输入更换原因",
|
||||||
"replace_duration": "更换耗时",
|
"replace_duration": "更换耗时",
|
||||||
"enter_replace_duration": "请输入更换耗时"
|
"enter_replace_duration": "请输入更换耗时",
|
||||||
|
"batch_delete": "批量删除",
|
||||||
|
"confirm_batch_delete": "确定要删除所选数据吗?",
|
||||||
|
"create_download_task_success": "创建下载任务成功",
|
||||||
|
"device_category": "设备类别",
|
||||||
|
"device_consumables_category_name": "损耗品类别名称",
|
||||||
|
"download_template": "下载模板",
|
||||||
|
"start_time": "开始时间",
|
||||||
|
"end_time": "结束时间",
|
||||||
|
"enter_standard_service_life": "请输入标准使用寿命",
|
||||||
|
"enter_warning_service_life": "请输入预警使用寿命",
|
||||||
|
"file_column_missing": "导入文件缺少列:{title}",
|
||||||
|
"file_format_error": "请上传 xls 或 xlsx 文件",
|
||||||
|
"import": "导入",
|
||||||
|
"import_template_name": "损耗品项目导入模板",
|
||||||
|
"import_tip": "上传的文件后缀必须是 xlsx/xls,且需要按模板填写",
|
||||||
|
"import_title": "损耗品项目数据导入",
|
||||||
|
"please_import_data": "请先导入数据",
|
||||||
|
"please_select_consumables_category": "请选择损耗品类别",
|
||||||
|
"please_select_data": "请先选择数据",
|
||||||
|
"please_select_device_category": "请选择设备类别",
|
||||||
|
"please_select_service_life_unit": "请选择寿命单位",
|
||||||
|
"select_file": "选择文件",
|
||||||
|
"service_life_unit": "寿命单位",
|
||||||
|
"sort": "序号",
|
||||||
|
"standard_service_life": "标准使用寿命",
|
||||||
|
"update_time": "更新时间",
|
||||||
|
"warning_life_not_greater_than_standard": "预警使用寿命不能大于标准使用寿命",
|
||||||
|
"warning_service_life": "预警使用寿命"
|
||||||
},
|
},
|
||||||
"consumables_lifecycle": {
|
"consumables_lifecycle": {
|
||||||
"search": "查询",
|
"search": "查询",
|
||||||
@@ -2199,7 +2350,49 @@
|
|||||||
"replace_reason": "更换原因",
|
"replace_reason": "更换原因",
|
||||||
"enter_replace_reason": "请输入更换原因",
|
"enter_replace_reason": "请输入更换原因",
|
||||||
"replace_duration": "更换耗时",
|
"replace_duration": "更换耗时",
|
||||||
"enter_replace_duration": "请输入更换耗时"
|
"enter_replace_duration": "请输入更换耗时",
|
||||||
|
"batch_delete": "批量删除",
|
||||||
|
"confirm_batch_delete": "确定要删除所选数据吗?",
|
||||||
|
"consumable_category": "损耗品类别",
|
||||||
|
"consumable_code": "损耗品编码",
|
||||||
|
"consumable_name": "损耗品名称",
|
||||||
|
"consumable_required": "请选择损耗品项目",
|
||||||
|
"create_download_task_success": "创建下载任务成功",
|
||||||
|
"declare_lifetime": "寿命申报",
|
||||||
|
"device_consumables_item": "损耗品项目",
|
||||||
|
"device_required": "请选择设备",
|
||||||
|
"download_template": "下载模板",
|
||||||
|
"start_time": "开始时间",
|
||||||
|
"end_time": "结束时间",
|
||||||
|
"exceed_standard_life": "超出标准寿命",
|
||||||
|
"file_column_missing": "导入文件缺少列:{title}",
|
||||||
|
"file_format_error": "请上传 xls 或 xlsx 文件",
|
||||||
|
"import": "导入",
|
||||||
|
"import_template_name": "损耗品寿命导入模板",
|
||||||
|
"import_tip": "上传的文件后缀必须是 xlsx/xls,且需要按模板填写",
|
||||||
|
"import_title": "损耗品寿命数据导入",
|
||||||
|
"input_replace_duration": "请输入更换耗时",
|
||||||
|
"input_replace_time": "请选择更换时间",
|
||||||
|
"input_replace_user": "请输入更换人员",
|
||||||
|
"input_used_life": "请输入已用寿命",
|
||||||
|
"near_standard_life": "接近标准寿命",
|
||||||
|
"normal": "正常",
|
||||||
|
"please_import_data": "请先导入数据",
|
||||||
|
"please_select_data": "请先选择数据",
|
||||||
|
"related_device": "所属设备",
|
||||||
|
"replace": "更换",
|
||||||
|
"replace_reason_abnormal": "异常损坏",
|
||||||
|
"replace_reason_exceed": "寿命逾期",
|
||||||
|
"replace_reason_normal": "正常磨损",
|
||||||
|
"replace_reason_required": "请选择更换原因",
|
||||||
|
"select_consumable": "请选择损耗品项目",
|
||||||
|
"select_device": "请选择设备",
|
||||||
|
"select_file": "选择文件",
|
||||||
|
"select_replace_reason": "请选择更换原因",
|
||||||
|
"sort": "序号",
|
||||||
|
"standard_service_life": "标准使用寿命",
|
||||||
|
"update_time": "更新时间",
|
||||||
|
"warning_service_life": "预警使用寿命"
|
||||||
},
|
},
|
||||||
"replacement_logs": {
|
"replacement_logs": {
|
||||||
"search": "查询",
|
"search": "查询",
|
||||||
@@ -2312,7 +2505,24 @@
|
|||||||
"replace_reason": "更换原因",
|
"replace_reason": "更换原因",
|
||||||
"enter_replace_reason": "请输入更换原因",
|
"enter_replace_reason": "请输入更换原因",
|
||||||
"replace_duration": "更换耗时",
|
"replace_duration": "更换耗时",
|
||||||
"enter_replace_duration": "请输入更换耗时"
|
"enter_replace_duration": "请输入更换耗时",
|
||||||
|
"abnormal_damage": "异常损坏",
|
||||||
|
"create_download_task_success": "创建下载任务成功",
|
||||||
|
"device_consumables_category_name": "损耗品类别名称",
|
||||||
|
"device_consumables_item_code": "损耗品编码",
|
||||||
|
"device_consumables_item_name": "损耗品名称",
|
||||||
|
"start_time": "开始时间",
|
||||||
|
"end_time": "结束时间",
|
||||||
|
"enter_replacement_time": "请输入更换耗时",
|
||||||
|
"id": "ID",
|
||||||
|
"normal_wear": "正常磨损",
|
||||||
|
"overdue_life": "寿命逾期",
|
||||||
|
"please_select_device_name": "请选择设备名称",
|
||||||
|
"related_device": "所属设备",
|
||||||
|
"replace_lifetime": "更换寿命",
|
||||||
|
"replacement_time": "更换耗时",
|
||||||
|
"standard_service_life": "标准使用寿命",
|
||||||
|
"warning_service_life": "预警使用寿命"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,15 +2,18 @@
|
|||||||
<d2-container>
|
<d2-container>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="search-bar">
|
<div class="search-bar">
|
||||||
<el-form :inline="true" size="mini">
|
<el-form :inline="true" :model="search" size="mini">
|
||||||
<el-form-item :label="$t(key('keyword'))">
|
<el-form-item :label="$t(key('consumables_category_code'))">
|
||||||
<el-input
|
<el-input v-model.trim="search.code" :placeholder="$t(key('enter_consumables_category_code'))" clearable style="width:220px" @keyup.enter.native="onSearch" />
|
||||||
v-model="search.keyword"
|
</el-form-item>
|
||||||
:placeholder="$t(key('enter_keyword'))"
|
<el-form-item :label="$t(key('consumables_category_name'))">
|
||||||
clearable
|
<el-input v-model.trim="search.name" :placeholder="$t(key('enter_consumables_category_name'))" clearable style="width:220px" @keyup.enter.native="onSearch" />
|
||||||
style="width:200px"
|
</el-form-item>
|
||||||
@keyup.enter.native="onSearch"
|
<el-form-item :label="$t(key('create_time'))">
|
||||||
/>
|
<el-date-picker v-model="search.create_time" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss" :start-placeholder="$t(key('start_time'))" :end-placeholder="$t(key('end_time'))" style="width:330px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t(key('update_time'))">
|
||||||
|
<el-date-picker v-model="search.update_time" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss" :start-placeholder="$t(key('start_time'))" :end-placeholder="$t(key('end_time'))" style="width:330px" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
|
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
|
||||||
@@ -30,14 +33,14 @@
|
|||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
auto-height
|
auto-height
|
||||||
@page-change="onPageChange"
|
@page-change="onPageChange"
|
||||||
@selection-change="onSelect"
|
@selection-change="selectedRows = $event"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<page-dialog-form
|
<page-dialog-form
|
||||||
ref="dialogForm"
|
ref="dialogForm"
|
||||||
:visible.sync="dialogVisible"
|
:visible.sync="dialogVisible"
|
||||||
:title="dialogTitle"
|
:title="dialogTitle"
|
||||||
width="40%"
|
width="520px"
|
||||||
:form-cols="formCols"
|
:form-cols="formCols"
|
||||||
:form-data="formData"
|
:form-data="formData"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
@@ -46,8 +49,25 @@
|
|||||||
:confirm-text="key('confirm')"
|
:confirm-text="key('confirm')"
|
||||||
:cancel-text="key('cancel')"
|
:cancel-text="key('cancel')"
|
||||||
@submit="onDialogSubmit"
|
@submit="onDialogSubmit"
|
||||||
@close="onDialogClose"
|
@close="resetForm"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<el-dialog :title="$t(key('import_title'))" :visible.sync="importVisible" width="760px" :close-on-click-modal="false">
|
||||||
|
<el-alert :title="$t(key('import_tip'))" type="warning" :closable="false" />
|
||||||
|
<el-upload class="import-upload" action="" :auto-upload="false" :show-file-list="true" :file-list="importFileList" accept=".xls,.xlsx" :on-change="onImportFileChange">
|
||||||
|
<el-button slot="trigger" size="mini" type="success">{{ $t(key('select_file')) }}</el-button>
|
||||||
|
<el-button style="margin-left:10px" size="mini" type="primary" :loading="importLoading" @click.stop="downloadTemplate">{{ $t(key('download_template')) }}</el-button>
|
||||||
|
</el-upload>
|
||||||
|
<el-table v-loading="importTableLoading" :data="importRows" border height="320" size="mini">
|
||||||
|
<el-table-column prop="code" :label="$t(key('consumables_category_code'))" />
|
||||||
|
<el-table-column prop="name" :label="$t(key('consumables_category_name'))" />
|
||||||
|
<el-table-column prop="remark" :label="$t(key('remark'))" />
|
||||||
|
</el-table>
|
||||||
|
<span slot="footer">
|
||||||
|
<el-button @click="importVisible = false">{{ $t(key('cancel')) }}</el-button>
|
||||||
|
<el-button type="primary" @click="submitImport">{{ $t(key('confirm')) }}</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
</d2-container>
|
</d2-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -58,7 +78,16 @@ import { i18nMixin } from '@/composables/useI18n'
|
|||||||
import { confirmMixin } from '@/composables/useConfirmHandle'
|
import { confirmMixin } from '@/composables/useConfirmHandle'
|
||||||
import PageTable from '@/components/page-table'
|
import PageTable from '@/components/page-table'
|
||||||
import PageDialogForm from '@/components/page-dialog-form'
|
import PageDialogForm from '@/components/page-dialog-form'
|
||||||
import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/consumables-category'
|
import { downloadRename, readExcel } from '@/utils/file'
|
||||||
|
import { getList, createItem, editItem, deleteItem, createExportTask, getImportTemplate, importData } from '@/api/equipment-management/consumables-category'
|
||||||
|
|
||||||
|
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 }
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'equipment-management-consumables-category',
|
name: 'equipment-management-consumables-category',
|
||||||
@@ -70,74 +99,48 @@ export default {
|
|||||||
submitting: false,
|
submitting: false,
|
||||||
tableData: [],
|
tableData: [],
|
||||||
selectedRows: [],
|
selectedRows: [],
|
||||||
|
search: { code: '', name: '', create_time: [], update_time: [] },
|
||||||
|
pagination: { current: 1, size: 10, total: 0 },
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
dialogTitle: '',
|
dialogTitle: '',
|
||||||
editId: '',
|
|
||||||
handleType: 'create',
|
handleType: 'create',
|
||||||
search: {
|
editId: '',
|
||||||
keyword: ''
|
formData: { code: '', name: '', remark: '' },
|
||||||
},
|
importVisible: false,
|
||||||
pagination: { current: 1, size: 10, total: 0 },
|
importFileList: [],
|
||||||
formData: {
|
importRows: [],
|
||||||
device_consumables_category_code: '',
|
importLoading: false,
|
||||||
device_consumables_category_name: '',
|
importTableLoading: false,
|
||||||
remark: ''
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
device_consumables_category_code: [{ required: true, message: this.key('enter_consumables_category_code'), trigger: 'blur' }],
|
|
||||||
device_consumables_category_name: [{ required: true, message: this.key('enter_consumables_category_name'), trigger: 'blur' }]
|
|
||||||
},
|
|
||||||
columns: [],
|
columns: [],
|
||||||
toolbarButtons: [],
|
toolbarButtons: [],
|
||||||
rowButtons: [],
|
rowButtons: [],
|
||||||
formCols: [
|
formCols: [
|
||||||
[
|
[{ type: 'input', prop: 'code', label: this.key('consumables_category_code'), placeholder: this.key('enter_consumables_category_code'), style: { width: '100%' } }],
|
||||||
{
|
[{ type: 'input', prop: 'name', label: this.key('consumables_category_name'), placeholder: this.key('enter_consumables_category_name'), style: { width: '100%' } }],
|
||||||
type: 'input',
|
[{ type: 'input', prop: 'remark', label: this.key('remark'), placeholder: this.key('enter_remark'), inputType: 'textarea', autosize: { minRows: 2, maxRows: 6 }, style: { width: '100%' } }]
|
||||||
prop: 'device_consumables_category_code',
|
],
|
||||||
label: this.key('consumables_category_code'),
|
rules: {
|
||||||
placeholder: this.key('enter_consumables_category_code'),
|
code: [{ required: true, message: this.key('enter_consumables_category_code'), trigger: 'blur' }, { min: 1, max: 100, message: this.key('length_1_100'), trigger: 'blur' }],
|
||||||
clearable: true,
|
name: [{ required: true, message: this.key('enter_consumables_category_name'), trigger: 'blur' }, { min: 1, max: 100, message: this.key('length_1_100'), trigger: 'blur' }]
|
||||||
style: { width: '90%' }
|
}
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
prop: 'device_consumables_category_name',
|
|
||||||
label: this.key('consumables_category_name'),
|
|
||||||
placeholder: this.key('enter_consumables_category_name'),
|
|
||||||
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%' }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
this.columns = useTableColumns([
|
this.columns = useTableColumns([
|
||||||
{ prop: 'device_consumables_category_code', label: this.key('consumables_category_code'), minWidth: 140 },
|
{ prop: 'sort', label: this.key('sort'), width: 80 },
|
||||||
{ prop: 'device_consumables_category_name', label: this.key('consumables_category_name'), minWidth: 140 },
|
{ prop: 'code', label: this.key('consumables_category_code'), minWidth: 160 },
|
||||||
{ prop: 'remark', label: this.key('remark'), minWidth: 140 },
|
{ prop: 'name', label: this.key('consumables_category_name'), minWidth: 160 },
|
||||||
{ prop: 'create_time', label: this.key('create_time'), minWidth: 140 },
|
{ prop: 'remark', label: this.key('remark'), minWidth: 160, 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' }
|
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
|
||||||
])
|
])
|
||||||
const btns = useTableButtons({
|
const btns = useTableButtons({
|
||||||
toolbar: [
|
toolbar: [
|
||||||
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_consumables/device_consumables_category/create', onClick: this.openAdd },
|
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_consumables/device_consumables_category/create', onClick: this.openAdd },
|
||||||
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_consumables/device_consumables_category/export', onClick: this.handleExport }
|
{ key: 'batch_delete', label: this.key('batch_delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_consumables/device_consumables_category/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_consumables/device_consumables_category/import', onClick: this.openImport },
|
||||||
|
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', type: 'primary', auth: '/device_management/device_consumables/device_consumables_category/export', onClick: this.handleExport }
|
||||||
],
|
],
|
||||||
row: [
|
row: [
|
||||||
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_consumables/device_consumables_category/edit', onClick: this.openEdit },
|
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_consumables/device_consumables_category/edit', onClick: this.openEdit },
|
||||||
@@ -149,71 +152,29 @@ export default {
|
|||||||
this.fetchData()
|
this.fetchData()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
normalizeResponse (res) {
|
buildSearchParams () {
|
||||||
const data = res && res.data !== undefined ? res.data : res
|
const params = { ...this.search }
|
||||||
if (Array.isArray(data)) return { list: data, total: data.length }
|
if (!Array.isArray(params.create_time) || !params.create_time.length) delete params.create_time
|
||||||
if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
|
if (!Array.isArray(params.update_time) || !params.update_time.length) delete params.update_time
|
||||||
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 params
|
||||||
return { list: [], total: 0 }
|
|
||||||
},
|
},
|
||||||
async fetchData () {
|
async fetchData () {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
try {
|
try {
|
||||||
const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
|
const res = await getList({ ...this.buildSearchParams(), page_no: this.pagination.current, page_size: this.pagination.size })
|
||||||
const data = this.normalizeResponse(res)
|
const page = readPageData(res)
|
||||||
this.tableData = data.list
|
this.tableData = page.list
|
||||||
this.pagination.total = data.total
|
this.pagination.total = page.total
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSearch () {
|
onSearch () { this.pagination.current = 1; this.fetchData() },
|
||||||
this.pagination.current = 1
|
onReset () { this.search = { code: '', name: '', create_time: [], update_time: [] }; this.pagination.current = 1; this.fetchData() },
|
||||||
this.fetchData()
|
onPageChange (page) { this.pagination.current = page.current; this.pagination.size = page.size; this.fetchData() },
|
||||||
},
|
resetForm () { this.formData = { code: '', name: '', remark: '' }; this.editId = '' },
|
||||||
onReset () {
|
openAdd () { this.handleType = 'create'; this.dialogTitle = this.key('add_title'); this.resetForm(); this.dialogVisible = true },
|
||||||
this.search = {
|
openEdit (row) { this.handleType = 'edit'; this.dialogTitle = this.key('edit_title'); this.editId = row.id; this.formData = { code: row.code || '', name: row.name || '', remark: row.remark || '' }; this.dialogVisible = true },
|
||||||
keyword: ''
|
|
||||||
}
|
|
||||||
this.pagination.current = 1
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onPageChange (page) {
|
|
||||||
this.pagination.current = page.current
|
|
||||||
this.pagination.size = page.size
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onSelect (rows) {
|
|
||||||
this.selectedRows = rows
|
|
||||||
},
|
|
||||||
resetForm () {
|
|
||||||
this.formData = {
|
|
||||||
device_consumables_category_code: '',
|
|
||||||
device_consumables_category_name: '',
|
|
||||||
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_consumables_category_code: row.device_consumables_category_code || '',
|
|
||||||
device_consumables_category_name: row.device_consumables_category_name || '',
|
|
||||||
remark: row.remark || ''
|
|
||||||
}
|
|
||||||
this.dialogVisible = true
|
|
||||||
},
|
|
||||||
async onDialogSubmit () {
|
async onDialogSubmit () {
|
||||||
this.submitting = true
|
this.submitting = true
|
||||||
try {
|
try {
|
||||||
@@ -226,26 +187,49 @@ export default {
|
|||||||
this.submitting = false
|
this.submitting = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onDialogClose () {
|
|
||||||
this.resetForm()
|
|
||||||
},
|
|
||||||
async handleDelete (row) {
|
async handleDelete (row) {
|
||||||
const cancelled = await this.$confirmAction(
|
const cancelled = await this.$confirmAction({ message: this.key('confirm_delete'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteItem({ id: [row.id] }))
|
||||||
{ message: this.key('confirm_delete'), title: this.key('tip') },
|
if (cancelled) return
|
||||||
() => deleteItem({ id: [row.id] })
|
this.$message.success(this.$t(this.key('operation_success')))
|
||||||
)
|
this.fetchData()
|
||||||
|
},
|
||||||
|
async handleBatchDelete () {
|
||||||
|
if (!this.selectedRows.length) { this.$message.error(this.$t(this.key('please_select_data'))); return }
|
||||||
|
const cancelled = await this.$confirmAction({ message: this.key('confirm_batch_delete'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteItem({ id: this.selectedRows.map(item => item.id) }))
|
||||||
if (cancelled) return
|
if (cancelled) return
|
||||||
this.$message.success(this.$t(this.key('operation_success')))
|
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.fetchData()
|
this.fetchData()
|
||||||
},
|
},
|
||||||
async handleExport () {
|
async handleExport () {
|
||||||
const cancelled = await this.$confirmAction(
|
const cancelled = await this.$confirmAction({ message: this.key('confirm_export'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => createExportTask({ ...this.buildSearchParams(), action: 'download' }))
|
||||||
{ message: this.key('confirm_export'), title: this.key('tip') },
|
|
||||||
() => createExportTask({ ...this.search })
|
|
||||||
)
|
|
||||||
if (cancelled) return
|
if (cancelled) return
|
||||||
|
this.$message.success(this.$t(this.key('create_download_task_success')))
|
||||||
|
},
|
||||||
|
openImport () { 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 required = [this.$t(this.key('consumables_category_code')), this.$t(this.key('consumables_category_name')), this.$t(this.key('remark'))]
|
||||||
|
if (rows.length && required.some(title => !Object.prototype.hasOwnProperty.call(rows[0], title))) {
|
||||||
|
this.$message.error(this.$t(this.key('file_column_missing'), { title: required.find(title => !Object.prototype.hasOwnProperty.call(rows[0], title)) }))
|
||||||
|
this.importRows = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.importRows = rows.map(row => ({ code: row[required[0]], name: row[required[1]], remark: row[required[2]] }))
|
||||||
|
} finally {
|
||||||
|
this.importTableLoading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async submitImport () {
|
||||||
|
if (!this.importRows.length) { this.$message.error(this.$t(this.key('please_import_data'))); return }
|
||||||
|
await importData({ import_data: JSON.stringify(this.importRows) })
|
||||||
this.$message.success(this.$t(this.key('operation_success')))
|
this.$message.success(this.$t(this.key('operation_success')))
|
||||||
|
this.importVisible = false
|
||||||
|
this.fetchData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,5 +237,6 @@ export default {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.search-bar { padding: 10px 0; }
|
.search-bar { padding: 10px 0; }
|
||||||
|
.import-upload { margin: 12px 0; }
|
||||||
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
|
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,15 +2,28 @@
|
|||||||
<d2-container>
|
<d2-container>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="search-bar">
|
<div class="search-bar">
|
||||||
<el-form :inline="true" size="mini">
|
<el-form :inline="true" :model="search" size="mini">
|
||||||
<el-form-item :label="$t(key('keyword'))">
|
<el-form-item :label="$t(key('device_category'))">
|
||||||
<el-input
|
<el-select v-model="search.device_category_id" :placeholder="$t(key('please_select_device_category'))" clearable filterable style="width:220px">
|
||||||
v-model="search.keyword"
|
<el-option v-for="item in deviceCategoryOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
:placeholder="$t(key('enter_keyword'))"
|
</el-select>
|
||||||
clearable
|
</el-form-item>
|
||||||
style="width:200px"
|
<el-form-item :label="$t(key('device_consumables_category_name'))">
|
||||||
@keyup.enter.native="onSearch"
|
<el-select v-model="search.device_consumables_category_id" :placeholder="$t(key('please_select_consumables_category'))" clearable filterable style="width:240px">
|
||||||
/>
|
<el-option v-for="item in consumablesCategoryOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t(key('consumables_item_code'))">
|
||||||
|
<el-input v-model.trim="search.code" :placeholder="$t(key('enter_consumables_item_code'))" clearable style="width:220px" @keyup.enter.native="onSearch" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t(key('consumables_item_name'))">
|
||||||
|
<el-input v-model.trim="search.name" :placeholder="$t(key('enter_consumables_item_name'))" clearable style="width:220px" @keyup.enter.native="onSearch" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t(key('create_time'))">
|
||||||
|
<el-date-picker v-model="search.create_time" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss" :start-placeholder="$t(key('start_time'))" :end-placeholder="$t(key('end_time'))" style="width:330px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t(key('update_time'))">
|
||||||
|
<el-date-picker v-model="search.update_time" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss" :start-placeholder="$t(key('start_time'))" :end-placeholder="$t(key('end_time'))" style="width:330px" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
|
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
|
||||||
@@ -20,34 +33,31 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<page-table
|
<page-table ref="pageTable" :columns="columns" :data="tableData" :loading="loading" :toolbar-buttons="toolbarButtons" :row-buttons="rowButtons" :pagination="pagination" auto-height @page-change="onPageChange" @selection-change="selectedRows = $event" />
|
||||||
ref="pageTable"
|
|
||||||
:columns="columns"
|
|
||||||
:data="tableData"
|
|
||||||
:loading="loading"
|
|
||||||
:toolbar-buttons="toolbarButtons"
|
|
||||||
:row-buttons="rowButtons"
|
|
||||||
:pagination="pagination"
|
|
||||||
auto-height
|
|
||||||
@page-change="onPageChange"
|
|
||||||
@selection-change="onSelect"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<page-dialog-form
|
<page-dialog-form ref="dialogForm" :visible.sync="dialogVisible" :title="dialogTitle" width="620px" :form-cols="formCols" :form-data="formData" :rules="rules" label-width="150px" :submitting="submitting" :confirm-text="key('confirm')" :cancel-text="key('cancel')" @submit="onDialogSubmit" @close="resetForm" />
|
||||||
ref="dialogForm"
|
|
||||||
:visible.sync="dialogVisible"
|
<el-dialog :title="$t(key('import_title'))" :visible.sync="importVisible" width="900px" :close-on-click-modal="false">
|
||||||
:title="dialogTitle"
|
<el-alert :title="$t(key('import_tip'))" type="warning" :closable="false" />
|
||||||
width="40%"
|
<el-upload class="import-upload" action="" :auto-upload="false" :show-file-list="true" :file-list="importFileList" accept=".xls,.xlsx" :on-change="onImportFileChange">
|
||||||
:form-cols="formCols"
|
<el-button slot="trigger" size="mini" type="success">{{ $t(key('select_file')) }}</el-button>
|
||||||
:form-data="formData"
|
<el-button style="margin-left:10px" size="mini" type="primary" :loading="importLoading" @click.stop="downloadTemplate">{{ $t(key('download_template')) }}</el-button>
|
||||||
:rules="rules"
|
</el-upload>
|
||||||
label-width="130px"
|
<el-table v-loading="importTableLoading" :data="importRows" border height="330" size="mini">
|
||||||
:submitting="submitting"
|
<el-table-column prop="code" :label="$t(key('consumables_item_code'))" min-width="130" />
|
||||||
:confirm-text="key('confirm')"
|
<el-table-column prop="name" :label="$t(key('consumables_item_name'))" min-width="130" />
|
||||||
:cancel-text="key('cancel')"
|
<el-table-column prop="device_consumables_category_name" :label="$t(key('device_consumables_category_name'))" min-width="150" />
|
||||||
@submit="onDialogSubmit"
|
<el-table-column prop="device_category_name" :label="$t(key('device_category'))" min-width="130" />
|
||||||
@close="onDialogClose"
|
<el-table-column prop="standard_service_life" :label="$t(key('standard_service_life'))" min-width="130" />
|
||||||
/>
|
<el-table-column prop="warning_service_life" :label="$t(key('warning_service_life'))" min-width="130" />
|
||||||
|
<el-table-column prop="unit_name" :label="$t(key('service_life_unit'))" min-width="120" />
|
||||||
|
<el-table-column prop="remark" :label="$t(key('remark'))" min-width="130" />
|
||||||
|
</el-table>
|
||||||
|
<span slot="footer">
|
||||||
|
<el-button @click="importVisible = false">{{ $t(key('cancel')) }}</el-button>
|
||||||
|
<el-button type="primary" @click="submitImport">{{ $t(key('confirm')) }}</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
</d2-container>
|
</d2-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -58,7 +68,22 @@ import { i18nMixin } from '@/composables/useI18n'
|
|||||||
import { confirmMixin } from '@/composables/useConfirmHandle'
|
import { confirmMixin } from '@/composables/useConfirmHandle'
|
||||||
import PageTable from '@/components/page-table'
|
import PageTable from '@/components/page-table'
|
||||||
import PageDialogForm from '@/components/page-dialog-form'
|
import PageDialogForm from '@/components/page-dialog-form'
|
||||||
import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/consumables-items'
|
import { downloadRename, readExcel } from '@/utils/file'
|
||||||
|
import { getEquipmentCategoryALL } from '@/api/equipment-management/equipment-category'
|
||||||
|
import { getUnitAll } from '@/api/production-master-data/material-unit'
|
||||||
|
import { getAll as getConsumablesCategoryAll } from '@/api/equipment-management/consumables-category'
|
||||||
|
import { getList, createItem, editItem, deleteItem, createExportTask, getImportTemplate, importData } from '@/api/equipment-management/consumables-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, label = 'name', value = 'id') {
|
||||||
|
return (Array.isArray(list) ? list : []).map(item => ({ label: item[label], value: item[value], raw: item }))
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'equipment-management-consumables-items',
|
name: 'equipment-management-consumables-items',
|
||||||
@@ -70,97 +95,76 @@ export default {
|
|||||||
submitting: false,
|
submitting: false,
|
||||||
tableData: [],
|
tableData: [],
|
||||||
selectedRows: [],
|
selectedRows: [],
|
||||||
|
search: { device_category_id: '', device_consumables_category_id: '', code: '', name: '', create_time: [], update_time: [] },
|
||||||
|
pagination: { current: 1, size: 10, total: 0 },
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
dialogTitle: '',
|
dialogTitle: '',
|
||||||
editId: '',
|
|
||||||
handleType: 'create',
|
handleType: 'create',
|
||||||
search: {
|
editId: '',
|
||||||
keyword: ''
|
formData: { device_category_id: '', device_consumables_category_id: '', code: '', name: '', standard_service_life: 0, warning_service_life: 0, unit_id: '', remark: '' },
|
||||||
},
|
deviceCategoryOptions: [],
|
||||||
pagination: { current: 1, size: 10, total: 0 },
|
consumablesCategoryOptions: [],
|
||||||
formData: {
|
unitOptions: [],
|
||||||
device_consumables_item_code: '',
|
importVisible: false,
|
||||||
device_consumables_item_name: '',
|
importFileList: [],
|
||||||
device_consumables_category_id: '',
|
importRows: [],
|
||||||
specification: '',
|
importLoading: false,
|
||||||
remark: ''
|
importTableLoading: false,
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
device_consumables_item_code: [{ required: true, message: this.key('enter_consumables_item_code'), trigger: 'blur' }],
|
|
||||||
device_consumables_item_name: [{ required: true, message: this.key('enter_consumables_item_name'), trigger: 'blur' }]
|
|
||||||
},
|
|
||||||
columns: [],
|
columns: [],
|
||||||
toolbarButtons: [],
|
toolbarButtons: [],
|
||||||
rowButtons: [],
|
rowButtons: [],
|
||||||
formCols: [
|
rules: {
|
||||||
|
device_category_id: [{ required: true, message: this.key('please_select_device_category'), trigger: 'change' }],
|
||||||
|
device_consumables_category_id: [{ required: true, message: this.key('please_select_consumables_category'), trigger: 'change' }],
|
||||||
|
code: [{ required: true, message: this.key('enter_consumables_item_code'), trigger: 'blur' }],
|
||||||
|
name: [{ required: true, message: this.key('enter_consumables_item_name'), trigger: 'blur' }],
|
||||||
|
standard_service_life: [{ required: true, message: this.key('enter_standard_service_life'), trigger: 'blur' }, { validator: this.validateLifeRule, trigger: 'change' }],
|
||||||
|
warning_service_life: [{ required: true, message: this.key('enter_warning_service_life'), trigger: 'blur' }, { validator: this.validateLifeRule, trigger: 'change' }],
|
||||||
|
unit_id: [{ required: true, message: this.key('please_select_service_life_unit'), trigger: 'change' }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
formCols () {
|
||||||
|
return [
|
||||||
[
|
[
|
||||||
{
|
{ type: 'select', prop: 'device_category_id', label: this.key('device_category'), placeholder: this.key('please_select_device_category'), options: this.deviceCategoryOptions, style: { width: '100%' }, onChange: this.onFormDeviceCategoryChange },
|
||||||
type: 'input',
|
{ type: 'select', prop: 'device_consumables_category_id', label: this.key('consumables_category'), placeholder: this.key('please_select_consumables_category'), options: this.consumablesCategoryOptions, style: { width: '100%' } }
|
||||||
prop: 'device_consumables_item_code',
|
|
||||||
label: this.key('consumables_item_code'),
|
|
||||||
placeholder: this.key('enter_consumables_item_code'),
|
|
||||||
clearable: true,
|
|
||||||
style: { width: '90%' }
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{ type: 'input', prop: 'code', label: this.key('consumables_item_code'), placeholder: this.key('enter_consumables_item_code'), style: { width: '100%' } },
|
||||||
type: 'input',
|
{ type: 'input', prop: 'name', label: this.key('consumables_item_name'), placeholder: this.key('enter_consumables_item_name'), style: { width: '100%' } }
|
||||||
prop: 'device_consumables_item_name',
|
|
||||||
label: this.key('consumables_item_name'),
|
|
||||||
placeholder: this.key('enter_consumables_item_name'),
|
|
||||||
clearable: true,
|
|
||||||
style: { width: '90%' }
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{ type: 'input-number', prop: 'standard_service_life', label: this.key('standard_life'), placeholder: this.key('enter_standard_service_life'), min: 0, style: { width: '100%' } },
|
||||||
type: 'input',
|
{ type: 'input-number', prop: 'warning_service_life', label: this.key('warning_life'), placeholder: this.key('enter_warning_service_life'), min: 0, style: { width: '100%' } }
|
||||||
prop: 'device_consumables_category_id',
|
|
||||||
label: this.key('consumables_category_id'),
|
|
||||||
placeholder: this.key('enter_consumables_category_id'),
|
|
||||||
clearable: true,
|
|
||||||
style: { width: '90%' }
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
[
|
[{ type: 'select', prop: 'unit_id', label: this.key('service_life_unit'), placeholder: this.key('please_select_service_life_unit'), options: this.unitOptions, style: { width: '100%' } }],
|
||||||
{
|
[{ type: 'input', prop: 'remark', label: this.key('remark'), placeholder: this.key('enter_remark'), inputType: 'textarea', autosize: { minRows: 2, maxRows: 6 }, style: { width: '100%' } }]
|
||||||
type: 'input',
|
|
||||||
prop: 'specification',
|
|
||||||
label: this.key('specification'),
|
|
||||||
placeholder: this.key('enter_specification'),
|
|
||||||
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%' }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
this.columns = useTableColumns([
|
this.columns = useTableColumns([
|
||||||
{ prop: 'device_consumables_item_code', label: this.key('consumables_item_code'), minWidth: 140 },
|
{ prop: 'sort', label: this.key('sort'), width: 80 },
|
||||||
{ prop: 'device_consumables_item_name', label: this.key('consumables_item_name'), minWidth: 140 },
|
{ prop: 'code', label: this.key('consumables_item_code'), minWidth: 140 },
|
||||||
{ prop: 'device_consumables_category_name', label: this.key('consumables_category'), minWidth: 140 },
|
{ prop: 'name', label: this.key('consumables_item_name'), minWidth: 140 },
|
||||||
{ prop: 'specification', label: this.key('specification'), minWidth: 140 },
|
{ prop: 'device_consumables_category_name', label: this.key('device_consumables_category_name'), minWidth: 160 },
|
||||||
{ prop: 'remark', label: this.key('remark'), minWidth: 140 },
|
{ prop: 'device_category_name', label: this.key('device_category'), minWidth: 140 },
|
||||||
|
{ prop: 'standard_service_life', label: this.key('standard_service_life'), minWidth: 130 },
|
||||||
|
{ prop: 'warning_service_life', label: this.key('warning_service_life'), minWidth: 130 },
|
||||||
|
{ prop: 'unit_name', label: this.key('service_life_unit'), minWidth: 120 },
|
||||||
|
{ 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' }
|
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
|
||||||
])
|
])
|
||||||
const btns = useTableButtons({
|
const btns = useTableButtons({
|
||||||
toolbar: [
|
toolbar: [
|
||||||
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_consumables/device_consumables_items/create', onClick: this.openAdd },
|
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_consumables/device_consumables_items/create', onClick: this.openAdd },
|
||||||
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_consumables/device_consumables_items/export', onClick: this.handleExport }
|
{ key: 'batch_delete', label: this.key('batch_delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_consumables/device_consumables_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_consumables/device_consumables_items/import', onClick: this.openImport },
|
||||||
|
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', type: 'primary', auth: '/device_management/device_consumables/device_consumables_items/export', onClick: this.handleExport }
|
||||||
],
|
],
|
||||||
row: [
|
row: [
|
||||||
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_consumables/device_consumables_items/edit', onClick: this.openEdit },
|
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_consumables/device_consumables_items/edit', onClick: this.openEdit },
|
||||||
@@ -169,79 +173,60 @@ export default {
|
|||||||
}, this.$permission)
|
}, this.$permission)
|
||||||
this.toolbarButtons = btns.toolbarButtons
|
this.toolbarButtons = btns.toolbarButtons
|
||||||
this.rowButtons = btns.rowButtons
|
this.rowButtons = btns.rowButtons
|
||||||
|
this.initOptions()
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
normalizeResponse (res) {
|
async initOptions () {
|
||||||
const data = res && res.data !== undefined ? res.data : res
|
const [devices, categories, units] = await Promise.all([getEquipmentCategoryALL({}), getConsumablesCategoryAll({}), getUnitAll({})])
|
||||||
if (Array.isArray(data)) return { list: data, total: data.length }
|
this.deviceCategoryOptions = toOptions((devices && devices.data) || devices)
|
||||||
if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
|
this.consumablesCategoryOptions = toOptions((categories && categories.data) || categories)
|
||||||
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) }
|
this.unitOptions = toOptions((units && units.data) || units)
|
||||||
return { list: [], total: 0 }
|
},
|
||||||
|
onFormDeviceCategoryChange () {
|
||||||
|
this.formData.device_consumables_category_id = ''
|
||||||
|
},
|
||||||
|
buildSearchParams () {
|
||||||
|
const params = { ...this.search }
|
||||||
|
if (!Array.isArray(params.create_time) || !params.create_time.length) delete params.create_time
|
||||||
|
if (!Array.isArray(params.update_time) || !params.update_time.length) delete params.update_time
|
||||||
|
return params
|
||||||
},
|
},
|
||||||
async fetchData () {
|
async fetchData () {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
try {
|
try {
|
||||||
const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
|
const res = await getList({ ...this.buildSearchParams(), page_no: this.pagination.current, page_size: this.pagination.size })
|
||||||
const data = this.normalizeResponse(res)
|
const page = readPageData(res)
|
||||||
this.tableData = data.list
|
this.tableData = page.list
|
||||||
this.pagination.total = data.total
|
this.pagination.total = page.total
|
||||||
} finally {
|
} finally { this.loading = false }
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onSearch () {
|
|
||||||
this.pagination.current = 1
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onReset () {
|
|
||||||
this.search = {
|
|
||||||
keyword: ''
|
|
||||||
}
|
|
||||||
this.pagination.current = 1
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onPageChange (page) {
|
|
||||||
this.pagination.current = page.current
|
|
||||||
this.pagination.size = page.size
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onSelect (rows) {
|
|
||||||
this.selectedRows = rows
|
|
||||||
},
|
|
||||||
resetForm () {
|
|
||||||
this.formData = {
|
|
||||||
device_consumables_item_code: '',
|
|
||||||
device_consumables_item_name: '',
|
|
||||||
device_consumables_category_id: '',
|
|
||||||
specification: '',
|
|
||||||
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
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
onSearch () { this.pagination.current = 1; this.fetchData() },
|
||||||
|
onReset () { this.search = { device_category_id: '', device_consumables_category_id: '', code: '', name: '', create_time: [], update_time: [] }; this.pagination.current = 1; this.fetchData() },
|
||||||
|
onPageChange (page) { this.pagination.current = page.current; this.pagination.size = page.size; this.fetchData() },
|
||||||
|
resetForm () { this.formData = { device_category_id: '', device_consumables_category_id: '', code: '', name: '', standard_service_life: 0, warning_service_life: 0, unit_id: '', remark: '' }; this.editId = '' },
|
||||||
|
openAdd () { this.handleType = 'create'; this.dialogTitle = this.key('add_title'); this.resetForm(); this.dialogVisible = true },
|
||||||
openEdit (row) {
|
openEdit (row) {
|
||||||
this.handleType = 'edit'
|
this.handleType = 'edit'; this.dialogTitle = this.key('edit_title'); this.editId = row.id
|
||||||
this.dialogTitle = this.key('edit_title')
|
this.formData = { device_category_id: row.device_category_id || '', device_consumables_category_id: row.device_consumables_category_id || '', code: row.code || '', name: row.name || '', standard_service_life: Number(row.standard_service_life || 0), warning_service_life: Number(row.warning_service_life || 0), unit_id: row.unit_id || '', remark: row.remark || '' }
|
||||||
this.editId = row.id
|
|
||||||
this.formData = {
|
|
||||||
device_consumables_item_code: row.device_consumables_item_code || '',
|
|
||||||
device_consumables_item_name: row.device_consumables_item_name || '',
|
|
||||||
device_consumables_category_id: row.device_consumables_category_id || '',
|
|
||||||
specification: row.specification || '',
|
|
||||||
remark: row.remark || ''
|
|
||||||
}
|
|
||||||
this.dialogVisible = true
|
this.dialogVisible = true
|
||||||
},
|
},
|
||||||
|
validateLife () {
|
||||||
|
if (Number(this.formData.standard_service_life) < Number(this.formData.warning_service_life)) {
|
||||||
|
this.$message.error(this.$t(this.key('warning_life_not_greater_than_standard')))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
validateLifeRule (rule, value, callback) {
|
||||||
|
if (Number(this.formData.standard_service_life) < Number(this.formData.warning_service_life)) {
|
||||||
|
callback(new Error(this.$t(this.key('warning_life_not_greater_than_standard'))))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
},
|
||||||
async onDialogSubmit () {
|
async onDialogSubmit () {
|
||||||
|
if (!this.validateLife()) return
|
||||||
this.submitting = true
|
this.submitting = true
|
||||||
try {
|
try {
|
||||||
if (this.handleType === 'create') await createItem(this.formData)
|
if (this.handleType === 'create') await createItem(this.formData)
|
||||||
@@ -249,30 +234,49 @@ export default {
|
|||||||
this.$message.success(this.$t(this.key('operation_success')))
|
this.$message.success(this.$t(this.key('operation_success')))
|
||||||
this.dialogVisible = false
|
this.dialogVisible = false
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
} finally {
|
} finally { this.submitting = false }
|
||||||
this.submitting = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onDialogClose () {
|
|
||||||
this.resetForm()
|
|
||||||
},
|
},
|
||||||
async handleDelete (row) {
|
async handleDelete (row) {
|
||||||
const cancelled = await this.$confirmAction(
|
const cancelled = await this.$confirmAction({ message: this.key('confirm_delete'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteItem({ id: [row.id] }))
|
||||||
{ message: this.key('confirm_delete'), title: this.key('tip') },
|
if (cancelled) return
|
||||||
() => deleteItem({ id: [row.id] })
|
this.$message.success(this.$t(this.key('operation_success')))
|
||||||
)
|
this.fetchData()
|
||||||
|
},
|
||||||
|
async handleBatchDelete () {
|
||||||
|
if (!this.selectedRows.length) { this.$message.error(this.$t(this.key('please_select_data'))); return }
|
||||||
|
const cancelled = await this.$confirmAction({ message: this.key('confirm_batch_delete'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteItem({ id: this.selectedRows.map(item => item.id) }))
|
||||||
if (cancelled) return
|
if (cancelled) return
|
||||||
this.$message.success(this.$t(this.key('operation_success')))
|
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.fetchData()
|
this.fetchData()
|
||||||
},
|
},
|
||||||
async handleExport () {
|
async handleExport () {
|
||||||
const cancelled = await this.$confirmAction(
|
const cancelled = await this.$confirmAction({ message: this.key('confirm_export'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => createExportTask({ ...this.buildSearchParams(), action: 'download' }))
|
||||||
{ message: this.key('confirm_export'), title: this.key('tip') },
|
|
||||||
() => createExportTask({ ...this.search })
|
|
||||||
)
|
|
||||||
if (cancelled) return
|
if (cancelled) return
|
||||||
|
this.$message.success(this.$t(this.key('create_download_task_success')))
|
||||||
|
},
|
||||||
|
openImport () { 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 = ['consumables_item_code', 'consumables_item_name', 'device_consumables_category_name', 'device_category', 'standard_service_life', 'warning_service_life', 'service_life_unit', 'remark'].map(k => this.$t(this.key(k)))
|
||||||
|
if (rows.length && headers.some(title => !Object.prototype.hasOwnProperty.call(rows[0], title))) {
|
||||||
|
this.$message.error(this.$t(this.key('file_column_missing'), { title: headers.find(title => !Object.prototype.hasOwnProperty.call(rows[0], title)) }))
|
||||||
|
this.importRows = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.importRows = rows.map(row => ({ code: row[headers[0]], name: row[headers[1]], device_consumables_category_name: row[headers[2]], device_category_name: row[headers[3]], standard_service_life: row[headers[4]], warning_service_life: row[headers[5]], unit_name: row[headers[6]], remark: row[headers[7]] }))
|
||||||
|
} finally { this.importTableLoading = false }
|
||||||
|
},
|
||||||
|
async submitImport () {
|
||||||
|
if (!this.importRows.length) { this.$message.error(this.$t(this.key('please_import_data'))); return }
|
||||||
|
await importData({ import_data: JSON.stringify(this.importRows) })
|
||||||
this.$message.success(this.$t(this.key('operation_success')))
|
this.$message.success(this.$t(this.key('operation_success')))
|
||||||
|
this.importVisible = false
|
||||||
|
this.fetchData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,5 +284,6 @@ export default {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.search-bar { padding: 10px 0; }
|
.search-bar { padding: 10px 0; }
|
||||||
|
.import-upload { margin: 12px 0; }
|
||||||
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
|
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,15 +2,23 @@
|
|||||||
<d2-container>
|
<d2-container>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="search-bar">
|
<div class="search-bar">
|
||||||
<el-form :inline="true" size="mini">
|
<el-form :inline="true" :model="search" size="mini">
|
||||||
<el-form-item :label="$t(key('keyword'))">
|
<el-form-item :label="$t(key('device_name'))">
|
||||||
<el-input
|
<el-select v-model="search.device_code" :placeholder="$t(key('select_device'))" clearable filterable style="width:220px">
|
||||||
v-model="search.keyword"
|
<el-option v-for="item in deviceOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
:placeholder="$t(key('enter_keyword'))"
|
</el-select>
|
||||||
clearable
|
</el-form-item>
|
||||||
style="width:200px"
|
<el-form-item :label="$t(key('consumable_code'))">
|
||||||
@keyup.enter.native="onSearch"
|
<el-input v-model.trim="search.device_consumables_item_code" :placeholder="$t(key('enter_consumables_item_code'))" clearable style="width:220px" @keyup.enter.native="onSearch" />
|
||||||
/>
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t(key('consumable_name'))">
|
||||||
|
<el-input v-model.trim="search.device_consumables_item_name" :placeholder="$t(key('enter_consumables_item_name'))" clearable style="width:220px" @keyup.enter.native="onSearch" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t(key('create_time'))">
|
||||||
|
<el-date-picker v-model="search.create_time" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss" :start-placeholder="$t(key('start_time'))" :end-placeholder="$t(key('end_time'))" style="width:330px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t(key('update_time'))">
|
||||||
|
<el-date-picker v-model="search.update_time" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss" :start-placeholder="$t(key('start_time'))" :end-placeholder="$t(key('end_time'))" style="width:330px" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
|
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
|
||||||
@@ -20,34 +28,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<page-table
|
<page-table ref="pageTable" :columns="columns" :data="tableData" :loading="loading" :toolbar-buttons="toolbarButtons" :row-buttons="rowButtons" :pagination="pagination" auto-height @page-change="onPageChange" @selection-change="selectedRows = $event">
|
||||||
ref="pageTable"
|
<template #col-status="{ row }">
|
||||||
:columns="columns"
|
<el-tag v-if="Number(row.status) === 0" size="mini">{{ $t(key('normal')) }}</el-tag>
|
||||||
:data="tableData"
|
<el-tag v-else-if="Number(row.status) === 1" type="warning" size="mini">{{ $t(key('near_standard_life')) }}</el-tag>
|
||||||
:loading="loading"
|
<el-tag v-else-if="Number(row.status) === 2" type="danger" size="mini">{{ $t(key('exceed_standard_life')) }}</el-tag>
|
||||||
:toolbar-buttons="toolbarButtons"
|
<el-tag v-else type="info" size="mini">-</el-tag>
|
||||||
:row-buttons="rowButtons"
|
</template>
|
||||||
:pagination="pagination"
|
</page-table>
|
||||||
auto-height
|
|
||||||
@page-change="onPageChange"
|
|
||||||
@selection-change="onSelect"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<page-dialog-form
|
<page-dialog-form ref="dialogForm" :visible.sync="dialogVisible" :title="dialogTitle" width="620px" :form-cols="formCols" :form-data="formData" :rules="activeRules" label-width="150px" :submitting="submitting" :confirm-text="key('confirm')" :cancel-text="key('cancel')" @submit="onDialogSubmit" @close="resetForm" />
|
||||||
ref="dialogForm"
|
|
||||||
:visible.sync="dialogVisible"
|
<el-dialog :title="$t(key('import_title'))" :visible.sync="importVisible" width="820px" :close-on-click-modal="false">
|
||||||
:title="dialogTitle"
|
<el-alert :title="$t(key('import_tip'))" type="warning" :closable="false" />
|
||||||
width="40%"
|
<el-upload class="import-upload" action="" :auto-upload="false" :show-file-list="true" :file-list="importFileList" accept=".xls,.xlsx" :on-change="onImportFileChange">
|
||||||
:form-cols="formCols"
|
<el-button slot="trigger" size="mini" type="success">{{ $t(key('select_file')) }}</el-button>
|
||||||
:form-data="formData"
|
<el-button style="margin-left:10px" size="mini" type="primary" :loading="importLoading" @click.stop="downloadTemplate">{{ $t(key('download_template')) }}</el-button>
|
||||||
:rules="rules"
|
</el-upload>
|
||||||
label-width="130px"
|
<el-table v-loading="importTableLoading" :data="importRows" border height="320" size="mini">
|
||||||
:submitting="submitting"
|
<el-table-column prop="device_consumables_item_name" :label="$t(key('device_consumables_item'))" min-width="160" />
|
||||||
:confirm-text="key('confirm')"
|
<el-table-column prop="device_name" :label="$t(key('related_device'))" min-width="160" />
|
||||||
:cancel-text="key('cancel')"
|
<el-table-column prop="device_consumables_lifetime" :label="$t(key('used_life'))" min-width="130" />
|
||||||
@submit="onDialogSubmit"
|
<el-table-column prop="remark" :label="$t(key('remark'))" min-width="140" />
|
||||||
@close="onDialogClose"
|
</el-table>
|
||||||
/>
|
<span slot="footer">
|
||||||
|
<el-button @click="importVisible = false">{{ $t(key('cancel')) }}</el-button>
|
||||||
|
<el-button type="primary" @click="submitImport">{{ $t(key('confirm')) }}</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
</d2-container>
|
</d2-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -58,7 +66,22 @@ import { i18nMixin } from '@/composables/useI18n'
|
|||||||
import { confirmMixin } from '@/composables/useConfirmHandle'
|
import { confirmMixin } from '@/composables/useConfirmHandle'
|
||||||
import PageTable from '@/components/page-table'
|
import PageTable from '@/components/page-table'
|
||||||
import PageDialogForm from '@/components/page-dialog-form'
|
import PageDialogForm from '@/components/page-dialog-form'
|
||||||
import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/consumables-lifecycle'
|
import { downloadRename, readExcel } from '@/utils/file'
|
||||||
|
import { getAll as getDeviceAll } from '@/api/equipment-management/equipment-registry'
|
||||||
|
import { getAll as getConsumablesItemsAll } from '@/api/equipment-management/consumables-items'
|
||||||
|
import { getList, createItem, editItem, deleteItem, createExportTask, getImportTemplate, importData } from '@/api/equipment-management/consumables-lifecycle'
|
||||||
|
import { createItem as createReplaceLog } from '@/api/equipment-management/replacement-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 toOptions (list, label = 'name', value = 'code') {
|
||||||
|
return (Array.isArray(list) ? list : []).map(item => ({ label: item[label], value: item[value], raw: item }))
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'equipment-management-consumables-lifecycle',
|
name: 'equipment-management-consumables-lifecycle',
|
||||||
@@ -70,223 +93,199 @@ export default {
|
|||||||
submitting: false,
|
submitting: false,
|
||||||
tableData: [],
|
tableData: [],
|
||||||
selectedRows: [],
|
selectedRows: [],
|
||||||
|
search: { device_code: '', device_consumables_item_code: '', device_consumables_item_name: '', create_time: [], update_time: [] },
|
||||||
|
pagination: { current: 1, size: 10, total: 0 },
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
dialogTitle: '',
|
dialogTitle: '',
|
||||||
editId: '',
|
|
||||||
handleType: 'create',
|
handleType: 'create',
|
||||||
search: {
|
editId: '',
|
||||||
keyword: ''
|
formData: { device_consumables_item_code: '', device_code: '', standard_service_life: 0, warning_service_life: 0, device_consumables_lifetime: 0, replace_user: '', replace_time: '', replace_reason: '', replacement_time: 0, remark: '' },
|
||||||
},
|
consumablesItemOptions: [],
|
||||||
pagination: { current: 1, size: 10, total: 0 },
|
deviceOptions: [],
|
||||||
formData: {
|
importVisible: false,
|
||||||
device_consumables_item_id: '',
|
importFileList: [],
|
||||||
device_id: '',
|
importRows: [],
|
||||||
standard_life: '',
|
importLoading: false,
|
||||||
warning_life: '',
|
importTableLoading: false,
|
||||||
used_life: '',
|
|
||||||
remark: ''
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
device_consumables_item_id: [{ required: true, message: this.key('enter_consumables_item_id'), trigger: 'blur' }],
|
|
||||||
device_id: [{ required: true, message: this.key('enter_device_id'), trigger: 'blur' }]
|
|
||||||
},
|
|
||||||
columns: [],
|
columns: [],
|
||||||
toolbarButtons: [],
|
toolbarButtons: [],
|
||||||
rowButtons: [],
|
rowButtons: []
|
||||||
formCols: [
|
}
|
||||||
[
|
},
|
||||||
{
|
computed: {
|
||||||
type: 'input',
|
replaceReasonOptions () {
|
||||||
prop: 'device_consumables_item_id',
|
return [
|
||||||
label: this.key('consumables_item_id'),
|
{ label: this.$t(this.key('replace_reason_abnormal')), value: this.$t(this.key('replace_reason_abnormal')) },
|
||||||
placeholder: this.key('enter_consumables_item_id'),
|
{ label: this.$t(this.key('replace_reason_normal')), value: this.$t(this.key('replace_reason_normal')) },
|
||||||
clearable: true,
|
{ label: this.$t(this.key('replace_reason_exceed')), value: this.$t(this.key('replace_reason_exceed')) }
|
||||||
style: { width: '90%' }
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
prop: 'device_id',
|
|
||||||
label: this.key('device_id'),
|
|
||||||
placeholder: this.key('enter_device_id'),
|
|
||||||
clearable: true,
|
|
||||||
style: { width: '90%' }
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
prop: 'standard_life',
|
|
||||||
label: this.key('standard_life'),
|
|
||||||
placeholder: this.key('enter_standard_life'),
|
|
||||||
clearable: true,
|
|
||||||
style: { width: '90%' }
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
prop: 'warning_life',
|
|
||||||
label: this.key('warning_life'),
|
|
||||||
placeholder: this.key('enter_warning_life'),
|
|
||||||
clearable: true,
|
|
||||||
style: { width: '90%' }
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
prop: 'used_life',
|
|
||||||
label: this.key('used_life'),
|
|
||||||
placeholder: this.key('enter_used_life'),
|
|
||||||
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%' }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
formCols () {
|
||||||
|
const disabledBase = this.handleType !== 'create'
|
||||||
|
const cols = [
|
||||||
|
[{ type: 'select', prop: 'device_consumables_item_code', label: this.key('device_consumables_item'), placeholder: this.key('select_consumable'), options: this.consumablesItemOptions, disabled: disabledBase, style: { width: '100%' }, onChange: this.onConsumablesItemChange }],
|
||||||
|
[{ type: 'select', prop: 'device_code', label: this.key('related_device'), placeholder: this.key('select_device'), options: this.deviceOptions, disabled: disabledBase, style: { width: '100%' } }],
|
||||||
|
[{ type: 'input-number', prop: 'standard_service_life', label: this.key('standard_life'), min: 0, disabled: true, style: { width: '100%' } }],
|
||||||
|
[{ type: 'input-number', prop: 'warning_service_life', label: this.key('warning_life'), min: 0, disabled: true, style: { width: '100%' } }]
|
||||||
|
]
|
||||||
|
if (this.handleType === 'replace') {
|
||||||
|
cols.push(
|
||||||
|
[{ type: 'input', prop: 'replace_user', label: this.key('replace_user'), placeholder: this.key('input_replace_user'), style: { width: '100%' } }],
|
||||||
|
[{ type: 'date-picker', prop: 'replace_time', label: this.key('replace_time'), placeholder: this.key('input_replace_time'), style: { width: '100%' } }],
|
||||||
|
[{ type: 'select', prop: 'replace_reason', label: this.key('replace_reason'), placeholder: this.key('select_replace_reason'), options: this.replaceReasonOptions, style: { width: '100%' } }],
|
||||||
|
[{ type: 'input-number', prop: 'replacement_time', label: this.key('replace_duration'), min: 0, style: { width: '100%' } }]
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
cols.push([{ type: 'input-number', prop: 'device_consumables_lifetime', label: this.key('used_life'), min: 0, style: { width: '100%' } }])
|
||||||
|
}
|
||||||
|
cols.push([{ type: 'input', prop: 'remark', label: this.key('remark'), placeholder: this.key('enter_remark'), inputType: 'textarea', autosize: { minRows: 2, maxRows: 6 }, style: { width: '100%' } }])
|
||||||
|
return cols
|
||||||
|
},
|
||||||
|
activeRules () {
|
||||||
|
const rules = {
|
||||||
|
device_code: [{ required: true, message: this.key('device_required'), trigger: 'change' }],
|
||||||
|
device_consumables_item_code: [{ required: true, message: this.key('consumable_required'), trigger: 'change' }]
|
||||||
|
}
|
||||||
|
if (this.handleType === 'replace') {
|
||||||
|
rules.replace_user = [{ required: true, message: this.key('input_replace_user'), trigger: 'blur' }]
|
||||||
|
rules.replace_time = [{ required: true, message: this.key('input_replace_time'), trigger: 'change' }]
|
||||||
|
rules.replace_reason = [{ required: true, message: this.key('replace_reason_required'), trigger: 'change' }]
|
||||||
|
rules.replacement_time = [{ required: true, message: this.key('input_replace_duration'), trigger: 'blur' }]
|
||||||
|
} else {
|
||||||
|
rules.device_consumables_lifetime = [{ required: true, message: this.key('input_used_life'), trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
return rules
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
this.columns = useTableColumns([
|
this.columns = useTableColumns([
|
||||||
{ prop: 'device_consumables_item_name', label: this.key('consumables_item'), minWidth: 140 },
|
{ prop: 'sort', label: this.key('sort'), width: 80 },
|
||||||
{ prop: 'device_name', label: this.key('device_name'), minWidth: 140 },
|
{ prop: 'status', label: this.key('status'), slot: 'status', width: 120 },
|
||||||
{ prop: 'standard_life', label: this.key('standard_life'), minWidth: 140 },
|
{ prop: 'device_consumables_item_code', label: this.key('consumable_code'), minWidth: 150 },
|
||||||
{ prop: 'warning_life', label: this.key('warning_life'), minWidth: 140 },
|
{ prop: 'device_consumables_item_name', label: this.key('consumable_name'), minWidth: 150 },
|
||||||
{ prop: 'used_life', label: this.key('used_life'), minWidth: 140 },
|
{ prop: 'device_consumables_category_name', label: this.key('consumable_category'), minWidth: 150 },
|
||||||
{ prop: 'replace_time', label: this.key('replace_time'), minWidth: 140 },
|
{ prop: 'device_name', label: this.key('related_device'), minWidth: 150 },
|
||||||
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
|
{ prop: 'standard_service_life', label: this.key('standard_service_life'), minWidth: 130 },
|
||||||
|
{ prop: 'warning_service_life', label: this.key('warning_service_life'), minWidth: 130 },
|
||||||
|
{ prop: 'device_consumables_lifetime', label: this.key('used_life'), minWidth: 120 },
|
||||||
|
{ 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: 230, fixed: 'right' }
|
||||||
])
|
])
|
||||||
const btns = useTableButtons({
|
const btns = useTableButtons({
|
||||||
toolbar: [
|
toolbar: [
|
||||||
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_consumables/device_consumables_lifetime_management/create', onClick: this.openAdd },
|
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_consumables/device_consumables_lifetime_management/create', onClick: this.openAdd },
|
||||||
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_consumables/device_consumables_lifetime_management/export', onClick: this.handleExport }
|
{ key: 'batch_delete', label: this.key('batch_delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_consumables/device_consumables_lifetime_management/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_consumables/device_consumables_lifetime_management/import', onClick: this.openImport },
|
||||||
|
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', type: 'primary', auth: '/device_management/device_consumables/device_consumables_lifetime_management/export', onClick: this.handleExport }
|
||||||
],
|
],
|
||||||
row: [
|
row: [
|
||||||
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_consumables/device_consumables_lifetime_management/edit', onClick: this.openEdit },
|
{ key: 'declare_lifetime', label: this.key('declare_lifetime'), icon: 'el-icon-edit', auth: '/device_management/device_consumables/device_consumables_lifetime_management/edit', onClick: this.openEdit },
|
||||||
|
{ key: 'replace', label: this.key('replace'), icon: 'el-icon-refresh', auth: '/device_management/device_consumables/device_consumables_lifetime_management/change', onClick: this.openReplace },
|
||||||
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_consumables/device_consumables_lifetime_management/delete', onClick: this.handleDelete }
|
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_consumables/device_consumables_lifetime_management/delete', onClick: this.handleDelete }
|
||||||
]
|
]
|
||||||
}, this.$permission)
|
}, this.$permission)
|
||||||
this.toolbarButtons = btns.toolbarButtons
|
this.toolbarButtons = btns.toolbarButtons
|
||||||
this.rowButtons = btns.rowButtons
|
this.rowButtons = btns.rowButtons
|
||||||
|
this.initOptions()
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
normalizeResponse (res) {
|
async initOptions () {
|
||||||
const data = res && res.data !== undefined ? res.data : res
|
const [items, devices] = await Promise.all([getConsumablesItemsAll({}), getDeviceAll({})])
|
||||||
if (Array.isArray(data)) return { list: data, total: data.length }
|
this.consumablesItemOptions = toOptions((items && items.data) || items)
|
||||||
if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
|
this.deviceOptions = toOptions((devices && devices.data) || devices)
|
||||||
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 onConsumablesItemChange (code) {
|
||||||
|
const option = this.consumablesItemOptions.find(item => item.value === code)
|
||||||
|
const row = option && option.raw ? option.raw : {}
|
||||||
|
this.formData.standard_service_life = Number(row.standard_service_life || 0)
|
||||||
|
this.formData.warning_service_life = Number(row.warning_service_life || 0)
|
||||||
|
this.formData.device_code = ''
|
||||||
|
if (row.device_category_id) {
|
||||||
|
const res = await getDeviceAll({ device_category_id: row.device_category_id })
|
||||||
|
this.deviceOptions = toOptions((res && res.data) || res)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buildSearchParams () {
|
||||||
|
const params = { ...this.search }
|
||||||
|
if (!Array.isArray(params.create_time) || !params.create_time.length) delete params.create_time
|
||||||
|
if (!Array.isArray(params.update_time) || !params.update_time.length) delete params.update_time
|
||||||
|
return params
|
||||||
},
|
},
|
||||||
async fetchData () {
|
async fetchData () {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
try {
|
try {
|
||||||
const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
|
const res = await getList({ ...this.buildSearchParams(), page_no: this.pagination.current, page_size: this.pagination.size })
|
||||||
const data = this.normalizeResponse(res)
|
const page = readPageData(res)
|
||||||
this.tableData = data.list
|
this.tableData = page.list
|
||||||
this.pagination.total = data.total
|
this.pagination.total = page.total
|
||||||
} finally {
|
} finally { this.loading = false }
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onSearch () {
|
onSearch () { this.pagination.current = 1; this.fetchData() },
|
||||||
this.pagination.current = 1
|
onReset () { this.search = { device_code: '', device_consumables_item_code: '', device_consumables_item_name: '', create_time: [], update_time: [] }; this.pagination.current = 1; this.fetchData() },
|
||||||
this.fetchData()
|
onPageChange (page) { this.pagination.current = page.current; this.pagination.size = page.size; this.fetchData() },
|
||||||
},
|
resetForm () { this.formData = { device_consumables_item_code: '', device_code: '', standard_service_life: 0, warning_service_life: 0, device_consumables_lifetime: 0, replace_user: '', replace_time: '', replace_reason: '', replacement_time: 0, remark: '' }; this.editId = '' },
|
||||||
onReset () {
|
fillForm (row) {
|
||||||
this.search = {
|
|
||||||
keyword: ''
|
|
||||||
}
|
|
||||||
this.pagination.current = 1
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onPageChange (page) {
|
|
||||||
this.pagination.current = page.current
|
|
||||||
this.pagination.size = page.size
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onSelect (rows) {
|
|
||||||
this.selectedRows = rows
|
|
||||||
},
|
|
||||||
resetForm () {
|
|
||||||
this.formData = {
|
|
||||||
device_consumables_item_id: '',
|
|
||||||
device_id: '',
|
|
||||||
standard_life: '',
|
|
||||||
warning_life: '',
|
|
||||||
used_life: '',
|
|
||||||
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.editId = row.id
|
||||||
this.formData = {
|
this.formData = { device_consumables_item_code: row.device_consumables_item_code || '', device_code: row.device_code || '', standard_service_life: Number(row.standard_service_life || 0), warning_service_life: Number(row.warning_service_life || 0), device_consumables_lifetime: Number(row.device_consumables_lifetime || 0), replace_user: row.replace_user || '', replace_time: row.replace_time || '', replace_reason: row.replace_reason || '', replacement_time: Number(row.replacement_time || 0), remark: row.remark || '' }
|
||||||
device_consumables_item_id: row.device_consumables_item_id || '',
|
|
||||||
device_id: row.device_id || '',
|
|
||||||
standard_life: row.standard_life || '',
|
|
||||||
warning_life: row.warning_life || '',
|
|
||||||
used_life: row.used_life || '',
|
|
||||||
remark: row.remark || ''
|
|
||||||
}
|
|
||||||
this.dialogVisible = true
|
|
||||||
},
|
},
|
||||||
|
openAdd () { this.handleType = 'create'; this.dialogTitle = this.key('add_title'); this.resetForm(); this.dialogVisible = true },
|
||||||
|
openEdit (row) { this.handleType = 'edit'; this.dialogTitle = this.key('declare_lifetime'); this.fillForm(row); this.dialogVisible = true },
|
||||||
|
openReplace (row) { this.handleType = 'replace'; this.dialogTitle = this.key('replace'); this.fillForm(row); this.formData.replace_time = this.formData.replace_time || ''; this.dialogVisible = true },
|
||||||
async onDialogSubmit () {
|
async onDialogSubmit () {
|
||||||
this.submitting = true
|
this.submitting = true
|
||||||
try {
|
try {
|
||||||
if (this.handleType === 'create') await createItem(this.formData)
|
if (this.handleType === 'create') await createItem(this.formData)
|
||||||
else await editItem({ ...this.formData, id: this.editId })
|
else if (this.handleType === 'edit') await editItem({ ...this.formData, id: this.editId })
|
||||||
|
else await createReplaceLog({ ...this.formData, id: this.editId })
|
||||||
this.$message.success(this.$t(this.key('operation_success')))
|
this.$message.success(this.$t(this.key('operation_success')))
|
||||||
this.dialogVisible = false
|
this.dialogVisible = false
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
} finally {
|
} finally { this.submitting = false }
|
||||||
this.submitting = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onDialogClose () {
|
|
||||||
this.resetForm()
|
|
||||||
},
|
},
|
||||||
async handleDelete (row) {
|
async handleDelete (row) {
|
||||||
const cancelled = await this.$confirmAction(
|
const cancelled = await this.$confirmAction({ message: this.key('confirm_delete'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteItem({ id: [row.id] }))
|
||||||
{ message: this.key('confirm_delete'), title: this.key('tip') },
|
if (cancelled) return
|
||||||
() => deleteItem({ id: [row.id] })
|
this.$message.success(this.$t(this.key('operation_success')))
|
||||||
)
|
this.fetchData()
|
||||||
|
},
|
||||||
|
async handleBatchDelete () {
|
||||||
|
if (!this.selectedRows.length) { this.$message.error(this.$t(this.key('please_select_data'))); return }
|
||||||
|
const cancelled = await this.$confirmAction({ message: this.key('confirm_batch_delete'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteItem({ id: this.selectedRows.map(item => item.id) }))
|
||||||
if (cancelled) return
|
if (cancelled) return
|
||||||
this.$message.success(this.$t(this.key('operation_success')))
|
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.fetchData()
|
this.fetchData()
|
||||||
},
|
},
|
||||||
async handleExport () {
|
async handleExport () {
|
||||||
const cancelled = await this.$confirmAction(
|
const cancelled = await this.$confirmAction({ message: this.key('confirm_export'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => createExportTask({ ...this.buildSearchParams(), action: 'download' }))
|
||||||
{ message: this.key('confirm_export'), title: this.key('tip') },
|
|
||||||
() => createExportTask({ ...this.search })
|
|
||||||
)
|
|
||||||
if (cancelled) return
|
if (cancelled) return
|
||||||
|
this.$message.success(this.$t(this.key('create_download_task_success')))
|
||||||
|
},
|
||||||
|
openImport () { 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 = ['device_consumables_item', 'related_device', 'used_life', 'remark'].map(k => this.$t(this.key(k)))
|
||||||
|
if (rows.length && headers.some(title => !Object.prototype.hasOwnProperty.call(rows[0], title))) {
|
||||||
|
this.$message.error(this.$t(this.key('file_column_missing'), { title: headers.find(title => !Object.prototype.hasOwnProperty.call(rows[0], title)) }))
|
||||||
|
this.importRows = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.importRows = rows.map(row => ({ device_consumables_item_name: row[headers[0]], device_name: row[headers[1]], device_consumables_lifetime: row[headers[2]], remark: row[headers[3]] }))
|
||||||
|
} finally { this.importTableLoading = false }
|
||||||
|
},
|
||||||
|
async submitImport () {
|
||||||
|
if (!this.importRows.length) { this.$message.error(this.$t(this.key('please_import_data'))); return }
|
||||||
|
await importData({ import_data: JSON.stringify(this.importRows) })
|
||||||
this.$message.success(this.$t(this.key('operation_success')))
|
this.$message.success(this.$t(this.key('operation_success')))
|
||||||
|
this.importVisible = false
|
||||||
|
this.fetchData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,5 +293,6 @@ export default {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.search-bar { padding: 10px 0; }
|
.search-bar { padding: 10px 0; }
|
||||||
|
.import-upload { margin: 12px 0; }
|
||||||
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
|
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,15 +2,23 @@
|
|||||||
<d2-container>
|
<d2-container>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="search-bar">
|
<div class="search-bar">
|
||||||
<el-form :inline="true" size="mini">
|
<el-form :inline="true" :model="search" size="mini">
|
||||||
<el-form-item :label="$t(key('keyword'))">
|
<el-form-item :label="$t(key('device_name'))">
|
||||||
<el-input
|
<el-select v-model="search.device_code" :placeholder="$t(key('please_select_device_name'))" clearable filterable style="width:220px">
|
||||||
v-model="search.keyword"
|
<el-option v-for="item in deviceOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
:placeholder="$t(key('enter_keyword'))"
|
</el-select>
|
||||||
clearable
|
</el-form-item>
|
||||||
style="width:200px"
|
<el-form-item :label="$t(key('consumables_item_code'))">
|
||||||
@keyup.enter.native="onSearch"
|
<el-input v-model.trim="search.device_consumables_item_code" :placeholder="$t(key('enter_consumables_item_code'))" clearable style="width:220px" @keyup.enter.native="onSearch" />
|
||||||
/>
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t(key('consumables_item_name'))">
|
||||||
|
<el-input v-model.trim="search.device_consumables_item_name" :placeholder="$t(key('enter_consumables_item_name'))" clearable style="width:220px" @keyup.enter.native="onSearch" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t(key('create_time'))">
|
||||||
|
<el-date-picker v-model="search.create_time" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss" :start-placeholder="$t(key('start_time'))" :end-placeholder="$t(key('end_time'))" style="width:330px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t(key('replace_time'))">
|
||||||
|
<el-date-picker v-model="search.replace_time" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss" :start-placeholder="$t(key('start_time'))" :end-placeholder="$t(key('end_time'))" style="width:330px" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
|
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
|
||||||
@@ -20,34 +28,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<page-table
|
<page-table ref="pageTable" :columns="columns" :data="tableData" :loading="loading" :toolbar-buttons="toolbarButtons" :row-buttons="rowButtons" :pagination="pagination" auto-height @page-change="onPageChange" />
|
||||||
ref="pageTable"
|
|
||||||
:columns="columns"
|
|
||||||
:data="tableData"
|
|
||||||
:loading="loading"
|
|
||||||
:toolbar-buttons="toolbarButtons"
|
|
||||||
:row-buttons="rowButtons"
|
|
||||||
:pagination="pagination"
|
|
||||||
auto-height
|
|
||||||
@page-change="onPageChange"
|
|
||||||
@selection-change="onSelect"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<page-dialog-form
|
<page-dialog-form ref="dialogForm" :visible.sync="dialogVisible" :title="dialogTitle" width="560px" :form-cols="formCols" :form-data="formData" :rules="rules" label-width="140px" :submitting="submitting" :confirm-text="key('confirm')" :cancel-text="key('cancel')" @submit="onDialogSubmit" @close="resetForm" />
|
||||||
ref="dialogForm"
|
|
||||||
:visible.sync="dialogVisible"
|
|
||||||
:title="dialogTitle"
|
|
||||||
width="40%"
|
|
||||||
:form-cols="formCols"
|
|
||||||
:form-data="formData"
|
|
||||||
:rules="rules"
|
|
||||||
label-width="130px"
|
|
||||||
:submitting="submitting"
|
|
||||||
:confirm-text="key('confirm')"
|
|
||||||
:cancel-text="key('cancel')"
|
|
||||||
@submit="onDialogSubmit"
|
|
||||||
@close="onDialogClose"
|
|
||||||
/>
|
|
||||||
</d2-container>
|
</d2-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -58,7 +41,19 @@ import { i18nMixin } from '@/composables/useI18n'
|
|||||||
import { confirmMixin } from '@/composables/useConfirmHandle'
|
import { confirmMixin } from '@/composables/useConfirmHandle'
|
||||||
import PageTable from '@/components/page-table'
|
import PageTable from '@/components/page-table'
|
||||||
import PageDialogForm from '@/components/page-dialog-form'
|
import PageDialogForm from '@/components/page-dialog-form'
|
||||||
import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/replacement-logs'
|
import { getAll as getDeviceAll } from '@/api/equipment-management/equipment-registry'
|
||||||
|
import { getList, editItem, createExportTask } from '@/api/equipment-management/replacement-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 toOptions (list) {
|
||||||
|
return (Array.isArray(list) ? list : []).map(item => ({ label: item.name, value: item.code, raw: item }))
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'equipment-management-replacement-logs',
|
name: 'equipment-management-replacement-logs',
|
||||||
@@ -69,237 +64,118 @@ export default {
|
|||||||
loading: false,
|
loading: false,
|
||||||
submitting: false,
|
submitting: false,
|
||||||
tableData: [],
|
tableData: [],
|
||||||
selectedRows: [],
|
search: { device_code: '', device_consumables_item_code: '', device_consumables_item_name: '', create_time: [], replace_time: [] },
|
||||||
|
pagination: { current: 1, size: 10, total: 0 },
|
||||||
|
deviceOptions: [],
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
dialogTitle: '',
|
dialogTitle: '',
|
||||||
editId: '',
|
editId: '',
|
||||||
handleType: 'create',
|
formData: { replace_user: '', replace_time: '', replace_reason: '', replacement_time: 0, remark: '' },
|
||||||
search: {
|
|
||||||
keyword: ''
|
|
||||||
},
|
|
||||||
pagination: { current: 1, size: 10, total: 0 },
|
|
||||||
formData: {
|
|
||||||
device_consumables_item_id: '',
|
|
||||||
device_id: '',
|
|
||||||
replace_user: '',
|
|
||||||
replace_time: '',
|
|
||||||
replace_reason: '',
|
|
||||||
replace_duration: '',
|
|
||||||
remark: ''
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
device_consumables_item_id: [{ required: true, message: this.key('enter_consumables_item_id'), trigger: 'blur' }],
|
|
||||||
device_id: [{ required: true, message: this.key('enter_device_id'), trigger: 'blur' }]
|
|
||||||
},
|
|
||||||
columns: [],
|
columns: [],
|
||||||
toolbarButtons: [],
|
toolbarButtons: [],
|
||||||
rowButtons: [],
|
rowButtons: []
|
||||||
formCols: [
|
}
|
||||||
[
|
},
|
||||||
{
|
computed: {
|
||||||
type: 'input',
|
replaceReasonOptions () {
|
||||||
prop: 'device_consumables_item_id',
|
return [
|
||||||
label: this.key('consumables_item_id'),
|
{ label: this.$t(this.key('abnormal_damage')), value: this.$t(this.key('abnormal_damage')) },
|
||||||
placeholder: this.key('enter_consumables_item_id'),
|
{ label: this.$t(this.key('normal_wear')), value: this.$t(this.key('normal_wear')) },
|
||||||
clearable: true,
|
{ label: this.$t(this.key('overdue_life')), value: this.$t(this.key('overdue_life')) }
|
||||||
style: { width: '90%' }
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
prop: 'device_id',
|
|
||||||
label: this.key('device_id'),
|
|
||||||
placeholder: this.key('enter_device_id'),
|
|
||||||
clearable: true,
|
|
||||||
style: { width: '90%' }
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
prop: 'replace_user',
|
|
||||||
label: this.key('replace_user'),
|
|
||||||
placeholder: this.key('enter_replace_user'),
|
|
||||||
clearable: true,
|
|
||||||
style: { width: '90%' }
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
prop: 'replace_time',
|
|
||||||
label: this.key('replace_time'),
|
|
||||||
placeholder: this.key('enter_replace_time'),
|
|
||||||
clearable: true,
|
|
||||||
style: { width: '90%' }
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
prop: 'replace_reason',
|
|
||||||
label: this.key('replace_reason'),
|
|
||||||
placeholder: this.key('enter_replace_reason'),
|
|
||||||
clearable: true,
|
|
||||||
style: { width: '90%' }
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
prop: 'replace_duration',
|
|
||||||
label: this.key('replace_duration'),
|
|
||||||
placeholder: this.key('enter_replace_duration'),
|
|
||||||
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%' }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
formCols () {
|
||||||
|
return [
|
||||||
|
[{ type: 'input', prop: 'replace_user', label: this.key('replace_user'), placeholder: this.key('enter_replace_user'), style: { width: '100%' } }],
|
||||||
|
[{ type: 'date-picker', prop: 'replace_time', label: this.key('replace_time'), placeholder: this.key('enter_replace_time'), style: { width: '100%' } }],
|
||||||
|
[{ type: 'select', prop: 'replace_reason', label: this.key('replace_reason'), placeholder: this.key('enter_replace_reason'), options: this.replaceReasonOptions, style: { width: '100%' } }],
|
||||||
|
[{ type: 'input-number', prop: 'replacement_time', label: this.key('replacement_time'), min: 0, style: { width: '100%' } }],
|
||||||
|
[{ type: 'input', prop: 'remark', label: this.key('remark'), placeholder: this.key('enter_remark'), inputType: 'textarea', autosize: { minRows: 2, maxRows: 6 }, style: { width: '100%' } }]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
rules () {
|
||||||
|
return {
|
||||||
|
replace_user: [{ required: true, message: this.key('enter_replace_user'), trigger: 'blur' }],
|
||||||
|
replace_time: [{ required: true, message: this.key('enter_replace_time'), trigger: 'change' }],
|
||||||
|
replace_reason: [{ required: true, message: this.key('enter_replace_reason'), trigger: 'change' }],
|
||||||
|
replacement_time: [{ required: true, message: this.key('enter_replacement_time'), trigger: 'blur' }]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
this.columns = useTableColumns([
|
this.columns = useTableColumns([
|
||||||
{ prop: 'device_consumables_item_name', label: this.key('consumables_item'), minWidth: 140 },
|
{ prop: 'id', label: this.key('id'), width: 80 },
|
||||||
{ prop: 'device_name', label: this.key('device_name'), minWidth: 140 },
|
{ prop: 'device_name', label: this.key('related_device'), minWidth: 150 },
|
||||||
{ prop: 'replace_user', label: this.key('replace_user'), minWidth: 140 },
|
{ prop: 'device_consumables_item_code', label: this.key('device_consumables_item_code'), minWidth: 150 },
|
||||||
{ prop: 'replace_time', label: this.key('replace_time'), minWidth: 140 },
|
{ prop: 'device_consumables_item_name', label: this.key('device_consumables_item_name'), minWidth: 150 },
|
||||||
{ prop: 'replace_reason', label: this.key('replace_reason'), minWidth: 140 },
|
{ prop: 'device_consumables_category_name', label: this.key('device_consumables_category_name'), minWidth: 150 },
|
||||||
{ prop: 'replace_duration', label: this.key('replace_duration'), minWidth: 140 },
|
{ prop: 'standard_service_life', label: this.key('standard_service_life'), minWidth: 130 },
|
||||||
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
|
{ prop: 'warning_service_life', label: this.key('warning_service_life'), minWidth: 130 },
|
||||||
])
|
{ prop: 'replace_lifetime', label: this.key('replace_lifetime'), minWidth: 130 },
|
||||||
|
{ prop: 'replace_user', label: this.key('replace_user'), minWidth: 120 },
|
||||||
|
{ prop: 'replace_time', label: this.key('replace_time'), minWidth: 160 },
|
||||||
|
{ prop: 'replace_reason', label: this.key('replace_reason'), minWidth: 130 },
|
||||||
|
{ prop: 'replacement_time', label: this.key('replacement_time'), minWidth: 130 },
|
||||||
|
{ prop: 'remark', label: this.key('remark'), minWidth: 140, showOverflowTooltip: true },
|
||||||
|
{ prop: 'create_time', label: this.key('create_time'), minWidth: 160 },
|
||||||
|
{ prop: '_actions', label: this.key('operation'), width: 100, fixed: 'right' }
|
||||||
|
], { selectionWidth: 0 })
|
||||||
const btns = useTableButtons({
|
const btns = useTableButtons({
|
||||||
toolbar: [
|
toolbar: [
|
||||||
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_consumables/device_consumables_replace_log/create', onClick: this.openAdd },
|
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', type: 'primary', auth: '/device_management/device_consumables/device_consumables_replace_log/export', onClick: this.handleExport }
|
||||||
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_consumables/device_consumables_replace_log/export', onClick: this.handleExport }
|
|
||||||
],
|
],
|
||||||
row: [
|
row: [
|
||||||
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_consumables/device_consumables_replace_log/edit', onClick: this.openEdit },
|
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_consumables/device_consumables_replace_log/edit', onClick: this.openEdit }
|
||||||
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_consumables/device_consumables_replace_log/delete', onClick: this.handleDelete }
|
|
||||||
]
|
]
|
||||||
}, this.$permission)
|
}, this.$permission)
|
||||||
this.toolbarButtons = btns.toolbarButtons
|
this.toolbarButtons = btns.toolbarButtons
|
||||||
this.rowButtons = btns.rowButtons
|
this.rowButtons = btns.rowButtons
|
||||||
|
this.initOptions()
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
normalizeResponse (res) {
|
async initOptions () {
|
||||||
const data = res && res.data !== undefined ? res.data : res
|
const res = await getDeviceAll({})
|
||||||
if (Array.isArray(data)) return { list: data, total: data.length }
|
this.deviceOptions = toOptions((res && res.data) || res)
|
||||||
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) }
|
buildSearchParams () {
|
||||||
return { list: [], total: 0 }
|
const params = { ...this.search }
|
||||||
|
if (!Array.isArray(params.create_time) || !params.create_time.length) delete params.create_time
|
||||||
|
if (!Array.isArray(params.replace_time) || !params.replace_time.length) delete params.replace_time
|
||||||
|
return params
|
||||||
},
|
},
|
||||||
async fetchData () {
|
async fetchData () {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
try {
|
try {
|
||||||
const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
|
const res = await getList({ ...this.buildSearchParams(), page_no: this.pagination.current, page_size: this.pagination.size })
|
||||||
const data = this.normalizeResponse(res)
|
const page = readPageData(res)
|
||||||
this.tableData = data.list
|
this.tableData = page.list
|
||||||
this.pagination.total = data.total
|
this.pagination.total = page.total
|
||||||
} finally {
|
} finally { this.loading = false }
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onSearch () {
|
|
||||||
this.pagination.current = 1
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onReset () {
|
|
||||||
this.search = {
|
|
||||||
keyword: ''
|
|
||||||
}
|
|
||||||
this.pagination.current = 1
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onPageChange (page) {
|
|
||||||
this.pagination.current = page.current
|
|
||||||
this.pagination.size = page.size
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onSelect (rows) {
|
|
||||||
this.selectedRows = rows
|
|
||||||
},
|
|
||||||
resetForm () {
|
|
||||||
this.formData = {
|
|
||||||
device_consumables_item_id: '',
|
|
||||||
device_id: '',
|
|
||||||
replace_user: '',
|
|
||||||
replace_time: '',
|
|
||||||
replace_reason: '',
|
|
||||||
replace_duration: '',
|
|
||||||
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
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
onSearch () { this.pagination.current = 1; this.fetchData() },
|
||||||
|
onReset () { this.search = { device_code: '', device_consumables_item_code: '', device_consumables_item_name: '', create_time: [], replace_time: [] }; this.pagination.current = 1; this.fetchData() },
|
||||||
|
onPageChange (page) { this.pagination.current = page.current; this.pagination.size = page.size; this.fetchData() },
|
||||||
|
resetForm () { this.formData = { replace_user: '', replace_time: '', replace_reason: '', replacement_time: 0, remark: '' }; this.editId = '' },
|
||||||
openEdit (row) {
|
openEdit (row) {
|
||||||
this.handleType = 'edit'
|
|
||||||
this.dialogTitle = this.key('edit_title')
|
this.dialogTitle = this.key('edit_title')
|
||||||
this.editId = row.id
|
this.editId = row.id
|
||||||
this.formData = {
|
this.formData = { replace_user: row.replace_user || '', replace_time: row.replace_time || '', replace_reason: row.replace_reason || '', replacement_time: Number(row.replacement_time || 0), remark: row.remark || '' }
|
||||||
device_consumables_item_id: row.device_consumables_item_id || '',
|
|
||||||
device_id: row.device_id || '',
|
|
||||||
replace_user: row.replace_user || '',
|
|
||||||
replace_time: row.replace_time || '',
|
|
||||||
replace_reason: row.replace_reason || '',
|
|
||||||
replace_duration: row.replace_duration || '',
|
|
||||||
remark: row.remark || ''
|
|
||||||
}
|
|
||||||
this.dialogVisible = true
|
this.dialogVisible = true
|
||||||
},
|
},
|
||||||
async onDialogSubmit () {
|
async onDialogSubmit () {
|
||||||
this.submitting = true
|
this.submitting = true
|
||||||
try {
|
try {
|
||||||
if (this.handleType === 'create') await createItem(this.formData)
|
await editItem({ ...this.formData, id: this.editId })
|
||||||
else await editItem({ ...this.formData, id: this.editId })
|
|
||||||
this.$message.success(this.$t(this.key('operation_success')))
|
this.$message.success(this.$t(this.key('operation_success')))
|
||||||
this.dialogVisible = false
|
this.dialogVisible = false
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
} finally {
|
} finally { this.submitting = false }
|
||||||
this.submitting = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onDialogClose () {
|
|
||||||
this.resetForm()
|
|
||||||
},
|
|
||||||
async handleDelete (row) {
|
|
||||||
const cancelled = await this.$confirmAction(
|
|
||||||
{ message: this.key('confirm_delete'), title: this.key('tip') },
|
|
||||||
() => deleteItem({ id: [row.id] })
|
|
||||||
)
|
|
||||||
if (cancelled) return
|
|
||||||
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.fetchData()
|
|
||||||
},
|
},
|
||||||
async handleExport () {
|
async handleExport () {
|
||||||
const cancelled = await this.$confirmAction(
|
const cancelled = await this.$confirmAction({ message: this.key('confirm_export'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => createExportTask({ ...this.buildSearchParams(), action: 'download' }))
|
||||||
{ message: this.key('confirm_export'), title: this.key('tip') },
|
|
||||||
() => createExportTask({ ...this.search })
|
|
||||||
)
|
|
||||||
if (cancelled) return
|
if (cancelled) return
|
||||||
this.$message.success(this.$t(this.key('operation_success')))
|
this.$message.success(this.$t(this.key('create_download_task_success')))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user