From beaed6d077e7c3e9abfad68acb8c587835b5a406 Mon Sep 17 00:00:00 2001
From: baoshiwei <baoshiwei@shlanbao.cn>
Date: 星期六, 12 四月 2025 16:17:16 +0800
Subject: [PATCH] feat(eims): 添加点检计划和保养计划的导入功能
---
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/listener/MaintCheckItemImportListener.java | 118 ++++
eims-ui/apps/web-antd/src/api/eims/insp-plan/index.ts | 28 +
eims/ruoyi-admin/src/main/resources/template/by.xls | 0
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/InspectCheckItemVo.java | 32 +
eims-ui/apps/web-antd/src/views/eims/insp-plan/index.vue | 18
eims-ui/apps/web-antd/src/views/eims/insp-plan/insp-plan-import-modal.vue | 112 ++++
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/listener/EasyExcelCellListener.java | 44 +
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsInspectPlanServiceImpl.java | 70 ++
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsMaintPlanServiceImpl.java | 175 +++++++
eims-ui/apps/web-antd/src/views/eims/maint-plan/maint-plan-import-modal.vue | 112 ++++
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsMaintPlanController.java | 60 ++
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsMaintPlanService.java | 5
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/MaintCheckItemVo.java | 95 +++
eims-ui/apps/web-antd/src/api/eims/maint-plan/index.ts | 27 +
eims-ui/apps/web-antd/src/views/eims/insp-plan/data.tsx | 284 +++++-----
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/listener/InspectCheckItemImportListener.java | 147 ++++++
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsInspectPlanService.java | 3
eims-ui/apps/web-antd/src/views/eims/maint-plan/index.vue | 18
eims/ruoyi-admin/src/main/resources/template/dj.xlsx | 0
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsInspectPlanController.java | 53 ++
20 files changed, 1,244 insertions(+), 157 deletions(-)
diff --git a/eims-ui/apps/web-antd/src/api/eims/insp-plan/index.ts b/eims-ui/apps/web-antd/src/api/eims/insp-plan/index.ts
index 792501d..075d144 100644
--- a/eims-ui/apps/web-antd/src/api/eims/insp-plan/index.ts
+++ b/eims-ui/apps/web-antd/src/api/eims/insp-plan/index.ts
@@ -1,14 +1,15 @@
import type { InspectPlanVO } from './model';
import type { ID, IDS } from '#/api/common';
-
-import { commonExport } from '#/api/helper';
+import { commonExport, ContentTypeEnum } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
inspectPlanExport = '/eims/inspectPlan/export',
inspectPlanList = '/eims/inspectPlan/list',
- root = '/eims/inspectPlan'
+ root = '/eims/inspectPlan',
+ inspectPlanImport = '/eims/inspectPlan/importData',
+ inspectPlanImportTemplate = '/eims/inspectPlan/importTemplate'
}
/**
@@ -61,3 +62,24 @@
export function inspPlanExport(data: any) {
return commonExport(Api.inspectPlanExport, data);
}
+
+/**
+ * 涓嬭浇鐐规璁″垝瀵煎叆妯℃澘
+ */
+export function downloadImportTemplate() {
+ return commonExport(Api.inspectPlanImportTemplate);
+}
+
+/**
+ * 浠巈xcel瀵煎叆鐐规璁″垝鏁版嵁
+ * @param data
+ * @returns void
+ */
+export function inspPlanImportData(data: any) {
+ return requestClient.post<{ code: number; msg: string }>(Api.inspectPlanImport, data, {
+ headers: {
+ 'Content-Type': ContentTypeEnum.FORM_DATA
+ },
+ isTransformResponse: false
+ });
+}
diff --git a/eims-ui/apps/web-antd/src/api/eims/maint-plan/index.ts b/eims-ui/apps/web-antd/src/api/eims/maint-plan/index.ts
index bba8da4..9ff0fff 100644
--- a/eims-ui/apps/web-antd/src/api/eims/maint-plan/index.ts
+++ b/eims-ui/apps/web-antd/src/api/eims/maint-plan/index.ts
@@ -2,13 +2,15 @@
import type { ID, IDS } from '#/api/common';
-import { commonExport } from '#/api/helper';
+import { commonExport, ContentTypeEnum } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
maintPlanExport = '/eims/maintPlan/export',
maintPlanList = '/eims/maintPlan/list',
- root = '/eims/maintPlan'
+ root = '/eims/maintPlan',
+ maintPlanImport = '/eims/maintPlan/importData',
+ maintPlanImportTemplate = '/eims/maintPlan/importTemplate'
}
/**
@@ -59,3 +61,24 @@
export function maintPlanExport(data: any) {
return commonExport(Api.maintPlanExport, data);
}
+
+/**
+ * 涓嬭浇淇濆吇璁″垝瀵煎叆妯℃澘
+ */
+export function downloadImportTemplate() {
+ return commonExport(Api.maintPlanImportTemplate);
+}
+
+/**
+ * 浠巈xcel瀵煎叆淇濆吇璁″垝鏁版嵁
+ * @param data
+ * @returns void
+ */
+export function maintPlanImportData(data: any) {
+ return requestClient.post<{ code: number; msg: string }>(Api.maintPlanImport, data, {
+ headers: {
+ 'Content-Type': ContentTypeEnum.FORM_DATA
+ },
+ isTransformResponse: false
+ });
+}
diff --git a/eims-ui/apps/web-antd/src/views/eims/insp-plan/data.tsx b/eims-ui/apps/web-antd/src/views/eims/insp-plan/data.tsx
index b07a476..5afb308 100644
--- a/eims-ui/apps/web-antd/src/views/eims/insp-plan/data.tsx
+++ b/eims-ui/apps/web-antd/src/views/eims/insp-plan/data.tsx
@@ -82,51 +82,51 @@
field: 'inspName',
minWidth: 200
},
- {
- title: '鐐规绫诲瀷',
- field: 'inspType',
- minWidth: 120,
- slots: {
- default: ({ row }) => {
- return renderDict(row.inspType, DictEnum.EIMS_INSPECT_TYPE);
- }
- }
- },
- {
- title: '鐐规浜�',
- field: 'inspUserName',
- minWidth: 100
- },
- {
- title: '寰幆鍛ㄦ湡',
- field: 'inspCycleUnitName',
- minWidth: 80
- },
- {
- title: '鏃堕棿璁$畻瑙勫垯',
- field: 'inspRule',
- minWidth: 140,
- slots: {
- default: ({ row }) => {
- return renderDict(row.inspRule, DictEnum.MAINT_TIME_RULE);
- }
- }
- },
- {
- title: '棣栨鎵ц鏃堕棿',
- field: 'inspFirstTime',
- minWidth: 160
- },
- {
- title: '涓婃鎵ц鏃堕棿',
- field: 'inspLastTime',
- minWidth: 160
- },
- {
- title: '涓嬫鎵ц鏃堕棿',
- field: 'inspNextTime',
- minWidth: 160
- },
+ // {
+ // title: '鐐规绫诲瀷',
+ // field: 'inspType',
+ // minWidth: 120,
+ // slots: {
+ // default: ({ row }) => {
+ // return renderDict(row.inspType, DictEnum.EIMS_INSPECT_TYPE);
+ // }
+ // }
+ // },
+ // {
+ // title: '鐐规浜�',
+ // field: 'inspUserName',
+ // minWidth: 100
+ // },
+ // {
+ // title: '寰幆鍛ㄦ湡',
+ // field: 'inspCycleUnitName',
+ // minWidth: 80
+ // },
+ // {
+ // title: '鏃堕棿璁$畻瑙勫垯',
+ // field: 'inspRule',
+ // minWidth: 140,
+ // slots: {
+ // default: ({ row }) => {
+ // return renderDict(row.inspRule, DictEnum.MAINT_TIME_RULE);
+ // }
+ // }
+ // },
+ // {
+ // title: '棣栨鎵ц鏃堕棿',
+ // field: 'inspFirstTime',
+ // minWidth: 160
+ // },
+ // {
+ // title: '涓婃鎵ц鏃堕棿',
+ // field: 'inspLastTime',
+ // minWidth: 160
+ // },
+ // {
+ // title: '涓嬫鎵ц鏃堕棿',
+ // field: 'inspNextTime',
+ // minWidth: 160
+ // },
{
title: '鍒涘缓鏃堕棿',
field: 'createTime',
@@ -169,75 +169,75 @@
fieldName: 'inspName',
label: '鐐规椤�'
},
- {
- component: 'RadioGroup',
- componentProps: {
- buttonStyle: 'solid',
- options: getDictOptions(DictEnum.EIMS_INSPECT_TYPE),
- optionType: 'button'
- },
- fieldName: 'inspType',
- defaultValue: '1',
- label: '鐐规绫诲瀷'
- },
+ // {
+ // component: 'RadioGroup',
+ // componentProps: {
+ // buttonStyle: 'solid',
+ // options: getDictOptions(DictEnum.EIMS_INSPECT_TYPE),
+ // optionType: 'button'
+ // },
+ // fieldName: 'inspType',
+ // defaultValue: '1',
+ // label: '鐐规绫诲瀷'
+ // },
{
component: 'Input',
fieldName: 'inspDesc',
label: '鐐规璇存槑'
},
- {
- component: 'InputNumber',
- fieldName: 'inspCycle',
- label: '鐐规鍛ㄦ湡',
- formItemClass: 'col-span-1',
- componentProps: {
- min: 1
- }
- },
- {
- component: 'Select',
- componentProps: {
- getPopupContainer,
- options: getDictOptions(DictEnum.MAINT_CYCLE_UNIT)
- },
- fieldName: 'inspCycleUnit',
- formItemClass: 'col-span-1 w-[80px]',
- labelWidth: 0,
- label: ''
- },
-
- {
- component: 'Select',
- componentProps: {
- getPopupContainer,
- options: getDictOptions(DictEnum.MAINT_TIME_RULE)
- },
- fieldName: 'inspRule',
- label: '鐐规瑙勫垯 '
- },
- {
- component: 'Input',
- fieldName: 'inspUser',
- label: '鐢ㄦ埛id',
- dependencies: {
- show: () => false,
- triggerFields: ['']
- }
- },
- {
- component: 'Input',
- fieldName: 'inspUserName',
- label: '鐐规浜�'
- },
- {
- component: 'Input',
- fieldName: 'inspDept',
- label: '閮ㄩ棬id',
- dependencies: {
- show: () => false,
- triggerFields: ['']
- }
- },
+ // {
+ // component: 'InputNumber',
+ // fieldName: 'inspCycle',
+ // label: '鐐规鍛ㄦ湡',
+ // formItemClass: 'col-span-1',
+ // componentProps: {
+ // min: 1
+ // }
+ // },
+ // {
+ // component: 'Select',
+ // componentProps: {
+ // getPopupContainer,
+ // options: getDictOptions(DictEnum.MAINT_CYCLE_UNIT)
+ // },
+ // fieldName: 'inspCycleUnit',
+ // formItemClass: 'col-span-1 w-[80px]',
+ // labelWidth: 0,
+ // label: ''
+ // },
+ //
+ // {
+ // component: 'Select',
+ // componentProps: {
+ // getPopupContainer,
+ // options: getDictOptions(DictEnum.MAINT_TIME_RULE)
+ // },
+ // fieldName: 'inspRule',
+ // label: '鐐规瑙勫垯 '
+ // },
+ // {
+ // component: 'Input',
+ // fieldName: 'inspUser',
+ // label: '鐢ㄦ埛id',
+ // dependencies: {
+ // show: () => false,
+ // triggerFields: ['']
+ // }
+ // },
+ // {
+ // component: 'Input',
+ // fieldName: 'inspUserName',
+ // label: '鐐规浜�'
+ // },
+ // {
+ // component: 'Input',
+ // fieldName: 'inspDept',
+ // label: '閮ㄩ棬id',
+ // dependencies: {
+ // show: () => false,
+ // triggerFields: ['']
+ // }
+ // },
{
component: 'RadioGroup',
componentProps: {
@@ -249,39 +249,39 @@
defaultValue: '0',
label: '鐘舵��'
},
- {
- component: 'DatePicker',
- componentProps: {
- format: 'YYYY-MM-DD',
- showTime: false,
- valueFormat: 'YYYY-MM-DD',
- getPopupContainer
- },
- fieldName: 'inspFirstTime',
- label: '棣栨鐐规鏃堕棿'
- },
- {
- component: 'DatePicker',
- componentProps: {
- format: 'YYYY-MM-DD',
- showTime: false,
- valueFormat: 'YYYY-MM-DD',
- getPopupContainer
- },
- fieldName: 'inspLastTime',
- label: '涓婃鐐规鏃堕棿'
- },
- {
- component: 'DatePicker',
- componentProps: {
- format: 'YYYY-MM-DD',
- showTime: false,
- valueFormat: 'YYYY-MM-DD',
- getPopupContainer
- },
- fieldName: 'inspNextTime',
- label: '涓嬫鐐规鏃堕棿',
- },
+ // {
+ // component: 'DatePicker',
+ // componentProps: {
+ // format: 'YYYY-MM-DD',
+ // showTime: false,
+ // valueFormat: 'YYYY-MM-DD',
+ // getPopupContainer
+ // },
+ // fieldName: 'inspFirstTime',
+ // label: '棣栨鐐规鏃堕棿'
+ // },
+ // {
+ // component: 'DatePicker',
+ // componentProps: {
+ // format: 'YYYY-MM-DD',
+ // showTime: false,
+ // valueFormat: 'YYYY-MM-DD',
+ // getPopupContainer
+ // },
+ // fieldName: 'inspLastTime',
+ // label: '涓婃鐐规鏃堕棿'
+ // },
+ // {
+ // component: 'DatePicker',
+ // componentProps: {
+ // format: 'YYYY-MM-DD',
+ // showTime: false,
+ // valueFormat: 'YYYY-MM-DD',
+ // getPopupContainer
+ // },
+ // fieldName: 'inspNextTime',
+ // label: '涓嬫鐐规鏃堕棿',
+ // },
{
component: 'Textarea',
fieldName: 'remark',
diff --git a/eims-ui/apps/web-antd/src/views/eims/insp-plan/index.vue b/eims-ui/apps/web-antd/src/views/eims/insp-plan/index.vue
index 3b1b351..191f18e 100644
--- a/eims-ui/apps/web-antd/src/views/eims/insp-plan/index.vue
+++ b/eims-ui/apps/web-antd/src/views/eims/insp-plan/index.vue
@@ -3,7 +3,7 @@
import { onMounted, ref } from 'vue';
-import { Page, useVbenDrawer, type VbenFormProps } from '@vben/common-ui';
+import { Page, useVbenDrawer, useVbenModal, type VbenFormProps } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { addFullName, getPopupContainer, getVxePopupContainer } from '@vben/utils';
@@ -19,6 +19,7 @@
import { columns, querySchema } from './data';
import inspPlanDrawer from './insp-plan-drawer.vue';
+import inspPlanImportModal from './insp-plan-import-modal.vue';
defineExpose({
tableSelect
@@ -94,6 +95,17 @@
const [InspRecordDrawer, inspRecordDrawerApi] = useVbenDrawer({
connectedComponent: inspRecordDrawer
});
+
+/**
+ * 瀵煎叆
+ */
+const [InspPlanImportModal, inspPlanImportModalApi] = useVbenModal({
+ connectedComponent: inspPlanImportModal
+});
+
+function handleImport() {
+ inspPlanImportModalApi.open();
+}
function handleAdd() {
inspPlanDrawerApi.setData({});
@@ -251,6 +263,9 @@
<a-button v-access:code="['eims:inspectPlan:export']" @click="handleDownloadExcel">
{{ $t('pages.common.export') }}
</a-button>
+ <a-button v-access:code="['eims:inspectPlan:import']" @click="handleImport">
+ {{ $t('pages.common.import') }}
+ </a-button>
<a-button
:disabled="!vxeCheckboxChecked(tableApi)"
danger
@@ -298,5 +313,6 @@
</div>
<InspPlanDrawer @reload="tableApi.query()" />
<InspRecordDrawer @reload="tableApi.query()" />
+ <InspPlanImportModal @reload="tableApi.query()" />
</Page>
</template>
diff --git a/eims-ui/apps/web-antd/src/views/eims/insp-plan/insp-plan-import-modal.vue b/eims-ui/apps/web-antd/src/views/eims/insp-plan/insp-plan-import-modal.vue
new file mode 100644
index 0000000..3baa409
--- /dev/null
+++ b/eims-ui/apps/web-antd/src/views/eims/insp-plan/insp-plan-import-modal.vue
@@ -0,0 +1,112 @@
+<script setup lang="ts">
+import type { UploadFile } from 'ant-design-vue/es/upload/interface';
+
+import { h, ref, unref } from 'vue';
+
+import { useVbenModal } from '@vben/common-ui';
+import { ExcelIcon, InBoxIcon } from '@vben/icons';
+
+import { Modal, Switch, Upload } from 'ant-design-vue';
+
+import { downloadImportTemplate, inspPlanImportData } from '#/api/eims/insp-plan';
+import { commonDownloadExcel } from '#/utils/file/download';
+
+const emit = defineEmits<{ reload: [] }>();
+
+const UploadDragger = Upload.Dragger;
+
+const [BasicModal, modalApi] = useVbenModal({
+ onCancel: handleCancel,
+ onConfirm: handleSubmit,
+});
+
+const fileList = ref<UploadFile[]>([]);
+const checked = ref(false);
+
+async function handleSubmit() {
+ try {
+ modalApi.modalLoading(true);
+ if (fileList.value.length !== 1) {
+ handleCancel();
+ return;
+ }
+ const data = {
+ file: fileList.value[0]!.originFileObj as Blob,
+ updateSupport: unref(checked),
+ };
+ const { code, msg } = await inspPlanImportData(data);
+ let modal = Modal.success;
+ if (code === 200) {
+ emit('reload');
+ } else {
+ emit('reload');
+ modal = Modal.error;
+ }
+ handleCancel();
+ modal({
+ content: h('div', {
+ class: 'max-h-[260px] overflow-y-auto',
+ innerHTML: msg, // 鍚庡彴宸茬粡澶勭悊xss闂
+ }),
+ title: '鎻愮ず',
+ });
+ } catch (error) {
+ console.warn(error);
+ modalApi.close();
+ } finally {
+ modalApi.modalLoading(false);
+ }
+}
+
+function handleCancel() {
+ modalApi.close();
+ fileList.value = [];
+ checked.value = false;
+}
+</script>
+
+<template>
+ <BasicModal
+ :close-on-click-modal="false"
+ :fullscreen-button="false"
+ title="鐐规璁″垝瀵煎叆"
+ >
+ <!-- z-index涓嶈缃細閬尅妯℃澘涓嬭浇loading -->
+ <!-- 鎵嬪姩澶勭悊 鑰屼笉鏄斁鍏ユ枃浠跺氨涓婁紶 -->
+ <UploadDragger
+ v-model:file-list="fileList"
+ :before-upload="() => false"
+ :max-count="1"
+ :show-upload-list="true"
+ accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
+ >
+ <p class="ant-upload-drag-icon flex items-center justify-center">
+ <InBoxIcon class="text-primary size-[48px]" />
+ </p>
+ <p class="ant-upload-text">鐐瑰嚮鎴栬�呮嫋鎷藉埌姝ゅ涓婁紶鏂囦欢</p>
+ </UploadDragger>
+ <div class="mt-2 flex flex-col gap-2">
+ <div class="flex items-center gap-2">
+ <span>鍏佽瀵煎叆xlsx, xls鏂囦欢</span>
+ <a-button
+ type="link"
+ @click="commonDownloadExcel(downloadImportTemplate, '鐐规璁″垝瀵煎叆妯℃澘')"
+ >
+ <div class="flex items-center gap-[4px]">
+ <ExcelIcon />
+ <span>涓嬭浇妯℃澘</span>
+ </div>
+ </a-button>
+ </div>
+ <div class="flex items-center gap-2">
+ <span class="text-red-500">鈿狅笍鐗瑰埆娉ㄦ剰鈿狅笍锛氳涓嬭浇妯$増淇濇寔瀵煎叆鏂囦欢琛ㄥご鍜屾ā鐗堜竴鑷村悗瀵煎叆</span>
+ </div>
+<!-- <div class="flex items-center gap-2">-->
+<!-- <span :class="{ 'text-red-500': checked }">-->
+<!-- 鏄惁鏇存柊/瑕嗙洊宸插瓨鍦ㄧ殑鐐规璁″垝鏁版嵁-->
+<!-- </span>-->
+<!-- <Switch v-model:checked="checked" />-->
+<!-- </div>-->
+ </div>
+ </BasicModal>
+</template>
diff --git a/eims-ui/apps/web-antd/src/views/eims/maint-plan/index.vue b/eims-ui/apps/web-antd/src/views/eims/maint-plan/index.vue
index 2ddc20e..4190da9 100644
--- a/eims-ui/apps/web-antd/src/views/eims/maint-plan/index.vue
+++ b/eims-ui/apps/web-antd/src/views/eims/maint-plan/index.vue
@@ -3,7 +3,7 @@
import { onMounted, ref } from 'vue';
-import { Page, useVbenDrawer, type VbenFormProps } from '@vben/common-ui';
+import { Page, useVbenDrawer, useVbenModal, type VbenFormProps } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { addFullName, getPopupContainer, getVxePopupContainer } from '@vben/utils';
@@ -19,6 +19,7 @@
import { columns, querySchema } from './data';
import maintPlanDrawer from './maint-plan-drawer.vue';
+import maintPlanImportModal from './maint-plan-import-modal.vue';
defineExpose({
@@ -93,6 +94,17 @@
const [MaintOrderDrawer, maintOrderDrawerApi] = useVbenDrawer({
connectedComponent: maintOrderDrawer,
});
+
+/**
+ * 瀵煎叆
+ */
+const [MaintPlanImportModal, maintPlanImportModalApi] = useVbenModal({
+ connectedComponent: maintPlanImportModal
+});
+
+function handleImport() {
+ maintPlanImportModalApi.open();
+}
function handleAdd() {
maintPlanDrawerApi.setData({});
@@ -250,6 +262,9 @@
<a-button v-access:code="['eims:maintPlan:export']" @click="handleDownloadExcel">
{{ $t('pages.common.export') }}
</a-button>
+ <a-button v-access:code="['eims:maintPlan:import']" @click="handleImport">
+ {{ $t('pages.common.import') }}
+ </a-button>
<a-button
:disabled="!vxeCheckboxChecked(tableApi)"
danger
@@ -297,5 +312,6 @@
</div>
<MaintPlanDrawer @reload="tableApi.query()" />
<MaintOrderDrawer @reload="tableApi.query()" />
+ <MaintPlanImportModal @reload="tableApi.query()" />
</Page>
</template>
diff --git a/eims-ui/apps/web-antd/src/views/eims/maint-plan/maint-plan-import-modal.vue b/eims-ui/apps/web-antd/src/views/eims/maint-plan/maint-plan-import-modal.vue
new file mode 100644
index 0000000..380d446
--- /dev/null
+++ b/eims-ui/apps/web-antd/src/views/eims/maint-plan/maint-plan-import-modal.vue
@@ -0,0 +1,112 @@
+<script setup lang="ts">
+import type { UploadFile } from 'ant-design-vue/es/upload/interface';
+
+import { h, ref, unref } from 'vue';
+
+import { useVbenModal } from '@vben/common-ui';
+import { ExcelIcon, InBoxIcon } from '@vben/icons';
+
+import { Modal, Switch, Upload } from 'ant-design-vue';
+
+import { downloadImportTemplate, maintPlanImportData } from '#/api/eims/maint-plan';
+import { commonDownloadExcel } from '#/utils/file/download';
+
+const emit = defineEmits<{ reload: [] }>();
+
+const UploadDragger = Upload.Dragger;
+
+const [BasicModal, modalApi] = useVbenModal({
+ onCancel: handleCancel,
+ onConfirm: handleSubmit,
+});
+
+const fileList = ref<UploadFile[]>([]);
+const checked = ref(false);
+
+async function handleSubmit() {
+ try {
+ modalApi.modalLoading(true);
+ if (fileList.value.length !== 1) {
+ handleCancel();
+ return;
+ }
+ const data = {
+ file: fileList.value[0]!.originFileObj as Blob,
+ updateSupport: unref(checked),
+ };
+ const { code, msg } = await maintPlanImportData(data);
+ let modal = Modal.success;
+ if (code === 200) {
+ emit('reload');
+ } else {
+ emit('reload');
+ modal = Modal.error;
+ }
+ handleCancel();
+ modal({
+ content: h('div', {
+ class: 'max-h-[260px] overflow-y-auto',
+ innerHTML: msg, // 鍚庡彴宸茬粡澶勭悊xss闂
+ }),
+ title: '鎻愮ず',
+ });
+ } catch (error) {
+ console.warn(error);
+ modalApi.close();
+ } finally {
+ modalApi.modalLoading(false);
+ }
+}
+
+function handleCancel() {
+ modalApi.close();
+ fileList.value = [];
+ checked.value = false;
+}
+</script>
+
+<template>
+ <BasicModal
+ :close-on-click-modal="false"
+ :fullscreen-button="false"
+ title="淇濆吇璁″垝瀵煎叆"
+ >
+ <!-- z-index涓嶈缃細閬尅妯℃澘涓嬭浇loading -->
+ <!-- 鎵嬪姩澶勭悊 鑰屼笉鏄斁鍏ユ枃浠跺氨涓婁紶 -->
+ <UploadDragger
+ v-model:file-list="fileList"
+ :before-upload="() => false"
+ :max-count="1"
+ :show-upload-list="true"
+ accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
+ >
+ <p class="ant-upload-drag-icon flex items-center justify-center">
+ <InBoxIcon class="text-primary size-[48px]" />
+ </p>
+ <p class="ant-upload-text">鐐瑰嚮鎴栬�呮嫋鎷藉埌姝ゅ涓婁紶鏂囦欢</p>
+ </UploadDragger>
+ <div class="mt-2 flex flex-col gap-2">
+ <div class="flex items-center gap-2">
+ <span>鍏佽瀵煎叆xlsx, xls鏂囦欢</span>
+ <a-button
+ type="link"
+ @click="commonDownloadExcel(downloadImportTemplate, '淇濆吇璁″垝瀵煎叆妯℃澘')"
+ >
+ <div class="flex items-center gap-[4px]">
+ <ExcelIcon />
+ <span>涓嬭浇妯℃澘</span>
+ </div>
+ </a-button>
+ </div>
+ <div class="flex items-center gap-2">
+ <span class="text-red-500">鈿狅笍鐗瑰埆娉ㄦ剰鈿狅笍锛氳涓嬭浇妯$増淇濇寔瀵煎叆鏂囦欢琛ㄥご鍜屾ā鐗堜竴鑷村悗瀵煎叆</span>
+ </div>
+<!-- <div class="flex items-center gap-2">-->
+<!-- <span :class="{ 'text-red-500': checked }">-->
+<!-- 鏄惁鏇存柊/瑕嗙洊宸插瓨鍦ㄧ殑淇濆吇璁″垝鏁版嵁-->
+<!-- </span>-->
+<!-- <Switch v-model:checked="checked" />-->
+<!-- </div>-->
+ </div>
+ </BasicModal>
+</template>
diff --git a/eims/ruoyi-admin/src/main/resources/template/by.xls b/eims/ruoyi-admin/src/main/resources/template/by.xls
new file mode 100644
index 0000000..fb73467
--- /dev/null
+++ b/eims/ruoyi-admin/src/main/resources/template/by.xls
Binary files differ
diff --git a/eims/ruoyi-admin/src/main/resources/template/dj.xlsx b/eims/ruoyi-admin/src/main/resources/template/dj.xlsx
new file mode 100644
index 0000000..ccb85ec
--- /dev/null
+++ b/eims/ruoyi-admin/src/main/resources/template/dj.xlsx
Binary files differ
diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsInspectPlanController.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsInspectPlanController.java
index a528722..2151c89 100644
--- a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsInspectPlanController.java
+++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsInspectPlanController.java
@@ -1,11 +1,18 @@
package org.dromara.eims.controller;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
import java.util.List;
+import jakarta.servlet.ServletOutputStream;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -21,6 +28,7 @@
import org.dromara.eims.domain.bo.EimsInspectPlanBo;
import org.dromara.eims.service.IEimsInspectPlanService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.springframework.web.multipart.MultipartFile;
/**
* 鐐规璁″垝
@@ -103,4 +111,49 @@
@PathVariable Long[] ids) {
return toAjax(eimsInspectPlanService.deleteWithValidByIds(List.of(ids), true));
}
+
+ /**
+ * 瀵煎叆鏁版嵁
+ *
+ * @param file 瀵煎叆鏂囦欢
+ * @param updateSupport 鏄惁鏇存柊宸插瓨鍦ㄦ暟鎹�
+ */
+ @Log(title = "鐐规璁″垝", businessType = BusinessType.IMPORT)
+ @SaCheckPermission("eims:inspectPlan:import")
+ @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+ public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception {
+ // ExcelResult<InspectCheckItemVo> result = ExcelUtil.importExcel(file.getInputStream(), InspectCheckItemVo.class, new InspectCheckItemImportListener(updateSupport));
+ String res = eimsInspectPlanService.importData(file, updateSupport);
+ return R.ok(res);
+ }
+
+ /**
+ * 鑾峰彇瀵煎叆妯℃澘
+ */
+ @PostMapping("/importTemplate")
+ public void importTemplate(HttpServletResponse response) throws UnsupportedEncodingException {
+ // 璁剧疆鍝嶅簲绫诲瀷
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+ response.setCharacterEncoding("utf-8");
+
+ // 璁剧疆鏂囦欢鍚�
+ String fileName = URLEncoder.encode("鐐规璁″垝瀵煎叆妯℃澘", "UTF-8");
+ response.setHeader("Content-Disposition",
+ "attachment;filename=" + fileName + ".xlsx");
+
+ // 璇诲彇妯℃澘鏂囦欢
+ ClassPathResource templateResource = new ClassPathResource("template/dj.xlsx");
+ try (InputStream inputStream = templateResource.getInputStream();
+ ServletOutputStream outputStream = response.getOutputStream()) {
+
+ // 娴佹嫹璐�
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("妯℃澘鏂囦欢璇诲彇澶辫触", e);
+ }
+ }
}
diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsMaintPlanController.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsMaintPlanController.java
index d2005dc..c00d56b 100644
--- a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsMaintPlanController.java
+++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsMaintPlanController.java
@@ -1,11 +1,17 @@
package org.dromara.eims.controller;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLEncoder;
import java.util.List;
+import jakarta.servlet.ServletOutputStream;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -21,6 +27,7 @@
import org.dromara.eims.domain.bo.EimsMaintPlanBo;
import org.dromara.eims.service.IEimsMaintPlanService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.springframework.web.multipart.MultipartFile;
/**
* 淇濆吇璁″垝
@@ -65,7 +72,7 @@
@SaCheckPermission("eims:maintPlan:query")
@GetMapping("/{id}")
public R<EimsMaintPlanVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
- @PathVariable Long id) {
+ @PathVariable Long id) {
return R.ok(eimsMaintPlanService.queryById(id));
}
@@ -103,4 +110,55 @@
@PathVariable Long[] ids) {
return toAjax(eimsMaintPlanService.deleteWithValidByIds(List.of(ids), true));
}
+
+ /**
+ * 瀵煎叆鏁版嵁
+ *
+ * @param file 瀵煎叆鏂囦欢
+ * @param updateSupport 鏄惁鏇存柊宸插瓨鍦ㄦ暟鎹�
+ */
+ @Log(title = "淇濆吇璁″垝", businessType = BusinessType.IMPORT)
+ @SaCheckPermission("eims:maintPlan:import")
+ @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+ public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception {
+ //ExcelResult<MaintCheckItemVo> result = ExcelUtil.importExcel(file.getInputStream(), MaintCheckItemVo.class, new MaintCheckItemImportListener(updateSupport));
+
+
+ String res = eimsMaintPlanService.importData(file, updateSupport);
+
+ return R.ok(res);
+ }
+
+ /**
+ * 鑾峰彇瀵煎叆妯℃澘
+ */
+ @PostMapping("/importTemplate")
+ public void importTemplate(HttpServletResponse response) throws IOException {
+ // 璁剧疆鍝嶅簲绫诲瀷
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+ response.setCharacterEncoding("utf-8");
+
+ // 璁剧疆鏂囦欢鍚�
+ String fileName = URLEncoder.encode("淇濆吇璁″垝瀵煎叆妯℃澘", "UTF-8");
+ response.setHeader("Content-Disposition",
+ "attachment;filename=" + fileName + ".xls");
+
+ // 璇诲彇妯℃澘鏂囦欢
+ ClassPathResource templateResource = new ClassPathResource("template/by.xls");
+ try (InputStream inputStream = templateResource.getInputStream();
+ ServletOutputStream outputStream = response.getOutputStream()) {
+
+ // 娴佹嫹璐�
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("妯℃澘鏂囦欢璇诲彇澶辫触", e);
+ }
+ }
}
+
+
+
diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/InspectCheckItemVo.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/InspectCheckItemVo.java
new file mode 100644
index 0000000..d636bc1
--- /dev/null
+++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/InspectCheckItemVo.java
@@ -0,0 +1,32 @@
+package org.dromara.eims.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 鐐规椤圭洰瀵煎叆VO
+ *
+ * @author zhuguifei
+ */
+@Data
+@NoArgsConstructor
+public class InspectCheckItemVo implements Serializable {
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+
+
+ /**
+ * 鐐规椤瑰悕绉�
+ */
+ @ExcelProperty(value = "鍐呭")
+ private String itemName;
+
+
+}
diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/MaintCheckItemVo.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/MaintCheckItemVo.java
new file mode 100644
index 0000000..7962bcf
--- /dev/null
+++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/MaintCheckItemVo.java
@@ -0,0 +1,95 @@
+package org.dromara.eims.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * 淇濆吇鐐规椤圭洰瀹炰綋
+ */
+@Data
+public class MaintCheckItemVo {
+
+ /**
+ * 瀹炴柦椤圭洰
+ */
+ @ExcelProperty("瀹炴柦椤圭洰")
+ private String itemName;
+
+ /**
+ * 鍛ㄦ湡锛堟湀锛�
+ */
+ @ExcelProperty("鍛ㄦ湡")
+ private String period;
+
+ /**
+ * 1鏈堟鏌ョ姸鎬�
+ */
+ @ExcelProperty("1鏈�")
+ private String january;
+
+ /**
+ * 2鏈堟鏌ョ姸鎬�
+ */
+ @ExcelProperty("2鏈�")
+ private String february;
+
+ /**
+ * 3鏈堟鏌ョ姸鎬�
+ */
+ @ExcelProperty("3鏈�")
+ private String march;
+
+ /**
+ * 4鏈堟鏌ョ姸鎬�
+ */
+ @ExcelProperty("4鏈�")
+ private String april;
+
+ /**
+ * 5鏈堟鏌ョ姸鎬�
+ */
+ @ExcelProperty("5鏈�")
+ private String may;
+
+ /**
+ * 6鏈堟鏌ョ姸鎬�
+ */
+ @ExcelProperty("6鏈�")
+ private String june;
+
+ /**
+ * 7鏈堟鏌ョ姸鎬�
+ */
+ @ExcelProperty("7鏈�")
+ private String july;
+
+ /**
+ * 8鏈堟鏌ョ姸鎬�
+ */
+ @ExcelProperty("8鏈�")
+ private String august;
+
+ /**
+ * 9鏈堟鏌ョ姸鎬�
+ */
+ @ExcelProperty("9鏈�")
+ private String september;
+
+ /**
+ * 10鏈堟鏌ョ姸鎬�
+ */
+ @ExcelProperty("10鏈�")
+ private String october;
+
+ /**
+ * 11鏈堟鏌ョ姸鎬�
+ */
+ @ExcelProperty("11鏈�")
+ private String november;
+
+ /**
+ * 12鏈堟鏌ョ姸鎬�
+ */
+ @ExcelProperty("12鏈�")
+ private String december;
+}
diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/listener/EasyExcelCellListener.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/listener/EasyExcelCellListener.java
new file mode 100644
index 0000000..5bc5758
--- /dev/null
+++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/listener/EasyExcelCellListener.java
@@ -0,0 +1,44 @@
+package org.dromara.eims.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.read.listener.ReadListener;
+
+import java.util.Map;
+
+public class EasyExcelCellListener implements ReadListener<Map<Integer,String>> {
+
+ private String cellValue;
+ private int targetRow;
+ private int targetColumn;
+
+ private boolean isCellRead = false;
+
+ public EasyExcelCellListener(int targetRow, int targetColumn) {
+ this.targetRow = targetRow;
+ this.targetColumn = targetColumn;
+ }
+
+ @Override
+ //invoke鏂规硶鐨勫弬鏁扮被鍨嬭窡闅忓疄鐜扮殑ReadListener鐨勭被鍨�
+ public void invoke(Map<Integer,String> map, AnalysisContext analysisContext) {
+ if(isCellRead){
+ return;
+ }
+ int currentRow = analysisContext.readRowHolder().getRowIndex()+1;
+ if(currentRow == targetRow ){
+ cellValue = map.get(targetColumn-1);
+ isCellRead = true;
+ }
+ }
+
+ @Override
+ public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+
+ }
+
+ public String getCellValue() {
+ return cellValue;
+ }
+
+
+}
diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/listener/InspectCheckItemImportListener.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/listener/InspectCheckItemImportListener.java
new file mode 100644
index 0000000..f1176e9
--- /dev/null
+++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/listener/InspectCheckItemImportListener.java
@@ -0,0 +1,147 @@
+package org.dromara.eims.listener;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.alibaba.excel.exception.ExcelDataConvertException;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.service.DictService;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.excel.core.ExcelListener;
+import org.dromara.common.excel.core.ExcelResult;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.eims.domain.vo.EimsEquVo;
+import org.dromara.eims.domain.vo.InspectCheckItemVo;
+import org.dromara.eims.service.IEimsEquService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鐐规椤圭洰瀵煎叆鐩戝惉鍣�
+ *
+ * @author zhuguifei
+ */
+@Data
+@Slf4j
+public class InspectCheckItemImportListener extends AnalysisEventListener<InspectCheckItemVo> implements ExcelListener<InspectCheckItemVo> {
+
+ private final IEimsEquService equService;
+ private final DictService dictService;
+ private final Long operUserId;
+ private final Boolean isUpdateSupport;
+
+ /**
+ * 鎴愬姛鏉℃暟
+ */
+ private Integer successCount = 0;
+
+ /**
+ * 澶辫触鏉℃暟
+ */
+ private Integer failureCount = 0;
+
+ /**
+ * 瀵煎叆鎴愬姛鏁版嵁鍒楄〃
+ */
+ private List<InspectCheckItemVo> successList = new ArrayList<>();
+
+ /**
+ * 瀵煎叆澶辫触鏁版嵁鍒楄〃
+ */
+ private List<InspectCheckItemVo> failureList = new ArrayList<>();
+
+ private final StringBuilder successMsg = new StringBuilder();
+ private final StringBuilder failureMsg = new StringBuilder();
+
+ public InspectCheckItemImportListener(Boolean isUpdateSupport) {
+ this.equService = SpringUtils.getBean(IEimsEquService.class);
+ this.dictService = SpringUtils.getBean(DictService.class);
+ this.isUpdateSupport = isUpdateSupport;
+ this.operUserId = LoginHelper.getUserId();
+ }
+
+ @Override
+ public void invoke(InspectCheckItemVo data, AnalysisContext context) {
+ try {
+ // 鏁版嵁鏍¢獙
+ if (!validateData(data)) {
+ failureList.add(data);
+ failureCount++;
+ failureMsg.append("<br/>").append(failureCount).append("銆佺偣妫�椤� ")
+ .append(data.getItemName()).append(" 鏁版嵁鏍¢獙澶辫触");
+ return;
+ }
+
+
+ successList.add(data);
+ successCount++;
+ successMsg.append("<br/>").append(successCount).append("銆佺偣妫�椤� ")
+ .append(data.getItemName()).append(" 瀵煎叆鎴愬姛");
+
+ } catch (Exception e) {
+ failureList.add(data);
+ failureCount++;
+ String msg = "<br/>" + failureCount + "銆佺偣妫�椤� " + data.getItemName() + " 瀵煎叆澶辫触锛�";
+ failureMsg.append(msg).append(e.getMessage());
+ log.error("瀵煎叆鐐规椤圭洰澶辫触锛�", e);
+ }
+ }
+
+ @Override
+ public void doAfterAllAnalysed(AnalysisContext context) {
+ log.info("鐐规椤圭洰瀵煎叆瀹屾垚锛屾垚鍔燂細{}鏉★紝澶辫触锛歿}鏉�", successCount, failureCount);
+ }
+
+ @Override
+ public void onException(Exception exception, AnalysisContext context) throws Exception {
+ log.error("瀵煎叆寮傚父", exception);
+ if (exception instanceof ExcelDataConvertException) {
+ ExcelDataConvertException e = (ExcelDataConvertException) exception;
+ failureMsg.append("<br/>").append("绗�").append(e.getRowIndex()).append("琛岋紝绗�").append(e.getColumnIndex())
+ .append("鍒楄В鏋愬紓甯革細").append(e.getCause().getMessage());
+ } else {
+ failureMsg.append(exception.getMessage());
+ }
+ }
+
+ @Override
+ public ExcelResult<InspectCheckItemVo> getExcelResult() {
+ return new ExcelResult<InspectCheckItemVo>() {
+ @Override
+ public List<InspectCheckItemVo> getList() {
+ return successList;
+ }
+
+ @Override
+ public List<String> getErrorList() {
+ return List.of();
+ }
+
+ @Override
+ public String getAnalysis() {
+ if (successCount > 0) {
+ successMsg.insert(0, "鎭枩鎮紝鍏� " + successCount + " 鏉℃暟鎹鍏ユ垚鍔燂紒");
+ }
+ if (failureCount > 0) {
+ failureMsg.insert(0, "寰堟姳姝夛紝鍏� " + failureCount + " 鏉℃暟鎹鍏ュけ璐ワ紒");
+ }
+ return successMsg + failureMsg.toString();
+ }
+ };
+ }
+
+ /**
+ * 鏍¢獙鏁版嵁
+ *
+ * @param data 寰呮牎楠屾暟鎹�
+ * @return 鏍¢獙缁撴灉
+ */
+ private boolean validateData(InspectCheckItemVo data) {
+ if (data.getItemName() == null || data.getItemName().trim().isEmpty()) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/listener/MaintCheckItemImportListener.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/listener/MaintCheckItemImportListener.java
new file mode 100644
index 0000000..b1e02a8
--- /dev/null
+++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/listener/MaintCheckItemImportListener.java
@@ -0,0 +1,118 @@
+package org.dromara.eims.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.excel.core.ExcelListener;
+import org.dromara.common.excel.core.ExcelResult;
+import org.dromara.eims.domain.vo.MaintCheckItemVo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 淇濆吇鐐规椤圭洰瀵煎叆鐩戝惉鍣�
+ *
+ * @author Lion Li
+ */
+@Data
+@Slf4j
+public class MaintCheckItemImportListener extends AnalysisEventListener<MaintCheckItemVo> implements ExcelListener<MaintCheckItemVo> {
+
+ /**
+ * 鎴愬姛鏉℃暟
+ */
+ private Integer successCount = 0;
+
+ /**
+ * 澶辫触鏉℃暟
+ */
+ private Integer failureCount = 0;
+
+ /**
+ * 瀵煎叆鎴愬姛鏁版嵁鍒楄〃
+ */
+ private List<MaintCheckItemVo> successList = new ArrayList<>();
+
+ /**
+ * 瀵煎叆澶辫触鏁版嵁鍒楄〃
+ */
+ private List<MaintCheckItemVo> failureList = new ArrayList<>();
+
+ public MaintCheckItemImportListener(Boolean isUpdateSupport) {
+ super();
+ }
+
+ @Override
+ public void invoke(MaintCheckItemVo data, AnalysisContext context) {
+ try {
+ // 鏁版嵁鏍¢獙
+ if (!validateData(data)) {
+ failureList.add(data);
+ failureCount++;
+ return;
+ }
+ successList.add(data);
+ successCount++;
+ } catch (Exception e) {
+ failureList.add(data);
+ failureCount++;
+ log.error("瀵煎叆淇濆吇鐐规椤圭洰澶辫触锛�", e);
+ }
+ }
+
+ @Override
+ public void doAfterAllAnalysed(AnalysisContext context) {
+ log.info("淇濆吇鐐规椤圭洰瀵煎叆瀹屾垚锛屾垚鍔燂細{}鏉★紝澶辫触锛歿}鏉�", successCount, failureCount);
+ }
+
+ /**
+ * 鏍¢獙鏁版嵁
+ *
+ * @param data 寰呮牎楠屾暟鎹�
+ * @return 鏍¢獙缁撴灉
+ */
+ private boolean validateData(MaintCheckItemVo data) {
+ if (data.getItemName() == null || data.getItemName().trim().isEmpty()) {
+ return false;
+ }
+ if (data.getPeriod() == null || data.getPeriod().trim().isEmpty()) {
+ return false;
+ }
+
+ // 鏍¢獙1-12鏈堜唤鐘舵�佸��
+ return validateMonthStatus(data.getJanuary())
+ && validateMonthStatus(data.getFebruary())
+ && validateMonthStatus(data.getMarch())
+ && validateMonthStatus(data.getApril())
+ && validateMonthStatus(data.getMay())
+ && validateMonthStatus(data.getJune())
+ && validateMonthStatus(data.getJuly())
+ && validateMonthStatus(data.getAugust())
+ && validateMonthStatus(data.getSeptember())
+ && validateMonthStatus(data.getOctober())
+ && validateMonthStatus(data.getNovember())
+ && validateMonthStatus(data.getDecember());
+ }
+
+ /**
+ * 鏍¢獙鏈堜唤鐘舵�佸��
+ *
+ * @param status 鐘舵�佸��
+ * @return 鏍¢獙缁撴灉
+ */
+ private boolean validateMonthStatus(String status) {
+ // 鐘舵�佸�煎彲浠ヤ负绌�
+ if (status == null || status.trim().isEmpty()) {
+ return true;
+ }
+ // 鐘舵�佸�煎繀椤荤鍚堣鑼冿紙鏍规嵁瀹為檯涓氬姟闇�姹傚畾涔夋湁鏁堢殑鐘舵�佸�硷級
+ return true;
+ }
+
+ @Override
+ public ExcelResult<MaintCheckItemVo> getExcelResult() {
+ return null;
+ }
+}
diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsInspectPlanService.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsInspectPlanService.java
index 9334744..12588ff 100644
--- a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsInspectPlanService.java
+++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsInspectPlanService.java
@@ -4,7 +4,9 @@
import org.dromara.eims.domain.bo.EimsInspectPlanBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.IOException;
import java.util.Collection;
import java.util.List;
@@ -75,4 +77,5 @@
*/
TableDataInfo<EimsInspectPlanVo> queryPageListCustom(EimsInspectPlanBo bo, PageQuery pageQuery);
+ String importData(MultipartFile file, boolean updateSupport) throws IOException;
}
diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsMaintPlanService.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsMaintPlanService.java
index e7b98ce..f0c98c4 100644
--- a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsMaintPlanService.java
+++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsMaintPlanService.java
@@ -4,7 +4,10 @@
import org.dromara.eims.domain.bo.EimsMaintPlanBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.Collection;
import java.util.List;
@@ -74,4 +77,6 @@
* @return 淇濆吇璁″垝鍒嗛〉鍒楄〃
*/
TableDataInfo<EimsMaintPlanVo> queryPageListCustom(EimsMaintPlanBo bo, PageQuery pageQuery);
+
+ String importData(MultipartFile inputStream, boolean updateSupport) throws IOException;
}
diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsInspectPlanServiceImpl.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsInspectPlanServiceImpl.java
index 865f6de..52e43d2 100644
--- a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsInspectPlanServiceImpl.java
+++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsInspectPlanServiceImpl.java
@@ -1,6 +1,9 @@
package org.dromara.eims.service.impl;
+import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -9,7 +12,13 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
+import org.dromara.eims.domain.EimsEqu;
+import org.dromara.eims.domain.vo.EimsEquVo;
import org.dromara.eims.domain.vo.EimsMaintPlanVo;
+import org.dromara.eims.domain.vo.InspectCheckItemVo;
+import org.dromara.eims.listener.EasyExcelCellListener;
+import org.dromara.eims.listener.InspectCheckItemImportListener;
+import org.dromara.eims.mapper.EimsEquMapper;
import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.mapper.SysDeptMapper;
@@ -19,11 +28,10 @@
import org.dromara.eims.domain.EimsInspectPlan;
import org.dromara.eims.mapper.EimsInspectPlanMapper;
import org.dromara.eims.service.IEimsInspectPlanService;
+import org.springframework.web.multipart.MultipartFile;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Collection;
+import java.io.IOException;
+import java.util.*;
/**
* 鐐规璁″垝Service涓氬姟灞傚鐞�
@@ -37,6 +45,7 @@
private final EimsInspectPlanMapper baseMapper;
private final SysDeptMapper sysDeptMapper;
+ private final EimsEquMapper equMapper;
/**
@@ -196,5 +205,58 @@
return baseMapper.deleteByIds(ids) > 0;
}
+ @Override
+ public String importData(MultipartFile file, boolean updateSupport) throws IOException, IOException {
+ int successNum = 0;
+ int failureNum = 0;
+ StringBuilder successMsg = new StringBuilder();
+ StringBuilder failureMsg = new StringBuilder();
+
+ // 鐐规椤圭洰鍒楄〃锛堝亣璁惧瓨鍦ㄥ搴旂殑鐐规椤筕O锛�
+ InspectCheckItemImportListener checkItemImportListener = new InspectCheckItemImportListener(updateSupport);
+ EasyExcel.read(file.getInputStream(), InspectCheckItemVo.class, checkItemImportListener).headRowNumber(3).sheet().doRead();
+ List<InspectCheckItemVo> successList = checkItemImportListener.getSuccessList();
+
+ // 璇诲彇鍥哄畾璧勪骇缂栧彿锛堝亣璁句綅缃笉鍚岋級
+ EasyExcelCellListener assetNoListener = new EasyExcelCellListener(2, 23);
+ EasyExcel.read(file.getInputStream(), assetNoListener).headRowNumber(0).sheet().doReadSync();
+ String assetNo = Optional.ofNullable(assetNoListener.getCellValue())
+ .map(value -> {
+ int colonIndex = Math.max(value.indexOf(":"), value.indexOf("锛�")); // 鍚堝苟鍐掑彿澶勭悊
+ return colonIndex != -1 ? value.substring(colonIndex + 1) : value;
+ })
+ .map(String::trim)
+ .orElseThrow(() -> new ServiceException("瀵煎叆澶辫触锛屾棤娉曡鍙栧浐瀹氳祫浜х紪鍙�"));
+
+
+
+ // 鏌ヨ璁惧淇℃伅
+ QueryWrapper<EimsEqu> query = new QueryWrapper<>();
+ query.eq("asset_no", assetNo);
+ EimsEquVo equVo = equMapper.selectVoOne(query);
+ if (equVo == null) throw new ServiceException("璁惧鏈壘鍒帮紝璇峰厛鍦ㄨ澶囧彴甯愪腑娣诲姞");
+
+
+ for (InspectCheckItemVo itemVo : successList) {
+ if ("璁惧鐘舵�佸崱鐘舵��".equals(itemVo.getItemName())) break;
+ EimsInspectPlanBo bo = new EimsInspectPlanBo();
+ bo.setEquId(equVo.getEquId());
+ bo.setInspName(itemVo.getItemName());
+ bo.setStatus("0");
+ bo.setInspType("1");
+ bo.setInspRule("0");
+
+ if (!insertByBo(bo)) {
+ failureNum++;
+ failureMsg.append(failureNum).append("銆佸鍏ュけ璐�<br>");
+ } else {
+ successNum++;
+ successMsg.append(successNum).append("銆佸鍏ユ垚鍔�<br>");
+ }
+ }
+
+ return failureNum > 0 ? failureMsg.toString() : successMsg.toString();
+ }
+
}
diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsMaintPlanServiceImpl.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsMaintPlanServiceImpl.java
index 937832b..f1e2647 100644
--- a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsMaintPlanServiceImpl.java
+++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsMaintPlanServiceImpl.java
@@ -1,8 +1,8 @@
package org.dromara.eims.service.impl;
+import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import lombok.SneakyThrows;
-import org.dromara.common.core.constant.DictConstants;
+import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
@@ -12,7 +12,12 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
-import org.dromara.eims.domain.vo.EimsRepairResVo;
+import org.dromara.eims.domain.EimsEqu;
+import org.dromara.eims.domain.vo.EimsEquVo;
+import org.dromara.eims.domain.vo.MaintCheckItemVo;
+import org.dromara.eims.listener.EasyExcelCellListener;
+import org.dromara.eims.listener.MaintCheckItemImportListener;
+import org.dromara.eims.mapper.EimsEquMapper;
import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.mapper.SysDeptMapper;
@@ -22,7 +27,9 @@
import org.dromara.eims.domain.EimsMaintPlan;
import org.dromara.eims.mapper.EimsMaintPlanMapper;
import org.dromara.eims.service.IEimsMaintPlanService;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.IOException;
import java.util.*;
/**
@@ -37,6 +44,7 @@
private final EimsMaintPlanMapper baseMapper;
private final SysDeptMapper sysDeptMapper;
+ private final EimsEquMapper equMapper;
/**
* 鏌ヨ淇濆吇璁″垝
@@ -194,4 +202,165 @@
}
+ public String importData(MultipartFile is, boolean updateSupport) throws IOException {
+ int successNum = 0;
+ int failureNum = 0;
+ StringBuilder successMsg = new StringBuilder();
+ StringBuilder failureMsg = new StringBuilder();
+
+
+ // 淇濆吇椤圭洰鍒楄〃
+ MaintCheckItemImportListener checkItemImportListener = new MaintCheckItemImportListener(updateSupport);
+ EasyExcel.read(is.getInputStream(), MaintCheckItemVo.class, checkItemImportListener).headRowNumber(4).sheet().doRead();
+ List<MaintCheckItemVo> successList = checkItemImportListener.getSuccessList();
+
+
+ // 璇诲彇鍥哄畾璧勪骇缂栧彿
+ EasyExcelCellListener readListener = new EasyExcelCellListener(3, 1);
+ EasyExcel.read(is.getInputStream(), readListener).headRowNumber(0).sheet().doReadSync();
+ String assetNo = Optional.ofNullable(readListener.getCellValue())
+ .map(value -> {
+ int colonIndex = Math.max(value.indexOf(":"), value.indexOf("锛�")); // 鍚堝苟鍐掑彿澶勭悊
+ return colonIndex != -1 ? value.substring(colonIndex + 1) : value;
+ })
+ .map(String::trim)
+ .orElseThrow(() -> new ServiceException("瀵煎叆澶辫触锛屾棤娉曡鍙栧浐瀹氳祫浜х紪鍙�"));
+
+
+
+ // 璇诲彇淇濆吇璁″垝骞翠唤
+ EasyExcelCellListener readYearListener = new EasyExcelCellListener(2, 3);
+ EasyExcel.read(is.getInputStream(), readYearListener).headRowNumber(0).sheet().doReadSync();
+ String yearStr = readYearListener.getCellValue();
+ String year = yearStr.replaceAll("[^\\d]", ""); // 鍘婚櫎闈炴暟瀛楀瓧绗�
+ year = (year.length() == 4) ? year : DateUtils.getDate().substring(0,4);
+
+ QueryWrapper<EimsEqu> queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("asset_no", assetNo);
+ EimsEquVo eimsEquVo = equMapper.selectVoOne(queryWrapper);
+ if (eimsEquVo == null) throw new ServiceException("瀵煎叆澶辫触锛岃澶囨湭鎵惧埌璇峰湪璁惧鍙板笎涓坊鍔�");
+
+ // 鏈堜唤瀛楁澶勭悊浼樺寲
+ String[] monthFields = {"january","february","march","april","may","june",
+ "july","august","september","october","november","december"};
+
+ for (MaintCheckItemVo itemVo : successList) {
+ if ("鎵ц浜虹鍚�".equals(itemVo.getItemName())) break;
+
+ EimsMaintPlanBo maintPlanBo = new EimsMaintPlanBo();
+ maintPlanBo.setEquId(eimsEquVo.getEquId());
+ maintPlanBo.setMaintName(itemVo.getItemName());
+ maintPlanBo.setStatus("0");
+ maintPlanBo.setMaintType("1");
+ maintPlanBo.setMaintRule("0");
+ // 娣诲姞period鏍¢獙
+ String period = itemVo.getPeriod();
+ if (StringUtils.isBlank(period)) {
+ failureNum++;
+ failureMsg.append(failureNum).append("銆佸懆鏈熷瓧娈典负绌�<br>");
+ continue;
+ }
+
+ try {
+ if (period.length() > 1) {
+ maintPlanBo.setMaintCycle(Long.parseLong(period.substring(0, period.length() - 1)));
+ String substring = period.substring(period.length() - 1);
+ // 杞崲鍛ㄦ湡鍗曚綅锛孧杞崲涓�3锛孌杞崲涓�1锛孻杞崲涓�5锛學杞崲涓�2锛孮杞崲涓�4
+ switch (substring) {
+ case "M":
+ substring = "3";
+ break;
+ case "D":
+ substring = "1";
+ break;
+ case "Y":
+ substring = "5";
+ break;
+ case "W":
+ substring = "2";
+ break;
+ case "Q":
+ substring = "4";
+ break;
+ default:
+ }
+ maintPlanBo.setMaintCycleUnit(substring);
+ } else {
+ maintPlanBo.setMaintCycle(Long.parseLong(period));
+ maintPlanBo.setMaintCycleUnit("");
+ }
+ } catch (NumberFormatException e) {
+ failureNum++;
+ failureMsg.append(failureNum).append("銆佹棤鏁堢殑鍛ㄦ湡鏍煎紡:").append(period).append("<br>");
+ continue;
+ }
+
+ // 鏈堜唤鍒ゆ柇浼樺寲
+ for (int i = 0; i < monthFields.length; i++) {
+ try {
+ String monthValue = (String) MaintCheckItemVo.class
+ .getMethod("get" + StringUtils.capitalize(monthFields[i]))
+ .invoke(itemVo);
+
+ if (StringUtils.isNotBlank(monthValue)) {
+ String month = String.format("%02d", i+1); // 淇濊瘉涓や綅鏈堜唤
+ maintPlanBo.setMaintFirstTime(DateUtils.parseDate(year + "-" + month + "-01"));
+ break;
+ }
+ } catch (Exception e) {
+ // 鍙嶅皠寮傚父澶勭悊
+ failureNum++;
+ failureMsg.append(failureNum).append("銆佹湀浠藉瓧娈佃闂紓甯�<br>");
+ continue;
+ }
+ }
+
+ if (maintPlanBo.getMaintFirstTime() != null) {
+ Date firstTime = maintPlanBo.getMaintFirstTime();
+ Date nextTime = calcNextTime(firstTime, maintPlanBo.getMaintCycle().intValue(), 1);
+ maintPlanBo.setMaintNextTime(nextTime);
+ }
+
+ if (!insertByBo(maintPlanBo)) {
+ failureNum++;
+ failureMsg.append(failureNum).append("銆佽澶囷細").append(eimsEquVo.getEquName()).append("锛屽鍏ュけ璐�<br>");
+ } else {
+ successNum++;
+ successMsg.append("<br/>").append(successNum).append("銆佽澶囷細").append(eimsEquVo.getEquName()).append("锛屽鍏ユ垚鍔�");
+ }
+ }
+
+ if (failureNum > 0) {
+ failureMsg.insert(0, "寰堟姳姝夛紝瀵煎叆澶辫触锛佸叡 " + failureNum + " 鏉℃暟鎹牸寮忎笉姝g‘锛岄敊璇涓嬶細");
+ return failureMsg.toString();
+ } else {
+ successMsg.insert(0, "鎭枩鎮紝鏁版嵁宸插叏閮ㄥ鍏ユ垚鍔燂紒鍏� " + successNum + " 鏉★紝鏁版嵁濡備笅锛�");
+ return successMsg.toString();
+ }
+}
+
+
+private Date calcNextTime(Date firstTime, int intervalMonths, int initialOffset) {
+ if (intervalMonths <= 0) {
+ throw new IllegalArgumentException("Interval months must be positive");
+ }
+ if (firstTime == null) {
+ throw new IllegalArgumentException("First time cannot be null");
+ }
+
+ Date current = new Date();
+ int adjustmentCount = initialOffset;
+
+ Date workingDate = (Date) firstTime.clone();
+ while (workingDate.before(current)) {
+ adjustmentCount++;
+ workingDate = DateUtils.addMonths(workingDate, intervalMonths);
+ }
+
+ return (Date) workingDate.clone();
+}
+
+
+
+
}
--
Gitblit v1.9.3