From 2496d0534972089fe4b49242ce2e4ecfa203680f Mon Sep 17 00:00:00 2001 From: jiangxh <1217934998@qq.com> Date: Thu, 21 May 2026 17:54:57 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E7=82=B9=E6=A3=80=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=96=B0=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...l-equip-inspect-record-menu-permission.sql | 138 ++++++ .../MesXslEquipInspectRecordController.java | 411 ++++++++++++++++++ .../entity/MesXslEquipInspectRecord.java | 126 ++++++ .../entity/MesXslEquipInspectRecordLine.java | 82 ++++ .../MesXslEquipInspectRecordLineMapper.java | 6 + .../MesXslEquipInspectRecordMapper.java | 6 + .../IMesXslEquipInspectRecordService.java | 34 ++ .../MesXslEquipInspectRecordServiceImpl.java | 312 +++++++++++++ .../xslmes/util/MesXslEquipInspectBizMsg.java | 27 ++ ...esXslEquipInspectRecordBatchCreateDTO.java | 19 + ...slEquipInspectRecordBatchCreateResult.java | 20 + .../vo/MesXslEquipInspectRecordHandleDTO.java | 32 ++ .../vo/MesXslEquipInspectRecordPage.java | 12 + .../jeecg-system-biz/docs/代码修改日志 | 56 +++ ...3.9.2_79__mes_xsl_equip_inspect_record.sql | 133 ++++++ ...0__mes_xsl_equip_inspect_record_handle.sql | 9 + jeecgboot-vue3/src/api/common/api.ts | 9 +- jeecgboot-vue3/src/utils/common/compUtils.ts | 10 +- jeecgboot-vue3/src/utils/env/apiBaseUrl.ts | 18 + .../MesXslEquipInspectRecord.api.ts | 65 +++ .../MesXslEquipInspectRecord.data.ts | 222 ++++++++++ .../MesXslEquipInspectRecordList.vue | 153 +++++++ .../MesXslEquipInspectRecordHandleModal.vue | 63 +++ .../MesXslEquipInspectRecordModal.vue | 173 ++++++++ .../MesXslEquipmentLedgerList.vue | 64 ++- 25 files changed, 2188 insertions(+), 12 deletions(-) create mode 100644 jeecg-boot/db/mes-xsl-equip-inspect-record-menu-permission.sql create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslEquipInspectRecordController.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslEquipInspectRecord.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslEquipInspectRecordLine.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslEquipInspectRecordLineMapper.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslEquipInspectRecordMapper.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslEquipInspectRecordService.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslEquipInspectRecordServiceImpl.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/util/MesXslEquipInspectBizMsg.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordBatchCreateDTO.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordBatchCreateResult.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordHandleDTO.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordPage.java create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_79__mes_xsl_equip_inspect_record.sql create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_80__mes_xsl_equip_inspect_record_handle.sql create mode 100644 jeecgboot-vue3/src/utils/env/apiBaseUrl.ts create mode 100644 jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.api.ts create mode 100644 jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.data.ts create mode 100644 jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecordList.vue create mode 100644 jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordHandleModal.vue create mode 100644 jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordModal.vue diff --git a/jeecg-boot/db/mes-xsl-equip-inspect-record-menu-permission.sql b/jeecg-boot/db/mes-xsl-equip-inspect-record-menu-permission.sql new file mode 100644 index 0000000..d288dfb --- /dev/null +++ b/jeecg-boot/db/mes-xsl-equip-inspect-record-menu-permission.sql @@ -0,0 +1,138 @@ +-- MES 点检/保养记录(主子表):建表 + 字典 + 菜单 + 按钮 + 租户 admin 授权 +-- 权限前缀:mes:mes_xsl_equip_inspect_record:* +-- 父菜单:设备管理;依赖设备点检配置、设备台账 +-- Flyway:V3.9.2_79__mes_xsl_equip_inspect_record.sql +SET NAMES utf8mb4; + +INSERT INTO `sys_dict`(`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`, `tenant_id`) +SELECT REPLACE(UUID(), '-', ''), 'MES点检记录结果', 'xslmes_im_inspect_result', '合格/不合格', 0, 'admin', NOW(), 0, 0 +WHERE NOT EXISTS (SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_im_inspect_result' AND `del_flag` = 0); + +INSERT INTO `sys_dict_item`(`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`) +SELECT REPLACE(UUID(), '-', ''), d.`id`, '合格', 'pass', '', 1, 1, 'admin', NOW() +FROM `sys_dict` d +WHERE d.`dict_code` = 'xslmes_im_inspect_result' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.`id` AND i.`item_value` = 'pass'); + +INSERT INTO `sys_dict_item`(`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`) +SELECT REPLACE(UUID(), '-', ''), d.`id`, '不合格', 'fail', '', 2, 1, 'admin', NOW() +FROM `sys_dict` d +WHERE d.`dict_code` = 'xslmes_im_inspect_result' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.`id` AND i.`item_value` = 'fail'); + +INSERT INTO `sys_dict`(`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`, `tenant_id`) +SELECT REPLACE(UUID(), '-', ''), 'MES点检记录状态', 'xslmes_im_record_status', '待点检/已点检', 0, 'admin', NOW(), 0, 0 +WHERE NOT EXISTS (SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_im_record_status' AND `del_flag` = 0); + +INSERT INTO `sys_dict_item`(`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`) +SELECT REPLACE(UUID(), '-', ''), d.`id`, '待点检', 'pending', '', 1, 1, 'admin', NOW() +FROM `sys_dict` d +WHERE d.`dict_code` = 'xslmes_im_record_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.`id` AND i.`item_value` = 'pending'); + +INSERT INTO `sys_dict_item`(`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`) +SELECT REPLACE(UUID(), '-', ''), d.`id`, '已点检', 'done', '', 2, 1, 'admin', NOW() +FROM `sys_dict` d +WHERE d.`dict_code` = 'xslmes_im_record_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.`id` AND i.`item_value` = 'done'); + +CREATE TABLE IF NOT EXISTS `mes_xsl_equip_inspect_record` ( + `id` varchar(32) NOT NULL COMMENT '主键', + `record_no` varchar(32) NOT NULL COMMENT '记录编号(EC+yyyyMMdd+4位流水,租户内按日递增)', + `plan_no` varchar(500) DEFAULT NULL COMMENT '计划单号', + `plan_id` varchar(32) DEFAULT NULL COMMENT '计划主键(隐藏)', + `equipment_ledger_id` varchar(32) NOT NULL COMMENT '设备台账主键 mes_xsl_equipment_ledger.id', + `equipment_code` varchar(500) DEFAULT NULL COMMENT '设备编码冗余', + `equipment_name` varchar(500) DEFAULT NULL COMMENT '设备名称冗余', + `equip_inspect_config_id` varchar(32) DEFAULT NULL COMMENT '设备点检配置主键 mes_xsl_equip_inspect_config.id', + `record_type` varchar(500) NOT NULL COMMENT '类型(字典xslmes_im_item_category:inspect点检/maintain保养)', + `inspect_date` date DEFAULT NULL COMMENT '点检日期', + `inspector_user_id` varchar(32) DEFAULT NULL COMMENT '点检人用户ID', + `inspector_username` varchar(500) DEFAULT NULL COMMENT '点检人账号', + `inspector_realname` varchar(500) DEFAULT NULL COMMENT '点检人姓名', + `inspect_result` varchar(500) NOT NULL COMMENT '点检结果(字典xslmes_im_inspect_result:pass合格/fail不合格)', + `record_status` varchar(500) NOT NULL COMMENT '状态(字典xslmes_im_record_status:pending待点检/done已点检)', + `handled_flag` varchar(1) DEFAULT NULL COMMENT '是否已处理(字典yn:1是0否,仅不合格记录使用)', + `handler_user_id` varchar(32) DEFAULT NULL COMMENT '处理人用户ID', + `handler_username` varchar(500) DEFAULT NULL COMMENT '处理人账号', + `handler_realname` varchar(500) DEFAULT NULL COMMENT '处理人姓名', + `handle_time` datetime DEFAULT NULL COMMENT '处理时间', + `tenant_id` int DEFAULT NULL COMMENT '租户', + `sys_org_code` varchar(500) DEFAULT NULL COMMENT '部门', + `create_by` varchar(500) DEFAULT NULL COMMENT '创建人', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(500) DEFAULT NULL COMMENT '更新人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `del_flag` int DEFAULT '0' COMMENT '删除标记(0正常1删除)', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_meir_tenant_record_no` (`tenant_id`, `record_no`), + KEY `idx_meir_equip_type` (`equipment_ledger_id`, `record_type`), + KEY `idx_meir_inspect_date` (`inspect_date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES点检保养记录'; + +CREATE TABLE IF NOT EXISTS `mes_xsl_equip_inspect_record_line` ( + `id` varchar(32) NOT NULL COMMENT '主键', + `record_id` varchar(32) NOT NULL COMMENT '主表主键 mes_xsl_equip_inspect_record.id', + `equip_inspect_config_line_id` varchar(32) NOT NULL COMMENT '设备点检配置明细主键 mes_xsl_equip_inspect_config_line.id', + `inspect_maintain_item_id` varchar(32) DEFAULT NULL COMMENT '点检及保养项目主键冗余', + `item_code` varchar(500) DEFAULT NULL COMMENT '点检项目编号冗余', + `item_name` varchar(500) DEFAULT NULL COMMENT '项目名称冗余', + `item_category` varchar(500) DEFAULT NULL COMMENT '项目类别冗余', + `item_type` varchar(500) DEFAULT NULL COMMENT '项目类型冗余', + `equipment_part_name` varchar(500) DEFAULT NULL COMMENT '设备部位冗余', + `equipment_sub_part_name` varchar(500) DEFAULT NULL COMMENT '设备小部位冗余', + `inspect_method` varchar(500) DEFAULT NULL COMMENT '点检方式冗余', + `judgment_criteria` varchar(500) DEFAULT NULL COMMENT '判断基准冗余', + `line_inspect_result` varchar(500) DEFAULT NULL COMMENT '明细点检结果(文本)', + `picture_files` varchar(2000) DEFAULT NULL COMMENT '图片(上传路径,逗号分隔)', + `sort_no` int DEFAULT '0' COMMENT '排序号', + `create_by` varchar(500) DEFAULT NULL COMMENT '创建人', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(500) DEFAULT NULL COMMENT '更新人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_meirl_record` (`record_id`), + KEY `idx_meirl_config_line` (`equip_inspect_config_line_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES点检保养记录明细'; + +SET @mes_tenant_id = 1002; + +SET @mes_equip_pid = ( + SELECT `id` FROM `sys_permission` + WHERE `del_flag` = 0 AND `menu_type` = 0 AND `name` = '设备管理' + LIMIT 1 +); +SET @mes_equip_pid = IFNULL(@mes_equip_pid, '1860000000000000133'); + +INSERT INTO `sys_permission`(`id`, `parent_id`, `name`, `url`, `component`, `component_name`, `menu_type`, `perms`, `perms_type`, `sort_no`, `is_route`, `is_leaf`, `hidden`, `status`, `del_flag`, `keep_alive`, `internal_or_external`, `create_by`, `create_time`) +VALUES ('1860000000000000155', @mes_equip_pid, '点检保养记录', '/xslmes/mesXslEquipInspectRecord', 'xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecordList', 'MesXslEquipInspectRecordList', 1, NULL, '1', 13, 1, 0, 0, '1', 0, 1, 0, 'admin', NOW()) +ON DUPLICATE KEY UPDATE +`parent_id` = VALUES(`parent_id`), `name` = VALUES(`name`), `url` = VALUES(`url`), `component` = VALUES(`component`), `component_name` = VALUES(`component_name`), +`menu_type` = VALUES(`menu_type`), `perms` = VALUES(`perms`), `perms_type` = VALUES(`perms_type`), `sort_no` = VALUES(`sort_no`), +`is_route` = VALUES(`is_route`), `is_leaf` = VALUES(`is_leaf`), `hidden` = VALUES(`hidden`), `status` = VALUES(`status`), `del_flag` = VALUES(`del_flag`), +`keep_alive` = VALUES(`keep_alive`), `internal_or_external` = VALUES(`internal_or_external`), `icon` = 'ant-design:file-done-outlined'; + +UPDATE `sys_permission` SET `icon` = 'ant-design:file-done-outlined' WHERE `id` = '1860000000000000155' AND `del_flag` = 0; + +INSERT INTO `sys_permission`(`id`, `parent_id`, `name`, `menu_type`, `perms`, `perms_type`, `status`, `del_flag`, `create_by`, `create_time`) VALUES +('1860000000000000156', '1860000000000000155', '新增', 2, 'mes:mes_xsl_equip_inspect_record:add', '1', '1', 0, 'admin', NOW()), +('1860000000000000157', '1860000000000000155', '编辑', 2, 'mes:mes_xsl_equip_inspect_record:edit', '1', '1', 0, 'admin', NOW()), +('1860000000000000158', '1860000000000000155', '删除', 2, 'mes:mes_xsl_equip_inspect_record:delete', '1', '1', 0, 'admin', NOW()), +('1860000000000000159', '1860000000000000155', '批量删除', 2, 'mes:mes_xsl_equip_inspect_record:deleteBatch', '1', '1', 0, 'admin', NOW()), +('1860000000000000160', '1860000000000000155', '导出', 2, 'mes:mes_xsl_equip_inspect_record:exportXls', '1', '1', 0, 'admin', NOW()), +('1860000000000000161', '1860000000000000155', '导入', 2, 'mes:mes_xsl_equip_inspect_record:importExcel', '1', '1', 0, 'admin', NOW()) +ON DUPLICATE KEY UPDATE +`parent_id` = VALUES(`parent_id`), `name` = VALUES(`name`), `menu_type` = VALUES(`menu_type`), `perms` = VALUES(`perms`), `perms_type` = VALUES(`perms_type`), +`status` = VALUES(`status`), `del_flag` = VALUES(`del_flag`); + +INSERT INTO `sys_role_permission`(`id`, `role_id`, `permission_id`, `operate_date`, `operate_ip`) +SELECT REPLACE(UUID(), '-', ''), r.`id`, p.`id`, NOW(), '127.0.0.1' +FROM `sys_role` r +CROSS JOIN `sys_permission` p +WHERE r.`tenant_id` = @mes_tenant_id + AND r.`role_code` = 'admin' + AND p.`id` IN ( + '1860000000000000155', + '1860000000000000156', '1860000000000000157', '1860000000000000158', '1860000000000000159', + '1860000000000000160', '1860000000000000161' + ) + AND NOT EXISTS ( + SELECT 1 FROM `sys_role_permission` rp + WHERE rp.`role_id` = r.`id` AND rp.`permission_id` = p.`id` + ); diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslEquipInspectRecordController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslEquipInspectRecordController.java new file mode 100644 index 0000000..237e9da --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslEquipInspectRecordController.java @@ -0,0 +1,411 @@ +package org.jeecg.modules.xslmes.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.system.base.controller.JeecgController; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.system.vo.LoginUser; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.xslmes.entity.MesXslEquipInspectConfig; +import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecord; +import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecordLine; +import org.jeecg.modules.xslmes.entity.MesXslEquipmentLedger; +import org.jeecg.modules.xslmes.service.IMesXslEquipInspectConfigService; +import org.jeecg.modules.xslmes.service.IMesXslEquipInspectRecordService; +import org.jeecg.modules.xslmes.service.IMesXslEquipmentLedgerService; +import org.jeecg.modules.xslmes.util.MesXslEquipInspectBizMsg; +import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordBatchCreateDTO; +import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordBatchCreateResult; +import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordHandleDTO; +import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordPage; +import org.springframework.beans.BeanUtils; +import org.springframework.util.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; + +/** + * MES 点检/保养记录(主子表) + */ +@Tag(name = "MES点检保养记录") +@RestController +@RequestMapping("/xslmes/mesXslEquipInspectRecord") +@Slf4j +public class MesXslEquipInspectRecordController + extends JeecgController { + + private static final Set RECORD_TYPE = Set.of("inspect", "maintain"); + private static final Set INSPECT_RESULT = Set.of("pass", "fail"); + private static final Set RECORD_STATUS = Set.of("pending", "done"); + + @Autowired + private IMesXslEquipInspectRecordService mesXslEquipInspectRecordService; + + @Autowired + private IMesXslEquipmentLedgerService mesXslEquipmentLedgerService; + + @Autowired + private IMesXslEquipInspectConfigService mesXslEquipInspectConfigService; + + @Operation(summary = "MES点检保养记录-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList( + MesXslEquipInspectRecord model, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(model, req.getParameterMap()); + queryWrapper.orderByDesc("create_time"); + Page page = new Page<>(pageNo, pageSize); + IPage pageList = mesXslEquipInspectRecordService.page(page, queryWrapper); + return Result.OK(pageList); + } + + @AutoLog(value = "MES点检保养记录-添加") + @Operation(summary = "MES点检保养记录-添加") + @RequiresPermissions("mes:mes_xsl_equip_inspect_record:add") + @PostMapping(value = "/add") + public Result add(@RequestBody MesXslEquipInspectRecordPage page) { + MesXslEquipInspectRecord main = new MesXslEquipInspectRecord(); + BeanUtils.copyProperties(page, main); + String err = validateForSave(main, page.getLineList(), null); + if (err != null) { + return Result.error(err); + } + fillRecordNoIfEmpty(main); + fillInspector(main); + mesXslEquipInspectRecordService.saveMain(main, page.getLineList()); + return Result.OK("添加成功!"); + } + + @AutoLog(value = "MES点检保养记录-编辑") + @Operation(summary = "MES点检保养记录-编辑") + @RequiresPermissions("mes:mes_xsl_equip_inspect_record:edit") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) + public Result edit(@RequestBody MesXslEquipInspectRecordPage page) { + MesXslEquipInspectRecord main = new MesXslEquipInspectRecord(); + BeanUtils.copyProperties(page, main); + //update-begin---author:jiangxh ---date:20260520 for:【MES】仅待点检可录入,保存后变已点检----------- + if (oConvertUtils.isEmpty(main.getId())) { + return Result.error("记录主键不能为空"); + } + MesXslEquipInspectRecord existing = mesXslEquipInspectRecordService.getById(main.getId()); + if (existing == null) { + return Result.error("未找到对应数据"); + } + if ("done".equals(existing.getRecordStatus())) { + return Result.error("已点检记录不可修改,仅可查看"); + } + main.setRecordStatus("done"); + String err = validateForEntry(main, page.getLineList()); + if (err != null) { + return Result.error(err); + } + fillInspector(main); + mesXslEquipInspectRecordService.updateMain(main, page.getLineList()); + return Result.OK("录入成功!"); + //update-end---author:jiangxh ---date:20260520 for:【MES】仅待点检可录入,保存后变已点检----------- + } + + @AutoLog(value = "MES点检保养记录-删除") + @Operation(summary = "MES点检保养记录-通过id删除") + @RequiresPermissions("mes:mes_xsl_equip_inspect_record:delete") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name = "id", required = true) String id) { + mesXslEquipInspectRecordService.delMain(id); + return Result.OK("删除成功!"); + } + + @AutoLog(value = "MES点检保养记录-批量删除") + @Operation(summary = "MES点检保养记录-批量删除") + @RequiresPermissions("mes:mes_xsl_equip_inspect_record:deleteBatch") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + mesXslEquipInspectRecordService.delBatchMain(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + @Operation(summary = "MES点检保养记录-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + MesXslEquipInspectRecord entity = mesXslEquipInspectRecordService.getById(id); + if (entity == null) { + return Result.error("未找到对应数据"); + } + return Result.OK(entity); + } + + @Operation(summary = "MES点检保养记录-查询明细") + @GetMapping(value = "/queryLineListByRecordId") + public Result> queryLineListByRecordId( + @RequestParam(name = "id", required = true) String id) { + return Result.OK(mesXslEquipInspectRecordService.selectLinesByRecordId(id)); + } + + //update-begin---author:jiangxh ---date:20260521 for:【MES】不合格点检记录登记处理人及处理时间----------- + @AutoLog(value = "MES点检保养记录-不合格处理") + @Operation(summary = "MES点检保养记录-不合格处理") + @RequiresPermissions("mes:mes_xsl_equip_inspect_record:edit") + @PostMapping(value = "/handleFail") + public Result handleFail(@RequestBody MesXslEquipInspectRecordHandleDTO dto) { + try { + mesXslEquipInspectRecordService.handleFailRecord(dto); + return Result.OK("处理成功!"); + } catch (IllegalArgumentException ex) { + return Result.error(ex.getMessage()); + } + } + //update-end---author:jiangxh ---date:20260521 for:【MES】不合格点检记录登记处理人及处理时间----------- + + @Operation(summary = "MES点检保养记录-生成记录编号") + @GetMapping(value = "/generateRecordNo") + public Result generateRecordNo() { + MesXslEquipInspectRecord ctx = new MesXslEquipInspectRecord(); + return Result.OK(mesXslEquipInspectRecordService.generateRecordNo(ctx)); + } + + @AutoLog(value = "MES点检保养记录-从设备台账批量生成") + @Operation(summary = "MES点检保养记录-从设备台账批量生成") + @RequiresPermissions("mes:mes_xsl_equip_inspect_record:add") + @PostMapping(value = "/batchCreateFromEquipment") + public Result batchCreateFromEquipment( + @RequestBody MesXslEquipInspectRecordBatchCreateDTO dto) { + if (dto == null || CollectionUtils.isEmpty(dto.getEquipmentLedgerIds())) { + return Result.error("请先选择设备"); + } + String recordType = dto.getRecordType(); + if (recordType != null) { + recordType = recordType.trim(); + } + if (oConvertUtils.isEmpty(recordType) || !RECORD_TYPE.contains(recordType)) { + return Result.error("类型无效,请使用点检或保养"); + } + MesXslEquipInspectRecord inspectorCtx = new MesXslEquipInspectRecord(); + fillInspector(inspectorCtx); + MesXslEquipInspectRecordBatchCreateResult result = + mesXslEquipInspectRecordService.batchCreateFromEquipment( + dto.getEquipmentLedgerIds(), recordType, inspectorCtx); + if (result.getSuccessCount() <= 0 && !result.getFailMessages().isEmpty()) { + return Result.error(String.join(";", result.getFailMessages())); + } + String msg = "成功生成 " + result.getSuccessCount() + " 条记录"; + if (!result.getFailMessages().isEmpty()) { + msg = msg + ";" + String.join(";", result.getFailMessages()); + } + return Result.OK(msg, result); + } + + @Operation(summary = "MES点检保养记录-按设备与类型带出配置明细") + @GetMapping(value = "/loadLinesByEquipment") + public Result> loadLinesByEquipment( + @RequestParam(name = "equipmentLedgerId") String equipmentLedgerId, + @RequestParam(name = "recordType") String recordType) { + String type = recordType != null ? recordType.trim() : ""; + if (oConvertUtils.isEmpty(equipmentLedgerId) || !RECORD_TYPE.contains(type)) { + return Result.error("请选择设备与类型(点检/保养)"); + } + List lines = + mesXslEquipInspectRecordService.buildLinesFromEquipConfig(equipmentLedgerId, type); + if (lines.isEmpty()) { + MesXslEquipmentLedger ledger = mesXslEquipmentLedgerService.getById(equipmentLedgerId); + String equipName = + ledger != null && oConvertUtils.isNotEmpty(ledger.getEquipmentName()) + ? ledger.getEquipmentName() + : (ledger != null ? ledger.getEquipmentCode() : equipmentLedgerId); + return Result.error(MesXslEquipInspectBizMsg.noConfigMessage(equipName, type)); + } + return Result.OK(lines); + } + + @RequiresPermissions("mes:mes_xsl_equip_inspect_record:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, MesXslEquipInspectRecord model) { + return super.exportXls(request, model, MesXslEquipInspectRecord.class, "MES点检保养记录"); + } + + @RequiresPermissions("mes:mes_xsl_equip_inspect_record:importExcel") + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, MesXslEquipInspectRecord.class); + } + + private void fillRecordNoIfEmpty(MesXslEquipInspectRecord main) { + if (oConvertUtils.isEmpty(main.getRecordNo())) { + main.setRecordNo(mesXslEquipInspectRecordService.generateRecordNo(main)); + } + } + + private void fillInspector(MesXslEquipInspectRecord main) { + if (SecurityUtils.getSubject() == null || SecurityUtils.getSubject().getPrincipal() == null) { + return; + } + if (!(SecurityUtils.getSubject().getPrincipal() instanceof LoginUser user)) { + return; + } + main.setInspectorUserId(user.getId()); + main.setInspectorUsername(user.getUsername()); + main.setInspectorRealname(user.getRealname()); + } + + //update-begin---author:jiangxh ---date:20260520 for:【MES】录入点检结果:必填项校验,保存为已点检----------- + private String validateForEntry(MesXslEquipInspectRecord main, List lineList) { + String err = validateForSave(main, lineList, main.getId()); + if (err != null) { + return err; + } + if (main.getInspectDate() == null) { + return "请选择点检日期"; + } + if (oConvertUtils.isEmpty(main.getInspectorUserId()) && oConvertUtils.isEmpty(main.getInspectorRealname())) { + return "点检人不能为空"; + } + String inspectResult = main.getInspectResult(); + if (inspectResult != null) { + inspectResult = inspectResult.trim(); + } + if (oConvertUtils.isEmpty(inspectResult) || !INSPECT_RESULT.contains(inspectResult)) { + return "请选择点检结果(合格/不合格)"; + } + main.setInspectResult(inspectResult); + main.setRecordStatus("done"); + //update-begin---author:jiangxh ---date:20260521 for:【MES】不合格记录默认未处理----------- + if ("fail".equals(inspectResult)) { + main.setHandledFlag("0"); + } else { + main.setHandledFlag(null); + main.setHandlerUserId(null); + main.setHandlerUsername(null); + main.setHandlerRealname(null); + main.setHandleTime(null); + } + //update-end---author:jiangxh ---date:20260521 for:【MES】不合格记录默认未处理----------- + return null; + } + //update-end---author:jiangxh ---date:20260520 for:【MES】录入点检结果:必填项校验,保存为已点检----------- + + //update-begin---author:jiangxh ---date:20260520 for:【MES】点检保养记录保存校验与配置明细关联----------- + private String validateForSave( + MesXslEquipInspectRecord main, List lineList, String excludeId) { + if (main == null) { + return "参数不能为空"; + } + if (oConvertUtils.isEmpty(main.getEquipmentLedgerId())) { + return "请选择设备"; + } + MesXslEquipmentLedger ledger = mesXslEquipmentLedgerService.getById(main.getEquipmentLedgerId()); + if (ledger == null || isDeleted(ledger.getDelFlag())) { + return "设备台账不存在或已删除"; + } + main.setEquipmentName(ledger.getEquipmentName()); + main.setEquipmentCode(ledger.getEquipmentCode()); + + String recordType = main.getRecordType(); + if (recordType != null) { + recordType = recordType.trim(); + } + if (oConvertUtils.isEmpty(recordType) || !RECORD_TYPE.contains(recordType)) { + return "类型无效,请选择点检或保养"; + } + main.setRecordType(recordType); + + if (main.getInspectDate() == null) { + main.setInspectDate(new Date()); + } + + String recordStatus = main.getRecordStatus(); + if (recordStatus != null) { + recordStatus = recordStatus.trim(); + } + if (oConvertUtils.isEmpty(recordStatus) || !RECORD_STATUS.contains(recordStatus)) { + return "请选择状态(待点检/已点检)"; + } + main.setRecordStatus(recordStatus); + + String inspectResult = main.getInspectResult(); + if (inspectResult != null) { + inspectResult = inspectResult.trim(); + } + if ("done".equals(recordStatus)) { + if (oConvertUtils.isEmpty(inspectResult) || !INSPECT_RESULT.contains(inspectResult)) { + return "已点检时请选择点检结果(合格/不合格)"; + } + main.setInspectResult(inspectResult); + } else { + if (oConvertUtils.isNotEmpty(inspectResult) && !INSPECT_RESULT.contains(inspectResult)) { + return "点检结果无效"; + } + main.setInspectResult(oConvertUtils.isEmpty(inspectResult) ? null : inspectResult); + } + + if (oConvertUtils.isEmpty(main.getRecordNo())) { + return "记录编号不能为空"; + } + + com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper cw = + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>(); + cw.eq(MesXslEquipInspectConfig::getEquipmentLedgerId, main.getEquipmentLedgerId()); + cw.eq(MesXslEquipInspectConfig::getConfigType, recordType); + cw.and( + q -> + q.eq(MesXslEquipInspectConfig::getDelFlag, CommonConstant.DEL_FLAG_0) + .or() + .isNull(MesXslEquipInspectConfig::getDelFlag)); + MesXslEquipInspectConfig config = mesXslEquipInspectConfigService.getOne(cw, false); + if (config == null) { + String equipName = + oConvertUtils.isNotEmpty(ledger.getEquipmentName()) + ? ledger.getEquipmentName() + : ledger.getEquipmentCode(); + return MesXslEquipInspectBizMsg.noConfigMessage(equipName, recordType); + } + main.setEquipInspectConfigId(config.getId()); + + if (lineList == null || lineList.isEmpty()) { + return "明细不能为空,请选择设备后自动带出点检项目"; + } + + Set configLineIds = new HashSet<>(); + int sort = 0; + for (int i = 0; i < lineList.size(); i++) { + MesXslEquipInspectRecordLine line = lineList.get(i); + if (line == null) { + continue; + } + int rowNo = i + 1; + if (oConvertUtils.isEmpty(line.getEquipInspectConfigLineId())) { + return "第 " + rowNo + " 行未关联点检配置明细"; + } + String lineId = line.getEquipInspectConfigLineId().trim(); + if (!configLineIds.add(lineId)) { + return "第 " + rowNo + " 行点检配置明细重复"; + } + line.setEquipInspectConfigLineId(lineId); + line.setSortNo(sort++); + } + if (configLineIds.isEmpty()) { + return "明细不能为空"; + } + return null; + } + + private static boolean isDeleted(Integer delFlag) { + return delFlag != null && delFlag.equals(CommonConstant.DEL_FLAG_1); + } + //update-end---author:jiangxh ---date:20260520 for:【MES】点检保养记录保存校验与配置明细关联----------- +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslEquipInspectRecord.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslEquipInspectRecord.java new file mode 100644 index 0000000..bb70d20 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslEquipInspectRecord.java @@ -0,0 +1,126 @@ +package org.jeecg.modules.xslmes.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.Serializable; +import java.util.Date; +import java.util.List; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecg.common.aspect.annotation.Dict; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +/** + * MES 点检/保养记录主表(表 mes_xsl_equip_inspect_record) + */ +@Data +@TableName("mes_xsl_equip_inspect_record") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@Schema(description = "MES点检保养记录") +public class MesXslEquipInspectRecord implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_ID) + private String id; + + @Excel(name = "记录编号", width = 20) + @Schema(description = "记录编号 EC+yyyyMMdd+4位流水") + private String recordNo; + + @Excel(name = "计划单号", width = 18) + @Schema(description = "计划单号") + private String planNo; + + @Schema(description = "计划主键") + private String planId; + + @Schema(description = "设备台账主键") + private String equipmentLedgerId; + + @Excel(name = "设备编码", width = 16) + @Schema(description = "设备编码冗余") + private String equipmentCode; + + @Excel(name = "设备名称", width = 20) + @Schema(description = "设备名称冗余") + private String equipmentName; + + @Schema(description = "设备点检配置主键") + private String equipInspectConfigId; + + @Excel(name = "类型", width = 10, dicCode = "xslmes_im_item_category") + @Dict(dicCode = "xslmes_im_item_category") + @Schema(description = "点检/保养类型") + private String recordType; + + @Excel(name = "点检日期", width = 12, format = "yyyy-MM-dd") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Schema(description = "点检日期") + private Date inspectDate; + + @Schema(description = "点检人用户ID") + private String inspectorUserId; + + @Schema(description = "点检人账号") + private String inspectorUsername; + + @Excel(name = "点检人", width = 12) + @Schema(description = "点检人姓名") + private String inspectorRealname; + + @Excel(name = "点检结果", width = 10, dicCode = "xslmes_im_inspect_result") + @Dict(dicCode = "xslmes_im_inspect_result") + @Schema(description = "点检结果 pass/fail") + private String inspectResult; + + @Excel(name = "状态", width = 10, dicCode = "xslmes_im_record_status") + @Dict(dicCode = "xslmes_im_record_status") + @Schema(description = "记录状态 pending/done") + private String recordStatus; + + @Excel(name = "是否已处理", width = 10, dicCode = "yn") + @Dict(dicCode = "yn") + @Schema(description = "是否已处理(字典yn:1是0否,不合格记录使用)") + private String handledFlag; + + @Schema(description = "处理人用户ID") + private String handlerUserId; + + @Schema(description = "处理人账号") + private String handlerUsername; + + @Excel(name = "处理人", width = 12) + @Schema(description = "处理人姓名") + private String handlerRealname; + + @Excel(name = "处理时间", width = 18, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(description = "处理时间") + private Date handleTime; + + private Integer tenantId; + private String sysOrgCode; + private String createBy; + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + private String updateBy; + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + private Integer delFlag; + + @TableField(exist = false) + @Schema(description = "点检明细") + private List lineList; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslEquipInspectRecordLine.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslEquipInspectRecordLine.java new file mode 100644 index 0000000..88a0e60 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslEquipInspectRecordLine.java @@ -0,0 +1,82 @@ +package org.jeecg.modules.xslmes.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.Serializable; +import java.util.Date; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecg.common.aspect.annotation.Dict; +import org.springframework.format.annotation.DateTimeFormat; + +/** + * MES 点检/保养记录明细(表 mes_xsl_equip_inspect_record_line) + */ +@Data +@TableName("mes_xsl_equip_inspect_record_line") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@Schema(description = "MES点检保养记录明细") +public class MesXslEquipInspectRecordLine implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_ID) + private String id; + + @Schema(description = "主表主键") + private String recordId; + + @Schema(description = "设备点检配置明细主键") + private String equipInspectConfigLineId; + + @Schema(description = "点检及保养项目主键冗余") + private String inspectMaintainItemId; + + @Schema(description = "点检项目编号") + private String itemCode; + + @Schema(description = "项目名称") + private String itemName; + + @Dict(dicCode = "xslmes_im_item_category") + @Schema(description = "项目类别") + private String itemCategory; + + @Dict(dicCode = "xslmes_im_item_type") + @Schema(description = "项目类型") + private String itemType; + + @Schema(description = "设备部位") + private String equipmentPartName; + + @Schema(description = "设备小部位") + private String equipmentSubPartName; + + @Dict(dicCode = "xslmes_im_inspect_method") + @Schema(description = "点检方式") + private String inspectMethod; + + @Schema(description = "判断基准") + private String judgmentCriteria; + + @Schema(description = "明细点检结果文本") + private String lineInspectResult; + + @Schema(description = "图片路径,逗号分隔") + private String pictureFiles; + + private Integer sortNo; + private String createBy; + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + private String updateBy; + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslEquipInspectRecordLineMapper.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslEquipInspectRecordLineMapper.java new file mode 100644 index 0000000..b1ec54a --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslEquipInspectRecordLineMapper.java @@ -0,0 +1,6 @@ +package org.jeecg.modules.xslmes.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecordLine; + +public interface MesXslEquipInspectRecordLineMapper extends BaseMapper {} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslEquipInspectRecordMapper.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslEquipInspectRecordMapper.java new file mode 100644 index 0000000..0fafdaa --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslEquipInspectRecordMapper.java @@ -0,0 +1,6 @@ +package org.jeecg.modules.xslmes.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecord; + +public interface MesXslEquipInspectRecordMapper extends BaseMapper {} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslEquipInspectRecordService.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslEquipInspectRecordService.java new file mode 100644 index 0000000..ab78416 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslEquipInspectRecordService.java @@ -0,0 +1,34 @@ +package org.jeecg.modules.xslmes.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import java.io.Serializable; +import java.util.Collection; +import java.util.List; +import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecord; +import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecordLine; +import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordBatchCreateResult; +import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordHandleDTO; + +public interface IMesXslEquipInspectRecordService extends IService { + + void saveMain(MesXslEquipInspectRecord main, List lineList); + + void updateMain(MesXslEquipInspectRecord main, List lineList); + + void delMain(String id); + + void delBatchMain(Collection idList); + + List selectLinesByRecordId(String recordId); + + String generateRecordNo(MesXslEquipInspectRecord context); + + List buildLinesFromEquipConfig(String equipmentLedgerId, String recordType); + + MesXslEquipInspectRecordBatchCreateResult batchCreateFromEquipment( + List equipmentLedgerIds, String recordType, MesXslEquipInspectRecord inspectorContext); + + //update-begin---author:jiangxh ---date:20260521 for:【MES】不合格点检记录登记处理人及处理时间----------- + void handleFailRecord(MesXslEquipInspectRecordHandleDTO dto); + //update-end---author:jiangxh ---date:20260521 for:【MES】不合格点检记录登记处理人及处理时间----------- +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslEquipInspectRecordServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslEquipInspectRecordServiceImpl.java new file mode 100644 index 0000000..c28795d --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslEquipInspectRecordServiceImpl.java @@ -0,0 +1,312 @@ +package org.jeecg.modules.xslmes.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import java.io.Serializable; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import org.jeecg.common.config.TenantContext; +import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.util.SpringContextUtils; +import org.jeecg.common.util.TokenUtils; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.xslmes.entity.MesXslEquipInspectConfig; +import org.jeecg.modules.xslmes.entity.MesXslEquipInspectConfigLine; +import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecord; +import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecordLine; +import org.jeecg.modules.xslmes.mapper.MesXslEquipInspectRecordLineMapper; +import org.jeecg.modules.xslmes.mapper.MesXslEquipInspectRecordMapper; +import org.jeecg.modules.xslmes.service.IMesXslEquipInspectConfigService; +import org.jeecg.modules.xslmes.service.IMesXslEquipInspectRecordService; +import org.jeecg.modules.xslmes.service.IMesXslEquipmentLedgerService; +import org.jeecg.modules.xslmes.entity.MesXslEquipmentLedger; +import org.jeecg.modules.xslmes.util.MesXslEquipInspectBizMsg; +import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordBatchCreateResult; +import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordHandleDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +@Service +public class MesXslEquipInspectRecordServiceImpl + extends ServiceImpl + implements IMesXslEquipInspectRecordService { + + @Autowired + private MesXslEquipInspectRecordLineMapper mesXslEquipInspectRecordLineMapper; + + @Autowired + private IMesXslEquipInspectConfigService mesXslEquipInspectConfigService; + + @Autowired + private IMesXslEquipmentLedgerService mesXslEquipmentLedgerService; + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveMain(MesXslEquipInspectRecord main, List lineList) { + this.save(main); + insertLines(main.getId(), lineList); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateMain(MesXslEquipInspectRecord main, List lineList) { + this.updateById(main); + mesXslEquipInspectRecordLineMapper.delete( + new LambdaQueryWrapper() + .eq(MesXslEquipInspectRecordLine::getRecordId, main.getId())); + insertLines(main.getId(), lineList); + } + + private void insertLines(String recordId, List lineList) { + if (CollectionUtils.isEmpty(lineList)) { + return; + } + int sort = 0; + for (MesXslEquipInspectRecordLine line : lineList) { + line.setId(null); + line.setRecordId(recordId); + line.setSortNo(sort++); + mesXslEquipInspectRecordLineMapper.insert(line); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delMain(String id) { + mesXslEquipInspectRecordLineMapper.delete( + new LambdaQueryWrapper().eq(MesXslEquipInspectRecordLine::getRecordId, id)); + this.removeById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delBatchMain(Collection idList) { + for (Serializable id : idList) { + delMain(id.toString()); + } + } + + @Override + public List selectLinesByRecordId(String recordId) { + return mesXslEquipInspectRecordLineMapper.selectList( + new LambdaQueryWrapper() + .eq(MesXslEquipInspectRecordLine::getRecordId, recordId) + .orderByAsc(MesXslEquipInspectRecordLine::getSortNo)); + } + + //update-begin---author:jiangxh ---date:20260520 for:【MES】点检保养记录编号 EC+日期+4位流水----------- + @Override + public String generateRecordNo(MesXslEquipInspectRecord context) { + String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date()); + String prefix = "EC" + dateStr; + Integer tenantId = resolveTenantId(context); + + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.likeRight(MesXslEquipInspectRecord::getRecordNo, prefix); + qw.and( + q -> + q.eq(MesXslEquipInspectRecord::getDelFlag, CommonConstant.DEL_FLAG_0) + .or() + .isNull(MesXslEquipInspectRecord::getDelFlag)); + if (tenantId != null) { + qw.eq(MesXslEquipInspectRecord::getTenantId, tenantId); + } + qw.select(MesXslEquipInspectRecord::getRecordNo); + qw.orderByDesc(MesXslEquipInspectRecord::getRecordNo); + qw.last("LIMIT 1"); + + MesXslEquipInspectRecord last = this.getOne(qw, false); + int nextSeq = 1; + if (last != null && oConvertUtils.isNotEmpty(last.getRecordNo()) && last.getRecordNo().length() >= prefix.length() + 4) { + String suffix = last.getRecordNo().substring(prefix.length()); + try { + nextSeq = Integer.parseInt(suffix) + 1; + } catch (NumberFormatException ignored) { + nextSeq = (int) this.count(qw) + 1; + } + } + return prefix + String.format("%04d", nextSeq); + } + //update-end---author:jiangxh ---date:20260520 for:【MES】点检保养记录编号 EC+日期+4位流水----------- + + //update-begin---author:jiangxh ---date:20260520 for:【MES】点检保养记录从设备点检配置带出明细----------- + @Override + public List buildLinesFromEquipConfig(String equipmentLedgerId, String recordType) { + if (oConvertUtils.isEmpty(equipmentLedgerId) || oConvertUtils.isEmpty(recordType)) { + return List.of(); + } + String type = recordType.trim(); + MesXslEquipInspectConfig config = findEquipInspectConfig(equipmentLedgerId.trim(), type); + if (config == null) { + return List.of(); + } + List configLines = + mesXslEquipInspectConfigService.selectLinesByConfigId(config.getId()); + if (CollectionUtils.isEmpty(configLines)) { + return List.of(); + } + return buildRecordLinesFromConfigLines(configLines); + } + + private MesXslEquipInspectConfig findEquipInspectConfig(String equipmentLedgerId, String configType) { + LambdaQueryWrapper cw = new LambdaQueryWrapper<>(); + cw.eq(MesXslEquipInspectConfig::getEquipmentLedgerId, equipmentLedgerId); + cw.eq(MesXslEquipInspectConfig::getConfigType, configType); + cw.and( + q -> + q.eq(MesXslEquipInspectConfig::getDelFlag, CommonConstant.DEL_FLAG_0) + .or() + .isNull(MesXslEquipInspectConfig::getDelFlag)); + return mesXslEquipInspectConfigService.getOne(cw, false); + } + + private List buildRecordLinesFromConfigLines( + List configLines) { + List result = new ArrayList<>(configLines.size()); + for (MesXslEquipInspectConfigLine cl : configLines) { + MesXslEquipInspectRecordLine line = new MesXslEquipInspectRecordLine(); + line.setEquipInspectConfigLineId(cl.getId()); + line.setInspectMaintainItemId(cl.getInspectMaintainItemId()); + line.setItemCode(cl.getItemCode()); + line.setItemName(cl.getItemName()); + line.setItemCategory(cl.getItemCategory()); + line.setItemType(cl.getItemType()); + line.setEquipmentPartName(cl.getEquipmentPartName()); + line.setEquipmentSubPartName(cl.getEquipmentSubPartName()); + line.setInspectMethod(cl.getInspectMethod()); + line.setJudgmentCriteria(cl.getJudgmentCriteria()); + result.add(line); + } + return result; + } + //update-end---author:jiangxh ---date:20260520 for:【MES】点检保养记录从设备点检配置带出明细----------- + + //update-begin---author:jiangxh ---date:20260520 for:【MES】设备台账多选批量生成点检保养记录(待点检)----------- + @Override + @Transactional(rollbackFor = Exception.class) + public MesXslEquipInspectRecordBatchCreateResult batchCreateFromEquipment( + List equipmentLedgerIds, String recordType, MesXslEquipInspectRecord inspectorContext) { + MesXslEquipInspectRecordBatchCreateResult result = new MesXslEquipInspectRecordBatchCreateResult(); + if (CollectionUtils.isEmpty(equipmentLedgerIds) || oConvertUtils.isEmpty(recordType)) { + result.getFailMessages().add("请选择设备并指定点检或保养类型"); + return result; + } + String type = recordType.trim(); + for (String equipmentLedgerId : equipmentLedgerIds) { + if (oConvertUtils.isEmpty(equipmentLedgerId)) { + continue; + } + String equipId = equipmentLedgerId.trim(); + MesXslEquipmentLedger ledger = mesXslEquipmentLedgerService.getById(equipId); + String equipName = + ledger != null + ? (oConvertUtils.isNotEmpty(ledger.getEquipmentName()) + ? ledger.getEquipmentName() + : ledger.getEquipmentCode()) + : equipId; + if (ledger == null + || (ledger.getDelFlag() != null && ledger.getDelFlag().equals(CommonConstant.DEL_FLAG_1))) { + result.getFailMessages().add("设备【" + equipName + "】不存在或已删除"); + continue; + } + //update-begin---author:jiangxh ---date:20260520 for:【MES】未维护对应类型设备点检配置则不生成记录并提示设备名称----------- + MesXslEquipInspectConfig config = findEquipInspectConfig(equipId, type); + if (config == null) { + result.getFailMessages().add(MesXslEquipInspectBizMsg.noConfigMessage(equipName, type)); + continue; + } + List configLines = + mesXslEquipInspectConfigService.selectLinesByConfigId(config.getId()); + if (CollectionUtils.isEmpty(configLines)) { + result.getFailMessages().add(MesXslEquipInspectBizMsg.noConfigLineMessage(equipName, type)); + continue; + } + List lines = buildRecordLinesFromConfigLines(configLines); + //update-end---author:jiangxh ---date:20260520 for:【MES】未维护对应类型设备点检配置则不生成记录并提示设备名称----------- + + MesXslEquipInspectRecord main = new MesXslEquipInspectRecord(); + main.setEquipmentLedgerId(equipId); + main.setEquipmentCode(ledger.getEquipmentCode()); + main.setEquipmentName(ledger.getEquipmentName()); + main.setEquipInspectConfigId(config.getId()); + main.setRecordType(type); + main.setRecordNo(generateRecordNo(main)); + main.setRecordStatus("pending"); + main.setInspectResult(""); + main.setInspectDate(new Date()); + if (inspectorContext != null) { + main.setInspectorUserId(inspectorContext.getInspectorUserId()); + main.setInspectorUsername(inspectorContext.getInspectorUsername()); + main.setInspectorRealname(inspectorContext.getInspectorRealname()); + } + saveMain(main, lines); + result.setSuccessCount(result.getSuccessCount() + 1); + } + return result; + } + //update-end---author:jiangxh ---date:20260520 for:【MES】设备台账多选批量生成点检保养记录(待点检)----------- + + //update-begin---author:jiangxh ---date:20260521 for:【MES】不合格点检记录登记处理人及处理时间----------- + @Override + @Transactional(rollbackFor = Exception.class) + public void handleFailRecord(MesXslEquipInspectRecordHandleDTO dto) { + if (dto == null || oConvertUtils.isEmpty(dto.getId())) { + throw new IllegalArgumentException("记录主键不能为空"); + } + MesXslEquipInspectRecord existing = this.getById(dto.getId().trim()); + if (existing == null) { + throw new IllegalArgumentException("未找到对应数据"); + } + if (!"fail".equals(existing.getInspectResult())) { + throw new IllegalArgumentException("仅不合格记录可处理"); + } + if (!"done".equals(existing.getRecordStatus())) { + throw new IllegalArgumentException("请先完成点检录入"); + } + if ("1".equals(existing.getHandledFlag())) { + throw new IllegalArgumentException("该记录已处理"); + } + if (oConvertUtils.isEmpty(dto.getHandlerUserId()) + && oConvertUtils.isEmpty(dto.getHandlerUsername()) + && oConvertUtils.isEmpty(dto.getHandlerRealname())) { + throw new IllegalArgumentException("请选择处理人"); + } + Date handleTime = dto.getHandleTime() != null ? dto.getHandleTime() : new Date(); + MesXslEquipInspectRecord patch = new MesXslEquipInspectRecord(); + patch.setId(existing.getId()); + patch.setHandledFlag("1"); + patch.setHandlerUserId(dto.getHandlerUserId()); + patch.setHandlerUsername(dto.getHandlerUsername()); + patch.setHandlerRealname(dto.getHandlerRealname()); + patch.setHandleTime(handleTime); + this.updateById(patch); + } + //update-end---author:jiangxh ---date:20260521 for:【MES】不合格点检记录登记处理人及处理时间----------- + + private static Integer resolveTenantId(MesXslEquipInspectRecord context) { + if (context != null && context.getTenantId() != null) { + return context.getTenantId(); + } + String ts = TenantContext.getTenant(); + if (oConvertUtils.isEmpty(ts)) { + try { + ts = TokenUtils.getTenantIdByRequest(SpringContextUtils.getHttpServletRequest()); + } catch (Exception ignored) { + // ignore + } + } + if (oConvertUtils.isEmpty(ts)) { + return null; + } + try { + return Integer.parseInt(ts); + } catch (NumberFormatException e) { + return null; + } + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/util/MesXslEquipInspectBizMsg.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/util/MesXslEquipInspectBizMsg.java new file mode 100644 index 0000000..26fab61 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/util/MesXslEquipInspectBizMsg.java @@ -0,0 +1,27 @@ +package org.jeecg.modules.xslmes.util; + +import org.jeecg.common.util.oConvertUtils; + +/** + * 设备点检/保养业务提示文案 + */ +public final class MesXslEquipInspectBizMsg { + + private MesXslEquipInspectBizMsg() {} + + public static String recordTypeLabel(String recordType) { + return "inspect".equals(recordType) ? "点检" : "保养"; + } + + /** 未维护该类型设备点检配置(不生成记录) */ + public static String noConfigMessage(String equipmentName, String recordType) { + String name = oConvertUtils.isNotEmpty(equipmentName) ? equipmentName.trim() : "该设备"; + return name + " 未维护" + recordTypeLabel(recordType) + "类型的设备点检配置"; + } + + /** 已有点检配置主表但无明细行 */ + public static String noConfigLineMessage(String equipmentName, String recordType) { + String name = oConvertUtils.isNotEmpty(equipmentName) ? equipmentName.trim() : "该设备"; + return name + " 的" + recordTypeLabel(recordType) + "类型设备点检配置未维护明细项"; + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordBatchCreateDTO.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordBatchCreateDTO.java new file mode 100644 index 0000000..57b95f8 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordBatchCreateDTO.java @@ -0,0 +1,19 @@ +package org.jeecg.modules.xslmes.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import lombok.Data; + +/** + * 从设备台账批量生成点检/保养记录 + */ +@Data +@Schema(description = "批量生成点检保养记录请求") +public class MesXslEquipInspectRecordBatchCreateDTO { + + @Schema(description = "设备台账主键列表") + private List equipmentLedgerIds; + + @Schema(description = "记录类型 inspect点检/maintain保养") + private String recordType; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordBatchCreateResult.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordBatchCreateResult.java new file mode 100644 index 0000000..3f79b4f --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordBatchCreateResult.java @@ -0,0 +1,20 @@ +package org.jeecg.modules.xslmes.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.ArrayList; +import java.util.List; +import lombok.Data; + +/** + * 批量生成点检/保养记录结果 + */ +@Data +@Schema(description = "批量生成点检保养记录结果") +public class MesXslEquipInspectRecordBatchCreateResult { + + @Schema(description = "成功条数") + private int successCount; + + @Schema(description = "失败说明(按设备)") + private List failMessages = new ArrayList<>(); +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordHandleDTO.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordHandleDTO.java new file mode 100644 index 0000000..70496f6 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordHandleDTO.java @@ -0,0 +1,32 @@ +package org.jeecg.modules.xslmes.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.Date; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +/** + * 不合格点检记录处理入参 + */ +@Data +@Schema(description = "点检保养记录-不合格处理") +public class MesXslEquipInspectRecordHandleDTO { + + @Schema(description = "记录主键", requiredMode = Schema.RequiredMode.REQUIRED) + private String id; + + @Schema(description = "处理人用户ID") + private String handlerUserId; + + @Schema(description = "处理人账号") + private String handlerUsername; + + @Schema(description = "处理人姓名") + private String handlerRealname; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(description = "处理时间") + private Date handleTime; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordPage.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordPage.java new file mode 100644 index 0000000..505d866 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordPage.java @@ -0,0 +1,12 @@ +package org.jeecg.modules.xslmes.vo; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecord; + +/** + * 点检/保养记录主子保存 VO + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class MesXslEquipInspectRecordPage extends MesXslEquipInspectRecord {} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/docs/代码修改日志 b/jeecg-boot/jeecg-module-system/jeecg-system-biz/docs/代码修改日志 index 4bfac8a..f6f1358 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/docs/代码修改日志 +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/docs/代码修改日志 @@ -362,3 +362,59 @@ jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectConfig/components/MesXslEquipInspectConfigModal.vue jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectConfig/components/MesXslInspectMaintainItemSelectModal.vue jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectConfig/MesXslEquipInspectConfig.data.ts +-- author:jiangxh---date:20260520--for: 【MES】点检保养记录主子表(EC编号、设备配置带出明细、字典与菜单)--- +jeecg-boot/db/mes-xsl-equip-inspect-record-menu-permission.sql +jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_79__mes_xsl_equip_inspect_record.sql +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslEquipInspectRecord.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslEquipInspectRecordLine.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordPage.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslEquipInspectRecordMapper.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslEquipInspectRecordLineMapper.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslEquipInspectRecordService.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslEquipInspectRecordServiceImpl.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslEquipInspectRecordController.java +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecordList.vue +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.data.ts +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.api.ts +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordModal.vue +-- author:jiangxh---date:20260520--for: 【MES】点检记录改由设备台账批量生成,去掉记录列表新增与表单选设备--- +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordBatchCreateDTO.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordBatchCreateResult.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslEquipInspectRecordService.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslEquipInspectRecordServiceImpl.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslEquipInspectRecordController.java +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecordList.vue +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.data.ts +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.api.ts +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordModal.vue +jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/MesXslEquipmentLedgerList.vue +-- author:jiangxh---date:20260520--for: 【MES】点检记录录入流程:去导入、待点检录入、保存变已点检--- +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslEquipInspectRecordController.java +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecordList.vue +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.data.ts +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordModal.vue +-- author:jiangxh---date:20260520--for: 【MES】修复点检记录明细图片上传一直转圈(uploadUrl 补全 jeecg-boot 上下文)--- +jeecgboot-vue3/src/api/common/api.ts +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.data.ts +-- author:jiangxh---date:20260520--for: 【MES】修复点检明细图片上传后预览「图片错误」(getFileAccessHttpUrl 补全 context-path)--- +jeecgboot-vue3/src/utils/env/apiBaseUrl.ts +jeecgboot-vue3/src/utils/common/compUtils.ts +jeecgboot-vue3/src/api/common/api.ts +-- author:jiangxh---date:20260520--for: 【MES】设备台账批量点检/保养:未维护对应类型点检配置不生成并提示设备名称--- +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/util/MesXslEquipInspectBizMsg.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslEquipInspectRecordServiceImpl.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslEquipInspectRecordController.java +jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/MesXslEquipmentLedgerList.vue +-- author:jiangxh---date:20260521--for: 【MES】点检保养记录不合格处理:是否已处理/处理人/处理时间字段与处理按钮--- +jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_80__mes_xsl_equip_inspect_record_handle.sql +jeecg-boot/db/mes-xsl-equip-inspect-record-menu-permission.sql +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslEquipInspectRecord.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslEquipInspectRecordHandleDTO.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslEquipInspectRecordService.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslEquipInspectRecordServiceImpl.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslEquipInspectRecordController.java +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.data.ts +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.api.ts +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecordList.vue +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordModal.vue +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordHandleModal.vue diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_79__mes_xsl_equip_inspect_record.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_79__mes_xsl_equip_inspect_record.sql new file mode 100644 index 0000000..bfa8a82 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_79__mes_xsl_equip_inspect_record.sql @@ -0,0 +1,133 @@ +-- MES 点检/保养记录(主子表):建表 + 字典 + 菜单 + 按钮 + 租户 admin 授权 +-- 权限前缀:mes:mes_xsl_equip_inspect_record:* +-- 父菜单:设备管理;依赖设备点检配置、设备台账 +-- Flyway:V3.9.2_79__mes_xsl_equip_inspect_record.sql +SET NAMES utf8mb4; + +INSERT INTO `sys_dict`(`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`, `tenant_id`) +SELECT REPLACE(UUID(), '-', ''), 'MES点检记录结果', 'xslmes_im_inspect_result', '合格/不合格', 0, 'admin', NOW(), 0, 0 +WHERE NOT EXISTS (SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_im_inspect_result' AND `del_flag` = 0); + +INSERT INTO `sys_dict_item`(`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`) +SELECT REPLACE(UUID(), '-', ''), d.`id`, '合格', 'pass', '', 1, 1, 'admin', NOW() +FROM `sys_dict` d +WHERE d.`dict_code` = 'xslmes_im_inspect_result' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.`id` AND i.`item_value` = 'pass'); + +INSERT INTO `sys_dict_item`(`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`) +SELECT REPLACE(UUID(), '-', ''), d.`id`, '不合格', 'fail', '', 2, 1, 'admin', NOW() +FROM `sys_dict` d +WHERE d.`dict_code` = 'xslmes_im_inspect_result' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.`id` AND i.`item_value` = 'fail'); + +INSERT INTO `sys_dict`(`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`, `tenant_id`) +SELECT REPLACE(UUID(), '-', ''), 'MES点检记录状态', 'xslmes_im_record_status', '待点检/已点检', 0, 'admin', NOW(), 0, 0 +WHERE NOT EXISTS (SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_im_record_status' AND `del_flag` = 0); + +INSERT INTO `sys_dict_item`(`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`) +SELECT REPLACE(UUID(), '-', ''), d.`id`, '待点检', 'pending', '', 1, 1, 'admin', NOW() +FROM `sys_dict` d +WHERE d.`dict_code` = 'xslmes_im_record_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.`id` AND i.`item_value` = 'pending'); + +INSERT INTO `sys_dict_item`(`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`) +SELECT REPLACE(UUID(), '-', ''), d.`id`, '已点检', 'done', '', 2, 1, 'admin', NOW() +FROM `sys_dict` d +WHERE d.`dict_code` = 'xslmes_im_record_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.`id` AND i.`item_value` = 'done'); + +CREATE TABLE IF NOT EXISTS `mes_xsl_equip_inspect_record` ( + `id` varchar(32) NOT NULL COMMENT '主键', + `record_no` varchar(32) NOT NULL COMMENT '记录编号(EC+yyyyMMdd+4位流水,租户内按日递增)', + `plan_no` varchar(500) DEFAULT NULL COMMENT '计划单号', + `plan_id` varchar(32) DEFAULT NULL COMMENT '计划主键(隐藏)', + `equipment_ledger_id` varchar(32) NOT NULL COMMENT '设备台账主键 mes_xsl_equipment_ledger.id', + `equipment_code` varchar(500) DEFAULT NULL COMMENT '设备编码冗余', + `equipment_name` varchar(500) DEFAULT NULL COMMENT '设备名称冗余', + `equip_inspect_config_id` varchar(32) DEFAULT NULL COMMENT '设备点检配置主键 mes_xsl_equip_inspect_config.id', + `record_type` varchar(500) NOT NULL COMMENT '类型(字典xslmes_im_item_category:inspect点检/maintain保养)', + `inspect_date` date DEFAULT NULL COMMENT '点检日期', + `inspector_user_id` varchar(32) DEFAULT NULL COMMENT '点检人用户ID', + `inspector_username` varchar(500) DEFAULT NULL COMMENT '点检人账号', + `inspector_realname` varchar(500) DEFAULT NULL COMMENT '点检人姓名', + `inspect_result` varchar(500) NOT NULL COMMENT '点检结果(字典xslmes_im_inspect_result:pass合格/fail不合格)', + `record_status` varchar(500) NOT NULL COMMENT '状态(字典xslmes_im_record_status:pending待点检/done已点检)', + `tenant_id` int DEFAULT NULL COMMENT '租户', + `sys_org_code` varchar(500) DEFAULT NULL COMMENT '部门', + `create_by` varchar(500) DEFAULT NULL COMMENT '创建人', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(500) DEFAULT NULL COMMENT '更新人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `del_flag` int DEFAULT '0' COMMENT '删除标记(0正常1删除)', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_meir_tenant_record_no` (`tenant_id`, `record_no`), + KEY `idx_meir_equip_type` (`equipment_ledger_id`, `record_type`), + KEY `idx_meir_inspect_date` (`inspect_date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES点检保养记录'; + +CREATE TABLE IF NOT EXISTS `mes_xsl_equip_inspect_record_line` ( + `id` varchar(32) NOT NULL COMMENT '主键', + `record_id` varchar(32) NOT NULL COMMENT '主表主键 mes_xsl_equip_inspect_record.id', + `equip_inspect_config_line_id` varchar(32) NOT NULL COMMENT '设备点检配置明细主键 mes_xsl_equip_inspect_config_line.id', + `inspect_maintain_item_id` varchar(32) DEFAULT NULL COMMENT '点检及保养项目主键冗余', + `item_code` varchar(500) DEFAULT NULL COMMENT '点检项目编号冗余', + `item_name` varchar(500) DEFAULT NULL COMMENT '项目名称冗余', + `item_category` varchar(500) DEFAULT NULL COMMENT '项目类别冗余', + `item_type` varchar(500) DEFAULT NULL COMMENT '项目类型冗余', + `equipment_part_name` varchar(500) DEFAULT NULL COMMENT '设备部位冗余', + `equipment_sub_part_name` varchar(500) DEFAULT NULL COMMENT '设备小部位冗余', + `inspect_method` varchar(500) DEFAULT NULL COMMENT '点检方式冗余', + `judgment_criteria` varchar(500) DEFAULT NULL COMMENT '判断基准冗余', + `line_inspect_result` varchar(500) DEFAULT NULL COMMENT '明细点检结果(文本)', + `picture_files` varchar(2000) DEFAULT NULL COMMENT '图片(上传路径,逗号分隔)', + `sort_no` int DEFAULT '0' COMMENT '排序号', + `create_by` varchar(500) DEFAULT NULL COMMENT '创建人', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(500) DEFAULT NULL COMMENT '更新人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_meirl_record` (`record_id`), + KEY `idx_meirl_config_line` (`equip_inspect_config_line_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES点检保养记录明细'; + +SET @mes_tenant_id = 1002; + +SET @mes_equip_pid = ( + SELECT `id` FROM `sys_permission` + WHERE `del_flag` = 0 AND `menu_type` = 0 AND `name` = '设备管理' + LIMIT 1 +); +SET @mes_equip_pid = IFNULL(@mes_equip_pid, '1860000000000000133'); + +INSERT INTO `sys_permission`(`id`, `parent_id`, `name`, `url`, `component`, `component_name`, `menu_type`, `perms`, `perms_type`, `sort_no`, `is_route`, `is_leaf`, `hidden`, `status`, `del_flag`, `keep_alive`, `internal_or_external`, `create_by`, `create_time`) +VALUES ('1860000000000000155', @mes_equip_pid, '点检保养记录', '/xslmes/mesXslEquipInspectRecord', 'xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecordList', 'MesXslEquipInspectRecordList', 1, NULL, '1', 13, 1, 0, 0, '1', 0, 1, 0, 'admin', NOW()) +ON DUPLICATE KEY UPDATE +`parent_id` = VALUES(`parent_id`), `name` = VALUES(`name`), `url` = VALUES(`url`), `component` = VALUES(`component`), `component_name` = VALUES(`component_name`), +`menu_type` = VALUES(`menu_type`), `perms` = VALUES(`perms`), `perms_type` = VALUES(`perms_type`), `sort_no` = VALUES(`sort_no`), +`is_route` = VALUES(`is_route`), `is_leaf` = VALUES(`is_leaf`), `hidden` = VALUES(`hidden`), `status` = VALUES(`status`), `del_flag` = VALUES(`del_flag`), +`keep_alive` = VALUES(`keep_alive`), `internal_or_external` = VALUES(`internal_or_external`), `icon` = 'ant-design:file-done-outlined'; + +UPDATE `sys_permission` SET `icon` = 'ant-design:file-done-outlined' WHERE `id` = '1860000000000000155' AND `del_flag` = 0; + +INSERT INTO `sys_permission`(`id`, `parent_id`, `name`, `menu_type`, `perms`, `perms_type`, `status`, `del_flag`, `create_by`, `create_time`) VALUES +('1860000000000000156', '1860000000000000155', '新增', 2, 'mes:mes_xsl_equip_inspect_record:add', '1', '1', 0, 'admin', NOW()), +('1860000000000000157', '1860000000000000155', '编辑', 2, 'mes:mes_xsl_equip_inspect_record:edit', '1', '1', 0, 'admin', NOW()), +('1860000000000000158', '1860000000000000155', '删除', 2, 'mes:mes_xsl_equip_inspect_record:delete', '1', '1', 0, 'admin', NOW()), +('1860000000000000159', '1860000000000000155', '批量删除', 2, 'mes:mes_xsl_equip_inspect_record:deleteBatch', '1', '1', 0, 'admin', NOW()), +('1860000000000000160', '1860000000000000155', '导出', 2, 'mes:mes_xsl_equip_inspect_record:exportXls', '1', '1', 0, 'admin', NOW()), +('1860000000000000161', '1860000000000000155', '导入', 2, 'mes:mes_xsl_equip_inspect_record:importExcel', '1', '1', 0, 'admin', NOW()) +ON DUPLICATE KEY UPDATE +`parent_id` = VALUES(`parent_id`), `name` = VALUES(`name`), `menu_type` = VALUES(`menu_type`), `perms` = VALUES(`perms`), `perms_type` = VALUES(`perms_type`), +`status` = VALUES(`status`), `del_flag` = VALUES(`del_flag`); + +INSERT INTO `sys_role_permission`(`id`, `role_id`, `permission_id`, `operate_date`, `operate_ip`) +SELECT REPLACE(UUID(), '-', ''), r.`id`, p.`id`, NOW(), '127.0.0.1' +FROM `sys_role` r +CROSS JOIN `sys_permission` p +WHERE r.`tenant_id` = @mes_tenant_id + AND r.`role_code` = 'admin' + AND p.`id` IN ( + '1860000000000000155', + '1860000000000000156', '1860000000000000157', '1860000000000000158', '1860000000000000159', + '1860000000000000160', '1860000000000000161' + ) + AND NOT EXISTS ( + SELECT 1 FROM `sys_role_permission` rp + WHERE rp.`role_id` = r.`id` AND rp.`permission_id` = p.`id` + ); diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_80__mes_xsl_equip_inspect_record_handle.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_80__mes_xsl_equip_inspect_record_handle.sql new file mode 100644 index 0000000..b9ad503 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_80__mes_xsl_equip_inspect_record_handle.sql @@ -0,0 +1,9 @@ +-- MES 点检保养记录:不合格处理字段(是否已处理/处理人/处理时间) +SET NAMES utf8mb4; + +ALTER TABLE `mes_xsl_equip_inspect_record` + ADD COLUMN `handled_flag` varchar(1) DEFAULT NULL COMMENT '是否已处理(字典yn:1是0否,仅不合格记录使用)' AFTER `record_status`, + ADD COLUMN `handler_user_id` varchar(32) DEFAULT NULL COMMENT '处理人用户ID' AFTER `handled_flag`, + ADD COLUMN `handler_username` varchar(500) DEFAULT NULL COMMENT '处理人账号' AFTER `handler_user_id`, + ADD COLUMN `handler_realname` varchar(500) DEFAULT NULL COMMENT '处理人姓名' AFTER `handler_username`, + ADD COLUMN `handle_time` datetime DEFAULT NULL COMMENT '处理时间' AFTER `handler_realname`; diff --git a/jeecgboot-vue3/src/api/common/api.ts b/jeecgboot-vue3/src/api/common/api.ts index fee7386..b481a9b 100644 --- a/jeecgboot-vue3/src/api/common/api.ts +++ b/jeecgboot-vue3/src/api/common/api.ts @@ -1,8 +1,7 @@ import { defHttp } from '/@/utils/http/axios'; import { message } from 'ant-design-vue'; -import { useGlobSetting } from '/@/hooks/setting'; -const globSetting = useGlobSetting(); -const baseUploadUrl = globSetting.uploadUrl; +import { resolveApiBaseUrl } from '/@/utils/env/apiBaseUrl'; + enum Api { positionList = '/sys/position/list', userList = '/sys/user/list', @@ -25,9 +24,9 @@ enum Api { } /** - * 上传父路径 + * 上传地址(须含 context-path;开发环境 domain 仅为 host 时需拼 apiUrl) */ -export const uploadUrl = `${baseUploadUrl}/sys/common/upload`; +export const uploadUrl = `${resolveApiBaseUrl()}/sys/common/upload`; /** * 职务列表 diff --git a/jeecgboot-vue3/src/utils/common/compUtils.ts b/jeecgboot-vue3/src/utils/common/compUtils.ts index 0faab61..a864c42 100644 --- a/jeecgboot-vue3/src/utils/common/compUtils.ts +++ b/jeecgboot-vue3/src/utils/common/compUtils.ts @@ -1,4 +1,3 @@ -import { useGlobSetting } from '/@/hooks/setting'; import { merge, random } from 'lodash-es'; import { isArray } from '/@/utils/is'; import { FormSchema } from '/@/components/Form'; @@ -14,11 +13,10 @@ import { useI18n } from "@/hooks/web/useI18n"; import {$electron} from "@/electron"; import {router} from "@/router"; import {encryptByBase64} from "@/utils/cipher"; +import { resolveApiBaseUrl } from '/@/utils/env/apiBaseUrl'; //存放部门路径的数组 const departNamePath = ref>({}); -const globSetting = useGlobSetting(); -const baseApiUrl = globSetting.domainUrl; /** * 获取文件服务访问路径 * @param fileUrl 文件路径 @@ -31,10 +29,10 @@ export const getFileAccessHttpUrl = (fileUrl, prefix = 'http') => { //判断是否是数组格式 let isArray = fileUrl.indexOf('[') != -1; if (!isArray) { - let prefix = `${baseApiUrl}/sys/common/static/`; + const staticPrefix = `${resolveApiBaseUrl()}/sys/common/static/`; // 判断是否已包含前缀 - if (!fileUrl.startsWith(prefix)) { - result = `${prefix}${fileUrl}`; + if (!fileUrl.startsWith(staticPrefix)) { + result = `${staticPrefix}${fileUrl}`; } } } diff --git a/jeecgboot-vue3/src/utils/env/apiBaseUrl.ts b/jeecgboot-vue3/src/utils/env/apiBaseUrl.ts new file mode 100644 index 0000000..85ccf59 --- /dev/null +++ b/jeecgboot-vue3/src/utils/env/apiBaseUrl.ts @@ -0,0 +1,18 @@ +import { useGlobSetting } from '/@/hooks/setting'; + +/** + * 后端 API 根地址(含 servlet.context-path,如 /jeecg-boot) + * 开发环境 VITE_GLOB_DOMAIN_URL 常为 http://host:port,需与 VITE_GLOB_API_URL 拼接 + */ +export function resolveApiBaseUrl(): string { + const { domainUrl, apiUrl } = useGlobSetting(); + const domain = (domainUrl || '').replace(/\/$/, ''); + const api = apiUrl || ''; + if (!domain) { + return api; + } + if (!api || domain.endsWith(api) || domain.includes(`${api}/`)) { + return domain; + } + return `${domain}${api}`; +} diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.api.ts b/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.api.ts new file mode 100644 index 0000000..9cecbf6 --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.api.ts @@ -0,0 +1,65 @@ +import { defHttp } from '/@/utils/http/axios'; +import { useMessage } from '/@/hooks/web/useMessage'; + +const { createConfirm } = useMessage(); + +enum Api { + list = '/xslmes/mesXslEquipInspectRecord/list', + save = '/xslmes/mesXslEquipInspectRecord/add', + edit = '/xslmes/mesXslEquipInspectRecord/edit', + deleteOne = '/xslmes/mesXslEquipInspectRecord/delete', + deleteBatch = '/xslmes/mesXslEquipInspectRecord/deleteBatch', + importExcel = '/xslmes/mesXslEquipInspectRecord/importExcel', + exportXls = '/xslmes/mesXslEquipInspectRecord/exportXls', + queryById = '/xslmes/mesXslEquipInspectRecord/queryById', + queryLineList = '/xslmes/mesXslEquipInspectRecord/queryLineListByRecordId', + generateRecordNo = '/xslmes/mesXslEquipInspectRecord/generateRecordNo', + loadLinesByEquipment = '/xslmes/mesXslEquipInspectRecord/loadLinesByEquipment', + batchCreateFromEquipment = '/xslmes/mesXslEquipInspectRecord/batchCreateFromEquipment', + handleFail = '/xslmes/mesXslEquipInspectRecord/handleFail', +} + +export const getExportUrl = Api.exportXls; +export const getImportUrl = Api.importExcel; + +export const list = (params) => defHttp.get({ url: Api.list, params }); + +export const queryById = (params: { id: string }) => defHttp.get({ url: Api.queryById, params }); + +export const queryLineListByRecordId = (params: { id: string }) => defHttp.get({ url: Api.queryLineList, params }); + +export const generateRecordNo = () => defHttp.get({ url: Api.generateRecordNo }); + +export const loadLinesByEquipment = (params: { equipmentLedgerId: string; recordType: string }) => + defHttp.get({ url: Api.loadLinesByEquipment, params }); + +export const batchCreateFromEquipment = (params: { equipmentLedgerIds: string[]; recordType: string }) => + defHttp.post({ url: Api.batchCreateFromEquipment, params }); + +export const deleteOne = (params, handleSuccess) => { + return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => { + handleSuccess(); + }); +}; + +export const batchDelete = (params, handleSuccess) => { + createConfirm({ + iconType: 'warning', + title: '确认删除', + content: '是否删除选中数据', + okText: '确认', + cancelText: '取消', + onOk: () => { + return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => { + handleSuccess(); + }); + }, + }); +}; + +export const saveOrUpdate = (params, isUpdate) => { + const url = isUpdate ? Api.edit : Api.save; + return defHttp.post({ url, params }); +}; + +export const handleFailRecord = (params: Recordable) => defHttp.post({ url: Api.handleFail, params }); diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.data.ts b/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.data.ts new file mode 100644 index 0000000..233c85e --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecord.data.ts @@ -0,0 +1,222 @@ +import { BasicColumn, FormSchema } from '/@/components/Table'; +import { JVxeColumn, JVxeTypes } from '/@/components/jeecg/JVxeTable/types'; +import { uploadUrl } from '/@/api/common/api'; + +export const columns: BasicColumn[] = [ + { title: '记录编号', align: 'center', dataIndex: 'recordNo', width: 150 }, + { title: '计划单号', align: 'center', dataIndex: 'planNo', width: 130 }, + { title: '设备名称', align: 'center', dataIndex: 'equipmentName', width: 150 }, + { title: '设备编码', align: 'center', dataIndex: 'equipmentCode', width: 130 }, + { title: '类型', align: 'center', dataIndex: 'recordType_dictText', width: 80 }, + { title: '点检日期', align: 'center', dataIndex: 'inspectDate', width: 110 }, + { title: '点检人', align: 'center', dataIndex: 'inspectorRealname', width: 100 }, + { title: '点检结果', align: 'center', dataIndex: 'inspectResult_dictText', width: 90 }, + { title: '是否已处理', align: 'center', dataIndex: 'handledFlag_dictText', width: 90 }, + { title: '状态', align: 'center', dataIndex: 'recordStatus_dictText', width: 90 }, + { + title: '创建时间', + align: 'center', + dataIndex: 'createTime', + width: 165, + customRender: ({ text }) => (!text ? '' : String(text).length > 19 ? String(text).substring(0, 19) : text), + }, +]; + +export const searchFormSchema: FormSchema[] = [ + { label: '记录编号', field: 'recordNo', component: 'Input', colProps: { span: 6 } }, + { label: '计划单号', field: 'planNo', component: 'Input', colProps: { span: 6 } }, + { label: '设备名称', field: 'equipmentName', component: 'Input', colProps: { span: 6 } }, + { + label: '类型', + field: 'recordType', + component: 'JDictSelectTag', + componentProps: { dictCode: 'xslmes_im_item_category' }, + colProps: { span: 6 }, + }, + { + label: '状态', + field: 'recordStatus', + component: 'JDictSelectTag', + componentProps: { dictCode: 'xslmes_im_record_status' }, + colProps: { span: 6 }, + }, +]; + +export const formSchema: FormSchema[] = [ + { label: '', field: 'id', component: 'Input', show: false }, + { label: '', field: 'equipmentLedgerId', component: 'Input', show: false }, + { label: '', field: 'planId', component: 'Input', show: false }, + { label: '', field: 'equipInspectConfigId', component: 'Input', show: false }, + { label: '', field: 'inspectorUserId', component: 'Input', show: false }, + { label: '', field: 'inspectorUsername', component: 'Input', show: false }, + { + label: '记录编号', + field: 'recordNo', + component: 'Input', + componentProps: { readonly: true, placeholder: '保存时自动生成' }, + dynamicRules: () => [{ required: true, message: '记录编号不能为空' }], + }, + { label: '计划单号', field: 'planNo', component: 'Input' }, + { + label: '设备名称', + field: 'equipmentName', + component: 'Input', + componentProps: { readonly: true }, + }, + { + label: '设备编码', + field: 'equipmentCode', + component: 'Input', + componentProps: { readonly: true }, + }, + { + label: '类型', + field: 'recordType', + component: 'JDictSelectTag', + componentProps: { dictCode: 'xslmes_im_item_category', disabled: true }, + }, + { + label: '点检日期', + field: 'inspectDate', + component: 'DatePicker', + required: true, + componentProps: { valueFormat: 'YYYY-MM-DD', style: { width: '100%' } }, + }, + { + label: '点检人', + field: 'inspectorRealname', + component: 'Input', + componentProps: { readonly: true, placeholder: '当前登录用户' }, + dynamicRules: () => [{ required: true, message: '点检人不能为空' }], + }, + { + label: '点检结果', + field: 'inspectResult', + component: 'JDictSelectTag', + required: true, + componentProps: { dictCode: 'xslmes_im_inspect_result', placeholder: '合格/不合格' }, + }, + { + label: '状态', + field: 'recordStatus', + component: 'JDictSelectTag', + componentProps: { dictCode: 'xslmes_im_record_status', disabled: true }, + }, +]; + +/** 详情页:仅不合格记录展示的处理信息(只读) */ +export const processDisplayFormSchema: FormSchema[] = [ + { + label: '是否已处理', + field: 'handledFlag', + component: 'JDictSelectTag', + componentProps: { dictCode: 'yn', disabled: true }, + }, + { + label: '处理人', + field: 'handlerRealname', + component: 'Input', + componentProps: { readonly: true }, + }, + { + label: '处理时间', + field: 'handleTime', + component: 'DatePicker', + componentProps: { + showTime: true, + valueFormat: 'YYYY-MM-DD HH:mm:ss', + style: { width: '100%' }, + disabled: true, + }, + }, +]; + +/** 不合格记录处理弹窗 */ +export const handleFormSchema: FormSchema[] = [ + { label: '', field: 'id', component: 'Input', show: false }, + { label: '', field: 'handlerUsername', component: 'Input', show: false }, + { label: '', field: 'handlerRealname', component: 'Input', show: false }, + { + label: '处理人', + field: 'handlerUserId', + component: 'JSelectUser', + required: true, + componentProps: ({ formActionType }) => ({ + rowKey: 'id', + labelKey: 'realname', + isRadioSelection: true, + maxSelectCount: 1, + onOptionsChange: (options) => { + const row = options?.[0]; + if (row && formActionType) { + formActionType.setFieldsValue({ + handlerUsername: row.username, + handlerRealname: row.realname, + }); + } + }, + }), + }, + { + label: '处理时间', + field: 'handleTime', + component: 'DatePicker', + required: true, + componentProps: { + showTime: true, + valueFormat: 'YYYY-MM-DD HH:mm:ss', + style: { width: '100%' }, + }, + }, +]; + +export const lineJVxeColumns: JVxeColumn[] = [ + { title: '', key: 'equipInspectConfigLineId', type: JVxeTypes.hidden }, + { title: '', key: 'inspectMaintainItemId', type: JVxeTypes.hidden }, + { title: '点检项目编号', key: 'itemCode', type: JVxeTypes.normal, width: 120, disabled: true }, + { title: '点检项目', key: 'itemName', type: JVxeTypes.normal, width: 130, disabled: true }, + { + title: '项目类别', + key: 'itemCategory', + type: JVxeTypes.select, + width: 90, + disabled: true, + dictCode: 'xslmes_im_item_category', + filters: false, + sortable: false, + }, + { + title: '项目类型', + key: 'itemType', + type: JVxeTypes.select, + width: 90, + disabled: true, + dictCode: 'xslmes_im_item_type', + filters: false, + sortable: false, + }, + { title: '设备部位', key: 'equipmentPartName', type: JVxeTypes.normal, width: 100, disabled: true }, + { title: '设备小部位', key: 'equipmentSubPartName', type: JVxeTypes.normal, width: 100, disabled: true }, + { + title: '点检方式', + key: 'inspectMethod', + type: JVxeTypes.select, + width: 90, + disabled: true, + dictCode: 'xslmes_im_inspect_method', + filters: false, + sortable: false, + }, + { title: '判断基准', key: 'judgmentCriteria', type: JVxeTypes.normal, width: 150, disabled: true }, + { title: '点检描述', key: 'lineInspectResult', type: JVxeTypes.input, width: 140 }, + { + title: '图片', + key: 'pictureFiles', + type: JVxeTypes.image, + width: 160, + maxCount: 3, + token: true, + action: uploadUrl, + responseName: 'message', + }, +]; diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecordList.vue b/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecordList.vue new file mode 100644 index 0000000..e2727d4 --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecordList.vue @@ -0,0 +1,153 @@ + + + diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordHandleModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordHandleModal.vue new file mode 100644 index 0000000..9252bb2 --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordHandleModal.vue @@ -0,0 +1,63 @@ + + + diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordModal.vue new file mode 100644 index 0000000..0570d68 --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordModal.vue @@ -0,0 +1,173 @@ + + + diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/MesXslEquipmentLedgerList.vue b/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/MesXslEquipmentLedgerList.vue index 11fe9a1..e6abef8 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/MesXslEquipmentLedgerList.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/MesXslEquipmentLedgerList.vue @@ -5,6 +5,24 @@ 新增 + + 点检 + + + 保养 + r.id).filter(Boolean); + const typeLabel = recordType === 'inspect' ? '点检' : '保养'; + createConfirm({ + iconType: 'info', + title: `生成${typeLabel}记录`, + content: `确定为选中的 ${ids.length} 台设备各生成一条${typeLabel}记录?`, + okText: '确定', + cancelText: '取消', + onOk: async () => { + try { + const res = await batchCreateFromEquipment({ equipmentLedgerIds: ids, recordType }); + const data = (res as any)?.result ?? res; + const failList: string[] = data?.failMessages || []; + const successCount = data?.successCount ?? 0; + if (successCount > 0 && !failList.length) { + createMessage.success(`成功生成 ${successCount} 条${typeLabel}记录`); + handleSuccess(); + } else if (successCount > 0 && failList.length) { + createMessage.warning(`成功生成 ${successCount} 条;未生成:${failList.join(';')}`); + handleSuccess(); + } else if (failList.length) { + createMessage.warning(failList.join(';')); + } else { + createMessage.warning((res as any)?.message || `未生成任何${typeLabel}记录`); + } + } catch (e: any) { + const errMsg = + e?.response?.data?.message || e?.message || `生成${typeLabel}记录失败`; + createMessage.warning(errMsg); + } + }, + }); + } + function getDropDownAction(record: Recordable) { return [ { label: '详情', onClick: handleDetail.bind(null, record) },