车间能级提升-智能设备管理系统
zhuguifei
2025-03-10 6648e74a007254e167c5508de5d25402cd4bb63b
完成保养工单明细
已添加60个文件
已修改13个文件
6563 ■■■■■ 文件已修改
eims-ui/apps/web-antd/src/api/eims/maint-order/index.ts 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/api/eims/maint-order/model.d.ts 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/api/eims/maint-orditm/index.ts 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/api/eims/maint-orditm/model.d.ts 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/api/eims/maint-plan/index.ts 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/api/eims/maint-plan/model.d.ts 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/api/eims/maint-stand/index.ts 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/api/eims/maint-stand/model.d.ts 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/constants/dict/index.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/components/basis-sub-table.vue 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/components/miant-order-modal.vue 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/maint-order/data.tsx 298 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/maint-order/index.vue 316 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/maint-order/maint-order-drawer.vue 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/maint-order/sub-orditm.vue 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/maint-orditm/data.tsx 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/maint-orditm/index.vue 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/maint-orditm/maint-orditm-drawer.vue 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/maint-plan/data.tsx 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/maint-plan/index.vue 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/maint-plan/maint-plan-drawer.vue 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/maint-stand/data.tsx 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/maint-stand/index.vue 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/maint-stand/maint-stand-drawer.vue 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/repair-req/data.tsx 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/repair-res/data.tsx 53 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/repair-res/index.vue 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/packages/@core/base/shared/src/constants/dict-enum.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-admin/src/main/resources/application-dev.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/DictConstants.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/MaintOrderService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/MaintOrderCodeTranslationImpl.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsMaintOrderController.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsMaintOrditmController.java 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsMaintPlanController.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsMaintStandController.java 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/GenerateCodeController.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/EimsMaintOrder.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/EimsMaintOrditm.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/EimsMaintPlan.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/EimsMaintStand.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsMaintOrderBo.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsMaintOrditmBo.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsMaintPlanBo.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsMaintStandBo.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsMaintOrderVo.java 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsMaintOrditmVo.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsMaintPlanVo.java 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsMaintStandVo.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/job/MaintPlanToOrderJob.java 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/mapper/EimsMaintOrderMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/mapper/EimsMaintOrditmMapper.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/mapper/EimsMaintPlanMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/mapper/EimsMaintStandMapper.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsMaintOrderService.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsMaintOrditmService.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsMaintPlanService.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsMaintStandService.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IGenerateCodeService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsMaintOrderServiceImpl.java 253 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsMaintOrditmServiceImpl.java 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsMaintPlanServiceImpl.java 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsMaintStandServiceImpl.java 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/GenerateCodeServiceImpl.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/resources/mapper/eims/EimsMaintOrderMapper.xml 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/resources/mapper/eims/EimsMaintOrditmMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/resources/mapper/eims/EimsMaintPlanMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/resources/mapper/eims/EimsMaintStandMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/api/eims/maint-order/index.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
import type { MaintOrderVO } from './model';
import type { ID, IDS } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
  maintOrderExport = '/eims/maintOrder/export',
  maintOrderList = '/eims/maintOrder/list',
  root = '/eims/maintOrder'
}
/**
 * æŸ¥è¯¢ä¿å…»å·¥å•列表
 * @param query
 * @returns {*}
 */
export function listMaintOrder(params?: any) {
  return requestClient.get<MaintOrderVO[]>(Api.maintOrderList, { params });
}
/**
 * æŸ¥è¯¢ä¿å…»å·¥å•详细
 * @param maintOrderId
 */
export function getMaintOrder(maintOrderId: ID) {
  return requestClient.get<MaintOrderVO>(`${Api.root}/${maintOrderId}`);
}
/**
 * æ–°å¢žä¿å…»å·¥å•
 * @param data
 */
export function addMaintOrder(data: any) {
  return requestClient.postWithMsg<void>(Api.root, data);
}
/**
 * ä¿®æ”¹ä¿å…»å·¥å•
 * @param data
 */
export function updateMaintOrder(data: any) {
  return requestClient.putWithMsg<void>(Api.root, data);
}
/**
 * åˆ é™¤ä¿å…»å·¥å•
 * @param maintOrderId
 */
export function delMaintOrder(maintOrderId: IDS) {
  return requestClient.deleteWithMsg<void>(`${Api.root}/${maintOrderId}`);
}
/**
 * å¯¼å‡º
 * @param
 */
export function maintOrderExport(data: any) {
  return commonExport(Api.maintOrderExport, data);
}
eims-ui/apps/web-antd/src/api/eims/maint-order/model.d.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,89 @@
export interface MaintOrderVO {
  /**
   *
   */
  id: number | string;
  /**
   *
   */
  equId: number | string;
  /**
   * è®¡åˆ’表冗余-保养类型(字典)
   */
  maintType: string;
  /**
   * è®¡åˆ’表冗余-保养周期
   */
  maintCycle: number;
  /**
   * è®¡åˆ’表冗余-保养周期单位(字典)
   */
  maintCycleUnit: string;
  /**
   * è®¡åˆ’表冗余- ä¿å…»è§„则(字典)保养时间计算:1-按周期  2-按上次保养时间
   */
  maintRule: string;
  /**
   * è®¡åˆ’表冗余-保养人
   */
  maintUser: number;
  maintUserName: string;
  /**
   * è®¡åˆ’表冗余-保养部门
   */
  maintDept: number;
  /**
   * ä¿å…»å•号
   */
  maintCode: string;
  /**
   *
   */
  status: string;
  verifyUser: number;
  /**
   * éªŒè¯äºº
   */
  verifyUserName: string;
  /**
   * ä¿å…»è®¡åˆ’æ—¶é—´
   */
  planTime: string;
  /**
   * ä¿å…»å¼€å§‹æ—¶é—´
   */
  startTime: string;
  /**
   * ä¿å…»ç»“束时间
   */
  endTime: string;
  /**
   * è®¡åˆ’id
   */
  planId: number | string;
  /**
   * åˆ›å»ºæ—¶é—´
   */
  createTime: string;
  /**
   * å¤‡æ³¨
   */
  remark: string;
}
eims-ui/apps/web-antd/src/api/eims/maint-orditm/index.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
import type { MaintOrditmVO } from './model';
import type { ID, IDS, PageResult } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
  maintOrditmExport = '/eims/maintOrditm/export',
  maintOrditmList = '/eims/maintOrditm/list',
  root = '/eims/maintOrditm'
}
/**
 * æŸ¥è¯¢å·¥å•条目列表
 * @param query
 * @returns {*}
 */
export function listMaintOrditm(params?: any) {
  return requestClient.get<PageResult<MaintOrditmVO>>(Api.maintOrditmList, { params });
}
/**
 * æŸ¥è¯¢å·¥å•条目详细
 * @param maintOrditmId
 */
export function getMaintOrditm(maintOrditmId: ID) {
  return requestClient.get<MaintOrditmVO>(`${Api.root}/${maintOrditmId}`);
}
/**
 * æ–°å¢žå·¥å•条目
 * @param data
 */
export function addMaintOrditm(data: any) {
  return requestClient.postWithMsg<void>(Api.root, data);
}
/**
 * ä¿®æ”¹å·¥å•条目
 * @param data
 */
export function updateMaintOrditm(data: any) {
  return requestClient.putWithMsg<void>(Api.root, data);
}
/**
 * åˆ é™¤å·¥å•条目
 * @param maintOrditmId
 */
export function delMaintOrditm(maintOrditmId: IDS) {
  return requestClient.deleteWithMsg<void>(`${Api.root}/${maintOrditmId}`);
}
/**
 * å¯¼å‡º
 * @param
 */
export function maintOrditmExport(data: any) {
  return commonExport(Api.maintOrditmExport, data);
}
eims-ui/apps/web-antd/src/api/eims/maint-orditm/model.d.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
export interface MaintOrditmVO {
  /**
   *
   */
  id: number | string;
  /**
   * å·¥å•id
   */
  orderId: number | string;
  /**
   * è®¾å¤‡id
   */
  equId: number | string;
  /**
   * ä¿å…»é¡¹ç›®åç§°
   */
  itmName: string;
  /**
   * ä¿å…»é¡¹ç›®æ“ä½œæ ‡å‡†
   */
  itmAction: string;
  /**
   * ä¿å…»æ“ä½œç”¨æˆ·
   */
  itmUser: number;
  /**
   * ä¿å…»æ—¶é—´
   */
  itmTime: string;
  /**
   * å®ŒæˆçŠ¶æ€ï¼ˆå­—å…¸ï¼‰
   */
  status: string;
  /**
   * å¤‡æ³¨
   */
  remark: string;
}
eims-ui/apps/web-antd/src/api/eims/maint-plan/index.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
import type { MaintPlanVO } from './model';
import type { ID, IDS } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
  maintPlanExport = '/eims/maintPlan/export',
  maintPlanList = '/eims/maintPlan/list',
  root = '/eims/maintPlan'
}
/**
 * æŸ¥è¯¢ä¿å…»è®¡åˆ’列表
 * @param query
 * @returns {*}
 */
export function listMaintPlan(params?: any) {
  return requestClient.get<MaintPlanVO[]>(Api.maintPlanList, { params });
}
/**
 * æŸ¥è¯¢ä¿å…»è®¡åˆ’详细
 * @param maintPlanId
 */
export function getMaintPlan(maintPlanId: ID) {
  return requestClient.get<MaintPlanVO>(`${Api.root}/${maintPlanId}`);
}
/**
 * æ–°å¢žä¿å…»è®¡åˆ’
 * @param data
 */
export function addMaintPlan(data: any) {
  return requestClient.postWithMsg<void>(Api.root, data);
}
/**
 * ä¿®æ”¹ä¿å…»è®¡åˆ’
 * @param data
 */
export function updateMaintPlan(data: any) {
  return requestClient.putWithMsg<void>(Api.root, data);
}
/**
 * åˆ é™¤ä¿å…»è®¡åˆ’
 * @param maintPlanId
 */
export function delMaintPlan(maintPlanId: IDS) {
  return requestClient.deleteWithMsg<void>(`${Api.root}/${maintPlanId}`);
}
/**
 * å¯¼å‡º
 * @param
 */
export function maintPlanExport(data: any) {
  return commonExport(Api.maintPlanExport, data);
}
eims-ui/apps/web-antd/src/api/eims/maint-plan/model.d.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
export interface MaintPlanVO {
  /**
   *
   */
  id: number | string;
  /**
   * è®¾å¤‡id
   */
  equId: number | string;
  /**
   * ä¿å…»ç±»åž‹ï¼ˆå­—典)
   */
  maintType: string;
  /**
   * ä¿å…»å‘¨æœŸ
   */
  maintCycle: number;
  /**
   * ä¿å…»å‘¨æœŸå•位(字典)
   */
  maintCycleUnit: string;
  /**
   * ä¿å…»è§„则(字典)保养时间计算:1-按周期  2-按上次保养时间
   */
  maintRule: string;
  /**
   * ä¿å…»äºº
   */
  maintUser: number;
  /**
   * ä¿å…»éƒ¨é—¨
   */
  maintDept: number;
  /**
   * çŠ¶æ€ï¼ˆå­—å…¸ï¼‰ 0-启用  1-禁用
   */
  status: string;
  /**
   * ä¸Šæ¬¡æ‰§è¡Œæ—¶é—´
   */
  maintFirstTime: string;
  /**
   * ä¸Šæ¬¡æ‰§è¡Œæ—¶é—´
   */
  maintLastTime: string;
  /**
   * ä¸‹æ¬¡æ‰§è¡Œæ—¶é—´
   */
  maintNextTime: string;
  /**
   * å¤‡æ³¨
   */
  remark: string;
}
eims-ui/apps/web-antd/src/api/eims/maint-stand/index.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
import type { MaintStandVO } from './model';
import type { ID, IDS, PageResult } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
  maintStandExport = '/eims/maintStand/export',
  maintStandList = '/eims/maintStand/list',
  root = '/eims/maintStand'
}
/**
 * æŸ¥è¯¢ä¿å…»æ ‡å‡†åˆ—表
 * @param query
 * @returns {*}
 */
export function listMaintStand(params?: any) {
  return requestClient.get<PageResult<MaintStandVO>>(Api.maintStandList, { params });
}
/**
 * æŸ¥è¯¢ä¿å…»æ ‡å‡†è¯¦ç»†
 * @param maintStandId
 */
export function getMaintStand(maintStandId: ID) {
  return requestClient.get<MaintStandVO>(`${Api.root}/${maintStandId}`);
}
/**
 * æ–°å¢žä¿å…»æ ‡å‡†
 * @param data
 */
export function addMaintStand(data: any) {
  return requestClient.postWithMsg<void>(Api.root, data);
}
/**
 * ä¿®æ”¹ä¿å…»æ ‡å‡†
 * @param data
 */
export function updateMaintStand(data: any) {
  return requestClient.putWithMsg<void>(Api.root, data);
}
/**
 * åˆ é™¤ä¿å…»æ ‡å‡†
 * @param maintStandId
 */
export function delMaintStand(maintStandId: IDS) {
  return requestClient.deleteWithMsg<void>(`${Api.root}/${maintStandId}`);
}
/**
 * å¯¼å‡º
 * @param
 */
export function maintStandExport(data: any) {
  return commonExport(Api.maintStandExport, data);
}
eims-ui/apps/web-antd/src/api/eims/maint-stand/model.d.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
export interface MaintStandVO {
  /**
   *
   */
  id: string | number;
  /**
   * è®¾å¤‡id
   */
  equId: string | number;
  /**
   * è®¾å¤‡ç¼–码
   */
  equCode: string;
  /**
   * è®¾å¤‡ç±»åž‹
   */
  equTypeId: string | number;
  /**
   * èµ„产编号
   */
  assetNo: string;
  /**
   * è®¾å¤‡åç§°
   */
  equName: string;
  /**
   * è®¾å¤‡åž‹å·
   */
  modelNo: string;
  /**
   * ä¿å…»é¡¹ç›®åç§°
   */
  name: string;
  /**
   * ä¿å…»é¡¹ç›®æ ‡å‡†
   */
  stand: string;
  /**
   * å¤‡æ³¨
   */
  remark: string;
}
eims-ui/apps/web-antd/src/constants/dict/index.ts
@@ -39,3 +39,13 @@
  WEIXIU = '2', // ç»´ä¿®ä¸­
  YIJIEDAN = '1' // å·²æŽ¥å•
}
/**
 * ä¿å…»å·¥å•状态
 */
export enum MAINT_ORDER_STATUS {
  BAOYANG = '1', // ä¿å…»ç»„
  DAIBAOYANG = '0', // å¾…保养
  DAIYANZHENG = '2', // å¾…验证
  WANCHENG = '3' // å®Œæˆ
}
eims-ui/apps/web-antd/src/views/eims/components/basis-sub-table.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,98 @@
<script setup lang="ts">
import { ref, watch } from 'vue';
import { Space } from 'ant-design-vue';
import { useVbenVxeGrid, type VxeGridProps, vxeSortEvent } from '#/adapter/vxe-table';
interface Props {
  reqKey: string;
  reqValue: any;
  title?: string;
  listApi: (params: any) => Promise<any>; // åŠ¨æ€API函数
  columns?: VxeGridProps['columns'];
}
const props = defineProps<Props>();
const columns = props?.columns?.filter((i) => i.field !== 'action');
const gridOptions: VxeGridProps = {
  checkboxConfig: {
    // é«˜äº®
    highlight: true,
    // ç¿»é¡µæ—¶ä¿ç•™é€‰ä¸­çŠ¶æ€
    reserve: true
    // ç‚¹å‡»è¡Œé€‰ä¸­
    // trigger: 'row'
  },
  columns,
  height: 'auto',
  keepSource: true,
  pagerConfig: {},
  proxyConfig: {
    ajax: {
      query: async ({ page }, formValues = {}) => {
        const keyName = props.reqKey;
        const keyValue = props.reqValue;
        if (keyName && keyValue) {
          const params = { [keyName]: props.reqValue };
          Object.assign(formValues, params);
        } else {
          // æœªä¼ å‚则查询一个不存在的值
          const params = { [keyName]: -1 };
          Object.assign(formValues, params);
        }
        return await props.listApi({
          pageNum: page.currentPage,
          pageSize: page.pageSize,
          ...formValues
        });
      }
    }
  },
  rowConfig: {
    isHover: true,
    keyField: 'id'
  },
  sortConfig: {
    // è¿œç¨‹æŽ’序
    remote: true,
    // æ”¯æŒå¤šå­—段排序 é»˜è®¤å…³é—­
    multiple: true
  },
  id: `basis-sub-table${props.reqValue}`
};
const [BasicTable, tableApi] = useVbenVxeGrid({
  gridOptions,
  gridEvents: {
    sortChange: (sortParams) => vxeSortEvent(tableApi, sortParams)
  }
});
// ä½¿ç”¨ watch ç›‘听 id çš„变化
watch(
  () => props.reqValue,
  (newVal, oldVal) => {
    if (newVal !== oldVal && newVal) {
      tableApi.query();
    }
  },
  { immediate: false }
);
/**
 * TODO åŽç»­æ‰©å±•点击事件
 */
const slotName = ref<string>('equName');
</script>
<template>
  <div class="w-full">
    <BasicTable :table-title="title">
      <template #[slotName]="{ row }">
        <Space>
          <span>{{ row[slotName] }}</span>
        </Space>
      </template>
    </BasicTable>
  </div>
</template>
eims-ui/apps/web-antd/src/views/eims/components/miant-order-modal.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue';
import MaintOrderView from '#/views/eims/maint-order/index.vue';
const emit = defineEmits<{ updateSelect: [any] }>();
const [BasicModal, modalApi] = useVbenModal({
  fullscreenButton: false,
  draggable: true,
  onCancel: handleCancel,
  onConfirm: handleConfirm
});
const innerView = ref();
async function handleConfirm() {
  try {
    modalApi.modalLoading(true);
    const tableSelect = innerView.value.tableSelect();
    if (tableSelect.length > 1) {
      message.error('最多只能选择一条数据!');
      modalApi.modalLoading(false);
      return false;
    }
    emit('updateSelect', tableSelect[0]);
    await handleCancel();
  } catch (error) {
    console.error(error);
  } finally {
    modalApi.modalLoading(false);
  }
}
async function handleCancel() {
  modalApi.close();
}
</script>
<template>
  <BasicModal :fullscreen-button="true" class="w-[800px]">
    <MaintOrderView ref="innerView" />
  </BasicModal>
</template>
<style scoped></style>
eims-ui/apps/web-antd/src/views/eims/maint-order/data.tsx
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,298 @@
import type { VxeGridProps } from '#/adapter/vxe-table';
import { DictEnum } from '@vben/constants';
import { getPopupContainer } from '@vben/utils';
import { type FormSchemaGetter } from '#/adapter/form';
import { getDictOptions } from '#/utils/dict';
import { renderDict } from '#/utils/render';
export const querySchema: FormSchemaGetter = () => [
  {
    component: 'Input',
    fieldName: 'equName',
    label: '设备名称'
  },
  {
    component: 'Input',
    fieldName: 'maintCode',
    label: '保养工单'
  },
  {
    component: 'Select',
    componentProps: {
      options: getDictOptions(DictEnum.EIMS_MAINT_TYPE)
    },
    fieldName: 'maintType',
    label: '保养类型'
  },
  {
    component: 'TreeSelect',
    // åœ¨drawer里更新 è¿™é‡Œä¸éœ€è¦é»˜è®¤çš„componentProps
    defaultValue: undefined,
    fieldName: 'maintDept',
    label: '保养部门'
  },
  {
    component: 'Select',
    componentProps: {
      allowClear: true,
      showSearch: true,
      getPopupContainer
    },
    fieldName: 'maintUser',
    label: '保养人'
  },
  {
    component: 'Select',
    componentProps: {
      options: getDictOptions(DictEnum.MAINT_TIME_RULE)
    },
    fieldName: 'maintRule',
    label: '计算规则'
  },
  {
    component: 'Select',
    componentProps: {
      options: getDictOptions(DictEnum.MAINT_ORDER_STATUS)
    },
    fieldName: 'status',
    label: '状态'
  }
];
export const columns: VxeGridProps['columns'] = [
  { type: 'checkbox', width: 60, fixed: 'left' },
  {
    title: '保养工单',
    field: 'maintCode',
    minWidth: 200,
    fixed: 'left'
  },
  {
    title: '状态',
    field: 'status',
    minWidth: 80,
    slots: {
      default: ({ row }) => {
        return renderDict(row.status, DictEnum.MAINT_ORDER_STATUS);
      }
    }
  },
  {
    title: '设备名称',
    field: 'equName',
    minWidth: 200,
    fixed: 'left'
  },
  {
    title: '资产编号',
    field: 'assetNo',
    minWidth: 160
  },
  {
    title: '保养类型',
    field: 'maintType',
    minWidth: 120,
    slots: {
      default: ({ row }) => {
        return renderDict(row.maintType, DictEnum.EIMS_MAINT_TYPE);
      }
    }
  },
  {
    title: '保养人',
    field: 'maintUserName',
    minWidth: 100
  },
  {
    title: '计划保养时间',
    field: 'planTime',
    minWidth: 160
  },
  {
    title: '保养开始时间',
    field: 'startTime',
    minWidth: 160
  },
  {
    title: '保养结束时间',
    field: 'endTime',
    minWidth: 160
  },
  {
    title: '验证人',
    field: 'verifyUserName',
    minWidth: 160
  },
  {
    title: '创建时间',
    field: 'createTime',
    minWidth: 200
  },
  {
    field: 'action',
    fixed: 'right',
    slots: { default: 'action' },
    title: '操作',
    width: 200
  }
];
export const drawerSchema: FormSchemaGetter = () => [
  {
    component: 'Input',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    },
    fieldName: 'id'
  },
  {
    component: 'Input',
    fieldName: 'equId',
    label: '设备id',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'Input',
    fieldName: 'maintCode',
    label: '保养单号'
  },
  {
    component: 'Input',
    fieldName: 'equName',
    label: '设备名称'
  },
  {
    component: 'RadioGroup',
    componentProps: {
      buttonStyle: 'solid',
      options: getDictOptions(DictEnum.EIMS_MAINT_TYPE),
      optionType: 'button'
    },
    fieldName: 'maintType',
    defaultValue: '1',
    label: '保养类型'
  },
  /*
  {
    component: 'InputNumber',
    fieldName: 'maintCycle',
    label: '保养周期',
    formItemClass: 'col-span-1',
    componentProps: {
      min: 1
    }
  },
 {
    component: 'Select',
    componentProps: {
      getPopupContainer,
      options: getDictOptions(DictEnum.MAINT_CYCLE_UNIT)
    },
    fieldName: 'maintCycleUnit',
    formItemClass: 'col-span-1 w-[80px]',
    labelWidth: 0,
    label: ''
  },
  {
    component: 'Select',
    componentProps: {
      getPopupContainer,
      options: getDictOptions(DictEnum.MAINT_TIME_RULE)
    },
    fieldName: 'maintRule',
    label: '保养规则 '
  },*/
  {
    component: 'Input',
    fieldName: 'maintUser',
    label: '保养人id',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'Input',
    fieldName: 'maintUserName',
    label: '保养人'
  },
  {
    component: 'Input',
    fieldName: 'maintDept',
    label: '部门id',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'RadioGroup',
    componentProps: {
      buttonStyle: 'solid',
      options: getDictOptions(DictEnum.MAINT_ORDER_STATUS),
      optionType: 'button'
    },
    fieldName: 'status',
    defaultValue: '0',
    label: '状态'
  },
  {
    component: 'DatePicker',
    componentProps: {
      format: 'YYYY-MM-DD',
      showTime: false,
      valueFormat: 'YYYY-MM-DD',
      getPopupContainer
    },
    fieldName: 'planTime',
    label: '计划保养日期'
  },
  {
    component: 'DatePicker',
    componentProps: {
      format: 'YYYY-MM-DD HH:mm:ss',
      showTime: true,
      valueFormat: 'YYYY-MM-DD HH:mm:ss',
      getPopupContainer
    },
    fieldName: 'startTime',
    label: '开始时间'
  },
  {
    component: 'DatePicker',
    componentProps: {
      format: 'YYYY-MM-DD HH:mm:ss',
      showTime: true,
      valueFormat: 'YYYY-MM-DD HH:mm:ss',
      getPopupContainer
    },
    fieldName: 'endTime',
    label: '结束时间'
  },
  {
    component: 'Input',
    fieldName: 'verifyUser',
    label: '验证人id',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'Input',
    fieldName: 'verifyUserName',
    label: '验证人'
  },
  {
    component: 'Textarea',
    fieldName: 'remark',
    label: '备注'
  }
];
eims-ui/apps/web-antd/src/views/eims/maint-order/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,316 @@
<script setup lang="ts">
import type { Recordable } from '@vben/types';
import { computed, onMounted, ref } from 'vue';
import { useAccess } from '@vben/access';
import { Page, useVbenDrawer, type VbenFormProps } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { useUserStore } from '@vben/stores';
import { addFullName, getPopupContainer, getVxePopupContainer } from '@vben/utils';
import { Modal, Popconfirm, Space } from 'ant-design-vue';
import { useVbenVxeGrid, vxeCheckboxChecked, type VxeGridProps, vxeSortEvent } from '#/adapter/vxe-table';
import { delMaintOrder, listMaintOrder, maintOrderExport } from '#/api/eims/maint-order';
import { getDeptTree, userList } from '#/api/system/user';
import { MAINT_ORDER_STATUS } from '#/constants/dict';
import { commonDownloadExcel } from '#/utils/file/download';
import { columns, querySchema } from './data';
import maintOrderDrawer from './maint-order-drawer.vue';
import SubOrditm from './sub-orditm.vue';
defineExpose({
  tableSelect
});
const formOptions: VbenFormProps = {
  commonConfig: {
    labelWidth: 80,
    componentProps: {
      allowClear: true
    }
  },
  collapsed: true,
  schema: querySchema(),
  wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'
};
const gridOptions: VxeGridProps = {
  checkboxConfig: {
    // é«˜äº®
    highlight: true,
    // ç¿»é¡µæ—¶ä¿ç•™é€‰ä¸­çŠ¶æ€
    reserve: true
    // ç‚¹å‡»è¡Œé€‰ä¸­
    // trigger: 'row'
  },
  columns,
  height: 'auto',
  keepSource: true,
  pagerConfig: {},
  proxyConfig: {
    ajax: {
      query: async ({ page }, formValues = {}) => {
        return await listMaintOrder({
          pageNum: page.currentPage,
          pageSize: page.pageSize,
          ...formValues
        });
      }
    }
  },
  rowConfig: {
    isHover: true,
    keyField: 'id'
  },
  sortConfig: {
    // è¿œç¨‹æŽ’序
    remote: true,
    // æ”¯æŒå¤šå­—段排序 é»˜è®¤å…³é—­
    multiple: true
  },
  id: 'maint-order-index'
};
const orderId = ref<string>();
const [BasicTable, tableApi] = useVbenVxeGrid({
  formOptions,
  gridOptions,
  gridEvents: {
    sortChange: (sortParams) => vxeSortEvent(tableApi, sortParams),
    cellClick: (e: any) => {
      const { row } = e;
      orderId.value = row.id;
    }
  }
});
const [MaintOrderDrawer, maintOrderDrawerApi] = useVbenDrawer({
  connectedComponent: maintOrderDrawer
});
function handleAdd() {
  maintOrderDrawerApi.setData({});
  maintOrderDrawerApi.open();
}
async function handleEdit(record: Recordable<any>) {
  maintOrderDrawerApi.setData({ id: record.id });
  maintOrderDrawerApi.open();
}
async function handleDelete(row: Recordable<any>) {
  await delMaintOrder(row.id);
  await tableApi.query();
}
function handleMultiDelete() {
  const rows = tableApi.grid.getCheckboxRecords();
  const ids = rows.map((row: any) => row.id);
  Modal.confirm({
    title: '提示',
    okType: 'danger',
    content: `确认删除选中的${ids.length}条记录吗?`,
    onOk: async () => {
      await delMaintOrder(ids);
      await tableApi.query();
    }
  });
}
function handleDownloadExcel() {
  commonDownloadExcel(maintOrderExport, '保养工单记录', tableApi.formApi.form.values, {
    fieldMappingTime: formOptions.fieldMappingTime
  });
}
/**
 * åˆå§‹åŒ–部门选择
 */
