From 2b3715f1610b4176d7abe33e34542389cef61853 Mon Sep 17 00:00:00 2001 From: zhuguifei <zhuguifei@zhuguifeideiMac.local> Date: 星期六, 12 四月 2025 17:12:22 +0800 Subject: [PATCH] Merge branch 'main' of http://lanpucloud.cn:1111/r/eims-master --- 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