From b7b10f78abc7ba462e5c602ba7e70d4739e316b8 Mon Sep 17 00:00:00 2001 From: baoshiwei <baoshiwei@shlanbao.cn> Date: 星期二, 24 六月 2025 09:00:39 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/main' --- eims-ui/apps/web-antd/src/api/eims/report/index.ts | 28 + eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/ReportReqBo.java | 19 + eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/ReportController.java | 50 ++ eims-ui/apps/web-antd/src/views/eims/insp-report/data.tsx | 53 ++ eims-ui/apps/web-antd/src/views/eims/maint-report/data.tsx | 46 ++ eims-ui/apps/web-antd/src/api/eims/report/model.d.ts | 97 +++++ eims-ui/apps/web-antd/src/views/eims/maint-report/index.vue | 213 +++++++++++ eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/ReportServiceImpl.java | 310 ++++++++++++++++ eims-ui/apps/web-antd/src/views/eims/insp-report/index.vue | 235 ++++++++++++ eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IReportService.java | 33 + eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsInspectReportVo.java | 38 ++ 11 files changed, 1,122 insertions(+), 0 deletions(-) diff --git a/eims-ui/apps/web-antd/src/api/eims/report/index.ts b/eims-ui/apps/web-antd/src/api/eims/report/index.ts new file mode 100644 index 0000000..84ae85c --- /dev/null +++ b/eims-ui/apps/web-antd/src/api/eims/report/index.ts @@ -0,0 +1,28 @@ +import { requestClient } from '#/api/request'; + +enum Api { + insp = '/eims/report/insp', + maint = '/eims/report/maint', +} + +/** + * 鏌ヨ鐐规璁板綍鍒楄〃 + * @param query + * @returns {*} + */ + +export function insp(params?: any) { + return requestClient.get<any[]>(Api.insp, { params }); +} + + +/** + * 鏌ヨ淇濆吇璁板綍鍒楄〃 + * @param query + * @returns {*} + */ + +export function maint(params?: any) { + return requestClient.get<any[]>(Api.maint, { params }); +} + diff --git a/eims-ui/apps/web-antd/src/api/eims/report/model.d.ts b/eims-ui/apps/web-antd/src/api/eims/report/model.d.ts new file mode 100644 index 0000000..688c76f --- /dev/null +++ b/eims-ui/apps/web-antd/src/api/eims/report/model.d.ts @@ -0,0 +1,97 @@ +export interface InspectRecordVO { + /** + * id + */ + id: string | number; + + /** + * 璁惧di + */ + equId: string | number; + /** + * 璁惧鍚嶇О + + */ + equName: string; + /** + * 璧勪骇缂栧彿 + + */ + assteNo: string; + + /** + * 鐐规鍚嶇О + */ + inspName: string; + + /** + * 鐐规鎻忚堪 + */ + inspDesc: string; + + /** + * 鐘舵�� + */ + status: string; + + /** + * 鐐规缂栫爜 + */ + inspCode: string; + + /** + * 鍊艰褰曟柟寮忥紙瀛楀吀锛� + */ + recordMode: string; + + /** + * 鍙傝�冨�� + */ + referenceValue: string; + + /** + * 涓婇檺 + */ + upperLimit: string; + + /** + * 涓嬮檺 + */ + lowLimit: string; + + /** + * 妫�鏌ュ�� + */ + checkValue: string; + + /** + * 鐐规缁撴灉锛堝瓧鍏革級 + */ + inspResult: string; + + /** + * 鐐规鏃堕棿 + */ + inspTime: string; + + /** + * 璁″垝鐐规鏃ユ湡 + */ + planTime: string; + + /** + * 楠岃瘉浜� + */ + verifyUser: number; + + /** + * 璁″垝id + */ + planId: string | number; + + /** + * 澶囨敞 + */ + remark: string; + +} diff --git a/eims-ui/apps/web-antd/src/views/eims/insp-report/data.tsx b/eims-ui/apps/web-antd/src/views/eims/insp-report/data.tsx new file mode 100644 index 0000000..64b9585 --- /dev/null +++ b/eims-ui/apps/web-antd/src/views/eims/insp-report/data.tsx @@ -0,0 +1,53 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { ref } from 'vue'; + +import dayjs from 'dayjs'; + +import { type FormSchemaGetter } from '#/adapter/form'; + +export const querySchema: FormSchemaGetter = () => [ + /* { + component: 'Select', + componentProps: { + showSearch: true, + allowClear: true, + getPopupContainer + }, + fieldName: 'equId', + label: '璁惧鍚嶇О' + },*/ + { + component: 'Input', + fieldName: 'keyword', + componentProps: { + placeholder: '璇疯緭鍏ヨ澶囧悕绉版垨璧勪骇缂栧彿' + }, + label: '鍏抽敭瀛�' + }, + { + component: 'DatePicker', + componentProps: { + picker: 'month', + format: 'YYYY-MM', + valueFormat: 'YYYY-MM', + placeholder: '璇烽�夋嫨鏈堜唤', + allowClear: true, + defaultValue: dayjs().format('YYYY-MM'), + getPopupContainer: (triggerNode: HTMLElement) => triggerNode.parentNode as HTMLElement + }, + fieldName: 'selectMonth', + defaultValue: dayjs().format('YYYY-MM'), + label: '鏈堜唤閫夋嫨' + } +]; + +export const columns = ref<VxeGridProps['columns']>([ + { type: 'checkbox', width: 60, fixed: 'left' }, + { + title: '璁惧鍚嶇О', + field: 'equName', + minWidth: 200, + fixed: 'left' + } +]); diff --git a/eims-ui/apps/web-antd/src/views/eims/insp-report/index.vue b/eims-ui/apps/web-antd/src/views/eims/insp-report/index.vue new file mode 100644 index 0000000..bc56f0e --- /dev/null +++ b/eims-ui/apps/web-antd/src/views/eims/insp-report/index.vue @@ -0,0 +1,235 @@ +<script setup lang="ts"> +import { h, onMounted, ref, toRaw } from 'vue'; + +import { Page, type VbenFormProps } from '@vben/common-ui'; + +import { Space } from 'ant-design-vue'; +import dayjs from 'dayjs'; + +import { useVbenVxeGrid, type VxeGridProps, vxeSortEvent } from '#/adapter/vxe-table'; +import { insp } from '#/api/eims/report'; + +import { columns as dynamicColumns, querySchema } from './data'; +// 鏁版嵁鏄惁鍒濆鍖� +const initFlag = ref(false); +const baseColumns: VxeGridProps['columns'] = [ + { + title: '璁惧鍚嶇О', + field: 'equName', + minWidth: 120, + fixed: 'left' + }, + { + title: '璧勪骇缂栧彿 - 鏃ユ湡', + field: 'assetNo', + minWidth: 120, + fixed: 'left' + } +]; +initColumns(); + +const formOptions: VbenFormProps = { + commonConfig: { + labelWidth: 80, + componentProps: { + allowClear: true + } + }, + schema: querySchema(), + wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4', + handleReset: async () => { + // eslint-disable-next-line no-use-before-define + const { formApi, reload } = tableApi; + await formApi.resetForm(); + const formValues = formApi.form.values; + formApi.setLatestSubmissionValues(formValues); + await reload(formValues); + initFlag.value = false; + initColumns(dayjs().format('YYYY-MM'), true); + }, + // 鏃ユ湡閫夋嫨鏍煎紡鍖� + fieldMappingTime: [['changeDate', ['params[beginTime]', 'params[endTime]'], ['YYYY-MM-DD 00:00:00', 'YYYY-MM-DD 23:59:59']]] +}; + +const gridOptions: VxeGridProps = { + checkboxConfig: { + // 楂樹寒 + highlight: true, + // 缈婚〉鏃朵繚鐣欓�変腑鐘舵�� + reserve: true + // 鐐瑰嚮琛岄�変腑 + // trigger: 'row' + }, + border: true, + size: 'mini', + columns: dynamicColumns.value, + height: 'auto', + keepSource: true, + pagerConfig: { + // 榛樿鏉℃暟 + pageSize: 20, + // 鍒嗛〉鍙�夋潯鏁� + pageSizes: [10, 20, 30, 50, 100, 200, 300, 500] + }, + proxyConfig: { + ajax: { + query: async ({ page }, formValues = {}) => { + // TODO 鏆傛椂瑙e喅鍔ㄦ�佷慨鏀硅〃澶村悗鍙傛暟涓㈠け闂 + // eslint-disable-next-line no-use-before-define + const p = await tableApi.formApi.getValues(); + const params = toRaw(p); + + return await insp({ + pageNum: page.currentPage, + pageSize: page.pageSize, + ...params + });; + } + } + }, + rowConfig: { + isHover: true, + keyField: 'inspReport' + }, + sortConfig: { + // 杩滅▼鎺掑簭 + remote: true, + // 鏀寔澶氬瓧娈垫帓搴� 榛樿鍏抽棴 + multiple: true + }, + id: 'eims-report-index' +}; + +const [BasicTable, tableApi] = useVbenVxeGrid({ + formOptions, + gridOptions, + gridEvents: { + sortChange: (sortParams) => vxeSortEvent(tableApi, sortParams) + } +}); + +onMounted(async () => { + initListener(); + // await setupEquSelect(); +}); +const selMonth = ref(''); + +function initListener() { + tableApi.formApi.updateSchema([ + { + component: 'DatePicker', + componentProps: { + onChange: (sMonth: string) => { + selMonth.value = sMonth; + dynamicColumns.value = []; + initFlag.value = false; + initColumns(sMonth, true); + } + }, + fieldName: 'selectMonth' + } + ]); +} + +function initColumns(selectMonth: string = dayjs().format('YYYY-MM'), isUpdate: boolean = false) { + if (initFlag.value) { + return false; + } + const dayNumbers = getDayNumbers(selectMonth); + const newColumns: VxeGridProps['columns'] = dayNumbers.map((day: number) => ({ + title: `${day}`, + field: `day_${day}`, + width: 40, + align: 'center', + slots: { + default: ({ row }) => { + const value = row[`day_${day}`]; + let className = ''; + + switch (value) { + case '宸插畬鎴�': { + className = 'dot-green'; + break; + } + case '寰呴獙璇�': { + className = 'dot-orange'; + break; + } + case '鏈偣妫�': { + className = 'dot-gray'; + break; + } + default: { + return '-'; + } + } + + return h('span', { class: className }); + } + } + // formatter: ({ row }: { row: any }) => { + // return row[`day_${day}`] || '-'; + // } + })); + dynamicColumns.value = [...(baseColumns || []), ...newColumns]; + initFlag.value = true; + if (isUpdate) { + tableApi.setGridOptions({ + ...gridOptions, + columns: dynamicColumns.value + }); + tableApi.query(); + } +} + +function getDayNumbers(yearMonth: string): number[] { + const days = dayjs(yearMonth).daysInMonth(); + return Array.from({ length: days }).map((_, i) => i + 1); +} +</script> + +<template> + <Page :auto-content-height="true"> + <div class="flex h-full gap-[8px]"> + <BasicTable class="flex-1 overflow-hidden" table-title="璇曚骇鍒楄〃"> + <template #toolbar-tools> + <Space> + <span class="ml-4 mr-2">-</span>鏈敓鎴愯鍒� <span class="dot-gray ml-4"></span>鏈偣妫� <span class="dot-orange ml-4"></span>寰呴獙璇� + <span class="dot-green ml-4"></span>宸茬偣妫� + </Space> + </template> + + <template #insp="{ row }"> + <Space> + <span>{{ row.equName }}</span> + </Space> + </template> + </BasicTable> + </div> + </Page> +</template> +<style lang="less" scoped> +:deep(.dot-green) { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 50%; + background-color: #52c41a; +} + +:deep(.dot-orange) { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 50%; + background-color: #faad14; +} + +:deep(.dot-gray) { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 50%; + background-color: #d9d9d9; +} +</style> diff --git a/eims-ui/apps/web-antd/src/views/eims/maint-report/data.tsx b/eims-ui/apps/web-antd/src/views/eims/maint-report/data.tsx new file mode 100644 index 0000000..af86655 --- /dev/null +++ b/eims-ui/apps/web-antd/src/views/eims/maint-report/data.tsx @@ -0,0 +1,46 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { ref } from 'vue'; + +import dayjs from 'dayjs'; + +import { type FormSchemaGetter } from '#/adapter/form'; + +export const querySchema: FormSchemaGetter = () => [ + /* { + component: 'Select', + componentProps: { + showSearch: true, + allowClear: true, + getPopupContainer + }, + fieldName: 'equId', + label: '璁惧鍚嶇О' + },*/ + { + component: 'Input', + fieldName: 'keyword', + componentProps: { + placeholder: '璇疯緭鍏ヨ澶囧悕绉版垨璧勪骇缂栧彿' + }, + label: '鍏抽敭瀛�' + }, + { + component: 'DatePicker', + componentProps: { + picker: 'year', + format: 'YYYY', + valueFormat: 'YYYY', + placeholder: '璇烽�夋嫨鏈堜唤', + allowClear: true, + defaultValue: dayjs().format('YYYY'), + getPopupContainer: (triggerNode: HTMLElement) => triggerNode.parentNode as HTMLElement + }, + fieldName: 'selectYear', + defaultValue: dayjs().format('YYYY'), + label: '骞翠唤閫夋嫨' + } +]; + +export const columns = ref<VxeGridProps['columns']>([ +]); diff --git a/eims-ui/apps/web-antd/src/views/eims/maint-report/index.vue b/eims-ui/apps/web-antd/src/views/eims/maint-report/index.vue new file mode 100644 index 0000000..ee92d5e --- /dev/null +++ b/eims-ui/apps/web-antd/src/views/eims/maint-report/index.vue @@ -0,0 +1,213 @@ +<script setup lang="ts"> +import { h, onMounted, ref, toRaw } from 'vue'; + +import { Page, type VbenFormProps } from '@vben/common-ui'; + +import { Space } from 'ant-design-vue'; + +import { useVbenVxeGrid, type VxeGridProps, vxeSortEvent } from '#/adapter/vxe-table'; +import { maint } from '#/api/eims/report'; + +import { columns as dynamicColumns, querySchema } from './data'; +// 鏁版嵁鏄惁鍒濆鍖� +const initFlag = ref(false); +const baseColumns: VxeGridProps['columns'] = [ + { type: 'checkbox', width: 60, fixed: 'left' }, + { + title: '璁惧鍚嶇О', + field: 'equName', + width: 200, + fixed: 'left' + }, + { + title: '璧勪骇缂栧彿', + field: 'assetNo', + width: 200, + fixed: 'left' + } +]; +initColumns(); + +const formOptions: VbenFormProps = { + commonConfig: { + labelWidth: 80, + componentProps: { + allowClear: true + } + }, + schema: querySchema(), + wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4', + handleReset: async () => { + // eslint-disable-next-line no-use-before-define + const { formApi, reload } = tableApi; + await formApi.resetForm(); + const formValues = formApi.form.values; + formApi.setLatestSubmissionValues(formValues); + await reload(formValues); + } +}; + +const gridOptions: VxeGridProps = { + checkboxConfig: { + // 楂樹寒 + highlight: true, + // 缈婚〉鏃朵繚鐣欓�変腑鐘舵�� + reserve: true + // 鐐瑰嚮琛岄�変腑 + // trigger: 'row' + }, + border: true, + size: 'mini', + columns: dynamicColumns.value, + height: 'auto', + keepSource: true, + pagerConfig: { + // 榛樿鏉℃暟 + pageSize: 20, + // 鍒嗛〉鍙�夋潯鏁� + pageSizes: [10, 20, 30, 50, 100, 200, 300, 500] + }, + proxyConfig: { + ajax: { + query: async ({ page }, formValues = {}) => { + // TODO 鏆傛椂瑙e喅鍔ㄦ�佷慨鏀硅〃澶村悗鍙傛暟涓㈠け闂 + // eslint-disable-next-line no-use-before-define + const p = await tableApi.formApi.getValues(); + const params = toRaw(p); + + return await maint({ + pageNum: page.currentPage, + pageSize: page.pageSize, + ...params + }); + } + } + }, + rowConfig: { + isHover: true, + keyField: 'maintReport' + }, + sortConfig: { + // 杩滅▼鎺掑簭 + remote: true, + // 鏀寔澶氬瓧娈垫帓搴� 榛樿鍏抽棴 + multiple: true + }, + id: 'mainit-report-index' +}; + +const [BasicTable, tableApi] = useVbenVxeGrid({ + formOptions, + gridOptions, + gridEvents: { + sortChange: (sortParams) => vxeSortEvent(tableApi, sortParams) + } +}); + +onMounted(async () => { + initListener(); + // await setupEquSelect(); +}); +const selYear = ref(''); + +function initListener() { + tableApi.formApi.updateSchema([ + { + component: 'DatePicker', + componentProps: { + onChange: (sYear: string) => { + selYear.value = sYear; + } + }, + fieldName: 'selectYear' + } + ]); +} + +function initColumns() { + if (initFlag.value) { + return false; + } + const dayNumbers = getMonthNumbers(); + const newColumns: VxeGridProps['columns'] = dayNumbers.map((month: number) => ({ + title: `${month}鏈坄, + field: `month_${month}`, + align: 'center', + slots: { + default: ({ row }) => { + const value = row[`month_${month}`]; + let className = ''; + + switch (value) { + case '宸插畬鎴�': { + className = 'dot-green'; + break; + } + case '鏈畬鎴�': { + className = 'dot-orange'; + break; + } + default: { + return '-'; + } + } + + return h('span', { class: className }); + } + } + })); + dynamicColumns.value = [...(baseColumns || []), ...newColumns]; + initFlag.value = true; +} + +function getMonthNumbers(): number[] { + return Array.from({ length: 12 }, (_, i) => i + 1); +} +</script> + +<template> + <Page :auto-content-height="true"> + <div class="flex h-full gap-[8px]"> + <BasicTable class="flex-1 overflow-hidden" table-title="璇曚骇鍒楄〃"> + <template #toolbar-tools> + <Space> + <span class="ml-4 mr-2">-</span>鏈敓鎴愯鍒� <span class="dot-orange ml-4"></span>鏈畬鎴� <span class="dot-green ml-4"></span>宸插畬鎴� + </Space> + </template> + </BasicTable> + </div> + </Page> +</template> +<style lang="less" scoped> +:deep(.dot-green) { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 50%; + background-color: #52c41a; +} + +:deep(.dot-orange) { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 50%; + background-color: #faad14; +} + +:deep(.dot-blue) { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 50%; + background-color: #2a5dd8; +} + +:deep(.dot-purple) { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 50%; + background-color: #8a2ad8; +} +</style> diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/ReportController.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/ReportController.java new file mode 100644 index 0000000..7e71d80 --- /dev/null +++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/ReportController.java @@ -0,0 +1,50 @@ +package org.dromara.eims.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import lombok.RequiredArgsConstructor; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.web.core.BaseController; +import org.dromara.eims.service.IReportService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +/** + * 鐐规鎶ヨ〃 + * + * @author zhuguifei + * @date + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/eims/report") +public class ReportController extends BaseController { + + private final IReportService reportService; + + /** + * 鏌ヨ鐐规璁板綍鍒楄〃 + */ + @SaCheckPermission("eims:inspReport:list") + @GetMapping("/insp") + public TableDataInfo<Map<String,Object>> list(@RequestParam Map<String, Object> queryParams, PageQuery pageQuery) { + return reportService.queryPageListCustom(queryParams, pageQuery); + } + + + /** + * 鏌ヨ淇濆吇璁板綍鍒楄〃 + */ + @SaCheckPermission("eims:maintReport:list") + @GetMapping("/maint") + public TableDataInfo<Map<String,Object>> maint(@RequestParam Map<String, Object> queryParams, PageQuery pageQuery) { + return reportService.queryMaintList(queryParams, pageQuery); + } + +} diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/ReportReqBo.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/ReportReqBo.java new file mode 100644 index 0000000..1462533 --- /dev/null +++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/ReportReqBo.java @@ -0,0 +1,19 @@ +package org.dromara.eims.domain.bo; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; + +/** + * 鐐规鎶ヨ〃璇锋眰鍙傛暟 + * + * @author zhuguifei + * @date + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class ReportReqBo extends BaseEntity { + + + +} diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsInspectReportVo.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsInspectReportVo.java new file mode 100644 index 0000000..132ecbb --- /dev/null +++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsInspectReportVo.java @@ -0,0 +1,38 @@ +package org.dromara.eims.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.translation.annotation.Translation; +import org.dromara.common.translation.constant.TransConstant; +import org.dromara.eims.domain.EimsInspectRecord; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + +/** + * 鐐规鎶ヨ〃瑙嗗浘瀵硅薄 + * + * @author zhuguifei + * @date + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class EimsInspectReportVo extends BaseEntity implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Integer year; + private Integer month; + + +} diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IReportService.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IReportService.java new file mode 100644 index 0000000..3036927 --- /dev/null +++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IReportService.java @@ -0,0 +1,33 @@ +package org.dromara.eims.service; + +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +import java.util.Map; + +/** + * 鐐规鎶ヨ〃Service鎺ュ彛 + * + * @author zhuguifei + * @date + */ +public interface IReportService { + + + /** + * 鍒嗛〉鏌ヨ鐐规璁板綍鍒楄〃-澶氳〃鏌ヨ + * + * @param queryParams 鏌ヨ鏉′欢 + * @param pageQuery 鍒嗛〉鍙傛暟 + * @return 鐐规璁板綍鍒嗛〉鍒楄〃 + */ + TableDataInfo<Map<String,Object>> queryPageListCustom(Map<String, Object> queryParams, PageQuery pageQuery); + + /** + * 鏌ヨ淇濆吇璁板綍 + * @param queryParams + * @param pageQuery + * @return + */ + TableDataInfo<Map<String, Object>> queryMaintList(Map<String, Object> queryParams, PageQuery pageQuery); +} diff --git a/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/ReportServiceImpl.java b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/ReportServiceImpl.java new file mode 100644 index 0000000..ce7d9a2 --- /dev/null +++ b/eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/ReportServiceImpl.java @@ -0,0 +1,310 @@ +package org.dromara.eims.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.eims.domain.*; +import org.dromara.eims.domain.vo.EimsEquVo; +import org.dromara.eims.mapper.*; +import org.dromara.eims.service.IReportService; +import org.dromara.system.mapper.SysDeptMapper; +import org.springframework.stereotype.Service; + +import java.time.*; +import java.util.*; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@Service +public class ReportServiceImpl implements IReportService { + + private static final String UNCHECKED = "鏈偣妫�"; + private static final String PENDING_VERIFICATION = "寰呴獙璇�"; + private static final String COMPLETED = "宸插畬鎴�"; + private static final String NOT_APPLICABLE = "/"; + + + private static final String MAINT_0 = "寰呬繚鍏�"; + private static final String MAINT_1 = "淇濆吇涓�"; + private static final String MAINT_2 = "寰呴獙璇�"; + private static final String MAINT_3 = "宸插畬鎴�"; + + private final EimsInspectRecordMapper baseMapper; + private final EimsInspectStMapper inspectStMapper; + private final EimsInspectPlanMapper inspectPlanMapper; + private final SysDeptMapper sysDeptMapper; + private final EimsEquMapper equMapper; + private final EimsMaintOrderMapper maintOrderMapper; + private final EimsMaintPlanMapper maintPlanMapper; + + @Override + public TableDataInfo<Map<String, Object>> queryPageListCustom(Map<String, Object> queryParams, PageQuery pageQuery) { + LambdaQueryWrapper<EimsEqu> equWrapper = Wrappers.lambdaQuery(); + + if (queryParams.containsKey("keyword")) { + String keyword = (String) queryParams.get("keyword"); + equWrapper.and(StringUtils.isNotBlank(keyword), + wrapper -> wrapper + .like(EimsEqu::getEquName, keyword) + .or() + .like(EimsEqu::getAssetNo, keyword) + ); + } + + Page<EimsEquVo> equList = equMapper.selectVoPage(pageQuery.build(), equWrapper); + return TableDataInfo.build(fitInspData(equList, queryParams)); + } + + @Override + public TableDataInfo<Map<String, Object>> queryMaintList(Map<String, Object> queryParams, PageQuery pageQuery) { + LambdaQueryWrapper<EimsEqu> equWrapper = Wrappers.lambdaQuery(); + + if (queryParams.containsKey("keyword")) { + String keyword = (String) queryParams.get("keyword"); + equWrapper.and(StringUtils.isNotBlank(keyword), + wrapper -> wrapper + .like(EimsEqu::getEquName, keyword) + .or() + .like(EimsEqu::getAssetNo, keyword) + ); + } + + Page<EimsEquVo> equList = equMapper.selectVoPage(pageQuery.build(), equWrapper); + return TableDataInfo.build(fitMaintData(equList, queryParams)); + } + + private Page<Map<String, Object>> fitMaintData(Page<EimsEquVo> equPageList, Map<String, Object> queryParams) { + Integer selectYear = getYearFromParams(queryParams); + LocalDate firstDay = Year.of(selectYear).atDay(1); // 绗竴澶� + LocalDate lastDay = Year.of(selectYear).atDay(Year.of(selectYear).length()); + Page<Map<String, Object>> page = new Page<>( + equPageList.getCurrent(), + equPageList.getSize(), + equPageList.getTotal(), + equPageList.searchCount() + ); + if (equPageList.getRecords().isEmpty()) { + return page; + } + + List<Long> equIds = equPageList.getRecords().stream() + .map(EimsEquVo::getEquId) + .collect(Collectors.toList()); + + Map<Long, List<EimsMaintOrder>> maintOrderMap = getMaintOrderMap(equIds, firstDay, lastDay); + Map<Long, List<EimsMaintPlan>> maintPlanMap = getMaintPlanMap(equIds,selectYear); + + List<Map<String, Object>> resultList = equPageList.getRecords().stream() + .map(equ -> buildMaintReport(equ, maintOrderMap, maintPlanMap)) + .collect(Collectors.toList()); + + page.setRecords(resultList); + + return page; + } + + private Page<Map<String, Object>> fitInspData(Page<EimsEquVo> equPageList, Map<String, Object> queryParams) { + YearMonth yearMonth = getYearMonthFromParams(queryParams); + LocalDate firstDay = yearMonth.atDay(1); + LocalDate lastDay = yearMonth.atEndOfMonth(); + + Page<Map<String, Object>> page = new Page<>( + equPageList.getCurrent(), + equPageList.getSize(), + equPageList.getTotal(), + equPageList.searchCount() + ); + + if (equPageList.getRecords().isEmpty()) { + return page; + } + + List<Long> equIds = equPageList.getRecords().stream() + .map(EimsEquVo::getEquId) + .collect(Collectors.toList()); + + Map<Long, List<EimsInspectSt>> inspectStMap = getInspectStMap(equIds, firstDay, lastDay); + Map<Long, List<EimsInspectPlan>> inspectPlanMap = getInspectPlanMap(equIds, yearMonth); + + List<Map<String, Object>> resultList = equPageList.getRecords().stream() + .map(equ -> buildEquipmentReport(equ, inspectStMap, inspectPlanMap, yearMonth)) + .collect(Collectors.toList()); + + page.setRecords(resultList); + return page; + } + + private YearMonth getYearMonthFromParams(Map<String, Object> queryParams) { + if (queryParams.containsKey("selectMonth")) { + String[] parts = queryParams.get("selectMonth").toString().split("-"); + return YearMonth.of(Integer.parseInt(parts[0]), Integer.parseInt(parts[1])); + } + return YearMonth.now(); + } + + private Map<Long, List<EimsInspectSt>> getInspectStMap(List<Long> equIds, LocalDate firstDay, LocalDate lastDay) { + LambdaQueryWrapper<EimsInspectSt> sWrapper = Wrappers.lambdaQuery(); + sWrapper.in(EimsInspectSt::getEquId, equIds) + .between(EimsInspectSt::getPlanTime, firstDay, lastDay) + .eq(EimsInspectSt::getType, "Day"); + + return inspectStMapper.selectList(sWrapper).stream() + .collect(Collectors.groupingBy(EimsInspectSt::getEquId)); + } + + private Map<Long, List<EimsInspectPlan>> getInspectPlanMap(List<Long> equIds, YearMonth yearMonth) { + LocalDateTime firstDayTime = yearMonth.atDay(1).atStartOfDay(); + LocalDateTime lastDayTime = yearMonth.atEndOfMonth().atTime(23, 59, 59); + + LambdaQueryWrapper<EimsInspectPlan> pWrapper = Wrappers.lambdaQuery(); + pWrapper.in(EimsInspectPlan::getEquId, equIds) + .between(EimsInspectPlan::getCreateTime, firstDayTime, lastDayTime); + + return inspectPlanMapper.selectList(pWrapper).stream() + .collect(Collectors.groupingBy(EimsInspectPlan::getEquId)); + } + + private Map<String, Object> buildEquipmentReport(EimsEquVo equ, + Map<Long, List<EimsInspectSt>> inspectStMap, + Map<Long, List<EimsInspectPlan>> inspectPlanMap, + YearMonth yearMonth) { + Map<String, Object> item = new HashMap<>(); + item.put("equName", equ.getEquName()); + item.put("assetNo", equ.getAssetNo()); + + List<EimsInspectSt> equInspList = inspectStMap.getOrDefault(equ.getEquId(), Collections.emptyList()); + List<EimsInspectPlan> equPlanList = inspectPlanMap.getOrDefault(equ.getEquId(), Collections.emptyList()); + + Map<String, EimsInspectSt> stMap = equInspList.stream() + .collect(Collectors.toMap( + inspSt -> String.valueOf(inspSt.getPlanTime().toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDate().getDayOfMonth()), + inspSt -> inspSt, + (existing, replacement) -> existing + )); + + Map<String, EimsInspectPlan> planMap = equPlanList.stream() + .collect(Collectors.toMap( + inspPlan -> String.valueOf(inspPlan.getCreateTime().toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDate().getDayOfMonth()), + inspPlan -> inspPlan, + (existing, replacement) -> existing + )); + + int daysInMonth = yearMonth.lengthOfMonth(); + for (int day = 1; day <= daysInMonth; day++) { + String dayKey = "day_" + day; + if (planMap.containsKey(String.valueOf(day))) { + item.put(dayKey, UNCHECKED); + } else if (stMap.containsKey(String.valueOf(day))) { + EimsInspectSt st = stMap.get(String.valueOf(day)); + switch (st.getStatus()) { + case "0": + item.put(dayKey, UNCHECKED); + break; + case "1": + item.put(dayKey, PENDING_VERIFICATION); + break; + case "2": + item.put(dayKey, COMPLETED); + break; + default: + item.put(dayKey, NOT_APPLICABLE); + } + } else { + item.put(dayKey, NOT_APPLICABLE); + } + } + + return item; + } + + + + + + private Integer getYearFromParams(Map<String, Object> queryParams) { + if (queryParams.containsKey("selectYear")) { + String year = queryParams.get("selectYear").toString(); + return Integer.parseInt(year); + } + return LocalDate.now().getYear(); + } + private Map<Long, List<EimsMaintOrder>> getMaintOrderMap(List<Long> equIds, LocalDate firstDay, LocalDate lastDay) { + LambdaQueryWrapper<EimsMaintOrder> sWrapper = Wrappers.lambdaQuery(); + sWrapper.in(EimsMaintOrder::getEquId, equIds) + .between(EimsMaintOrder::getPlanTime, firstDay, lastDay); + + return maintOrderMapper.selectList(sWrapper).stream() + .collect(Collectors.groupingBy(EimsMaintOrder::getEquId)); + } + + private Map<Long, List<EimsMaintPlan>> getMaintPlanMap(List<Long> equIds, Integer year) { + LocalDateTime firstDay = Year.of(year).atDay(1).atStartOfDay(); + LocalDateTime lastDay = Year.of(year).atDay(Year.of(year).length()) + .atTime(23, 59, 59); + + LambdaQueryWrapper<EimsMaintPlan> pWrapper = Wrappers.lambdaQuery(); + pWrapper.in(EimsMaintPlan::getEquId, equIds) + .between(EimsMaintPlan::getCreateTime, firstDay, lastDay); + + return maintPlanMapper.selectList(pWrapper).stream() + .collect(Collectors.groupingBy(EimsMaintPlan::getEquId)); + } + + private Map<String, Object> buildMaintReport(EimsEquVo equ, + Map<Long, List<EimsMaintOrder>> maintOrderMap, + Map<Long, List<EimsMaintPlan>> maintPlanMap) { + Map<String, Object> item = new HashMap<>(); + item.put("equName", equ.getEquName()); + item.put("assetNo", equ.getAssetNo()); + + List<EimsMaintOrder> equMaintOrderList = maintOrderMap.getOrDefault(equ.getEquId(), Collections.emptyList()); + List<EimsMaintPlan> equMaintPlanList = maintPlanMap.getOrDefault(equ.getEquId(), Collections.emptyList()); + + + Map<String, String> orderMap = equMaintOrderList.stream() + .collect(Collectors.groupingBy( + order -> String.valueOf(order.getPlanTime().toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDate().getMonthValue()), + // 鎸夋湀浠藉垎缁勫悗锛屽垽鏂鏈堟槸鍚﹀叏閮╯tatus=3 + Collectors.collectingAndThen( + Collectors.toList(), + orders -> orders.stream().allMatch(o -> o.getStatus().equals("3")) + ? "宸插畬鎴�" + : "鏈畬鎴�" + ) + )); + Map<String, EimsMaintPlan> planMap = equMaintPlanList.stream() + .collect(Collectors.toMap( + maintPlan -> String.valueOf(maintPlan.getCreateTime().toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDate().getMonthValue()), + maintPlan -> maintPlan, + (existing, replacement) -> existing + )); + + int monthInYear = 12; + for (int month = 1; month <= monthInYear; month++) { + String monthKey = "month_" + month; + if (planMap.containsKey(String.valueOf(month))) { + item.put(monthKey, UNCHECKED); + } else if (orderMap.containsKey(String.valueOf(month))) { + String result = orderMap.get(String.valueOf(month)); + item.put(monthKey, result); + + } else { + item.put(monthKey, NOT_APPLICABLE); + } + } + + return item; + } +} -- Gitblit v1.9.3