async function setupDeptSelect() {
  // updateSchema
  const deptTree = await getDeptTree();
  // é€‰ä¸­åŽæ˜¾ç¤ºåœ¨è¾“入框的值 å³çˆ¶èŠ‚ç‚¹ / å­èŠ‚ç‚¹
  addFullName(deptTree, 'label', ' / ');
  tableApi.formApi.updateSchema([
    {
      componentProps: (formModel) => ({
        class: 'w-full',
        fieldNames: {
          key: 'id',
          value: 'id',
          children: 'children'
        },
        getPopupContainer,
        async onSelect(deptId: number | string) {
          /** æ ¹æ®éƒ¨é—¨ID加载用户 */
          await setupUserOptions(deptId);
          /** å˜åŒ–后需要重新选择用户 */
          formModel.maintUser = undefined;
        },
        placeholder: '请选择',
        showSearch: true,
        treeData: deptTree,
        treeDefaultExpandAll: true,
        treeLine: { showLeafIcon: false },
        // ç­›é€‰çš„字段
        treeNodeFilterProp: 'label',
        // é€‰ä¸­åŽæ˜¾ç¤ºåœ¨è¾“入框的值
        treeNodeLabelProp: 'fullName'
      }),
      fieldName: 'maintDept'
    }
  ]);
}
/**
 * ç”¨æˆ·çš„加载
 */
async function setupUserOptions(deptId: any) {
  const params = { deptId };
  const userPageResult = await userList({
    pageNum: 1,
    pageSize: 500,
    ...params
  });
  const options = userPageResult.rows.map((item) => ({
    label: item.nickName || item.userName,
    value: item.userId
  }));
  // ç­›é€‰
  const filterOption = (input: string, option: any) => {
    return option.label.toLowerCase().includes(input.toLowerCase());
  };
  const placeholder = options.length > 0 ? '请选择' : '该部门下暂无用户';
  tableApi.formApi.updateSchema([
    {
      componentProps: { options, placeholder, filterOption },
      fieldName: 'maintUser'
    }
  ]);
}
onMounted(async () => {
  await setupDeptSelect();
});
async function handleEditStatus(record: Recordable<any>, status: string) {
  maintOrderDrawerApi.setData({ id: record.id, status });
  maintOrderDrawerApi.open();
}
const userStore = useUserStore();
const userId = userStore.userInfo?.userId;
const deptId = userStore.userInfo?.deptId;
const { hasAccessByRoles } = useAccess();
const isSuperAdmin = computed(() => hasAccessByRoles(['superadmin']));
const isLeader = computed(() => hasAccessByRoles(['leader']));
/**
 * å¾…保养状态-保养人操作
 * @param row
 */
function daibaoyang(row: any) {
  return (isSuperAdmin.value || isLeader.value || row.maintUser === userId) && row.status === MAINT_ORDER_STATUS.DAIBAOYANG;
}
/**
 * ä¿å…»çŠ¶æ€-保养人操作
 * @param row
 */
function baoyang(row: any) {
  return (isSuperAdmin.value || isLeader.value || row.maintUser === userId) && row.status === MAINT_ORDER_STATUS.BAOYANG;
}
/**
 * å¾…验证状态-验证人操作
 * @param row
 */
function yanzheng(row: any) {
  return (isSuperAdmin.value || isLeader.value || row.verifyUser === userId) && row.status === MAINT_ORDER_STATUS.DAIYANZHENG;
}
// é€‰ä¸­æ•°æ®
function tableSelect() {
  return tableApi.grid.getCheckboxRecords();
}
</script>
<template>
  <Page :auto-content-height="true">
    <div class="flex h-full gap-[8px] flex-col">
      <BasicTable class="h-2/3" table-title="保养工单列表">
        <template #toolbar-tools>
          <Space>
            <a-button v-access:code="['eims:maintOrder:export']" @click="handleDownloadExcel">
              {{ $t('pages.common.export') }}
            </a-button>
            <a-button
              :disabled="!vxeCheckboxChecked(tableApi)"
              danger
              type="primary"
              v-access:code="['eims:maintOrder:remove']"
              @click="handleMultiDelete"
            >
              {{ $t('pages.common.delete') }}
            </a-button>
            <a-button type="primary" v-access:code="['eims:maintOrder:add']" @click="handleAdd">
              {{ $t('pages.common.add') }}
            </a-button>
          </Space>
        </template>
        <template #equName="{ row }">
          <Space>
            <span>{{ row.equName }}</span>
          </Space>
        </template>
        <template #action="{ row }">
          <Space>
            <ghost-button
              v-if="daibaoyang(row)"
              class="btn-success"
              v-access:code="['eims:maintOrder:edit']"
              @click.stop="handleEditStatus(row, MAINT_ORDER_STATUS.BAOYANG)"
            >
              ä¿å…»
            </ghost-button>
            <ghost-button
              v-if="baoyang(row)"
              class="btn-success"
              v-access:code="['eims:maintOrder:edit']"
              @click.stop="handleEditStatus(row, MAINT_ORDER_STATUS.DAIYANZHENG)"
            >
              å®Œæˆ
            </ghost-button>
            <ghost-button
              v-if="yanzheng(row)"
              class="btn-success"
              v-access:code="['eims:maintOrder:edit']"
              @click.stop="handleEditStatus(row, MAINT_ORDER_STATUS.WANCHENG)"
            >
              éªŒè¯
            </ghost-button>
            <ghost-button v-access:code="['eims:maintOrder:edit']" @click.stop="handleEdit(row)">
              {{ $t('pages.common.edit') }}
            </ghost-button>
            <Popconfirm :get-popup-container="getVxePopupContainer" placement="left" title="确认删除?"
                        @confirm="handleDelete(row)">
              <ghost-button danger v-access:code="['eims:maintOrder:remove']" @click.stop="">
                {{ $t('pages.common.delete') }}
              </ghost-button>
            </Popconfirm>
          </Space>
        </template>
      </BasicTable>
      <!--<BasisSubTable :columns="maintStandCol" :list-api="listMaintStand" :req-value="equId" class="h-1/3" req-key="equId" title="保养实施项目" />-->
      <SubOrditm :order-id="orderId" class="h-1/3" />
    </div>
    <MaintOrderDrawer @reload="tableApi.query()" />
  </Page>
</template>
eims-ui/apps/web-antd/src/views/eims/maint-order/maint-order-drawer.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,201 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { cloneDeep } from '@vben/utils';
import { InputSearch } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { addMaintOrder, getMaintOrder, updateMaintOrder } from '#/api/eims/maint-order';
import CodeInput from '#/views/eims/components/code-input.vue';
import equModal from '#/views/eims/components/equ-modal.vue';
import userModal from '#/views/eims/components/user-modal.vue';
import { drawerSchema } from './data';
const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false);
const title = computed(() => {
  return isUpdate.value ? '编辑保养工单' : '新增保养工单';
});
const [BasicForm, formApi] = useVbenForm({
  commonConfig: {
    formItemClass: 'col-span-2',
    componentProps: {
      class: 'w-full'
    },
    labelWidth: 120
  },
  schema: drawerSchema(),
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2'
});
const [BasicDrawer, drawerApi] = useVbenDrawer({
  onCancel: handleCancel,
  onConfirm: handleConfirm,
  async onOpenChange(isOpen) {
    if (!isOpen) {
      return null;
    }
    drawerApi.drawerLoading(true);
    const { id } = drawerApi.getData() as { id?: number | string };
    const { status } = drawerApi.getData() as { status?: string };
    // ä»Žä¿å…»è®¡åˆ’页面生成保养工单
    const { planOrder } = drawerApi.getData();
    isUpdate.value = !!id;
    // æ–°å¢ž-从保养计划页面生成保养工单
    if (!isUpdate.value && !id) {
      await formApi.setValues(planOrder);
    }
    // é‡ç½®
    baoyangCol(false);
    // æ›´æ–° && èµ‹å€¼
    if (isUpdate.value && id) {
      const record = await getMaintOrder(id);
      /**
       * æ›´æ–°çŠ¶æ€
       */
      if (status) {
        record.status = status;
        baoyangCol(true);
        // TODO ç²¾ç»†åŒ–控制输入
        /* switch (status) {
          case MAINT_ORDER_STATUS.BAOYANG: {
            break;
          }
          case MAINT_ORDER_STATUS.DAIYANZHENG: {
            break;
          }
        }*/
      }
      await formApi.setValues(record);
    }
    drawerApi.drawerLoading(false);
  }
});
async function handleConfirm() {
  try {
    drawerApi.drawerLoading(true);
    const { valid } = await formApi.validate();
    if (!valid) {
      return;
    }
    const data = cloneDeep(await formApi.getValues());
    await (isUpdate.value ? updateMaintOrder(data) : addMaintOrder(data));
    emit('reload');
    await handleCancel();
  } catch (error) {
    console.error(error);
  } finally {
    drawerApi.drawerLoading(false);
  }
}
function baoyangCol(disable: boolean) {
  const show = disable;
  formApi.updateSchema([
    {
      componentProps: {
        disabled: show
      },
      fieldName: 'maintType'
    },
    {
      componentProps: {
        disabled: show
      },
      fieldName: 'planTime'
    },
    {
      componentProps: {
        disabled: show
      },
      fieldName: 'status'
    }
  ]);
}
async function handleCancel() {
  drawerApi.close();
  await formApi.resetForm();
}
// equ modal
const [EquModal, equModalApi] = useVbenModal({
  connectedComponent: equModal,
  draggable: true,
  title: '选择设备'
});
function handleEquModal() {
  equModalApi.setData({});
  equModalApi.open();
}
// user modal
const [UserModal, userModalApi] = useVbenModal({
  connectedComponent: userModal,
  draggable: true,
  title: '选择保养人'
});
const userType = ref<number | undefined>(undefined);
function handleUserModal(type: number) {
  userType.value = type;
  userModalApi.setData({});
  userModalApi.open();
}
/**
 * æ›´æ–°é€‰æ‹©çš„设备
 * @param equ
 */
async function updateEqu(equ: any) {
  await formApi.setValues({equId:equ.equId,equName:equ.equName});
}
/**
 * æ›´æ–°é€‰æ‹©çš„用户
 * @param user
 */
async function updateUser(user: any) {
  if (userType.value === 1) {
    await formApi.setValues({ 'maintUserName': user.nickName, 'maintUser': user.userId, 'maintDept': user.deptId });
  } else if (userType.value === 2) {
    await formApi.setValues({ 'verifyUserName': user.nickName, 'verifyUser': user.userId, 'verifyDept': user.deptId });
  }
}
</script>
<template>
  <BasicDrawer :close-on-click-modal="false" :title="title" class="w-[600px]">
    <BasicForm>
      <template #equName="slotProps">
        <InputSearch :enter-button="true" placeholder="请选择" @search="handleEquModal" v-bind="slotProps"
                     :disabled="isUpdate" />
      </template>
      <template #maintUserName="slotProps">
        <InputSearch :enter-button="true" placeholder="请选择" @search="handleUserModal(1)" v-bind="slotProps" />
      </template>
      <template #verifyUserName="slotProps">
        <InputSearch :enter-button="true" placeholder="请选择" @search="handleUserModal(2)" v-bind="slotProps" />
      </template>
      <template #maintCode="slotProps">
        <CodeInput v-bind="slotProps" :disabled="isUpdate" prefix="BYSD" />
      </template>
    </BasicForm>
    <EquModal class="w-[1200px]" @update-equ="updateEqu" />
    <UserModal class="w-[1200px]" @select-user="updateUser" />
  </BasicDrawer>
</template>
eims-ui/apps/web-antd/src/views/eims/maint-order/sub-orditm.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,147 @@
<script setup lang="ts">
import type { Recordable } from '@vben/types';
import { nextTick, ref, watch } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { getVxePopupContainer } from '@vben/utils';
import { Popconfirm, Space } from 'ant-design-vue';
import { useVbenVxeGrid, type VxeGridProps, vxeSortEvent } from '#/adapter/vxe-table';
import { listMaintOrditm } from '#/api/eims/maint-orditm';
import { columns } from '#/views/eims/maint-orditm/data';
import maintOrditmDrawer from '#/views/eims/maint-orditm/maint-orditm-drawer.vue';
interface Props {
  orderId?: string;
}
const props = defineProps<Props>();
const completed = ref<string>('已完成');
// æœªç›˜ç‚¹
const uncompleted = ref<string>('未完成');
const gridOptions: VxeGridProps = {
  checkboxConfig: {
    // é«˜äº®
    highlight: true,
    // ç¿»é¡µæ—¶ä¿ç•™é€‰ä¸­çŠ¶æ€
    reserve: true
    // ç‚¹å‡»è¡Œé€‰ä¸­
    // trigger: 'row'
  },
  columns,
  height: 'auto',
  keepSource: true,
  pagerConfig: {},
  proxyConfig: {
    ajax: {
      query: async ({ page }, formValues = {}) => {
        if (props.orderId) {
          const params = { orderId: props.orderId };
          Object.assign(formValues, params);
        } else {
          const params = { orderId: -1 };
          Object.assign(formValues, params);
        }
        return await listMaintOrditm({
          pageNum: page.currentPage,
          pageSize: page.pageSize,
          ...formValues
        });
      },
      querySuccess: () => {
        nextTick(() => {
          // eslint-disable-next-line no-use-before-define
          const data = tableApi?.grid.getData();
          completed.value = '已完成';
          uncompleted.value = '未完成';
          if (data.length <= 0) return false;
          const wc = data?.filter((i) => i.status === '1')?.length;
          completed.value = `已完成(${wc})`;
          uncompleted.value = `未完成(${data.length - wc})`;
        });
      }
    }
  },
  rowConfig: {
    isHover: true,
    keyField: 'id'
  },
  sortConfig: {
    // è¿œç¨‹æŽ’序
    remote: true,
    // æ”¯æŒå¤šå­—段排序 é»˜è®¤å…³é—­
    multiple: true
  },
  id: 'sub-orditm-index'
};
const [BasicTable, tableApi] = useVbenVxeGrid({
  gridOptions,
  gridEvents: {
    sortChange: (sortParams) => vxeSortEvent(tableApi, sortParams)
  }
});
const [MaintOrditmDrawer, maintOrditmDrawerApi] = useVbenDrawer({
  connectedComponent: maintOrditmDrawer
});
function handleAdd() {
  maintOrditmDrawerApi.setData({});
  maintOrditmDrawerApi.open();
}
async function handleEdit(record: Recordable<any>) {
  maintOrditmDrawerApi.setData({ id: record.id });
  maintOrditmDrawerApi.open();
}
// ä½¿ç”¨ watch ç›‘听 resId çš„变化
watch(
  () => props.orderId,
  (newVal, oldVal) => {
    if (newVal !== oldVal && newVal) {
      tableApi.query();
    }
  },
  { immediate: false }
);
</script>
<template>
  <div class="w-full">
    <BasicTable table-title="实施项目">
      <template #toolbar-tools>
        <Space>
          <a-button>{{ uncompleted }}</a-button>
          <a-button type="primary"> {{ completed }}</a-button>
        </Space>
      </template>
      <template #equName="{ row }">
        <Space>
          <span>{{ row.equName }}</span>
        </Space>
      </template>
      <template #action="{ row }">
        <Space>
          <ghost-button v-access:code="['eims:maintOrditm:edit']" @click.stop="handleEdit(row)">
            {{ $t('pages.common.edit') }}
          </ghost-button>
          <Popconfirm :get-popup-container="getVxePopupContainer" placement="left" title="确认删除?" @confirm="handleDelete(row)">
            <ghost-button danger v-access:code="['eims:maintOrditm:remove']" @click.stop="">
              {{ $t('pages.common.delete') }}
            </ghost-button>
          </Popconfirm>
        </Space>
      </template>
    </BasicTable>
    <MaintOrditmDrawer @reload="tableApi.query()" />
  </div>
</template>
eims-ui/apps/web-antd/src/views/eims/maint-orditm/data.tsx
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,169 @@
import type { VxeGridProps } from '#/adapter/vxe-table';
import { DictEnum } from '@vben/constants';
import { getPopupContainer } from '@vben/utils';
import { type FormSchemaGetter } from '#/adapter/form';
import { getDictOptions } from '#/utils/dict';
import { renderDict } from '#/utils/render';
export const querySchema: FormSchemaGetter = () => [
  {
    component: 'Input',
    fieldName: 'equName',
    label: '设备名称'
  },
  {
    component: 'Input',
    fieldName: 'assetNo',
    label: '资产编号'
  }
];
export const columns: VxeGridProps['columns'] = [
  { type: 'checkbox', width: 60, fixed: 'left' },
  {
    title: '状态',
    field: 'status',
    minWidth: 80,
    slots: {
      default: ({ row }) => {
        return renderDict(row.status, DictEnum.EIMS_ORDITM_STATUS);
      }
    }
  },
  {
    title: '完成时间',
    field: 'itmTime',
    minWidth: 200
  },
  {
    title: '设备名称',
    field: 'equName',
    minWidth: 160,
    slots: { default: 'equName' }
  },
  {
    title: '保养项目',
    field: 'itmName',
    minWidth: 200
  },
  {
    title: '项目标准',
    field: 'itmAction',
    minWidth: 200
  },
  {
    title: '保养用户',
    field: 'itmUserName',
    minWidth: 200
  },
  {
    field: 'action',
    fixed: 'right',
    slots: { default: 'action' },
    title: '操作',
    width: 200
  }
];
export const drawerSchema: FormSchemaGetter = () => [
  {
    component: 'Input',
    fieldName: 'orderId',
    label: '工单id',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'Input',
    fieldName: 'orderName',
    label: '保养工单'
  },
  {
    component: 'Input',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    },
    fieldName: 'id'
  },
  {
    component: 'Input',
    fieldName: 'equId',
    label: '设备id',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'Input',
    fieldName: 'equName',
    label: '设备名称',
    componentProps: {
      readonly: true
    },
  },
  {
    component: 'Select',
    componentProps: {
      allowClear: true,
      showSearch: true,
      getPopupContainer
    },
    fieldName: 'itmName',
    label: '保养项目',
  },
  {
    component: 'Input',
    fieldName: 'itmAction',
    label: '项目标准',
    componentProps: {
      readonly: true
    },
  },
  {
    component: 'Input',
    fieldName: 'itmUser',
    label: '保养人id',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'Input',
    fieldName: 'itmUserName',
    label: '保养人'
  },
  {
    component: 'RadioGroup',
    componentProps: {
      buttonStyle: 'solid',
      options: getDictOptions(DictEnum.EIMS_ORDITM_STATUS),
      optionType: 'button'
    },
    fieldName: 'status',
    defaultValue: '0',
    label: '状态'
  },
  {
    component: 'DatePicker',
    componentProps: {
      format: 'YYYY-MM-DD HH:mm:ss',
      showTime: true,
      valueFormat: 'YYYY-MM-DD HH:mm:ss',
      getPopupContainer
    },
    fieldName: 'itmTime',
    label: '完成时间'
  },
  {
    component: 'Textarea',
    fieldName: 'remark',
    label: '备注'
  }
];
eims-ui/apps/web-antd/src/views/eims/maint-orditm/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,159 @@
<script setup lang="ts">
import type { Recordable } from '@vben/types';
import { Page, useVbenDrawer, type VbenFormProps } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { getVxePopupContainer } from '@vben/utils';
import { Modal, Popconfirm, Space } from 'ant-design-vue';
import { useVbenVxeGrid, vxeCheckboxChecked, type VxeGridProps, vxeSortEvent } from '#/adapter/vxe-table';
import { delMaintOrditm, listMaintOrditm, maintOrditmExport } from '#/api/eims/maint-orditm';
import { commonDownloadExcel } from '#/utils/file/download';
import { columns, querySchema } from './data';
import maintOrditmDrawer from './maint-orditm-drawer.vue';
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'
};
const gridOptions: VxeGridProps = {
  checkboxConfig: {
    // é«˜äº®
    highlight: true,
    // ç¿»é¡µæ—¶ä¿ç•™é€‰ä¸­çŠ¶æ€
    reserve: true
    // ç‚¹å‡»è¡Œé€‰ä¸­
    // trigger: 'row'
  },
  columns,
  height: 'auto',
  keepSource: true,
  pagerConfig: {},
  proxyConfig: {
    ajax: {
      query: async ({ page }, formValues = {}) => {
        return await listMaintOrditm({
          pageNum: page.currentPage,
          pageSize: page.pageSize,
          ...formValues
        });
      }
    }
  },
  rowConfig: {
    isHover: true,
    keyField: 'id'
  },
  sortConfig: {
    // è¿œç¨‹æŽ’序
    remote: true,
    // æ”¯æŒå¤šå­—段排序 é»˜è®¤å…³é—­
    multiple: true
  },
  id: 'maint-orditm-index'
};
const [BasicTable, tableApi] = useVbenVxeGrid({
  formOptions,
  gridOptions,
  gridEvents: {
    sortChange: (sortParams) => vxeSortEvent(tableApi, sortParams)
  }
});
const [MaintOrditmDrawer, maintOrditmDrawerApi] = useVbenDrawer({
  connectedComponent: maintOrditmDrawer
});
function handleAdd() {
  maintOrditmDrawerApi.setData({});
  maintOrditmDrawerApi.open();
}
async function handleEdit(record: Recordable<any>) {
  maintOrditmDrawerApi.setData({ id: record.id });
  maintOrditmDrawerApi.open();
}
async function handleDelete(row: Recordable<any>) {
  await delMaintOrditm(row.id);
  await tableApi.query();
}
function handleMultiDelete() {
  const rows = tableApi.grid.getCheckboxRecords();
  const ids = rows.map((row: any) => row.id);
  Modal.confirm({
    title: '提示',
    okType: 'danger',
    content: `确认删除选中的${ids.length}条记录吗?`,
    onOk: async () => {
      await delMaintOrditm(ids);
      await tableApi.query();
    }
  });
}
function handleDownloadExcel() {
  commonDownloadExcel(maintOrditmExport, '保养工单明细记录', tableApi.formApi.form.values, {
    fieldMappingTime: formOptions.fieldMappingTime
  });
}
</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>
            <a-button v-access:code="['eims:maintOrditm:export']" @click="handleDownloadExcel">
              {{ $t('pages.common.export') }}
            </a-button>
            <a-button
              :disabled="!vxeCheckboxChecked(tableApi)"
              danger
              type="primary"
              v-access:code="['eims:maintOrditm:remove']"
              @click="handleMultiDelete"
            >
              {{ $t('pages.common.delete') }}
            </a-button>
            <a-button type="primary" v-access:code="['eims:maintOrditm:add']" @click="handleAdd">
              {{ $t('pages.common.add') }}
            </a-button>
          </Space>
        </template>
        <template #equName="{ row }">
          <Space>
            <span>{{ row.equName }}</span>
          </Space>
        </template>
        <template #action="{ row }">
          <Space>
            <ghost-button v-access:code="['eims:maintOrditm:edit']" @click.stop="handleEdit(row)">
              {{ $t('pages.common.edit') }}
            </ghost-button>
            <Popconfirm :get-popup-container="getVxePopupContainer" placement="left" title="确认删除?" @confirm="handleDelete(row)">
              <ghost-button danger v-access:code="['eims:maintOrditm:remove']" @click.stop="">
                {{ $t('pages.common.delete') }}
              </ghost-button>
            </Popconfirm>
          </Space>
        </template>
      </BasicTable>
    </div>
    <MaintOrditmDrawer @reload="tableApi.query()" />
  </Page>
</template>
eims-ui/apps/web-antd/src/views/eims/maint-orditm/maint-orditm-drawer.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,175 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { cloneDeep } from '@vben/utils';
import { InputSearch } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { addMaintOrditm, getMaintOrditm, updateMaintOrditm } from '#/api/eims/maint-orditm';
import { listMaintStand } from '#/api/eims/maint-stand';
import orderModal from '#/views/eims/components/miant-order-modal.vue';
import userModal from '#/views/eims/components/user-modal.vue';
import { drawerSchema } from './data';
const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false);
const title = computed(() => {
  return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});
const [BasicForm, formApi] = useVbenForm({
  commonConfig: {
    formItemClass: 'col-span-2',
    componentProps: {
      class: 'w-full'
    },
    labelWidth: 120
  },
  schema: drawerSchema(),
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2'
});
const [BasicDrawer, drawerApi] = useVbenDrawer({
  onCancel: handleCancel,
  onConfirm: handleConfirm,
  async onOpenChange(isOpen) {
    if (!isOpen) {
      return null;
    }
    drawerApi.drawerLoading(true);
    const { id } = drawerApi.getData() as { id?: number | string };
    isUpdate.value = !!id;
    // æ›´æ–° && èµ‹å€¼
    if (isUpdate.value && id) {
      const record = await getMaintOrditm(id);
      await formApi.setValues(record);
    }
    drawerApi.drawerLoading(false);
  }
});
/**
 * å·¥å•明细的加载
 */
async function setupOrditmOptions(equId: any) {
  const params = { equId };
  const userPageResult = await listMaintStand({
    pageNum: 1,
    pageSize: 50,
    ...params
  });
  const options = userPageResult?.rows.map((item) => ({
    label: item.name,
    value: item.name
  }));
  // ç­›é€‰
  const filterOption = (input: string, option: any) => {
    return option.label.toLowerCase().includes(input.toLowerCase());
  };
  const placeholder = options.length > 0 ? '请选择' : '该工单暂无明细';
  formApi.updateSchema([
    {
      componentProps: {
        options,
        placeholder,
        filterOption,
        async onSelect(name: string) {
          const item = userPageResult?.rows.find((i) => i.name === name);
          await formApi.setValues({ itmAction: item?.stand });
        }
      },
      fieldName: 'itmName'
    }
  ]);
}
async function handleConfirm() {
  try {
    drawerApi.drawerLoading(true);
    const { valid } = await formApi.validate();
    if (!valid) {
      return;
    }
    const data = cloneDeep(await formApi.getValues());
    await (isUpdate.value ? updateMaintOrditm(data) : addMaintOrditm(data));
    emit('reload');
    await handleCancel();
  } catch (error) {
    console.error(error);
  } finally {
    drawerApi.drawerLoading(false);
  }
}
async function handleCancel() {
  drawerApi.close();
  await formApi.resetForm();
}
// order modal
const [OrderModal, orderModalApi] = useVbenModal({
  connectedComponent: orderModal,
  draggable: true,
  title: '选择工单'
});
function handleOrderModal() {
  orderModalApi.setData({});
  orderModalApi.open();
}
/**
 * æ›´æ–°é€‰æ‹©çš„工单
 * @param order
 */
async function updateOrderSelect(order: any) {
  await formApi.setValues({ 'orderId': order.id, 'orderName': order.maintCode, 'equId': order.equId, 'equName': order.equName });
  await setupOrditmOptions(order?.equId);
}
// user modal
const [UserModal, userModalApi] = useVbenModal({
  connectedComponent: userModal,
  draggable: true,
  title: '选择成员'
});
/**
 * æ‰“开选择用户
 */
function handleUserModal() {
  userModalApi.setData({});
  userModalApi.open();
}
/**
 * æ›´æ–°é€‰æ‹©çš„用户
 * @param user
 */
async function updateUserSelect(user: any) {
  await formApi.setValues({ 'itmUser': user.userId, 'itmUserName': user.nickName });
}
</script>
<template>
  <BasicDrawer :close-on-click-modal="false" :title="title" class="w-[600px]">
    <BasicForm>
      <template #orderName="slotProps">
        <InputSearch :enter-button="true" placeholder="请选择" @search="handleOrderModal" v-bind="slotProps" />
      </template>
      <template #itmUserName="slotProps">
        <InputSearch :enter-button="true" placeholder="请选择" @search="handleUserModal" v-bind="slotProps" />
      </template>
    </BasicForm>
    <OrderModal class="w-[1200px]" @update-select="updateOrderSelect" />
    <UserModal class="w-[1200px]" @select-user="updateUserSelect" />
  </BasicDrawer>
</template>
eims-ui/apps/web-antd/src/views/eims/maint-plan/data.tsx
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,278 @@
import type { VxeGridProps } from '#/adapter/vxe-table';
import { DictEnum } from '@vben/constants';
import { getPopupContainer } from '@vben/utils';
import { type FormSchemaGetter } from '#/adapter/form';
import { getDictOptions } from '#/utils/dict';
import { renderDict } from '#/utils/render';
export const querySchema: FormSchemaGetter = () => [
  {
    component: 'Input',
    fieldName: 'equName',
    label: '设备名称'
  },
  {
    component: 'Input',
    fieldName: 'assetNo',
    label: '资产编号'
  },
  {
    component: 'Select',
    componentProps: {
      options: getDictOptions(DictEnum.EIMS_MAINT_TYPE)
    },
    fieldName: 'maintType',
    label: '保养类型'
  },
  {
    component: 'TreeSelect',
    // åœ¨drawer里更新 è¿™é‡Œä¸éœ€è¦é»˜è®¤çš„componentProps
    defaultValue: undefined,
    fieldName: 'maintDept',
    label: '保养部门',
  },
  {
    component: 'Select',
    componentProps: {
      allowClear: true,
      showSearch: true,
      getPopupContainer
    },
    fieldName: 'maintUser',
    label: '保养人',
  },
  {
    component: 'Select',
    componentProps: {
      options: getDictOptions(DictEnum.MAINT_TIME_RULE)
    },
    fieldName: 'maintRule',
    label: '计算规则'
  },
  {
    component: 'Select',
    componentProps: {
      options: getDictOptions(DictEnum.SYS_NORMAL_DISABLE)
    },
    fieldName: 'status',
    label: '状态'
  },
];
export const columns: VxeGridProps['columns'] = [
  { type: 'checkbox', width: 60, fixed: 'left' },
  {
    title: '设备名称',
    field: 'equName',
    minWidth: 200,
    fixed: 'left'
  },
  {
    title: '资产编号',
    field: 'assetNo',
    minWidth: 160
  },
  {
    title: '状态',
    field: 'status',
    minWidth: 80,
    slots: {
      default: ({ row }) => {
        return renderDict(row.status, DictEnum.SYS_NORMAL_DISABLE);
      }
    }
  },
  {
    title: '保养类型',
    field: 'maintType',
    minWidth: 120,
    slots: {
      default: ({ row }) => {
        return renderDict(row.maintType, DictEnum.EIMS_MAINT_TYPE);
      }
    }
  },
  {
    title: '保养人',
    field: 'maintUserName',
    minWidth: 100
  },
  {
    title: '循环周期',
    field: 'maintCycleUnitName',
    minWidth: 80
  },
  {
    title: '时间计算规则',
    field: 'maintRule',
    minWidth: 140,
    slots: {
      default: ({ row }) => {
        return renderDict(row.maintRule, DictEnum.MAINT_TIME_RULE);
      }
    }
  },
  {
    title: '首次执行时间',
    field: 'maintFirstTime',
    minWidth: 160
  },
  {
    title: '上次执行时间',
    field: 'maintLastTime',
    minWidth: 160
  },
  {
    title: '下次执行时间',
    field: 'maintNextTime',
    minWidth: 160
  },
  {
    field: 'action',
    fixed: 'right',
    slots: { default: 'action' },
    title: '操作',
    width: 200
  }
];
export const drawerSchema: FormSchemaGetter = () => [
  {
    component: 'Input',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    },
    fieldName: 'id'
  },
  {
    component: 'Input',
    fieldName: 'equId',
    label: '设备id',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'Input',
    fieldName: 'equName',
    label: '设备名称'
  },
  {
    component: 'RadioGroup',
    componentProps: {
      buttonStyle: 'solid',
      options: getDictOptions(DictEnum.EIMS_MAINT_TYPE),
      optionType: 'button'
    },
    fieldName: 'maintType',
    defaultValue: '1',
    label: '保养类型'
  },
  {
    component: 'InputNumber',
    fieldName: 'maintCycle',
    label: '保养周期',
    formItemClass: 'col-span-1',
    componentProps: {
      min: 1
    }
  },
  {
    component: 'Select',
    componentProps: {
      getPopupContainer,
      options: getDictOptions(DictEnum.MAINT_CYCLE_UNIT)
    },
    fieldName: 'maintCycleUnit',
    formItemClass: 'col-span-1 w-[80px]',
    labelWidth: 0,
    label: ''
  },
  {
    component: 'Select',
    componentProps: {
      getPopupContainer,
      options: getDictOptions(DictEnum.MAINT_TIME_RULE)
    },
    fieldName: 'maintRule',
    label: '保养规则 '
  },
  {
    component: 'Input',
    fieldName: 'maintUser',
    label: '用户id',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'Input',
    fieldName: 'maintUserName',
    label: '保养人'
  },
  {
    component: 'Input',
    fieldName: 'maintDept',
    label: '部门id',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'RadioGroup',
    componentProps: {
      buttonStyle: 'solid',
      options: getDictOptions(DictEnum.SYS_NORMAL_DISABLE),
      optionType: 'button'
    },
    fieldName: 'status',
    defaultValue: '0',
    label: '状态'
  },
  {
    component: 'DatePicker',
    componentProps: {
      format: 'YYYY-MM-DD',
      showTime: false,
      valueFormat: 'YYYY-MM-DD',
      getPopupContainer
    },
    fieldName: 'maintFirstTime',
    label: '首次执行时间'
  },
  {
    component: 'DatePicker',
    componentProps: {
      format: 'YYYY-MM-DD',
      showTime: false,
      valueFormat: 'YYYY-MM-DD',
      getPopupContainer
    },
    fieldName: 'maintLastTime',
    label: '上次执行时间'
  },
  {
    component: 'DatePicker',
    componentProps: {
      format: 'YYYY-MM-DD',
      showTime: false,
      valueFormat: 'YYYY-MM-DD',
      getPopupContainer
    },
    fieldName: 'maintNextTime',
    label: '下次执行时间',
  },
  {
    component: 'Textarea',
    fieldName: 'remark',
    label: '备注'
  }
];
eims-ui/apps/web-antd/src/views/eims/maint-plan/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,293 @@
<script setup lang="ts">
import type { Recordable } from '@vben/types';
import { onMounted, ref } from 'vue';
import { Page, useVbenDrawer, type VbenFormProps } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { addFullName, getPopupContainer, getVxePopupContainer } from '@vben/utils';
import { Dropdown, Menu, MenuItem, Modal, Popconfirm, Space } from 'ant-design-vue';
import { useVbenVxeGrid, vxeCheckboxChecked, type VxeGridProps, vxeSortEvent } from '#/adapter/vxe-table';
import { delMaintPlan, listMaintPlan, maintPlanExport } from '#/api/eims/maint-plan';
import { listMaintStand } from '#/api/eims/maint-stand';
import { generateCode } from '#/api/eims/utils';
import { getDeptTree, userList } from '#/api/system/user';
import { MAINT_ORDER_STATUS } from '#/constants/dict';
import { commonDownloadExcel } from '#/utils/file/download';
import BasisSubTable from '#/views/eims/components/basis-sub-table.vue';
import maintOrderDrawer from '#/views/eims/maint-order/maint-order-drawer.vue';
import { columns as maintSrandCol } from '#/views/eims/maint-stand/data';
import { columns, querySchema } from './data';
import maintPlanDrawer from './maint-plan-drawer.vue';
const formOptions: VbenFormProps = {
  commonConfig: {
    labelWidth: 80,
    componentProps: {
      allowClear: true
    }
  },
  collapsed: true,
  schema: querySchema(),
  wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'
};
const gridOptions: VxeGridProps = {
  checkboxConfig: {
    // é«˜äº®
    highlight: true,
    // ç¿»é¡µæ—¶ä¿ç•™é€‰ä¸­çŠ¶æ€
    reserve: true
    // ç‚¹å‡»è¡Œé€‰ä¸­
    // trigger: 'row'
  },
  columns,
  height: 'auto',
  keepSource: true,
  pagerConfig: {},
  proxyConfig: {
    ajax: {
      query: async ({ page }, formValues = {}) => {
        return await listMaintPlan({
          pageNum: page.currentPage,
          pageSize: page.pageSize,
          ...formValues
        });
      }
    }
  },
  rowConfig: {
    isHover: true,
    keyField: 'id'
  },
  sortConfig: {
    // è¿œç¨‹æŽ’序
    remote: true,
    // æ”¯æŒå¤šå­—段排序 é»˜è®¤å…³é—­
    multiple: true
  },
  id: 'maint-plan-index'
};
const equId = ref<string>();
const [BasicTable, tableApi] = useVbenVxeGrid({
  formOptions,
  gridOptions,
  gridEvents: {
    sortChange: (sortParams) => vxeSortEvent(tableApi, sortParams),
    cellClick: (e: any) => {
      const { row } = e;
      equId.value = row.equId;
    }
  }
});
const [MaintPlanDrawer, maintPlanDrawerApi] = useVbenDrawer({
  connectedComponent: maintPlanDrawer
});
const [MaintOrderDrawer, maintOrderDrawerApi] = useVbenDrawer({
  connectedComponent: maintOrderDrawer,
});
function handleAdd() {
  maintPlanDrawerApi.setData({});
  maintPlanDrawerApi.open();
}
async function handleEdit(record: Recordable<any>) {
  maintPlanDrawerApi.setData({ id: record.id });
  maintPlanDrawerApi.open();
}
async function handleDelete(row: Recordable<any>) {
  await delMaintPlan(row.id);
  await tableApi.query();
}
function handleMultiDelete() {
  const rows = tableApi.grid.getCheckboxRecords();
  const ids = rows.map((row: any) => row.id);
  Modal.confirm({
    title: '提示',
    okType: 'danger',
    content: `确认删除选中的${ids.length}条记录吗?`,
    onOk: async () => {
      await delMaintPlan(ids);
      await tableApi.query();
    }
  });
}
function handleDownloadExcel() {
  commonDownloadExcel(maintPlanExport, '保养计划记录', tableApi.formApi.form.values, {
    fieldMappingTime: formOptions.fieldMappingTime
  });
}
/**
 * ç”Ÿæˆä¿å…»å·¥å•
 * @param record
 */
async function handleAddOrder(record: Recordable<any>) {
  /**
   * ç”Ÿæˆä¿å…»å·¥å•code
   */
  const code = await generateCode('BYYJ');
  if (!code) {
    Modal.error({
      content: '生成保养工单失败,请重试!',
      title: '提示'
    });
    return false;
  }
  const planOrder = {
    equId: record.equId,
    equName: record.equName,
    maintUser: record.maintUser,
    maintUserName: record.maintUserName,
    maintDept: record.maintDept,
    maintDeptName: record.maintDeptName,
    maintType: record.maintType,
    planTime: record.maintNextTime,
    status: MAINT_ORDER_STATUS.DAIBAOYANG,
    maintCode: code
  };
  maintOrderDrawerApi.setData({ planOrder });
  maintOrderDrawerApi.open();
  // await addMaintOrder(order.value);
}
/**
 * åˆå§‹åŒ–部门选择
 */
async function setupDeptSelect() {
  // updateSchema
  const deptTree = await getDeptTree();
  // é€‰ä¸­åŽæ˜¾ç¤ºåœ¨è¾“入框的值 å³çˆ¶èŠ‚ç‚¹ / å­èŠ‚ç‚¹
  addFullName(deptTree, 'label', ' / ');
  tableApi.formApi.updateSchema([
    {
      componentProps: (formModel) => ({
        class: 'w-full',
        fieldNames: {
          key: 'id',
          value: 'id',
          children: 'children'
        },
        getPopupContainer,
        async onSelect(deptId: number | string) {
          /** æ ¹æ®éƒ¨é—¨ID加载用户 */
          await setupUserOptions(deptId);
          /** å˜åŒ–后需要重新选择用户 */
          formModel.maintUser = undefined;
        },
        placeholder: '请选择',
        showSearch: true,
        treeData: deptTree,
        treeDefaultExpandAll: true,
        treeLine: { showLeafIcon: false },
        // ç­›é€‰çš„字段
        treeNodeFilterProp: 'label',
        // é€‰ä¸­åŽæ˜¾ç¤ºåœ¨è¾“入框的值
        treeNodeLabelProp: 'fullName'
      }),
      fieldName: 'maintDept'
    }
  ]);
}
/**
 * ç”¨æˆ·çš„加载
 */
async function setupUserOptions(deptId: any) {
  const params = { deptId };
  const userPageResult = await userList({
    pageNum: 1,
    pageSize: 500,
    ...params
  });
  const options = userPageResult.rows.map((item) => ({
    label: item.nickName || item.userName,
    value: item.userId
  }));
  // ç­›é€‰
  const filterOption = (input: string, option: any) => {
    return option.label.toLowerCase().includes(input.toLowerCase());
  };
  const placeholder = options.length > 0 ? '请选择' : '该部门下暂无用户';
  tableApi.formApi.updateSchema([
    {
      componentProps: { options, placeholder, filterOption },
      fieldName: 'maintUser'
    }
  ]);
}
onMounted(async () => {
  await setupDeptSelect();
});
</script>
<template>
  <Page :auto-content-height="true">
    <div class="flex h-full gap-[8px] flex-col">
      <BasicTable class="h-2/3" table-title="保养计划列表">
        <template #toolbar-tools>
          <Space>
            <a-button v-access:code="['eims:maintPlan:export']" @click="handleDownloadExcel">
              {{ $t('pages.common.export') }}
            </a-button>
            <a-button
              :disabled="!vxeCheckboxChecked(tableApi)"
              danger
              type="primary"
              v-access:code="['eims:maintPlan:remove']"
              @click="handleMultiDelete"
            >
              {{ $t('pages.common.delete') }}
            </a-button>
            <a-button type="primary" v-access:code="['eims:maintPlan:add']" @click="handleAdd">
              {{ $t('pages.common.add') }}
            </a-button>
          </Space>
        </template>
        <template #equName="{ row }">
          <Space>
            <span>{{ row.equName }}</span>
          </Space>
        </template>
        <template #action="{ row }">
          <Space>
            <ghost-button class="btn-success" v-access:code="['eims:maintPlan:edit']" @click.stop="handleAddOrder(row)"> ç”Ÿæˆå·¥å• </ghost-button>
            <ghost-button v-access:code="['eims:maintPlan:edit']" @click.stop="handleEdit(row)">
              {{ $t('pages.common.edit') }}
            </ghost-button>
          </Space>
          <Dropdown :get-popup-container="getVxePopupContainer" placement="bottomRight">
            <template #overlay>
              <Menu>
                <Popconfirm :get-popup-container="getVxePopupContainer" placement="left" title="确认删除?" @confirm="handleDelete(row)">
                  <MenuItem key="1" @click.stop="">
                    {{ $t('pages.common.delete') }}
                  </MenuItem>
                </Popconfirm>
              </Menu>
            </template>
            <a-button size="small" type="link" v-access:code="['eims:maintPlan:remove']">
              {{ $t('pages.common.more') }}
            </a-button>
          </Dropdown>
        </template>
      </BasicTable>
      <BasisSubTable :columns="maintSrandCol" :list-api="listMaintStand" :req-value="equId" class="h-1/3" req-key="equId" title="保养实施项目" />
    </div>
    <MaintPlanDrawer @reload="tableApi.query()" />
    <MaintOrderDrawer @reload="tableApi.query()" />
  </Page>
</template>
eims-ui/apps/web-antd/src/views/eims/maint-plan/maint-plan-drawer.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,154 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { addFullName, cloneDeep, getPopupContainer } from '@vben/utils';
import { InputSearch } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { addMaintPlan, getMaintPlan, updateMaintPlan } from '#/api/eims/maint-plan';
import { getDeptTree, userList } from '#/api/system/user';
import equModal from '#/views/eims/components/equ-modal.vue';
import userModal from '#/views/eims/components/user-modal.vue';
import { drawerSchema } from './data';
const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false);
const title = computed(() => {
  return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});
const [BasicForm, formApi] = useVbenForm({
  commonConfig: {
    formItemClass: 'col-span-2',
    componentProps: {
      class: 'w-full'
    },
    labelWidth: 120
  },
  layout: 'horizontal',
  fieldMappingTime: [['field4', ['phoneType', 'phoneNumber'], null]],
  schema: drawerSchema(),
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2'
});
const [BasicDrawer, drawerApi] = useVbenDrawer({
  onCancel: handleCancel,
  onConfirm: handleConfirm,
  async onOpenChange(isOpen) {
    if (!isOpen) {
      return null;
    }
    drawerApi.drawerLoading(true);
    const { id } = drawerApi.getData() as { id?: number | string };
    isUpdate.value = !!id;
    formApi.updateSchema([
      {
        dependencies: {
          show: () => isUpdate.value,
          triggerFields: ['']
        },
        fieldName: 'maintLastTime'
      },
      {
        dependencies: {
          show: () => isUpdate.value,
          triggerFields: ['']
        },
        fieldName: 'maintNextTime'
      }
    ]);
    // æ›´æ–° && èµ‹å€¼
    if (isUpdate.value && id) {
      const record = await getMaintPlan(id);
      await formApi.setValues(record);
    }
    drawerApi.drawerLoading(false);
  }
});
async function handleConfirm() {
  try {
    drawerApi.drawerLoading(true);
    const { valid } = await formApi.validate();
    if (!valid) {
      return;
    }
    const data = cloneDeep(await formApi.getValues());
    await (isUpdate.value ? updateMaintPlan(data) : addMaintPlan(data));
    emit('reload');
    await handleCancel();
  } catch (error) {
    console.error(error);
  } finally {
    drawerApi.drawerLoading(false);
  }
}
async function handleCancel() {
  drawerApi.close();
  await formApi.resetForm();
}
// equ modal
const [EquModal, equModalApi] = useVbenModal({
  connectedComponent: equModal,
  draggable: true,
  title: '选择设备'
});
function handleEquModal() {
  equModalApi.setData({});
  equModalApi.open();
}
// user modal
const [UserModal, userModalApi] = useVbenModal({
  connectedComponent: userModal,
  draggable: true,
  title: '选择保养人'
});
function handleUserModal() {
  userModalApi.setData({});
  userModalApi.open();
}
/**
 * æ›´æ–°é€‰æ‹©çš„设备
 * @param equ
 */
async function updateEqu(equ: any) {
  await formApi.setValues(equ);
}
/**
 * æ›´æ–°é€‰æ‹©çš„用户
 * @param user
 */
async function updateUser(user: any) {
  await formApi.setValues({ 'maintUserName': user.nickName, 'maintUser': user.userId, 'maintDept': user.deptId });
}
</script>
<template>
  <BasicDrawer :close-on-click-modal="false" :title="title" class="w-[600px]">
    <BasicForm>
      <template #equName="slotProps">
        <InputSearch :enter-button="true" placeholder="请选择" @search="handleEquModal" v-bind="slotProps" />
      </template>
      <template #maintUserName="slotProps">
        <InputSearch :enter-button="true" placeholder="请选择" @search="handleUserModal" v-bind="slotProps" />
      </template>
    </BasicForm>
    <EquModal class="w-[1200px]" @update-equ="updateEqu" />
    <UserModal class="w-[1200px]" @select-user="updateUser" />
  </BasicDrawer>
</template>
eims-ui/apps/web-antd/src/views/eims/maint-stand/data.tsx
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,111 @@
import type { VxeGridProps } from '#/adapter/vxe-table';
import { type FormSchemaGetter } from '#/adapter/form';
export const querySchema: FormSchemaGetter = () => [
  {
    component: 'Input',
    fieldName: 'equName',
    label: '设备名称'
  },
  {
    component: 'Input',
    fieldName: 'assetNo',
    label: '资产编号'
  }
];
export const columns: VxeGridProps['columns'] = [
  { type: 'checkbox', width: 60, fixed: 'left' },
  {
    title: '设备名称',
    field: 'equName',
    minWidth: 200,
    fixed: 'left',
    slots: { default: 'equName' }
  },
  {
    title: '资产编号',
    field: 'assetNo',
    minWidth: 160
  },
  {
    title: '保养项目',
    field: 'name',
    minWidth: 300
  },
  {
    title: '项目标准',
    field: 'stand',
    minWidth: 200
  },
  {
    field: 'action',
    fixed: 'right',
    slots: { default: 'action' },
    title: '操作',
    width: 200
  }
];
export const drawerSchema: FormSchemaGetter = () => [
  {
    component: 'Input',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    },
    fieldName: 'id'
  },
  {
    component: 'Input',
    fieldName: 'equId',
    label: '设备id',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'Input',
    fieldName: 'equCode',
    label: '设备编码',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'Input',
    fieldName: 'assetNo',
    label: '资产编号',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'Input',
    fieldName: 'modelNo',
    label: '设备型号',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    }
  },
  {
    component: 'Input',
    fieldName: 'equName',
    label: '设备名称'
  },
  {
    component: 'Textarea',
    fieldName: 'name',
    label: '实施项目'
  },
  {
    component: 'Textarea',
    fieldName: 'stand',
    label: '实施标准'
  }
];
eims-ui/apps/web-antd/src/views/eims/maint-stand/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,159 @@
<script setup lang="ts">
import type { Recordable } from '@vben/types';
import { Page, useVbenDrawer, type VbenFormProps } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { getVxePopupContainer } from '@vben/utils';
import { Modal, Popconfirm, Space } from 'ant-design-vue';
import { useVbenVxeGrid, vxeCheckboxChecked, type VxeGridProps, vxeSortEvent } from '#/adapter/vxe-table';
import { delMaintStand, listMaintStand, maintStandExport } from '#/api/eims/maint-stand';
import { commonDownloadExcel } from '#/utils/file/download';
import { columns, querySchema } from './data';
import maintStandDrawer from './maint-stand-drawer.vue';
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'
};
const gridOptions: VxeGridProps = {
  checkboxConfig: {
    // é«˜äº®
    highlight: true,
    // ç¿»é¡µæ—¶ä¿ç•™é€‰ä¸­çŠ¶æ€
    reserve: true
    // ç‚¹å‡»è¡Œé€‰ä¸­
    // trigger: 'row'
  },
  columns,
  height: 'auto',
  keepSource: true,
  pagerConfig: {},
  proxyConfig: {
    ajax: {
      query: async ({ page }, formValues = {}) => {
        return await listMaintStand({
          pageNum: page.currentPage,
          pageSize: page.pageSize,
          ...formValues
        });
      }
    }
  },
  rowConfig: {
    isHover: true,
    keyField: 'id'
  },
  sortConfig: {
    // è¿œç¨‹æŽ’序
    remote: true,
    // æ”¯æŒå¤šå­—段排序 é»˜è®¤å…³é—­
    multiple: true
  },
  id: 'maint-stand-index'
};
const [BasicTable, tableApi] = useVbenVxeGrid({
  formOptions,
  gridOptions,
  gridEvents: {
    sortChange: (sortParams) => vxeSortEvent(tableApi, sortParams)
  }
});
const [MaintStandDrawer, maintStandDrawerApi] = useVbenDrawer({
  connectedComponent: maintStandDrawer
});
function handleAdd() {
  maintStandDrawerApi.setData({});
  maintStandDrawerApi.open();
}
async function handleEdit(record: Recordable<any>) {
  maintStandDrawerApi.setData({ id: record.id });
  maintStandDrawerApi.open();
}
async function handleDelete(row: Recordable<any>) {
  await delMaintStand(row.id);
  await tableApi.query();
}
function handleMultiDelete() {
  const rows = tableApi.grid.getCheckboxRecords();
  const ids = rows.map((row: any) => row.id);
  Modal.confirm({
    title: '提示',
    okType: 'danger',
    content: `确认删除选中的${ids.length}条记录吗?`,
    onOk: async () => {
      await delMaintStand(ids);
      await tableApi.query();
    }
  });
}
function handleDownloadExcel() {
  commonDownloadExcel(maintStandExport, '保养标准记录', tableApi.formApi.form.values, {
    fieldMappingTime: formOptions.fieldMappingTime
  });
}
</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>
            <a-button v-access:code="['eims:maintStand:export']" @click="handleDownloadExcel">
              {{ $t('pages.common.export') }}
            </a-button>
            <a-button
              :disabled="!vxeCheckboxChecked(tableApi)"
              danger
              type="primary"
              v-access:code="['eims:maintStand:remove']"
              @click="handleMultiDelete"
            >
              {{ $t('pages.common.delete') }}
            </a-button>
            <a-button type="primary" v-access:code="['eims:maintStand:add']" @click="handleAdd">
              {{ $t('pages.common.add') }}
            </a-button>
          </Space>
        </template>
        <template #equName="{ row }">
          <Space>
            <span>{{ row.equName }}</span>
          </Space>
        </template>
        <template #action="{ row }">
          <Space>
            <ghost-button v-access:code="['eims:maintStand:edit']" @click.stop="handleEdit(row)">
              {{ $t('pages.common.edit') }}
            </ghost-button>
            <Popconfirm :get-popup-container="getVxePopupContainer" placement="left" title="确认删除?" @confirm="handleDelete(row)">
              <ghost-button danger v-access:code="['eims:maintStand:remove']" @click.stop="">
                {{ $t('pages.common.delete') }}
              </ghost-button>
            </Popconfirm>
          </Space>
        </template>
      </BasicTable>
    </div>
    <MaintStandDrawer @reload="tableApi.query()" />
  </Page>
</template>
eims-ui/apps/web-antd/src/views/eims/maint-stand/maint-stand-drawer.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,111 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { cloneDeep } from '@vben/utils';
import { InputSearch } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { addMaintStand, getMaintStand, updateMaintStand } from '#/api/eims/maint-stand';
import equModal from '#/views/eims/components/equ-modal.vue';
import { drawerSchema } from './data';
import type { MaintStandVO } from '#/api/eims/maint-stand/model';
const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false);
const title = computed(() => {
  return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});
const [BasicForm, formApi] = useVbenForm({
  commonConfig: {
    formItemClass: 'col-span-2',
    componentProps: {
      class: 'w-full'
    },
    labelWidth: 120
  },
  schema: drawerSchema(),
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2'
});
const [BasicDrawer, drawerApi] = useVbenDrawer({
  onCancel: handleCancel,
  onConfirm: handleConfirm,
  async onOpenChange(isOpen) {
    if (!isOpen) {
      return null;
    }
    drawerApi.drawerLoading(true);
    const { id } = drawerApi.getData() as { id?: number | string };
    isUpdate.value = !!id;
    // æ›´æ–° && èµ‹å€¼
    if (isUpdate.value && id) {
      const record = await getMaintStand(id);
      await formApi.setValues(record);
    }
    drawerApi.drawerLoading(false);
  }
});
async function handleConfirm() {
  try {
    drawerApi.drawerLoading(true);
    const { valid } = await formApi.validate();
    if (!valid) {
      return;
    }
    const data = cloneDeep(await formApi.getValues());
    await (isUpdate.value ? updateMaintStand(data) : addMaintStand(data));
    emit('reload');
    await handleCancel();
  } catch (error) {
    console.error(error);
  } finally {
    drawerApi.drawerLoading(false);
  }
}
async function handleCancel() {
  drawerApi.close();
  await formApi.resetForm();
}
// equ modal
const [EquModal, equModalApi] = useVbenModal({
  connectedComponent: equModal,
  draggable: true,
  title: '选择设备'
});
function handleEquModal() {
  equModalApi.setData({});
  equModalApi.open();
}
/**
 * æ›´æ–°é€‰æ‹©çš„设备
 * @param equ
 */
async function updateSelect(equ: any) {
  await formApi.setValues(equ);
}
</script>
<template>
  <BasicDrawer :close-on-click-modal="false" :title="title" class="w-[600px]">
    <BasicForm>
      <template #equName="slotProps">
        <InputSearch :enter-button="true" placeholder="请选择" @search="handleEquModal" v-bind="slotProps" />
      </template>
    </BasicForm>
    <EquModal class="w-[1200px]" @update-equ="updateSelect" />
  </BasicDrawer>
</template>
eims-ui/apps/web-antd/src/views/eims/repair-req/data.tsx
@@ -79,6 +79,23 @@
export const columns: VxeGridProps['columns'] = [
  { type: 'checkbox', width: 60, fixed: 'left' },
  {
    title: '设备(工具)名称',
    sortable: true,
    minWidth: 150,
    fixed: 'left',
    slots: {
      default: ({ row }) => {
        if (row.reqType === REPAIR_REQ_TYPE.EQU) {
          return row.equName;
        } else if (row.reqType === REPAIR_REQ_TYPE.FIXTURE) {
          return row.fixtureName;
        } else {
          return '';
        }
      }
    }
  },
  {
    title: '报修单号',
    field: 'code',
    minWidth: 160,
@@ -116,22 +133,6 @@
    field: 'reqTime',
    sortable: true,
    minWidth: 200
  },
  {
    title: '设备(工具)名称',
    sortable: true,
    minWidth: 150,
    slots: {
      default: ({ row }) => {
        if (row.reqType === REPAIR_REQ_TYPE.EQU) {
          return row.equName;
        } else if (row.reqType === REPAIR_REQ_TYPE.FIXTURE) {
          return row.fixtureName;
        } else {
          return '';
        }
      }
    }
  },
  {
    title: '故障类别',
eims-ui/apps/web-antd/src/views/eims/repair-res/data.tsx
@@ -50,6 +50,33 @@
export const columns: VxeGridProps['columns'] = [
  { type: 'checkbox', width: 60, fixed: 'left' },
  {
    title: '设备(工具)名称',
    sortable: true,
    minWidth: 150,
    fixed: 'left',
    slots: {
      default: ({ row }) => {
        if (!row.reqType) {
          return '';
        }
        // æ ¹æ®ä¸åŒçš„请求类型返回相应的名称
        switch (row.reqType) {
          case REPAIR_REQ_TYPE.EQU: {
            return row.equName;
          }
          case REPAIR_REQ_TYPE.FIXTURE: {
            return row.fixtureName;
          }
          default: {
            // å¦‚果请求类型既不是 EQU ä¹Ÿä¸æ˜¯ FIXTURE,则返回空字符串
            return '';
          }
        }
      }
    }
  },
  {
    title: '维修单号',
    field: 'resCode',
    minWidth: 160,
@@ -103,32 +130,6 @@
    field: 'reqTime',
    sortable: true,
    minWidth: 200
  },
  {
    title: '设备(工具)名称',
    sortable: true,
    minWidth: 150,
    slots: {
      default: ({ row }) => {
        if (!row.reqType) {
          return '';
        }
        // æ ¹æ®ä¸åŒçš„请求类型返回相应的名称
        switch (row.reqType) {
          case REPAIR_REQ_TYPE.EQU: {
            return row.equName;
          }
          case REPAIR_REQ_TYPE.FIXTURE: {
            return row.fixtureName;
          }
          default: {
            // å¦‚果请求类型既不是 EQU ä¹Ÿä¸æ˜¯ FIXTURE,则返回空字符串
            return '';
          }
        }
      }
    }
  },
  {
    title: '故障类别',
eims-ui/apps/web-antd/src/views/eims/repair-res/index.vue
@@ -12,17 +12,18 @@
import { Modal, Popconfirm, Space } from 'ant-design-vue';
import { useVbenVxeGrid, vxeCheckboxChecked, type VxeGridProps, vxeSortEvent } from '#/adapter/vxe-table';
import { listRepairRecord } from '#/api/eims/repair-record';
import { delRepairRes, listRepairRes, repairResExport } from '#/api/eims/repair-res';
import { getDeptTree, userList } from '#/api/system/user';
import { REPAIR_RES_STATUS } from '#/constants/dict';
import { commonDownloadExcel } from '#/utils/file/download';
import BasisSubTable from '#/views/eims/components/basis-sub-table.vue';
import RepairRecord from '../repair-record/index.vue';
import fbPreviewDrawer from '../repair-fb/fb-preview-drawer.vue';
import repairFbDrawer from '../repair-fb/repair-fb-drawer.vue';
import { columns as repairRecordCol } from '../repair-record/data';
import { columns, querySchema } from './data';
import repairResDrawer from './repair-res-drawer.vue';
import repairFbDrawer from '../repair-fb/repair-fb-drawer.vue'
import fbPreviewDrawer from '../repair-fb/fb-preview-drawer.vue'
const userStore = useUserStore();
const userId = userStore.userInfo?.userId;
@@ -106,7 +107,7 @@
});
function handleAddFb(record: Recordable<any>) {
  repairFbDrawerApi.setData({ resId: record.id, resCode: record.resCode, fbUser: userId, fbDept: deptId});
  repairFbDrawerApi.setData({ resId: record.id, resCode: record.resCode, fbUser: userId, fbDept: deptId });
  repairFbDrawerApi.open();
}
@@ -114,7 +115,6 @@
  fbPreviewDrawerApi.setData({ id: record.fbId });
  fbPreviewDrawerApi.open();
}
function handleAdd() {
  repairResDrawerApi.setData({ resUser: userId, resDept: deptId });
@@ -133,22 +133,22 @@
const { hasAccessByRoles } = useAccess();
const isSuperAdmin = computed(() => hasAccessByRoles(['superadmin']));
const isLeader = computed(() => hasAccessByRoles(['leader']));
function pingjiaAdd(row: any) {
  return (isSuperAdmin.value || row.reqUser === userId) && row.status === REPAIR_RES_STATUS.WANCHENG && !row.fbId;
  return (isSuperAdmin.value || isLeader.value || row.reqUser === userId) && row.status === REPAIR_RES_STATUS.WANCHENG && !row.fbId;
}
function pingjiaDetail(row: any) {
  return (isSuperAdmin.value || row.reqUser === userId) && row.status === REPAIR_RES_STATUS.WANCHENG && row.fbId;
  return (isSuperAdmin.value || isLeader.value || row.reqUser === userId) && row.status === REPAIR_RES_STATUS.WANCHENG && row.fbId;
}
function weixiu(row: any) {
  return (isSuperAdmin.value || row.resUser === userId) && row.status === REPAIR_RES_STATUS.YIJIEDAN;
  return (isSuperAdmin.value || isLeader.value || row.resUser === userId) && row.status === REPAIR_RES_STATUS.YIJIEDAN;
}
function wancheng(row: any) {
  return (isSuperAdmin.value || row.resUser === userId) && row.status === REPAIR_RES_STATUS.WEIXIU;
  return (isSuperAdmin.value || isLeader.value || row.resUser === userId) && row.status === REPAIR_RES_STATUS.WEIXIU;
}
async function handleDelete(row: Recordable<any>) {
@@ -272,8 +272,12 @@
        <template #action="{ row }">
          <Space>
            <ghost-button v-if="pingjiaAdd(row)" class="btn-success" v-access:code="['eims:repairRes:edit']" @click.stop="handleAddFb(row)"> è¯„ä»· </ghost-button>
            <ghost-button v-if="pingjiaDetail(row)" class="btn-success" v-access:code="['eims:repairRes:edit']" @click.stop="handleDetailFb(row)"> é˜…评 </ghost-button>
            <ghost-button v-if="pingjiaAdd(row)" class="btn-success" v-access:code="['eims:repairRes:edit']" @click.stop="handleAddFb(row)">
              è¯„ä»·
            </ghost-button>
            <ghost-button v-if="pingjiaDetail(row)" class="btn-success" v-access:code="['eims:repairRes:edit']" @click.stop="handleDetailFb(row)">
              é˜…评
            </ghost-button>
            <ghost-button
              v-if="weixiu(row)"
              class="btn-success"
@@ -303,7 +307,7 @@
          </Space>
        </template>
      </BasicTable>
      <RepairRecord :res-id="resId" class="h-1/3" table-title="维修记录" />
      <BasisSubTable :columns="repairRecordCol" :list-api="listRepairRecord" :req-value="resId" class="h-1/3" req-key="resId" title="操作记录" />
    </div>
    <RepairResDrawer @reload="tableApi.query()" />
    <RepairFbDrawer @reload="tableApi.query()" />
eims-ui/packages/@core/base/shared/src/constants/dict-enum.ts
@@ -3,9 +3,14 @@
  EIMS_FIXTURE_STATUS = 'eims_fixture_status', // å·¥å…·ï¼ˆæ²»å…·ï¼‰çŠ¶æ€
  EIMS_INVENTORY_DETAIL_STATU = 'inventory_detail_statu', // è®¾å¤‡ç›˜ç‚¹çŠ¶æ€
  EIMS_INVENTORY_STATU = 'inventory_statu', // è®¾å¤‡ç›˜ç‚¹çŠ¶æ€
  EIMS_MAINT_TYPE = 'eims_maint_type', // ä¿å…»ç±»åž‹
  EIMS_ORDITM_STATUS = 'eims_orditm_status', // ä¿å…»å·¥å•明细完成状态
  EQU_IMPORT_STATU = 'equ_import_status', // è®¾å¤‡å¯¼å…¥çŠ¶æ€
  FIXTURE_BORROW_RECORD_STATUS = 'fixture_borrow_record_status', // å·¥å…·ï¼ˆæ²»å…·ï¼‰å€Ÿç”¨è®°å½•状态
  FIXTURE_BORROW_STATUS = 'fixture_borrow_status', // å·¥å…·ï¼ˆæ²»å…·ï¼‰å€Ÿç”¨çŠ¶æ€
  MAINT_CYCLE_UNIT = 'maint_cycle_unit', // ä¿å…»å‘¨æœŸå•位
  MAINT_ORDER_STATUS = 'maint_order_status', // ä¿å…»å·¥å•状态
  MAINT_TIME_RULE = 'maint_time_rule', // ä¿å…»è§„则
  REPAIR_FAULT_TYPE = 'repair_fault_type', // æŠ¥ä¿®çŠ¶æ€
  REPAIR_RECORD_HANDLE = 'repair_record_handle', // ç»´ä¿®è®°å½•操作
  REPAIR_REQ_STATUS = 'repair_req_status', // æŠ¥ä¿®çŠ¶æ€
eims/ruoyi-admin/src/main/resources/application-dev.yml
@@ -13,7 +13,7 @@
--- # snail-job é…ç½®
snail-job:
  enabled: false
  enabled: true
  # éœ€è¦åœ¨ SnailJob åŽå°ç»„管理创建对应名称的组,然后创建任务的时候选择对应的组,才能正确分派任务
  group: "ruoyi_group"
  # SnailJob æŽ¥å…¥éªŒè¯ä»¤ç‰Œ è¯¦è§ script/sql/snail_job.sql `sj_group_config` è¡¨
eims/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/DictConstants.java
@@ -19,6 +19,7 @@
     * æŠ¥ä¿®çŠ¶æ€
     */
    String REPAIR_REQ_STATUS = "repair_req_status";
    interface REPAIR_REQ_STATUS_DETAIL {
        /**
         * å·²æŽ¥å•
@@ -38,6 +39,7 @@
     * ç»´ä¿®å·¥å•状态
     */
    String REPAIR_RES_STATUS = "repair_res_status";
    interface REPAIR_RES_STATUS_DETAIL {
        /**
         * æŽ¥å•
@@ -58,6 +60,7 @@
     * ç»´ä¿®å·¥å•状态
     */
    String REPAIR_RECORD_HANDLE = "repair_record_handle";
    interface REPAIR_RECORD_HANDLE_DETAIL {
        /**
         * æ–°å¢ž
@@ -79,4 +82,63 @@
        String WANCHENG = "4";
    }
    /**
     * ä¿å…»æ—¶é—´è®¡ç®—规则
     */
    String MAINT_TIME_RULE = "maint_time_rule";
    interface MAINT_TIME_RULE_DETAIL {
        /**
         * æŒ‰å›ºå®šå‘¨æœŸ
         */
        String CYCLE = "0";
        /**
         * æŒ‰ä¸Šæ¬¡ä¿å…»æ—¶é—´
         */
        String LAST = "1";
    }
    /**
     * ç³»ç»Ÿæ˜¾ç¤ºéšè—
     */
    String SYS_NORMAL_DISABLE = "sys_normal_disable";
    interface SYS_NORMAL_DISABLE_DETAIL {
        String NORMAL = "0";
        String DISABLE = "1";
    }
    /**
     * ä¿å…»æ—¶é—´å•位
     */
    String MAINT_CYCLE_UNIT = "maint_cycle_unit";
    interface MAINT_CYCLE_UNIT_DETAIL {
        String DAY = "1";
        String WEEK = "2";
        String MONTH = "3";
        String SEASON = "4";
        String YEAR = "5";
    }
    /**
     * ä¿å…»å·¥å•状态
     */
    String MAINT_ORDER_STATUS = "maint_order_status";
    interface MAINT_ORDER_STATUS_DETAIL {
        String BAOYANG = "1";// ä¿å…»ç»„
        String DAIBAOYANG = "0"; // å¾…保养
        String DAIYANZHENG = "2"; // å¾…验证
        String WANCHENG = "3"; // å®Œæˆ
    }
    /**
     * ä¿å…»å·¥å•项完成状态
     */
    String EIMS_ORDITM_STATUS = "eims_orditm_status";
    interface EIMS_ORDITM_STATUS_DETAIL {
        String WEIWANCHENG = "0";// æœªå®Œæˆ
        String YIWANCHENG = "1"; // å·²å®Œæˆ
    }
}
eims/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/MaintOrderService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package org.dromara.common.core.service;
public interface MaintOrderService {
    /**
     * é€šè¿‡ä¿å…»å·¥å•ID查询保养工单code
     *
     * @param orderIds ä¿å…»å·¥å•ID串逗号分隔
     * @return ä¿å…»å·¥å•名称串逗号分隔
     */
    String selectMaintOrderCodeByIds(String orderIds);
}
eims/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java
@@ -129,6 +129,13 @@
    }
    /**
     * è®¡ç®—相差天数
     */
    public static int differentDays(Date date1, Date date2) {
        return  (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24));
    }
    /**
     * è®¡ç®—两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate) {
eims/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java
@@ -60,4 +60,9 @@
     */
    String REPAIR_RES_ID_TO_CODE = "repair_res_id_to_code";
    /**
     * ä¿å…»å·¥å•id转code
     */
    String MAINT_ORDER_ID_TO_CODE = "maint_order_id_to_code";
}
eims/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/MaintOrderCodeTranslationImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package org.dromara.common.translation.core.impl;
import lombok.AllArgsConstructor;
import org.dromara.common.core.service.MaintOrderService;
import org.dromara.common.core.service.RepairResService;
import org.dromara.common.translation.annotation.TranslationType;
import org.dromara.common.translation.constant.TransConstant;
import org.dromara.common.translation.core.TranslationInterface;
/**
 * ä¿å…»å·¥å•id转code
 *
 * @author zhuguifei
 */
@AllArgsConstructor
@TranslationType(type = TransConstant.MAINT_ORDER_ID_TO_CODE)
public class MaintOrderCodeTranslationImpl implements TranslationInterface<String> {
    private final MaintOrderService orderService;
    @Override
    public String translation(Object key, String other) {
        if (key instanceof String ids) {
            return orderService.selectMaintOrderCodeByIds(ids);
        } else if (key instanceof Long id) {
            return orderService.selectMaintOrderCodeByIds(id.toString());
        }
        return null;
    }
}
eims/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -10,3 +10,4 @@
org.dromara.common.translation.core.impl.FixtureNameTranslationImpl
org.dromara.common.translation.core.impl.RepairReqCodeTranslationImpl
org.dromara.common.translation.core.impl.RepairResCodeTranslationImpl
org.dromara.common.translation.core.impl.MaintOrderCodeTranslationImpl
eims/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml
@@ -2,9 +2,9 @@
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    url: jdbc:mysql://localhost:3306/eims?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    username: root
    password: root
    password: 123456
    hikari:
      connection-timeout: 30000
      validation-timeout: 5000
eims/ruoyi-modules/lb-eims/pom.xml
@@ -102,5 +102,10 @@
            <artifactId>ruoyi-system</artifactId>
        </dependency>
        <dependency>
            <groupId>org.dromara</groupId>
            <artifactId>ruoyi-common-job</artifactId>
        </dependency>
    </dependencies>
</project>
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsMaintOrderController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,106 @@
package org.dromara.eims.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.eims.domain.vo.EimsMaintOrderVo;
import org.dromara.eims.domain.bo.EimsMaintOrderBo;
import org.dromara.eims.service.IEimsMaintOrderService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
 * ä¿å…»å·¥å•
 *
 * @author zhuguifei
 * @date 2025-03-06
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/eims/maintOrder")
public class EimsMaintOrderController extends BaseController {
    private final IEimsMaintOrderService eimsMaintOrderService;
    /**
     * æŸ¥è¯¢ä¿å…»å·¥å•列表
     */
    @SaCheckPermission("eims:maintOrder:list")
    @GetMapping("/list")
    public TableDataInfo<EimsMaintOrderVo> list(EimsMaintOrderBo bo, PageQuery pageQuery) {
//        return eimsMaintOrderService.queryPageList(bo, pageQuery);
        return eimsMaintOrderService.queryPageListCustom(bo, pageQuery);
    }
    /**
     * å¯¼å‡ºä¿å…»å·¥å•列表
     */
    @SaCheckPermission("eims:maintOrder:export")
    @Log(title = "保养工单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(EimsMaintOrderBo bo, HttpServletResponse response) {
        List<EimsMaintOrderVo> list = eimsMaintOrderService.queryList(bo);
        ExcelUtil.exportExcel(list, "保养工单", EimsMaintOrderVo.class, response);
    }
    /**
     * èŽ·å–ä¿å…»å·¥å•è¯¦ç»†ä¿¡æ¯
     *
     * @param id ä¸»é”®
     */
    @SaCheckPermission("eims:maintOrder:query")
    @GetMapping("/{id}")
    public R<EimsMaintOrderVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long id) {
        return R.ok(eimsMaintOrderService.queryById(id));
    }
    /**
     * æ–°å¢žä¿å…»å·¥å•
     */
    @SaCheckPermission("eims:maintOrder:add")
    @Log(title = "保养工单", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody EimsMaintOrderBo bo) {
        return toAjax(eimsMaintOrderService.insertByBo(bo));
    }
    /**
     * ä¿®æ”¹ä¿å…»å·¥å•
     */
    @SaCheckPermission("eims:maintOrder:edit")
    @Log(title = "保养工单", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody EimsMaintOrderBo bo) {
        return toAjax(eimsMaintOrderService.updateByBo(bo));
    }
    /**
     * åˆ é™¤ä¿å…»å·¥å•
     *
     * @param ids ä¸»é”®ä¸²
     */
    @SaCheckPermission("eims:maintOrder:remove")
    @Log(title = "保养工单", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(eimsMaintOrderService.deleteWithValidByIds(List.of(ids), true));
    }
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsMaintOrditmController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,105 @@
package org.dromara.eims.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.eims.domain.vo.EimsMaintOrditmVo;
import org.dromara.eims.domain.bo.EimsMaintOrditmBo;
import org.dromara.eims.service.IEimsMaintOrditmService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
 * å·¥å•条目
 *
 * @author zhuguifei
 * @date 2025-03-10
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/eims/maintOrditm")
public class EimsMaintOrditmController extends BaseController {
    private final IEimsMaintOrditmService eimsMaintOrditmService;
    /**
     * æŸ¥è¯¢å·¥å•条目列表
     */
    @SaCheckPermission("eims:maintOrditm:list")
    @GetMapping("/list")
    public TableDataInfo<EimsMaintOrditmVo> list(EimsMaintOrditmBo bo, PageQuery pageQuery) {
        return eimsMaintOrditmService.queryPageList(bo, pageQuery);
    }
    /**
     * å¯¼å‡ºå·¥å•条目列表
     */
    @SaCheckPermission("eims:maintOrditm:export")
    @Log(title = "工单条目", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(EimsMaintOrditmBo bo, HttpServletResponse response) {
        List<EimsMaintOrditmVo> list = eimsMaintOrditmService.queryList(bo);
        ExcelUtil.exportExcel(list, "工单条目", EimsMaintOrditmVo.class, response);
    }
    /**
     * èŽ·å–å·¥å•æ¡ç›®è¯¦ç»†ä¿¡æ¯
     *
     * @param id ä¸»é”®
     */
    @SaCheckPermission("eims:maintOrditm:query")
    @GetMapping("/{id}")
    public R<EimsMaintOrditmVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long id) {
        return R.ok(eimsMaintOrditmService.queryById(id));
    }
    /**
     * æ–°å¢žå·¥å•条目
     */
    @SaCheckPermission("eims:maintOrditm:add")
    @Log(title = "工单条目", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody EimsMaintOrditmBo bo) {
        return toAjax(eimsMaintOrditmService.insertByBo(bo));
    }
    /**
     * ä¿®æ”¹å·¥å•条目
     */
    @SaCheckPermission("eims:maintOrditm:edit")
    @Log(title = "工单条目", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody EimsMaintOrditmBo bo) {
        return toAjax(eimsMaintOrditmService.updateByBo(bo));
    }
    /**
     * åˆ é™¤å·¥å•条目
     *
     * @param ids ä¸»é”®ä¸²
     */
    @SaCheckPermission("eims:maintOrditm:remove")
    @Log(title = "工单条目", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(eimsMaintOrditmService.deleteWithValidByIds(List.of(ids), true));
    }
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsMaintPlanController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,106 @@
package org.dromara.eims.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.eims.domain.vo.EimsMaintPlanVo;
import org.dromara.eims.domain.bo.EimsMaintPlanBo;
import org.dromara.eims.service.IEimsMaintPlanService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
 * ä¿å…»è®¡åˆ’
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/eims/maintPlan")
public class EimsMaintPlanController extends BaseController {
    private final IEimsMaintPlanService eimsMaintPlanService;
    /**
     * æŸ¥è¯¢ä¿å…»è®¡åˆ’列表
     */
    @SaCheckPermission("eims:maintPlan:list")
    @GetMapping("/list")
    public TableDataInfo<EimsMaintPlanVo> list(EimsMaintPlanBo bo, PageQuery pageQuery) {
//        return eimsMaintPlanService.queryPageList(bo, pageQuery);
        return eimsMaintPlanService.queryPageListCustom(bo, pageQuery);
    }
    /**
     * å¯¼å‡ºä¿å…»è®¡åˆ’列表
     */
    @SaCheckPermission("eims:maintPlan:export")
    @Log(title = "保养计划", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(EimsMaintPlanBo bo, HttpServletResponse response) {
        List<EimsMaintPlanVo> list = eimsMaintPlanService.queryList(bo);
        ExcelUtil.exportExcel(list, "保养计划", EimsMaintPlanVo.class, response);
    }
    /**
     * èŽ·å–ä¿å…»è®¡åˆ’è¯¦ç»†ä¿¡æ¯
     *
     * @param id ä¸»é”®
     */
    @SaCheckPermission("eims:maintPlan:query")
    @GetMapping("/{id}")
    public R<EimsMaintPlanVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long id) {
        return R.ok(eimsMaintPlanService.queryById(id));
    }
    /**
     * æ–°å¢žä¿å…»è®¡åˆ’
     */
    @SaCheckPermission("eims:maintPlan:add")
    @Log(title = "保养计划", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody EimsMaintPlanBo bo) {
        return toAjax(eimsMaintPlanService.insertByBo(bo));
    }
    /**
     * ä¿®æ”¹ä¿å…»è®¡åˆ’
     */
    @SaCheckPermission("eims:maintPlan:edit")
    @Log(title = "保养计划", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody EimsMaintPlanBo bo) {
        return toAjax(eimsMaintPlanService.updateByBo(bo));
    }
    /**
     * åˆ é™¤ä¿å…»è®¡åˆ’
     *
     * @param ids ä¸»é”®ä¸²
     */
    @SaCheckPermission("eims:maintPlan:remove")
    @Log(title = "保养计划", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(eimsMaintPlanService.deleteWithValidByIds(List.of(ids), true));
    }
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsMaintStandController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,105 @@
package org.dromara.eims.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.eims.domain.vo.EimsMaintStandVo;
import org.dromara.eims.domain.bo.EimsMaintStandBo;
import org.dromara.eims.service.IEimsMaintStandService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
 * ä¿å…»æ ‡å‡†
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/eims/maintStand")
public class EimsMaintStandController extends BaseController {
    private final IEimsMaintStandService eimsMaintStandService;
    /**
     * æŸ¥è¯¢ä¿å…»æ ‡å‡†åˆ—表
     */
    @SaCheckPermission("eims:maintStand:list")
    @GetMapping("/list")
    public TableDataInfo<EimsMaintStandVo> list(EimsMaintStandBo bo, PageQuery pageQuery) {
        return eimsMaintStandService.queryPageList(bo, pageQuery);
    }
    /**
     * å¯¼å‡ºä¿å…»æ ‡å‡†åˆ—表
     */
    @SaCheckPermission("eims:maintStand:export")
    @Log(title = "保养标准", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(EimsMaintStandBo bo, HttpServletResponse response) {
        List<EimsMaintStandVo> list = eimsMaintStandService.queryList(bo);
        ExcelUtil.exportExcel(list, "保养标准", EimsMaintStandVo.class, response);
    }
    /**
     * èŽ·å–ä¿å…»æ ‡å‡†è¯¦ç»†ä¿¡æ¯
     *
     * @param id ä¸»é”®
     */
    @SaCheckPermission("eims:maintStand:query")
    @GetMapping("/{id}")
    public R<EimsMaintStandVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long id) {
        return R.ok(eimsMaintStandService.queryById(id));
    }
    /**
     * æ–°å¢žä¿å…»æ ‡å‡†
     */
    @SaCheckPermission("eims:maintStand:add")
    @Log(title = "保养标准", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody EimsMaintStandBo bo) {
        return toAjax(eimsMaintStandService.insertByBo(bo));
    }
    /**
     * ä¿®æ”¹ä¿å…»æ ‡å‡†
     */
    @SaCheckPermission("eims:maintStand:edit")
    @Log(title = "保养标准", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody EimsMaintStandBo bo) {
        return toAjax(eimsMaintStandService.updateByBo(bo));
    }
    /**
     * åˆ é™¤ä¿å…»æ ‡å‡†
     *
     * @param ids ä¸»é”®ä¸²
     */
    @SaCheckPermission("eims:maintStand:remove")
    @Log(title = "保养标准", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(eimsMaintStandService.deleteWithValidByIds(List.of(ids), true));
    }
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/GenerateCodeController.java
@@ -5,6 +5,8 @@
import org.dromara.common.core.constant.CacheConstants;
import org.dromara.common.core.domain.R;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.eims.service.IEimsRepairResService;
import org.dromara.eims.service.IGenerateCodeService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -26,6 +28,8 @@
@RestController
@RequestMapping("/eims/generate")
public class GenerateCodeController {
    private final IGenerateCodeService  eimsRepairResService;
    /**
     * æ ¹æ®å‰ç¼€ç”Ÿæˆå„种编码
     *
@@ -35,25 +39,9 @@
    @GetMapping("/{prefix}")
    public R<String> generateCode(@NotNull(message = "类型不能为空")
                                      @PathVariable String prefix) {
        String todayStr = DateTimeFormatter.ofPattern("yyyyMMdd").format(LocalDate.now());
        String key = CacheConstants.EIMS_GENERATE_CODE + ":" + prefix;
        String code;
        // ä½¿ç”¨Redis的原子性操作避免并发问题
        String oldCode = RedisUtils.getCacheObject(key);
        if (oldCode != null && oldCode.contains(todayStr)) {
            int no = Integer.parseInt(oldCode.substring(oldCode.length() - 4));
            code = String.format("%s%s%04d", prefix, todayStr, no + 1);
        } else {
            code = String.format("%s%s%04d", prefix, todayStr, 1);
        }
        // æ›´æ–°ç¼“å­˜
        try {
            RedisUtils.setCacheObject(key, code);
        } catch (Exception e) {
            return R.fail("生成编码失败,请稍后重试!");
        }
        return R.ok("生成成功!", code);
        String code = eimsRepairResService.generateCode(prefix);
        return code == null ? R.fail("生成失败!") :R.ok("生成成功!", code);
    }
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/EimsMaintOrder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,109 @@
package org.dromara.eims.domain;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
 * ä¿å…»å·¥å•对象 eims_maint_order
 *
 * @author zhuguifei
 * @date 2025-03-06
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("eims_maint_order")
public class EimsMaintOrder extends BaseEntity {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @TableId(value = "id")
    private Long id;
    /**
     *
     */
    private Long equId;
    /**
     * è®¡åˆ’表冗余-保养类型(字典)
     */
    private String maintType;
    /**
     * è®¡åˆ’表冗余-保养周期
     */
    private Long maintCycle;
    /**
     * è®¡åˆ’表冗余-保养周期单位(字典)
     */
    private String maintCycleUnit;
    /**
     * è®¡åˆ’表冗余- ä¿å…»è§„则(字典)保养时间计算:1-按周期  2-按上次保养时间
     */
    private String maintRule;
    /**
     * è®¡åˆ’表冗余-保养人
     */
    private Long maintUser;
    /**
     * éªŒè¯äºº
     */
    private Long verifyUser;
    /**
     * è®¡åˆ’表冗余-保养部门
     */
    private Long maintDept;
    /**
     * ä¿å…»å•号
     */
    private String maintCode;
    /**
     *
     */
    private String status;
    /**
     * ä¿å…»è®¡åˆ’æ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date planTime;
    /**
     * ä¿å…»å¼€å§‹æ—¶é—´
     */
    private Date startTime;
    /**
     * ä¿å…»ç»“束时间
     */
    private Date endTime;
    /**
     * è®¡åˆ’id
     */
    private Long planId;
    /**
     * å¤‡æ³¨
     */
    private String remark;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/EimsMaintOrditm.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
package org.dromara.eims.domain;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
 * å·¥å•条目对象 eims_maint_orditm
 *
 * @author zhuguifei
 * @date 2025-03-10
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("eims_maint_orditm")
public class EimsMaintOrditm extends BaseEntity {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @TableId(value = "id")
    private Long id;
    /**
     * å·¥å•id
     */
    private Long orderId;
    /**
     * è®¾å¤‡id
     */
    private Long equId;
    /**
     * ä¿å…»é¡¹ç›®åç§°
     */
    private String itmName;
    /**
     * ä¿å…»é¡¹ç›®æ“ä½œæ ‡å‡†
     */
    private String itmAction;
    /**
     * ä¿å…»æ“ä½œç”¨æˆ·
     */
    private Long itmUser;
    /**
     * ä¿å…»æ—¶é—´
     */
    private Date itmTime;
    /**
     * å®ŒæˆçŠ¶æ€ï¼ˆå­—å…¸ï¼‰
     */
    private String status;
    /**
     * å¤‡æ³¨
     */
    private String remark;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/EimsMaintPlan.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,106 @@
package org.dromara.eims.domain;
import jakarta.validation.constraints.NotNull;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
 * ä¿å…»è®¡åˆ’对象 eims_maint_plan
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("eims_maint_plan")
public class EimsMaintPlan extends BaseEntity {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @TableId(value = "id")
    private Long id;
    /**
     * è®¾å¤‡id
     */
    private Long equId;
    /**
     * ä¿å…»ç±»åž‹ï¼ˆå­—典)
     */
    private String maintType;
    /**
     * ä¿å…»å‘¨æœŸ
     */
    private Long maintCycle;
    /**
     * ä¿å…»å‘¨æœŸå•位(字典)
     */
    private String maintCycleUnit;
    /**
     * ä¿å…»è§„则(字典)保养时间计算:1-按周期  2-按上次保养时间
     */
    private String maintRule;
    /**
     * ä¿å…»äºº
     */
    private Long maintUser;
    /**
     * ä¿å…»éƒ¨é—¨
     */
    private Long maintDept;
    /**
     * çŠ¶æ€ï¼ˆå­—å…¸ï¼‰ 0-启用  1-禁用
     */
    private String status;
    /**
     * é¦–次执行时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date maintFirstTime;
    /**
     * ä¸Šæ¬¡æ‰§è¡Œæ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date maintLastTime;
    /**
     * ä¸‹æ¬¡æ‰§è¡Œæ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date maintNextTime;
    /**
     * å¤‡æ³¨
     */
    private String remark;
    /**
     * ä¸Šæ¬¡ç”Ÿæˆå·¥å•æ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date lastGenerateDate;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/EimsMaintStand.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
package org.dromara.eims.domain;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
 * ä¿å…»æ ‡å‡†å¯¹è±¡ eims_maint_stand
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("eims_maint_stand")
public class EimsMaintStand extends BaseEntity {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @TableId(value = "id")
    private Long id;
    /**
     * è®¾å¤‡id
     */
    private Long equId;
    /**
     * è®¾å¤‡ç¼–码
     */
    private String equCode;
    /**
     * è®¾å¤‡ç±»åž‹
     */
    private Long equTypeId;
    /**
     * èµ„产编号
     */
    private String assetNo;
    /**
     * è®¾å¤‡åç§°
     */
    private String equName;
    /**
     * è®¾å¤‡åž‹å·
     */
    private String modelNo;
    /**
     * ä¿å…»é¡¹ç›®åç§°
     */
    private String name;
    /**
     * ä¿å…»é¡¹ç›®æ ‡å‡†
     */
    private String stand;
    /**
     * å¤‡æ³¨
     */
    private String remark;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsMaintOrderBo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,118 @@
package org.dromara.eims.domain.bo;
import org.dromara.eims.domain.EimsMaintOrder;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
 * ä¿å…»å·¥å•业务对象 eims_maint_order
 *
 * @author zhuguifei
 * @date 2025-03-06
 */
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = EimsMaintOrder.class, reverseConvertGenerate = false)
public class EimsMaintOrderBo extends BaseEntity {
    /**
     *
     */
    @NotNull(message = "id不能为空", groups = { EditGroup.class })
    private Long id;
    /**
     *
     */
    @NotNull(message = "设备id不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long equId;
    /**
     * è®¡åˆ’表冗余-保养类型(字典)
     */
    private String maintType;
    /**
     * è®¡åˆ’表冗余-保养周期
     */
    private Long maintCycle;
    /**
     * è®¡åˆ’表冗余-保养周期单位(字典)
     */
    private String maintCycleUnit;
    /**
     * è®¡åˆ’表冗余- ä¿å…»è§„则(字典)保养时间计算:1-按周期  2-按上次保养时间
     */
    private String maintRule;
    /**
     * è®¡åˆ’表冗余-保养人
     */
    @NotNull(message = "计划表冗余-保养人不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long maintUser;
    /**
     * éªŒè¯äºº
     */
    private Long verifyUser;
    /**
     * è®¡åˆ’表冗余-保养部门
     */
    @NotNull(message = "计划表冗余-保养部门不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long maintDept;
    /**
     * ä¿å…»å•号
     */
    @NotBlank(message = "保养单号不能为空", groups = { AddGroup.class, EditGroup.class })
    private String maintCode;
    /**
     *
     */
    @NotBlank(message = "状态不能为空", groups = { AddGroup.class, EditGroup.class })
    private String status;
    /**
     * ä¿å…»è®¡åˆ’æ—¶é—´
     */
    @NotNull(message = "保养计划时间不能为空", groups = { AddGroup.class, EditGroup.class })
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date planTime;
    /**
     * ä¿å…»å¼€å§‹æ—¶é—´
     */
    private Date startTime;
    /**
     * ä¿å…»ç»“束时间
     */
    private Date endTime;
    /**
     * è®¡åˆ’id
     */
    private Long planId;
    /**
     * å¤‡æ³¨
     */
    private String remark;
    // å…³è”表字段
    private String equName;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsMaintOrditmBo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,76 @@
package org.dromara.eims.domain.bo;
import org.dromara.eims.domain.EimsMaintOrditm;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
 * å·¥å•条目业务对象 eims_maint_orditm
 *
 * @author zhuguifei
 * @date 2025-03-10
 */
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = EimsMaintOrditm.class, reverseConvertGenerate = false)
public class EimsMaintOrditmBo extends BaseEntity {
    /**
     *
     */
    @NotNull(message = "不能为空", groups = { EditGroup.class })
    private Long id;
    /**
     * å·¥å•id
     */
    @NotNull(message = "工单id不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long orderId;
    /**
     * è®¾å¤‡id
     */
    @NotNull(message = "设备id不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long equId;
    /**
     * ä¿å…»é¡¹ç›®åç§°
     */
    @NotBlank(message = "保养项目名称不能为空", groups = { AddGroup.class, EditGroup.class })
    private String itmName;
    /**
     * ä¿å…»é¡¹ç›®æ“ä½œæ ‡å‡†
     */
    private String itmAction;
    /**
     * ä¿å…»æ“ä½œç”¨æˆ·
     */
    @NotNull(message = "保养操作用户不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long itmUser;
    /**
     * ä¿å…»æ—¶é—´
     */
    private Date itmTime;
    /**
     * å®ŒæˆçŠ¶æ€ï¼ˆå­—å…¸ï¼‰
     */
    private String status;
    /**
     * å¤‡æ³¨
     */
    private String remark;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsMaintPlanBo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,115 @@
package org.dromara.eims.domain.bo;
import org.dromara.eims.domain.EimsMaintPlan;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
 * ä¿å…»è®¡åˆ’业务对象 eims_maint_plan
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = EimsMaintPlan.class, reverseConvertGenerate = false)
public class EimsMaintPlanBo extends BaseEntity {
    /**
     *
     */
    @NotNull(message = "不能为空", groups = { EditGroup.class })
    private Long id;
    /**
     * è®¾å¤‡id
     */
    @NotNull(message = "设备id ä¸èƒ½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class })
    private Long equId;
    /**
     * ä¿å…»ç±»åž‹ï¼ˆå­—典)
     */
    @NotBlank(message = "保养类型(字典)不能为空", groups = { AddGroup.class, EditGroup.class })
    private String maintType;
    /**
     * ä¿å…»å‘¨æœŸ
     */
    @NotNull(message = "保养周期不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long maintCycle;
    /**
     * ä¿å…»å‘¨æœŸå•位(字典)
     */
    @NotBlank(message = "保养周期单位(字典)不能为空", groups = { AddGroup.class, EditGroup.class })
    private String maintCycleUnit;
    /**
     * ä¿å…»è§„则(字典)保养时间计算:1-按周期  2-按上次保养时间
     */
    @NotBlank(message = "保养规则(字典)保养时间计算:1-按周期  2-按上次保养时间不能为空", groups = { AddGroup.class, EditGroup.class })
    private String maintRule;
    /**
     * ä¿å…»äºº
     */
    @NotNull(message = "保养人不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long maintUser;
    /**
     * ä¿å…»éƒ¨é—¨
     */
    @NotNull(message = "保养部门不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long maintDept;
    /**
     * çŠ¶æ€ï¼ˆå­—å…¸ï¼‰ 0-启用  1-禁用
     */
    @NotNull(message = "状态(字典) 0-启用  1-禁用不能为空", groups = { AddGroup.class, EditGroup.class })
    private String status;
    /**
     * é¦–次执行时间
     */
    @NotNull(message = "保养计划首次执行时间不能为空", groups = { AddGroup.class, EditGroup.class })
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date maintFirstTime;
    /**
     * ä¸Šæ¬¡æ‰§è¡Œæ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date maintLastTime;
    /**
     * ä¸‹æ¬¡æ‰§è¡Œæ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date maintNextTime;
    /**
     * å¤‡æ³¨
     */
    private String remark;
    /**
     * ä¸Šæ¬¡ç”Ÿæˆå·¥å•æ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date lastGenerateDate;
    // å…³è”表字段
    private String equName;
    private String assetNo;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsMaintStandBo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,78 @@
package org.dromara.eims.domain.bo;
import org.dromara.eims.domain.EimsMaintStand;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
/**
 * ä¿å…»æ ‡å‡†ä¸šåŠ¡å¯¹è±¡ eims_maint_stand
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = EimsMaintStand.class, reverseConvertGenerate = false)
public class EimsMaintStandBo extends BaseEntity {
    /**
     *
     */
    @NotNull(message = "不能为空", groups = { EditGroup.class })
    private Long id;
    /**
     * è®¾å¤‡id
     */
    @NotNull(message = "设备id不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long equId;
    /**
     * è®¾å¤‡ç¼–码
     */
    private String equCode;
    /**
     * è®¾å¤‡ç±»åž‹
     */
    private Long equTypeId;
    /**
     * èµ„产编号
     */
    private String assetNo;
    /**
     * è®¾å¤‡åç§°
     */
    private String equName;
    /**
     * è®¾å¤‡åž‹å·
     */
    private String modelNo;
    /**
     * ä¿å…»é¡¹ç›®åç§°
     */
    private String name;
    /**
     * ä¿å…»é¡¹ç›®æ ‡å‡†
     */
    private String stand;
    /**
     * å¤‡æ³¨
     */
    @NotBlank(message = "备注不能为空", groups = { EditGroup.class })
    private String remark;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsMaintOrderVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,149 @@
package org.dromara.eims.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
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.EimsMaintOrder;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
 * ä¿å…»å·¥å•视图对象 eims_maint_order
 *
 * @author zhuguifei
 * @date 2025-03-06
 */
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = EimsMaintOrder.class)
public class EimsMaintOrderVo extends BaseEntity implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @ExcelProperty(value = "")
    private Long id;
    /**
     *
     */
    @ExcelProperty(value = "")
    private Long equId;
    @Translation(type = TransConstant.EQU_ID_TO_NAME, mapper = "equId")
    private String equName;
    /**
     * è®¾å¤‡èµ„产编号
     */
    private String assetNo;
    /**
     * è®¡åˆ’表冗余-保养类型(字典)
     */
    @ExcelProperty(value = "计划表冗余-保养类型", converter = ExcelDictConvert.class)
    @ExcelDictFormat(readConverterExp = "字=典")
    private String maintType;
    /**
     * è®¡åˆ’表冗余-保养周期
     */
    @ExcelProperty(value = "计划表冗余-保养周期")
    private Long maintCycle;
    /**
     * è®¡åˆ’表冗余-保养周期单位(字典)
     */
    @ExcelProperty(value = "计划表冗余-保养周期单位", converter = ExcelDictConvert.class)
    @ExcelDictFormat(readConverterExp = "字=典")
    private String maintCycleUnit;
    /**
     * è®¡åˆ’表冗余- ä¿å…»è§„则(字典)保养时间计算:1-按周期  2-按上次保养时间
     */
    @ExcelProperty(value = "计划表冗余- ä¿å…»è§„则", converter = ExcelDictConvert.class)
    @ExcelDictFormat(readConverterExp = "字=典")
    private String maintRule;
    /**
     * è®¡åˆ’表冗余-保养人
     */
    @ExcelProperty(value = "计划表冗余-保养人")
    private Long maintUser;
    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "maintUser")
    private String maintUserName;
    /**
     * éªŒè¯äºº
     */
    private Long verifyUser;
    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "verifyUser")
    private String verifyUserName;
    /**
     * è®¡åˆ’表冗余-保养部门
     */
    @ExcelProperty(value = "计划表冗余-保养部门")
    private Long maintDept;
    /**
     * ä¿å…»å•号
     */
    @ExcelProperty(value = "保养单号")
    private String maintCode;
    /**
     *
     */
    @ExcelProperty(value = "")
    private String status;
    /**
     * ä¿å…»è®¡åˆ’æ—¶é—´
     */
    @ExcelProperty(value = "保养计划时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date planTime;
    /**
     * ä¿å…»å¼€å§‹æ—¶é—´
     */
    @ExcelProperty(value = "保养开始时间")
    private Date startTime;
    /**
     * ä¿å…»ç»“束时间
     */
    @ExcelProperty(value = "保养结束时间")
    private Date endTime;
    /**
     * è®¡åˆ’id
     */
    @ExcelProperty(value = "计划id")
    private Long planId;
    /**
     * å¤‡æ³¨
     */
    @ExcelProperty(value = "备注")
    private String remark;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsMaintOrditmVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,100 @@
package org.dromara.eims.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.dromara.common.translation.annotation.Translation;
import org.dromara.common.translation.constant.TransConstant;
import org.dromara.eims.domain.EimsMaintOrditm;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
 * å·¥å•条目视图对象 eims_maint_orditm
 *
 * @author zhuguifei
 * @date 2025-03-10
 */
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = EimsMaintOrditm.class)
public class EimsMaintOrditmVo implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @ExcelProperty(value = "")
    private Long id;
    /**
     * å·¥å•id
     */
    @ExcelProperty(value = "工单id")
    private Long orderId;
    @Translation(type = TransConstant.MAINT_ORDER_ID_TO_CODE, mapper = "orderId")
    private String orderName;
    /**
     * è®¾å¤‡id
     */
    @ExcelProperty(value = "设备id")
    private Long equId;
    @Translation(type = TransConstant.EQU_ID_TO_NAME, mapper = "equId")
    private String equName;
    /**
     * ä¿å…»é¡¹ç›®åç§°
     */
    @ExcelProperty(value = "保养项目名称")
    private String itmName;
    /**
     * ä¿å…»é¡¹ç›®æ“ä½œæ ‡å‡†
     */
    @ExcelProperty(value = "保养项目操作标准")
    private String itmAction;
    /**
     * ä¿å…»æ“ä½œç”¨æˆ·
     */
    @ExcelProperty(value = "保养操作用户")
    private Long itmUser;
    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "itmUser")
    private String itmUserName;
    /**
     * ä¿å…»æ—¶é—´
     */
    @ExcelProperty(value = "保养时间")
    private Date itmTime;
    /**
     * å®ŒæˆçŠ¶æ€ï¼ˆå­—å…¸ï¼‰
     */
    @ExcelProperty(value = "完成状态", converter = ExcelDictConvert.class)
    @ExcelDictFormat(dictType = "eims_orditm_status")
    private String status;
    /**
     * å¤‡æ³¨
     */
    @ExcelProperty(value = "备注")
    private String remark;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsMaintPlanVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,150 @@
package org.dromara.eims.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.NotNull;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.translation.annotation.Translation;
import org.dromara.common.translation.constant.TransConstant;
import org.dromara.eims.domain.EimsMaintPlan;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
 * ä¿å…»è®¡åˆ’视图对象 eims_maint_plan
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = EimsMaintPlan.class)
public class EimsMaintPlanVo implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @ExcelProperty(value = "")
    private Long id;
    /**
     * è®¾å¤‡id
     */
    @ExcelProperty(value = "设备id")
    private Long equId;
    /**
     * è®¾å¤‡åç§°
     */
    @Translation(type = TransConstant.EQU_ID_TO_NAME, mapper = "equId")
    private String equName;
    /**
     * è®¾å¤‡èµ„产编号
     */
    private String assetNo;
    /**
     * ä¿å…»ç±»åž‹ï¼ˆå­—典)
     */
    @ExcelProperty(value = "保养类型", converter = ExcelDictConvert.class)
    @ExcelDictFormat(dictType = "eims_maint_type")
    private String maintType;
    /**
     * ä¿å…»å‘¨æœŸ
     */
    @ExcelProperty(value = "保养周期")
    private Long maintCycle;
    /**
     * ä¿å…»å‘¨æœŸå•位(字典)
     */
    @ExcelProperty(value = "保养周期单位", converter = ExcelDictConvert.class)
    @ExcelDictFormat(dictType = "maint_cycle_unit")
    private String maintCycleUnit;
    /**
     * å­—段拼接 maintCycle + maintCycleUnit的dictLabel
     */
    private String maintCycleUnitName;
    /**
     * ä¿å…»è§„则(字典)保养时间计算:1-按周期  2-按上次保养时间
     */
    @ExcelProperty(value = "保养规则", converter = ExcelDictConvert.class)
    @ExcelDictFormat(dictType = "maint_time_rule")
    private String maintRule;
    /**
     * ä¿å…»äºº
     */
    @ExcelProperty(value = "保养人")
    private Long maintUser;
    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "maintUser")
    private String maintUserName;
    /**
     * ä¿å…»éƒ¨é—¨
     */
    @ExcelProperty(value = "保养部门")
    private Long maintDept;
    private String maintDeptName;
    /**
     * çŠ¶æ€ï¼ˆå­—å…¸ï¼‰ 0-启用  1-禁用
     */
    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
    @ExcelDictFormat(dictType = "sys_normal_disable")
    private String status;
    /**
     * é¦–次执行时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date maintFirstTime;
    /**
     * ä¸Šæ¬¡æ‰§è¡Œæ—¶é—´
     */
    @ExcelProperty(value = "上次执行时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date maintLastTime;
    /**
     * ä¸‹æ¬¡æ‰§è¡Œæ—¶é—´
     */
    @ExcelProperty(value = "下次执行时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date maintNextTime;
    /**
     * å¤‡æ³¨
     */
    @ExcelProperty(value = "备注")
    private String remark;
    /**
     * ä¸Šæ¬¡ç”Ÿæˆå·¥å•æ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date lastGenerateDate;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsMaintStandVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,93 @@
package org.dromara.eims.domain.vo;
import org.dromara.eims.domain.EimsMaintStand;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
 * ä¿å…»æ ‡å‡†è§†å›¾å¯¹è±¡ eims_maint_stand
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = EimsMaintStand.class)
public class EimsMaintStandVo implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @ExcelProperty(value = "")
    private Long id;
    /**
     * è®¾å¤‡id
     */
    @ExcelProperty(value = "设备id")
    private Long equId;
    /**
     * è®¾å¤‡ç¼–码
     */
    @ExcelProperty(value = "设备编码")
    private String equCode;
    /**
     * è®¾å¤‡ç±»åž‹
     */
    @ExcelProperty(value = "设备类型")
    private Long equTypeId;
    /**
     * èµ„产编号
     */
    @ExcelProperty(value = "资产编号")
    private String assetNo;
    /**
     * è®¾å¤‡åç§°
     */
    @ExcelProperty(value = "设备名称")
    private String equName;
    /**
     * è®¾å¤‡åž‹å·
     */
    @ExcelProperty(value = "设备型号")
    private String modelNo;
    /**
     * ä¿å…»é¡¹ç›®åç§°
     */
    @ExcelProperty(value = "保养项目名称")
    private String name;
    /**
     * ä¿å…»é¡¹ç›®æ ‡å‡†
     */
    @ExcelProperty(value = "保养项目标准")
    private String stand;
    /**
     * å¤‡æ³¨
     */
    @ExcelProperty(value = "备注")
    private String remark;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/job/MaintPlanToOrderJob.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,142 @@
package org.dromara.eims.job;
import com.aizuda.snailjob.client.job.core.annotation.JobExecutor;
import com.aizuda.snailjob.client.job.core.dto.JobArgs;
import com.aizuda.snailjob.client.model.ExecuteResult;
import com.aizuda.snailjob.common.core.util.JsonUtil;
import com.aizuda.snailjob.common.log.SnailJobLog;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.dromara.common.core.constant.DictConstants;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.eims.domain.*;
import org.dromara.eims.domain.bo.EimsMaintPlanBo;
import org.dromara.eims.domain.vo.EimsMaintPlanVo;
import org.dromara.eims.domain.vo.EimsMaintStandVo;
import org.dromara.eims.mapper.EimsMaintOrderMapper;
import org.dromara.eims.mapper.EimsMaintOrditmMapper;
import org.dromara.eims.mapper.EimsMaintPlanMapper;
import org.dromara.eims.mapper.EimsMaintStandMapper;
import org.dromara.eims.service.IEimsMaintOrderService;
import org.dromara.eims.service.IEimsMaintPlanService;
import org.dromara.eims.service.IGenerateCodeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
@Component
@RequiredArgsConstructor
@JobExecutor(name = "maintPlanToOrderJob")
public class MaintPlanToOrderJob {
    private final EimsMaintOrderMapper orderMapper;
    private final EimsMaintStandMapper standMapper;
    private final EimsMaintOrditmMapper orditmMapper;
    private final EimsMaintPlanMapper planMapper;
    private final IGenerateCodeService codeService;
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public ExecuteResult jobExecute(JobArgs jobArgs) {
        // èŽ·å–ä»Šå¤©æ—¥æœŸ
        Date today = new Date();
        LambdaQueryWrapper<EimsMaintPlan> planBoQueryWrapper = Wrappers.lambdaQuery();
        // æŸ¥è¯¢å¯ç”¨çš„保养计划
        planBoQueryWrapper.eq(EimsMaintPlan::getStatus, DictConstants.SYS_NORMAL_DISABLE_DETAIL.NORMAL);
        // è¿‡æ»¤æ²¡æœ‰é¦–次运行时间
        planBoQueryWrapper.isNotNull(EimsMaintPlan::getMaintFirstTime);
        // è¿‡æ»¤æ²¡æœ‰ä¸‹æ¬¡è¿è¡Œæ—¶é—´
        planBoQueryWrapper.isNotNull(EimsMaintPlan::getMaintNextTime);
        // è¿‡æ»¤æ²¡æœ‰ä¿å…»å‘¨æœŸçš„æ•°æ®
        planBoQueryWrapper.isNotNull(EimsMaintPlan::getMaintCycle);
        planBoQueryWrapper.isNotNull(EimsMaintPlan::getMaintCycleUnit);
        planBoQueryWrapper.isNotNull(EimsMaintPlan::getMaintRule);
        List<EimsMaintPlanVo> planVoList = planMapper.selectVoList(planBoQueryWrapper);
        for (int i = 0; i < planVoList.size(); i++) {
            EimsMaintPlanVo planVo = planVoList.get(i);
            // ä¿å…»è®¡åˆ’add的时候会自动生成下次运行时间
            Date createOrderTime = planVo.getMaintNextTime();
            int day = DateUtils.differentDays(today,createOrderTime );
            // å¦‚果计划生成工单日期大于今天则不生成工单
            if (day >= 1) {
                continue;
            }
            // è®¡ç®—生成工单时间
            Long maintCycle = planVo.getMaintCycle();
            String maintRule = planVo.getMaintRule();
            Date firstTime = planVo.getMaintFirstTime();
            Date lastTime = planVo.getMaintLastTime();
            Date nextTime = null;
            String maintCycleUnit = planVo.getMaintCycleUnit();
            switch (maintCycleUnit) {
                case DictConstants.MAINT_CYCLE_UNIT_DETAIL.DAY:
                    break;
                case DictConstants.MAINT_CYCLE_UNIT_DETAIL.WEEK:
                    maintCycle *= 7;
                    break;
                case DictConstants.MAINT_CYCLE_UNIT_DETAIL.MONTH:
                    maintCycle *= 30;
                    break;
                case DictConstants.MAINT_CYCLE_UNIT_DETAIL.SEASON:
                    maintCycle *= 90;
                    break;
                case DictConstants.MAINT_CYCLE_UNIT_DETAIL.YEAR:
                    maintCycle *= 365;
                    break;
            }
            // é¦–次
            if (lastTime == null ) {
                nextTime = DateUtils.addDays(createOrderTime, maintCycle.intValue());
            } else {
                nextTime = DateUtils.addDays(lastTime, maintCycle.intValue());
            }
            EimsMaintOrder order = new EimsMaintOrder();
            BeanUtils.copyProperties(planVo, order);
            order.setId(null);
            order.setStatus(DictConstants.MAINT_ORDER_STATUS_DETAIL.DAIBAOYANG);
            order.setPlanTime(createOrderTime);
            order.setMaintCode(codeService.generateCode("BYZD"));
            EimsMaintPlan plan = MapstructUtils.convert(planVo, EimsMaintPlan.class);
            assert plan != null;
            plan.setLastGenerateDate(new Date());
            plan.setMaintLastTime(createOrderTime);
            plan.setMaintNextTime(nextTime);
            boolean flag  = orderMapper.insert(order) > 0;
            //TODO ç”Ÿæˆå¤±è´¥ï¼Œæ·»åŠ å¼‚å¸¸è®°å½•
            if (!flag) continue;
            planMapper.updateById(plan);
            //生成保养明细
            Long equId = plan.getEquId();
            List<EimsMaintStandVo> standList = standMapper.selectVoList(new LambdaQueryWrapper<EimsMaintStand>().eq(EimsMaintStand::getEquId, equId));
            //TODO æ²¡æœ‰ä¿å…»é¡¹ï¼Œæ·»åŠ å¼‚å¸¸è®°å½•
            if(standList.isEmpty()) continue;
            for (int j = 0; j < standList.size(); j++) {
                EimsMaintStandVo stand = standList.get(j);
                EimsMaintOrditm itm = new EimsMaintOrditm();
                itm.setOrderId(order.getId());
                itm.setEquId(equId);
                itm.setItmName(stand.getName());
                itm.setItmAction(stand.getStand());
                itm.setItmUser(order.getMaintUser());
                orditmMapper.insert(itm);
            }
        }
        return ExecuteResult.success("保养计划生成保养工单成功");
    }
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/mapper/EimsMaintOrderMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package org.dromara.eims.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.dromara.eims.domain.EimsMaintOrder;
import org.dromara.eims.domain.EimsMaintPlan;
import org.dromara.eims.domain.vo.EimsMaintOrderVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.eims.domain.vo.EimsMaintPlanVo;
/**
 * ä¿å…»å·¥å•Mapper接口
 *
 * @author zhuguifei
 * @date 2025-03-06
 */
public interface EimsMaintOrderMapper extends BaseMapperPlus<EimsMaintOrder, EimsMaintOrderVo> {
    Page<EimsMaintOrderVo> selectMaintOrderList(@Param("page") Page<EimsMaintOrderVo> page, @Param(Constants.WRAPPER) Wrapper<EimsMaintOrder> queryWrapper);
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/mapper/EimsMaintOrditmMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package org.dromara.eims.mapper;
import org.dromara.eims.domain.EimsMaintOrditm;
import org.dromara.eims.domain.vo.EimsMaintOrditmVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
 * å·¥å•条目Mapper接口
 *
 * @author zhuguifei
 * @date 2025-03-10
 */
public interface EimsMaintOrditmMapper extends BaseMapperPlus<EimsMaintOrditm, EimsMaintOrditmVo> {
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/mapper/EimsMaintPlanMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package org.dromara.eims.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.dromara.eims.domain.EimsMaintPlan;
import org.dromara.eims.domain.EimsRepairReq;
import org.dromara.eims.domain.vo.EimsMaintPlanVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.eims.domain.vo.EimsRepairReqVo;
/**
 * ä¿å…»è®¡åˆ’Mapper接口
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
public interface EimsMaintPlanMapper extends BaseMapperPlus<EimsMaintPlan, EimsMaintPlanVo> {
    Page<EimsMaintPlanVo> selectMaintPlanList(@Param("page") Page<EimsMaintPlanVo> page, @Param(Constants.WRAPPER) Wrapper<EimsMaintPlan> queryWrapper);
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/mapper/EimsMaintStandMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package org.dromara.eims.mapper;
import org.dromara.eims.domain.EimsMaintStand;
import org.dromara.eims.domain.vo.EimsMaintStandVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
 * ä¿å…»æ ‡å‡†Mapper接口
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
public interface EimsMaintStandMapper extends BaseMapperPlus<EimsMaintStand, EimsMaintStandVo> {
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsMaintOrderService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
package org.dromara.eims.service;
import org.dromara.eims.domain.vo.EimsMaintOrderVo;
import org.dromara.eims.domain.bo.EimsMaintOrderBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
 * ä¿å…»å·¥å•Service接口
 *
 * @author zhuguifei
 * @date 2025-03-06
 */
public interface IEimsMaintOrderService {
    /**
     * æŸ¥è¯¢ä¿å…»å·¥å•
     *
     * @param id ä¸»é”®
     * @return ä¿å…»å·¥å•
     */
    EimsMaintOrderVo queryById(Long id);
    /**
     * åˆ†é¡µæŸ¥è¯¢ä¿å…»å·¥å•列表
     *
     * @param bo        æŸ¥è¯¢æ¡ä»¶
     * @param pageQuery åˆ†é¡µå‚æ•°
     * @return ä¿å…»å·¥å•分页列表
     */
    TableDataInfo<EimsMaintOrderVo> queryPageList(EimsMaintOrderBo bo, PageQuery pageQuery);
    /**
     * æŸ¥è¯¢ç¬¦åˆæ¡ä»¶çš„保养工单列表
     *
     * @param bo æŸ¥è¯¢æ¡ä»¶
     * @return ä¿å…»å·¥å•列表
     */
    List<EimsMaintOrderVo> queryList(EimsMaintOrderBo bo);
    /**
     * æ–°å¢žä¿å…»å·¥å•
     *
     * @param bo ä¿å…»å·¥å•
     * @return æ˜¯å¦æ–°å¢žæˆåŠŸ
     */
    Boolean insertByBo(EimsMaintOrderBo bo);
    /**
     * ä¿®æ”¹ä¿å…»å·¥å•
     *
     * @param bo ä¿å…»å·¥å•
     * @return æ˜¯å¦ä¿®æ”¹æˆåŠŸ
     */
    Boolean updateByBo(EimsMaintOrderBo bo);
    /**
     * æ ¡éªŒå¹¶æ‰¹é‡åˆ é™¤ä¿å…»å·¥å•信息
     *
     * @param ids     å¾…删除的主键集合
     * @param isValid æ˜¯å¦è¿›è¡Œæœ‰æ•ˆæ€§æ ¡éªŒ
     * @return æ˜¯å¦åˆ é™¤æˆåŠŸ
     */
    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
    /**
     * åˆ†é¡µæŸ¥è¯¢ä¿å…»å·¥å•列表-多表查询
     *
     * @param bo        æŸ¥è¯¢æ¡ä»¶
     * @param pageQuery åˆ†é¡µå‚æ•°
     * @return ä¿å…»å·¥å•分页列表
     */
    TableDataInfo<EimsMaintOrderVo> queryPageListCustom(EimsMaintOrderBo bo, PageQuery pageQuery);
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsMaintOrditmService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
package org.dromara.eims.service;
import org.dromara.eims.domain.vo.EimsMaintOrditmVo;
import org.dromara.eims.domain.bo.EimsMaintOrditmBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
 * å·¥å•条目Service接口
 *
 * @author zhuguifei
 * @date 2025-03-10
 */
public interface IEimsMaintOrditmService {
    /**
     * æŸ¥è¯¢å·¥å•条目
     *
     * @param id ä¸»é”®
     * @return å·¥å•条目
     */
    EimsMaintOrditmVo queryById(Long id);
    /**
     * åˆ†é¡µæŸ¥è¯¢å·¥å•条目列表
     *
     * @param bo        æŸ¥è¯¢æ¡ä»¶
     * @param pageQuery åˆ†é¡µå‚æ•°
     * @return å·¥å•条目分页列表
     */
    TableDataInfo<EimsMaintOrditmVo> queryPageList(EimsMaintOrditmBo bo, PageQuery pageQuery);
    /**
     * æŸ¥è¯¢ç¬¦åˆæ¡ä»¶çš„工单条目列表
     *
     * @param bo æŸ¥è¯¢æ¡ä»¶
     * @return å·¥å•条目列表
     */
    List<EimsMaintOrditmVo> queryList(EimsMaintOrditmBo bo);
    /**
     * æ–°å¢žå·¥å•条目
     *
     * @param bo å·¥å•条目
     * @return æ˜¯å¦æ–°å¢žæˆåŠŸ
     */
    Boolean insertByBo(EimsMaintOrditmBo bo);
    /**
     * ä¿®æ”¹å·¥å•条目
     *
     * @param bo å·¥å•条目
     * @return æ˜¯å¦ä¿®æ”¹æˆåŠŸ
     */
    Boolean updateByBo(EimsMaintOrditmBo bo);
    /**
     * æ ¡éªŒå¹¶æ‰¹é‡åˆ é™¤å·¥å•条目信息
     *
     * @param ids     å¾…删除的主键集合
     * @param isValid æ˜¯å¦è¿›è¡Œæœ‰æ•ˆæ€§æ ¡éªŒ
     * @return æ˜¯å¦åˆ é™¤æˆåŠŸ
     */
    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsMaintPlanService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
package org.dromara.eims.service;
import org.dromara.eims.domain.vo.EimsMaintPlanVo;
import org.dromara.eims.domain.bo.EimsMaintPlanBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
 * ä¿å…»è®¡åˆ’Service接口
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
public interface IEimsMaintPlanService {
    /**
     * æŸ¥è¯¢ä¿å…»è®¡åˆ’
     *
     * @param id ä¸»é”®
     * @return ä¿å…»è®¡åˆ’
     */
    EimsMaintPlanVo queryById(Long id);
    /**
     * åˆ†é¡µæŸ¥è¯¢ä¿å…»è®¡åˆ’列表
     *
     * @param bo        æŸ¥è¯¢æ¡ä»¶
     * @param pageQuery åˆ†é¡µå‚æ•°
     * @return ä¿å…»è®¡åˆ’分页列表
     */
    TableDataInfo<EimsMaintPlanVo> queryPageList(EimsMaintPlanBo bo, PageQuery pageQuery);
    /**
     * æŸ¥è¯¢ç¬¦åˆæ¡ä»¶çš„保养计划列表
     *
     * @param bo æŸ¥è¯¢æ¡ä»¶
     * @return ä¿å…»è®¡åˆ’列表
     */
    List<EimsMaintPlanVo> queryList(EimsMaintPlanBo bo);
    /**
     * æ–°å¢žä¿å…»è®¡åˆ’
     *
     * @param bo ä¿å…»è®¡åˆ’
     * @return æ˜¯å¦æ–°å¢žæˆåŠŸ
     */
    Boolean insertByBo(EimsMaintPlanBo bo);
    /**
     * ä¿®æ”¹ä¿å…»è®¡åˆ’
     *
     * @param bo ä¿å…»è®¡åˆ’
     * @return æ˜¯å¦ä¿®æ”¹æˆåŠŸ
     */
    Boolean updateByBo(EimsMaintPlanBo bo);
    /**
     * æ ¡éªŒå¹¶æ‰¹é‡åˆ é™¤ä¿å…»è®¡åˆ’信息
     *
     * @param ids     å¾…删除的主键集合
     * @param isValid æ˜¯å¦è¿›è¡Œæœ‰æ•ˆæ€§æ ¡éªŒ
     * @return æ˜¯å¦åˆ é™¤æˆåŠŸ
     */
    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
    /**
     * åˆ†é¡µæŸ¥è¯¢ä¿å…»è®¡åˆ’列表-多表查询
     *
     * @param bo        æŸ¥è¯¢æ¡ä»¶
     * @param pageQuery åˆ†é¡µå‚æ•°
     * @return ä¿å…»è®¡åˆ’分页列表
     */
    TableDataInfo<EimsMaintPlanVo> queryPageListCustom(EimsMaintPlanBo bo, PageQuery pageQuery);
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsMaintStandService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
package org.dromara.eims.service;
import org.dromara.eims.domain.vo.EimsMaintStandVo;
import org.dromara.eims.domain.bo.EimsMaintStandBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
 * ä¿å…»æ ‡å‡†Service接口
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
public interface IEimsMaintStandService {
    /**
     * æŸ¥è¯¢ä¿å…»æ ‡å‡†
     *
     * @param id ä¸»é”®
     * @return ä¿å…»æ ‡å‡†
     */
    EimsMaintStandVo queryById(Long id);
    /**
     * åˆ†é¡µæŸ¥è¯¢ä¿å…»æ ‡å‡†åˆ—表
     *
     * @param bo        æŸ¥è¯¢æ¡ä»¶
     * @param pageQuery åˆ†é¡µå‚æ•°
     * @return ä¿å…»æ ‡å‡†åˆ†é¡µåˆ—表
     */
    TableDataInfo<EimsMaintStandVo> queryPageList(EimsMaintStandBo bo, PageQuery pageQuery);
    /**
     * æŸ¥è¯¢ç¬¦åˆæ¡ä»¶çš„保养标准列表
     *
     * @param bo æŸ¥è¯¢æ¡ä»¶
     * @return ä¿å…»æ ‡å‡†åˆ—表
     */
    List<EimsMaintStandVo> queryList(EimsMaintStandBo bo);
    /**
     * æ–°å¢žä¿å…»æ ‡å‡†
     *
     * @param bo ä¿å…»æ ‡å‡†
     * @return æ˜¯å¦æ–°å¢žæˆåŠŸ
     */
    Boolean insertByBo(EimsMaintStandBo bo);
    /**
     * ä¿®æ”¹ä¿å…»æ ‡å‡†
     *
     * @param bo ä¿å…»æ ‡å‡†
     * @return æ˜¯å¦ä¿®æ”¹æˆåŠŸ
     */
    Boolean updateByBo(EimsMaintStandBo bo);
    /**
     * æ ¡éªŒå¹¶æ‰¹é‡åˆ é™¤ä¿å…»æ ‡å‡†ä¿¡æ¯
     *
     * @param ids     å¾…删除的主键集合
     * @param isValid æ˜¯å¦è¿›è¡Œæœ‰æ•ˆæ€§æ ¡éªŒ
     * @return æ˜¯å¦åˆ é™¤æˆåŠŸ
     */
    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IGenerateCodeService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
package org.dromara.eims.service;
public interface IGenerateCodeService {
   String generateCode(String prefix);
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsMaintOrderServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,253 @@
package org.dromara.eims.service.impl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.SneakyThrows;
import org.dromara.common.core.constant.DictConstants;
import org.dromara.common.core.service.MaintOrderService;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.eims.domain.EimsMaintOrditm;
import org.dromara.eims.domain.EimsMaintStand;
import org.dromara.eims.domain.vo.EimsMaintPlanVo;
import org.dromara.eims.domain.vo.EimsMaintStandVo;
import org.dromara.eims.domain.vo.EimsRepairResVo;
import org.dromara.eims.mapper.EimsMaintOrditmMapper;
import org.dromara.eims.mapper.EimsMaintStandMapper;
import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.mapper.SysDeptMapper;
import org.springframework.stereotype.Service;
import org.dromara.eims.domain.bo.EimsMaintOrderBo;
import org.dromara.eims.domain.vo.EimsMaintOrderVo;
import org.dromara.eims.domain.EimsMaintOrder;
import org.dromara.eims.mapper.EimsMaintOrderMapper;
import org.dromara.eims.service.IEimsMaintOrderService;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
 * ä¿å…»å·¥å•Service业务层处理
 *
 * @author zhuguifei
 * @date 2025-03-06
 */
@RequiredArgsConstructor
@Service
public class EimsMaintOrderServiceImpl implements IEimsMaintOrderService, MaintOrderService {
    private final EimsMaintOrderMapper baseMapper;
    private final EimsMaintOrditmMapper orditmMapper;
    private final SysDeptMapper sysDeptMapper;
    private final EimsMaintStandMapper standMapper;
    /**
     * æŸ¥è¯¢ä¿å…»å·¥å•
     *
     * @param id ä¸»é”®
     * @return ä¿å…»å·¥å•
     */
    @Override
    public EimsMaintOrderVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }
    /**
     * åˆ†é¡µæŸ¥è¯¢ä¿å…»å·¥å•列表
     *
     * @param bo        æŸ¥è¯¢æ¡ä»¶
     * @param pageQuery åˆ†é¡µå‚æ•°
     * @return ä¿å…»å·¥å•分页列表
     */
    @Override
    public TableDataInfo<EimsMaintOrderVo> queryPageList(EimsMaintOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<EimsMaintOrder> lqw = buildQueryWrapper(bo);
        Page<EimsMaintOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }
    @Override
    public TableDataInfo<EimsMaintOrderVo> queryPageListCustom(EimsMaintOrderBo bo, PageQuery pageQuery) {
        Page<EimsMaintOrderVo> page = baseMapper.selectMaintOrderList(pageQuery.build(), buildWrapper(bo));
        return TableDataInfo.build(page);
    }
    /**
     * æŸ¥è¯¢ç¬¦åˆæ¡ä»¶çš„保养工单列表
     *
     * @param bo æŸ¥è¯¢æ¡ä»¶
     * @return ä¿å…»å·¥å•列表
     */
    @Override
    public List<EimsMaintOrderVo> queryList(EimsMaintOrderBo bo) {
        LambdaQueryWrapper<EimsMaintOrder> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }
    private QueryWrapper<EimsMaintOrder> buildWrapper(EimsMaintOrderBo bo) {
        Map<String, Object> params = bo.getParams();
        QueryWrapper<EimsMaintOrder> qw =  Wrappers.query();
        qw.like(StringUtils.isNotBlank(bo.getMaintCode()),"mo.maint_code", bo.getMaintCode());
        qw.like(bo.getEquName() != null, "equ.equ_name", bo.getEquName());
        qw.eq(StringUtils.isNotBlank(bo.getMaintType()), "mo.maint_type", bo.getMaintType());
        qw.eq(StringUtils.isNotBlank(bo.getMaintCycleUnit()), "mo.maint_cycle_unit", bo.getMaintCycleUnit());
        qw.eq(StringUtils.isNotBlank(bo.getMaintRule()), "mo.maint_rule", bo.getMaintRule());
        qw.eq(bo.getMaintUser() != null, "mo.maint_user", bo.getMaintUser());
        qw.in(bo.getMaintDept() != null, "mo.maint_dept", getAllDescendantIds(bo.getMaintDept()));
        qw.eq(bo.getStatus() != null, "mo.status", bo.getStatus());
        qw.orderByDesc("mo.create_time");
        return qw;
    }
    /**
     * æ ¹æ®id,获取所有后代id
     *
     * @param rootId
     * @return
     */
    public List<Long> getAllDescendantIds(Long rootId) {
        List<Long> result = new ArrayList<>();
        result.add(rootId);
        collectDescendants(rootId, result);
        return result;
    }
    private void collectDescendants(Long currentId, List<Long> collector) {
        QueryWrapper<SysDept> sysDeptWrapper = new QueryWrapper<>();
        sysDeptWrapper.lambda().eq(SysDept::getParentId, currentId);
        List<SysDeptVo> children = sysDeptMapper.selectVoList(sysDeptWrapper);
        if (children != null && !children.isEmpty()) {
            for (SysDeptVo child : children) {
                Long childId = child.getDeptId();
                collector.add(childId);
                collectDescendants(childId, collector);
            }
        }
    }
    private LambdaQueryWrapper<EimsMaintOrder> buildQueryWrapper(EimsMaintOrderBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<EimsMaintOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getEquId() != null, EimsMaintOrder::getEquId, bo.getEquId());
        lqw.eq(StringUtils.isNotBlank(bo.getMaintType()), EimsMaintOrder::getMaintType, bo.getMaintType());
        lqw.eq(bo.getMaintCycle() != null, EimsMaintOrder::getMaintCycle, bo.getMaintCycle());
        lqw.eq(StringUtils.isNotBlank(bo.getMaintCycleUnit()), EimsMaintOrder::getMaintCycleUnit, bo.getMaintCycleUnit());
        lqw.eq(StringUtils.isNotBlank(bo.getMaintRule()), EimsMaintOrder::getMaintRule, bo.getMaintRule());
        lqw.eq(bo.getMaintUser() != null, EimsMaintOrder::getMaintUser, bo.getMaintUser());
        lqw.eq(bo.getMaintDept() != null, EimsMaintOrder::getMaintDept, bo.getMaintDept());
        lqw.eq(StringUtils.isNotBlank(bo.getMaintCode()), EimsMaintOrder::getMaintCode, bo.getMaintCode());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), EimsMaintOrder::getStatus, bo.getStatus());
        lqw.eq(bo.getPlanTime() != null, EimsMaintOrder::getPlanTime, bo.getPlanTime());
        lqw.eq(bo.getPlanId() != null, EimsMaintOrder::getPlanId, bo.getPlanId());
        return lqw;
    }
    /**
     * æ–°å¢žä¿å…»å·¥å•
     *
     * @param bo ä¿å…»å·¥å•
     * @return æ˜¯å¦æ–°å¢žæˆåŠŸ
     */
    @Override
    public Boolean insertByBo(EimsMaintOrderBo bo) {
        EimsMaintOrder add = MapstructUtils.convert(bo, EimsMaintOrder.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
            //生成保养明细
            Long equId = bo.getEquId();
            List<EimsMaintStandVo> standList = standMapper.selectVoList(new LambdaQueryWrapper<EimsMaintStand>().eq(EimsMaintStand::getEquId, equId));
            //TODO æ²¡æœ‰ä¿å…»é¡¹ï¼Œæ·»åŠ å¼‚å¸¸è®°å½•
            for (int j = 0; j < standList.size(); j++) {
                EimsMaintStandVo stand = standList.get(j);
                EimsMaintOrditm itm = new EimsMaintOrditm();
                itm.setOrderId(bo.getId());
                itm.setEquId(equId);
                itm.setItmName(stand.getName());
                itm.setItmAction(stand.getStand());
                itm.setItmUser(bo.getMaintUser());
                orditmMapper.insert(itm);
            }
        }
        return flag;
    }
    /**
     * ä¿®æ”¹ä¿å…»å·¥å•
     *
     * @param bo ä¿å…»å·¥å•
     * @return æ˜¯å¦ä¿®æ”¹æˆåŠŸ
     */
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateByBo(EimsMaintOrderBo bo) {
        EimsMaintOrder update = MapstructUtils.convert(bo, EimsMaintOrder.class);
        EimsMaintOrder old = baseMapper.selectById(bo.getId());
        // ä¿å…»çŠ¶æ€å˜æ›´å¾…å®¡æ ¸æ—¶éœ€è¦æ ¡éªŒä¿å…»é¡¹æ•°æ®
        if(old.getStatus().equals(DictConstants.MAINT_ORDER_STATUS_DETAIL.BAOYANG)&&bo.getStatus().equals(DictConstants.MAINT_ORDER_STATUS_DETAIL.DAIYANZHENG)){
            LambdaQueryWrapper<EimsMaintOrditm>  itmQueryWrapper = Wrappers.lambdaQuery();
            itmQueryWrapper.eq(EimsMaintOrditm::getOrderId, bo.getId());
            List<EimsMaintOrditm> eimsMaintOrditms = orditmMapper.selectList(itmQueryWrapper);
            List<EimsMaintOrditm> wwc = eimsMaintOrditms.stream().filter(item->!item.getStatus().equals(DictConstants.EIMS_ORDITM_STATUS_DETAIL.YIWANCHENG)).toList();
             if(!wwc.isEmpty()){
                return false;
             }
        }
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }
    /**
     * ä¿å­˜å‰çš„æ•°æ®æ ¡éªŒ
     */
    private void validEntityBeforeSave(EimsMaintOrder entity){
        //TODO åšä¸€äº›æ•°æ®æ ¡éªŒ,如唯一约束
    }
    /**
     * æ ¡éªŒå¹¶æ‰¹é‡åˆ é™¤ä¿å…»å·¥å•信息
     *
     * @param ids     å¾…删除的主键集合
     * @param isValid æ˜¯å¦è¿›è¡Œæœ‰æ•ˆæ€§æ ¡éªŒ
     * @return æ˜¯å¦åˆ é™¤æˆåŠŸ
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO åšä¸€äº›ä¸šåŠ¡ä¸Šçš„æ ¡éªŒ,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
    @Override
    public String selectMaintOrderCodeByIds(String orderIds) {
        List<String> list = new ArrayList<>();
        for (Long id : StringUtils.splitTo(orderIds, Convert::toLong)) {
            EimsMaintOrderVo vo = SpringUtils.getAopProxy(this).queryById(id);
            if (ObjectUtil.isNotNull(vo)) {
                list.add(vo.getMaintCode());
            }
        }
        return String.join(StringUtils.SEPARATOR, list);
    }
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsMaintOrditmServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,170 @@
package org.dromara.eims.service.impl;
import org.dromara.common.core.constant.DictConstants;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.eims.domain.EimsMaintOrder;
import org.dromara.eims.mapper.EimsMaintOrderMapper;
import org.springframework.stereotype.Service;
import org.dromara.eims.domain.bo.EimsMaintOrditmBo;
import org.dromara.eims.domain.vo.EimsMaintOrditmVo;
import org.dromara.eims.domain.EimsMaintOrditm;
import org.dromara.eims.mapper.EimsMaintOrditmMapper;
import org.dromara.eims.service.IEimsMaintOrditmService;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
 * å·¥å•条目Service业务层处理
 *
 * @author zhuguifei
 * @date 2025-03-10
 */
@RequiredArgsConstructor
@Service
public class EimsMaintOrditmServiceImpl implements IEimsMaintOrditmService {
    private final EimsMaintOrditmMapper baseMapper;
    private final EimsMaintOrderMapper orderMapper;
    /**
     * æŸ¥è¯¢å·¥å•条目
     *
     * @param id ä¸»é”®
     * @return å·¥å•条目
     */
    @Override
    public EimsMaintOrditmVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }
    /**
     * åˆ†é¡µæŸ¥è¯¢å·¥å•条目列表
     *
     * @param bo        æŸ¥è¯¢æ¡ä»¶
     * @param pageQuery åˆ†é¡µå‚æ•°
     * @return å·¥å•条目分页列表
     */
    @Override
    public TableDataInfo<EimsMaintOrditmVo> queryPageList(EimsMaintOrditmBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<EimsMaintOrditm> lqw = buildQueryWrapper(bo);
        Page<EimsMaintOrditmVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }
    /**
     * æŸ¥è¯¢ç¬¦åˆæ¡ä»¶çš„工单条目列表
     *
     * @param bo æŸ¥è¯¢æ¡ä»¶
     * @return å·¥å•条目列表
     */
    @Override
    public List<EimsMaintOrditmVo> queryList(EimsMaintOrditmBo bo) {
        LambdaQueryWrapper<EimsMaintOrditm> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }
    private LambdaQueryWrapper<EimsMaintOrditm> buildQueryWrapper(EimsMaintOrditmBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<EimsMaintOrditm> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getOrderId() != null, EimsMaintOrditm::getOrderId, bo.getOrderId());
        lqw.eq(bo.getEquId() != null, EimsMaintOrditm::getEquId, bo.getEquId());
        lqw.like(StringUtils.isNotBlank(bo.getItmName()), EimsMaintOrditm::getItmName, bo.getItmName());
        lqw.eq(StringUtils.isNotBlank(bo.getItmAction()), EimsMaintOrditm::getItmAction, bo.getItmAction());
        lqw.eq(bo.getItmUser() != null, EimsMaintOrditm::getItmUser, bo.getItmUser());
        lqw.eq(bo.getItmTime() != null, EimsMaintOrditm::getItmTime, bo.getItmTime());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), EimsMaintOrditm::getStatus, bo.getStatus());
        return lqw;
    }
    /**
     * æ–°å¢žå·¥å•条目
     *
     * @param bo å·¥å•条目
     * @return æ˜¯å¦æ–°å¢žæˆåŠŸ
     */
    @Override
    public Boolean insertByBo(EimsMaintOrditmBo bo) {
        EimsMaintOrditm add = MapstructUtils.convert(bo, EimsMaintOrditm.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }
    /**
     * ä¿®æ”¹å·¥å•条目
     *
     * @param bo å·¥å•条目
     * @return æ˜¯å¦ä¿®æ”¹æˆåŠŸ
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateByBo(EimsMaintOrditmBo bo) {
        EimsMaintOrditm update = MapstructUtils.convert(bo, EimsMaintOrditm.class);
        // å®Œæˆå·¥å•明细同步修改工单状态
        //1.第一次完成保养工单明细把保养工单状态修改为 ä¿å…»ä¸­
        Long orderId = bo.getOrderId();
        EimsMaintOrder order = orderMapper.selectById(orderId);
        if(bo.getStatus().equals(DictConstants.EIMS_ORDITM_STATUS_DETAIL.YIWANCHENG)){
            //没有完成时间自动添加完成时间
            if(bo.getItmTime()==null){
                update.setItmTime(new Date());
            }
            if(order.getStatus().equals(DictConstants.MAINT_ORDER_STATUS_DETAIL.DAIBAOYANG)){
                order.setStatus(DictConstants.MAINT_ORDER_STATUS_DETAIL.BAOYANG);
                if(order.getStartTime()==null){
                    order.setStartTime(new Date());
                }
                orderMapper.updateById(order);
            }
        }
        validEntityBeforeSave(update);
        boolean flag = baseMapper.updateById(update) > 0;
        //2.查询所有保养项是否都已完成
        LambdaQueryWrapper<EimsMaintOrditm> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(EimsMaintOrditm::getOrderId, bo.getOrderId());
        List<EimsMaintOrditm> eimsMaintOrditms = baseMapper.selectList(queryWrapper);
        List<EimsMaintOrditm> wwc = eimsMaintOrditms.stream().filter(item->!item.getStatus().equals(DictConstants.EIMS_ORDITM_STATUS_DETAIL.YIWANCHENG)).toList();
        if(wwc.isEmpty()){
            order.setStatus(DictConstants.MAINT_ORDER_STATUS_DETAIL.DAIYANZHENG);
            orderMapper.updateById(order);
        }
        return flag;
    }
    /**
     * ä¿å­˜å‰çš„æ•°æ®æ ¡éªŒ
     */
    private void validEntityBeforeSave(EimsMaintOrditm entity){
        //TODO åšä¸€äº›æ•°æ®æ ¡éªŒ,如唯一约束
    }
    /**
     * æ ¡éªŒå¹¶æ‰¹é‡åˆ é™¤å·¥å•条目信息
     *
     * @param ids     å¾…删除的主键集合
     * @param isValid æ˜¯å¦è¿›è¡Œæœ‰æ•ˆæ€§æ ¡éªŒ
     * @return æ˜¯å¦åˆ é™¤æˆåŠŸ
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO åšä¸€äº›ä¸šåŠ¡ä¸Šçš„æ ¡éªŒ,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsMaintPlanServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,235 @@
package org.dromara.eims.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.SneakyThrows;
import org.dromara.common.core.constant.DictConstants;
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;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.system.domain.SysDept;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.mapper.SysDeptMapper;
import org.springframework.stereotype.Service;
import org.dromara.eims.domain.bo.EimsMaintPlanBo;
import org.dromara.eims.domain.vo.EimsMaintPlanVo;
import org.dromara.eims.domain.EimsMaintPlan;
import org.dromara.eims.mapper.EimsMaintPlanMapper;
import org.dromara.eims.service.IEimsMaintPlanService;
import java.util.*;
/**
 * ä¿å…»è®¡åˆ’Service业务层处理
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
@RequiredArgsConstructor
@Service
public class EimsMaintPlanServiceImpl implements IEimsMaintPlanService {
    private final EimsMaintPlanMapper baseMapper;
    private final SysDeptMapper sysDeptMapper;
    /**
     * æŸ¥è¯¢ä¿å…»è®¡åˆ’
     *
     * @param id ä¸»é”®
     * @return ä¿å…»è®¡åˆ’
     */
    @Override
    public EimsMaintPlanVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }
    /**
     * åˆ†é¡µæŸ¥è¯¢ä¿å…»è®¡åˆ’列表
     *
     * @param bo        æŸ¥è¯¢æ¡ä»¶
     * @param pageQuery åˆ†é¡µå‚æ•°
     * @return ä¿å…»è®¡åˆ’分页列表
     */
    @Override
    public TableDataInfo<EimsMaintPlanVo> queryPageList(EimsMaintPlanBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<EimsMaintPlan> lqw = buildQueryWrapper(bo);
        Page<EimsMaintPlanVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }
    @Override
    public TableDataInfo<EimsMaintPlanVo> queryPageListCustom(EimsMaintPlanBo bo, PageQuery pageQuery) {
        Page<EimsMaintPlanVo> page = baseMapper.selectMaintPlanList(pageQuery.build(), buildWrapper(bo));
        return TableDataInfo.build(page);
    }
    /**
     * æŸ¥è¯¢ç¬¦åˆæ¡ä»¶çš„保养计划列表
     *
     * @param bo æŸ¥è¯¢æ¡ä»¶
     * @return ä¿å…»è®¡åˆ’列表
     */
    @Override
    public List<EimsMaintPlanVo> queryList(EimsMaintPlanBo bo) {
        LambdaQueryWrapper<EimsMaintPlan> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }
    private LambdaQueryWrapper<EimsMaintPlan> buildQueryWrapper(EimsMaintPlanBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<EimsMaintPlan> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getEquId() != null, EimsMaintPlan::getEquId, bo.getEquId());
        lqw.eq(StringUtils.isNotBlank(bo.getMaintType()), EimsMaintPlan::getMaintType, bo.getMaintType());
        lqw.eq(StringUtils.isNotBlank(bo.getMaintCycleUnit()), EimsMaintPlan::getMaintCycleUnit, bo.getMaintCycleUnit());
        lqw.eq(StringUtils.isNotBlank(bo.getMaintRule()), EimsMaintPlan::getMaintRule, bo.getMaintRule());
        lqw.eq(bo.getMaintUser() != null, EimsMaintPlan::getMaintUser, bo.getMaintUser());
        lqw.eq(bo.getMaintDept() != null, EimsMaintPlan::getMaintDept, bo.getMaintDept());
        lqw.eq(bo.getStatus() != null, EimsMaintPlan::getStatus, bo.getStatus());
        return lqw;
    }
    private QueryWrapper<EimsMaintPlan> buildWrapper(EimsMaintPlanBo bo) {
        Map<String, Object> params = bo.getParams();
        QueryWrapper<EimsMaintPlan> qw = Wrappers.query();
        qw.eq(bo.getEquId() != null, "mp.equ_id", bo.getEquId());
        qw.like(bo.getEquName() != null, "equ.equ_name", bo.getEquName());
        qw.like(bo.getAssetNo() != null, "equ.asset_no", bo.getAssetNo());
        qw.eq(StringUtils.isNotBlank(bo.getMaintType()), "mp.maint_type", bo.getMaintType());
        qw.eq(StringUtils.isNotBlank(bo.getMaintCycleUnit()), "mp.maint_cycle_unit", bo.getMaintCycleUnit());
        qw.eq(StringUtils.isNotBlank(bo.getMaintRule()), "mp.maint_rule", bo.getMaintRule());
        qw.eq(bo.getMaintUser() != null, "mp.maint_user", bo.getMaintUser());
        qw.in(bo.getMaintDept() != null, "mp.maint_dept", getAllDescendantIds(bo.getMaintDept()));
        qw.eq(bo.getStatus() != null, "mp.status", bo.getStatus());
        return qw;
    }
    /**
     * æ ¹æ®id,获取所有后代id
     *
     * @param rootId
     * @return
     */
    public List<Long> getAllDescendantIds(Long rootId) {
        List<Long> result = new ArrayList<>();
        result.add(rootId);
        collectDescendants(rootId, result);
        return result;
    }
    private void collectDescendants(Long currentId, List<Long> collector) {
        QueryWrapper<SysDept> sysDeptWrapper = new QueryWrapper<>();
        sysDeptWrapper.lambda().eq(SysDept::getParentId, currentId);
        List<SysDeptVo> children = sysDeptMapper.selectVoList(sysDeptWrapper);
        if (children != null && !children.isEmpty()) {
            for (SysDeptVo child : children) {
                Long childId = child.getDeptId();
                collector.add(childId);
                collectDescendants(childId, collector);
            }
        }
    }
    /**
     * æ–°å¢žä¿å…»è®¡åˆ’
     *
     * @param bo ä¿å…»è®¡åˆ’
     * @return æ˜¯å¦æ–°å¢žæˆåŠŸ
     */
    @Override
    public Boolean insertByBo(EimsMaintPlanBo bo) {
        setMaintNextTime(bo);
        EimsMaintPlan add = MapstructUtils.convert(bo, EimsMaintPlan.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }
    /**
     * è®¡ç®—保养计划下次执行时间
     */
    @SneakyThrows
    private void setMaintNextTime(EimsMaintPlanBo bo) {
        Date maintFirstTime = bo.getMaintFirstTime();
        Date maintLastTime = bo.getMaintLastTime();
        //下次保养时间计算规则 0-按固定周期  1-按上次保养时间
        Date nextDate = (maintLastTime != null && bo.getMaintRule().equals(DictConstants.MAINT_TIME_RULE_DETAIL.LAST)) ? maintLastTime :maintFirstTime;
        //首次执行时间为空抛出异常
        if (maintFirstTime == null) {
            throw new Exception("首次执行时间不能为空!");
        }
        //周期
        Long maintCycle = bo.getMaintCycle();
        //单位 1-天 2-周 3-月 4-å­£ 5-å¹´
        String maintCycleUnit = bo.getMaintCycleUnit();
        switch (maintCycleUnit) {
            case "1":
                nextDate = DateUtils.addDays(nextDate, maintCycle.intValue());
                break;
            case "2":
                nextDate = DateUtils.addWeeks(nextDate, maintCycle.intValue());
                break;
            case "3":
                nextDate = DateUtils.addMonths(nextDate, maintCycle.intValue());
                break;
            case "4":
                nextDate = DateUtils.addMonths(nextDate, maintCycle.intValue() * 3);
                break;
            case "5":
                nextDate = DateUtils.addYears(nextDate, maintCycle.intValue());
                break;
        }
        bo.setMaintNextTime(nextDate);
    }
    /**
     * ä¿®æ”¹ä¿å…»è®¡åˆ’
     *
     * @param bo ä¿å…»è®¡åˆ’
     * @return æ˜¯å¦ä¿®æ”¹æˆåŠŸ
     */
    @Override
    public Boolean updateByBo(EimsMaintPlanBo bo) {
        //setMaintNextTime(bo);
        EimsMaintPlan update = MapstructUtils.convert(bo, EimsMaintPlan.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }
    /**
     * ä¿å­˜å‰çš„æ•°æ®æ ¡éªŒ
     */
    private void validEntityBeforeSave(EimsMaintPlan entity) {
        //TODO åšä¸€äº›æ•°æ®æ ¡éªŒ,如唯一约束
    }
    /**
     * æ ¡éªŒå¹¶æ‰¹é‡åˆ é™¤ä¿å…»è®¡åˆ’信息
     *
     * @param ids     å¾…删除的主键集合
     * @param isValid æ˜¯å¦è¿›è¡Œæœ‰æ•ˆæ€§æ ¡éªŒ
     * @return æ˜¯å¦åˆ é™¤æˆåŠŸ
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO åšä¸€äº›ä¸šåŠ¡ä¸Šçš„æ ¡éªŒ,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsMaintStandServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,135 @@
package org.dromara.eims.service.impl;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.dromara.eims.domain.bo.EimsMaintStandBo;
import org.dromara.eims.domain.vo.EimsMaintStandVo;
import org.dromara.eims.domain.EimsMaintStand;
import org.dromara.eims.mapper.EimsMaintStandMapper;
import org.dromara.eims.service.IEimsMaintStandService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
 * ä¿å…»æ ‡å‡†Service业务层处理
 *
 * @author zhuguifei
 * @date 2025-03-04
 */
@RequiredArgsConstructor
@Service
public class EimsMaintStandServiceImpl implements IEimsMaintStandService {
    private final EimsMaintStandMapper baseMapper;
    /**
     * æŸ¥è¯¢ä¿å…»æ ‡å‡†
     *
     * @param id ä¸»é”®
     * @return ä¿å…»æ ‡å‡†
     */
    @Override
    public EimsMaintStandVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }
    /**
     * åˆ†é¡µæŸ¥è¯¢ä¿å…»æ ‡å‡†åˆ—表
     *
     * @param bo        æŸ¥è¯¢æ¡ä»¶
     * @param pageQuery åˆ†é¡µå‚æ•°
     * @return ä¿å…»æ ‡å‡†åˆ†é¡µåˆ—表
     */
    @Override
    public TableDataInfo<EimsMaintStandVo> queryPageList(EimsMaintStandBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<EimsMaintStand> lqw = buildQueryWrapper(bo);
        Page<EimsMaintStandVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }
    /**
     * æŸ¥è¯¢ç¬¦åˆæ¡ä»¶çš„保养标准列表
     *
     * @param bo æŸ¥è¯¢æ¡ä»¶
     * @return ä¿å…»æ ‡å‡†åˆ—表
     */
    @Override
    public List<EimsMaintStandVo> queryList(EimsMaintStandBo bo) {
        LambdaQueryWrapper<EimsMaintStand> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }
    private LambdaQueryWrapper<EimsMaintStand> buildQueryWrapper(EimsMaintStandBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<EimsMaintStand> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getEquId() != null, EimsMaintStand::getEquId, bo.getEquId());
        lqw.eq(bo.getEquTypeId() != null, EimsMaintStand::getEquTypeId, bo.getEquTypeId());
        lqw.like(StringUtils.isNotBlank(bo.getAssetNo()), EimsMaintStand::getAssetNo, bo.getAssetNo());
        lqw.like(StringUtils.isNotBlank(bo.getEquName()), EimsMaintStand::getEquName, bo.getEquName());
        lqw.like(StringUtils.isNotBlank(bo.getModelNo()), EimsMaintStand::getModelNo, bo.getModelNo());
        lqw.like(StringUtils.isNotBlank(bo.getName()), EimsMaintStand::getName, bo.getName());
        lqw.like(StringUtils.isNotBlank(bo.getStand()), EimsMaintStand::getStand, bo.getStand());
        return lqw;
    }
    /**
     * æ–°å¢žä¿å…»æ ‡å‡†
     *
     * @param bo ä¿å…»æ ‡å‡†
     * @return æ˜¯å¦æ–°å¢žæˆåŠŸ
     */
    @Override
    public Boolean insertByBo(EimsMaintStandBo bo) {
        EimsMaintStand add = MapstructUtils.convert(bo, EimsMaintStand.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }
    /**
     * ä¿®æ”¹ä¿å…»æ ‡å‡†
     *
     * @param bo ä¿å…»æ ‡å‡†
     * @return æ˜¯å¦ä¿®æ”¹æˆåŠŸ
     */
    @Override
    public Boolean updateByBo(EimsMaintStandBo bo) {
        EimsMaintStand update = MapstructUtils.convert(bo, EimsMaintStand.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }
    /**
     * ä¿å­˜å‰çš„æ•°æ®æ ¡éªŒ
     */
    private void validEntityBeforeSave(EimsMaintStand entity){
        //TODO åšä¸€äº›æ•°æ®æ ¡éªŒ,如唯一约束
    }
    /**
     * æ ¡éªŒå¹¶æ‰¹é‡åˆ é™¤ä¿å…»æ ‡å‡†ä¿¡æ¯
     *
     * @param ids     å¾…删除的主键集合
     * @param isValid æ˜¯å¦è¿›è¡Œæœ‰æ•ˆæ€§æ ¡éªŒ
     * @return æ˜¯å¦åˆ é™¤æˆåŠŸ
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO åšä¸€äº›ä¸šåŠ¡ä¸Šçš„æ ¡éªŒ,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/GenerateCodeServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
package org.dromara.eims.service.impl;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.CacheConstants;
import org.dromara.common.core.domain.R;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.eims.service.IGenerateCodeService;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
@RequiredArgsConstructor
@Service
public class GenerateCodeServiceImpl implements IGenerateCodeService {
    @Override
    public String generateCode(String prefix) {
        String key = CacheConstants.EIMS_GENERATE_CODE + ":" + prefix;
        String todayStr = DateTimeFormatter.ofPattern("yyyyMMdd").format(LocalDate.now());
        String code;
        // ä½¿ç”¨Redis的原子性操作避免并发问题
        String oldCode = RedisUtils.getCacheObject(key);
        if (oldCode != null && oldCode.contains(todayStr)) {
            int no = Integer.parseInt(oldCode.substring(oldCode.length() - 4));
            code = String.format("%s%s%04d", prefix, todayStr, no + 1);
        } else {
            code = String.format("%s%s%04d", prefix, todayStr, 1);
        }
        // æ›´æ–°ç¼“å­˜
        try {
            RedisUtils.setCacheObject(key, code);
            return code;
        } catch (Exception e) {
            return null;
        }
    }
}
eims/ruoyi-modules/lb-eims/src/main/resources/mapper/eims/EimsMaintOrderMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.eims.mapper.EimsMaintOrderMapper">
    <resultMap type="org.dromara.eims.domain.vo.EimsMaintOrderVo" id="EimsMaintOrderResult">
    </resultMap>
    <select id="selectMaintOrderList" resultMap="EimsMaintOrderResult">
        SELECT mo.*,equ.equ_name equName,equ.equ_code equCode,equ.asset_no assetNo,equ.model_no modelNo,mo.create_time createTime,
               us.nick_name maintUserName,dp.dept_name maintDeptName,ue.nick_name verifyUserName,
               CONCAT_WS('', mo.maint_cycle, dd.dict_label) maintCycleUnitName
        FROM eims_maint_order mo
                 LEFT JOIN eims_equ equ ON mo.equ_id = equ.equ_id
                 LEFT JOIN sys_user us ON mo.maint_user = us.user_id
                 LEFT JOIN sys_user ue ON mo.verify_user = ue.user_id
                 LEFT JOIN sys_dept dp ON mo.maint_dept = dp.dept_id
                 LEFT JOIN sys_dict_data dd on dd.dict_type = 'maint_cycle_unit' and dd.dict_value = mo.maint_cycle_unit
            ${ew.getCustomSqlSegment}
    </select>
</mapper>
eims/ruoyi-modules/lb-eims/src/main/resources/mapper/eims/EimsMaintOrditmMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.eims.mapper.EimsMaintOrditmMapper">
</mapper>
eims/ruoyi-modules/lb-eims/src/main/resources/mapper/eims/EimsMaintPlanMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.eims.mapper.EimsMaintPlanMapper">
    <resultMap type="org.dromara.eims.domain.vo.EimsMaintPlanVo" id="EimsMaintPlanResult">
    </resultMap>
    <select id="selectMaintPlanList" resultMap="EimsMaintPlanResult">
        SELECT mp.*,equ.equ_name equName,equ.equ_code equCode,equ.asset_no assetNo,equ.model_no modelNo,
               us.nick_name maintUserName,dp.dept_name maintDeptName,
               CONCAT_WS('', mp.maint_cycle, dd.dict_label) maintCycleUnitName
        FROM eims_maint_plan mp
                 LEFT JOIN eims_equ equ ON mp.equ_id = equ.equ_id
                 LEFT JOIN sys_user us ON mp.maint_user = us.user_id
                 LEFT JOIN sys_dept dp ON mp.maint_dept = dp.dept_id
                 LEFT JOIN sys_dict_data dd on dd.dict_type = 'maint_cycle_unit' and dd.dict_value = mp.maint_cycle_unit
            ${ew.getCustomSqlSegment}
    </select>
</mapper>
eims/ruoyi-modules/lb-eims/src/main/resources/mapper/eims/EimsMaintStandMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.eims.mapper.EimsMaintStandMapper">
</mapper>