From 8aa86ec2b6bd6ab1ad71131d990eed7f29500fea Mon Sep 17 00:00:00 2001 From: "B.E.N.S.O.N" Date: Mon, 5 Jan 2026 19:27:24 +0800 Subject: [PATCH] Supporting Function: Equipment Repair & Maintenance --- .../modules/master/entity/EquipmentDetail.kt | 14 ++++ .../master/service/EquipmentDetailService.kt | 80 ++++++++++++++++++- .../master/service/EquipmentService.kt | 52 +++++++----- .../master/web/EquipmentDetailController.kt | 17 +++- .../master/web/UpdateMaintenanceRequest.kt | 6 ++ 5 files changed, 142 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/ffii/fpsms/modules/master/web/UpdateMaintenanceRequest.kt diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/EquipmentDetail.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/EquipmentDetail.kt index efda5c8..2e10d80 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/EquipmentDetail.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/EquipmentDetail.kt @@ -6,6 +6,7 @@ import jakarta.persistence.Entity import jakarta.persistence.Table import jakarta.validation.constraints.NotNull import jakarta.validation.constraints.Size +import java.time.LocalDateTime @Table(name = "equipment_detail") @Entity @@ -15,6 +16,19 @@ open class EquipmentDetail : BaseEntity() { @Column(name = "equipmentCode", nullable = true, length = 255) open var equipmentCode: String? = null + @Column(name = "repairAndMaintenanceStatus", nullable = true) + open var repairAndMaintenanceStatus: Boolean? = null + + @Column(name = "latestRepairAndMaintenanceDate", nullable = true) + open var latestRepairAndMaintenanceDate: LocalDateTime? = null + + @Column(name = "lastRepairAndMaintenanceDate", nullable = true) + open var lastRepairAndMaintenanceDate: LocalDateTime? = null + + @Size(max = 255) + @Column(name = "repairAndMaintenanceRemarks", nullable = true, length = 255) + open var repairAndMaintenanceRemarks: String? = null + @Size(max = 30) @NotNull @Column(name = "code", nullable = false, length = 30) diff --git a/src/main/java/com/ffii/fpsms/modules/master/service/EquipmentDetailService.kt b/src/main/java/com/ffii/fpsms/modules/master/service/EquipmentDetailService.kt index 008184a..d14144d 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/service/EquipmentDetailService.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/service/EquipmentDetailService.kt @@ -7,6 +7,9 @@ import com.ffii.fpsms.modules.master.entity.EquipmentDetailRepository import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import com.ffii.fpsms.modules.master.web.models.NewEquipmentDetailRequest +import com.ffii.fpsms.modules.master.web.models.UpdateMaintenanceRequest +import java.time.LocalDateTime + @Service open class EquipmentDetailService( private val jdbcDao: JdbcDao, @@ -18,21 +21,54 @@ open class EquipmentDetailService( } open fun getEquipmentDetailsByPage(args: Map): List> { + println("Search args: $args") + val sql = StringBuilder( - "SELECT e.id, e.code, e.name, e.description FROM equipment_detail e WHERE e.deleted = FALSE" + """ + SELECT + e.id AS id, + e.code AS code, + e.name AS name, + e.description AS description, + e.equipmentCode AS equipmentCode, + e.repairAndMaintenanceStatus AS repairAndMaintenanceStatus, + e.latestRepairAndMaintenanceDate AS latestRepairAndMaintenanceDate, + e.lastRepairAndMaintenanceDate AS lastRepairAndMaintenanceDate, + e.repairAndMaintenanceRemarks AS repairAndMaintenanceRemarks + FROM equipment_detail e + WHERE e.deleted = FALSE + """ ) - if (args.containsKey("code")) { - sql.append(" AND e.code like :code ") + + // Handle combined search for code and equipmentCode (OR logic) + val searchTerm = args["equipmentCode"] as? String + val codeTerm = args["code"] as? String + + if (searchTerm != null && codeTerm != null && searchTerm == codeTerm) { + // When both are provided with the same value, search using OR + sql.append(" AND (LOWER(e.code) LIKE LOWER(:equipmentCode) OR LOWER(e.equipmentCode) LIKE LOWER(:equipmentCode)) ") + } else { + // Otherwise, use individual conditions + if (codeTerm != null && (searchTerm == null || searchTerm != codeTerm)) { + sql.append(" AND LOWER(e.code) LIKE LOWER(:code) ") + } + if (searchTerm != null && (codeTerm == null || searchTerm != codeTerm)) { + sql.append(" AND LOWER(e.equipmentCode) LIKE LOWER(:equipmentCode) ") + } } + if (args.containsKey("id")) { sql.append(" AND e.id like :id ") } if (args.containsKey("name")) { - sql.append(" AND e.name like :name ") + sql.append(" AND LOWER(e.name) LIKE LOWER(:name) ") } if (args.containsKey("description")) { sql.append(" AND e.description like :description ") } + if (args.containsKey("repairAndMaintenanceStatus")) { + sql.append(" AND e.repairAndMaintenanceStatus = :repairAndMaintenanceStatus ") + } return jdbcDao.queryForList(sql.toString(), args) } @@ -51,6 +87,42 @@ open class EquipmentDetailService( open fun findByDescription(description: String): EquipmentDetail? { return equipmentDetailRepository.findByDescriptionAndDeletedIsFalse(description) } + + @Transactional + open fun updateMaintenanceAndRepair( + id: Long, + request: UpdateMaintenanceRequest + ): EquipmentDetail { + val equipmentDetail = findById(id) + ?: throw IllegalArgumentException("Equipment detail not found with id: $id") + + // Store the previous status and latest date before updating + val previousStatus = equipmentDetail.repairAndMaintenanceStatus + val previousLatestDate = equipmentDetail.latestRepairAndMaintenanceDate + + // Update status and remarks + equipmentDetail.repairAndMaintenanceStatus = request.repairAndMaintenanceStatus + equipmentDetail.repairAndMaintenanceRemarks = request.repairAndMaintenanceRemarks + + // Handle date updates based on status change + when { + // Changing from "是" (true) to "否" (false) + previousStatus == true && request.repairAndMaintenanceStatus == false -> { + // Save current latestRepairAndMaintenanceDate to lastRepairAndMaintenanceDate + equipmentDetail.lastRepairAndMaintenanceDate = previousLatestDate + // Update latestRepairAndMaintenanceDate to current time + equipmentDetail.latestRepairAndMaintenanceDate = LocalDateTime.now() + } + // Changing from "否" (false) to "是" (true) + // Keep dates unchanged - no action needed + previousStatus == false && request.repairAndMaintenanceStatus == true -> { + // Dates remain unchanged + } + // Other cases (null to true/false, or same status) - no date changes + } + + return equipmentDetailRepository.saveAndFlush(equipmentDetail) + } /* @Transactional open fun saveEquipmentDetail(request: NewEquipmentDetailRequest): EquipmentDetail { diff --git a/src/main/java/com/ffii/fpsms/modules/master/service/EquipmentService.kt b/src/main/java/com/ffii/fpsms/modules/master/service/EquipmentService.kt index e40444d..9bc2d8f 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/service/EquipmentService.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/service/EquipmentService.kt @@ -18,26 +18,40 @@ open class EquipmentService( } open fun getEquipmentsByPage(args: Map): List> { - val sql = StringBuilder( - "SELECT e.id, e.code, e.name, e.description, e.equipmentTypeId FROM equipment e WHERE e.deleted = FALSE" - ) - if (args.containsKey("code")) { - sql.append(" AND e.code like :code ") - } - if (args.containsKey("id")) { - sql.append(" AND e.id like :id ") - } - if (args.containsKey("name")) { - sql.append(" AND e.name like :name ") - } - if (args.containsKey("description")) { - sql.append(" AND e.description like :description ") - } - if (args.containsKey("equipmentTypeId")) { - sql.append(" AND e.equipmentTypeId like :equipmentTypeId ") - } - return jdbcDao.queryForList(sql.toString(), args) + val sql = StringBuilder( + """ + SELECT + e.id AS id, + e.code AS code, + e.name AS name, + e.description AS description, + e.equipmentTypeId AS equipmentTypeId, + ed.repairAndMaintenanceStatus AS repairAndMaintenanceStatus, + ed.latestRepairAndMaintenanceDate AS latestRepairAndMaintenanceDate, + ed.lastRepairAndMaintenanceDate AS lastRepairAndMaintenanceDate, + ed.repairAndMaintenanceRemarks AS repairAndMaintenanceRemarks + FROM equipment e + LEFT JOIN equipment_detail ed ON e.code = ed.equipmentCode + WHERE e.deleted = FALSE + """ + ) + if (args.containsKey("code")) { + sql.append(" AND e.code like :code ") + } + if (args.containsKey("id")) { + sql.append(" AND e.id like :id ") + } + if (args.containsKey("name")) { + sql.append(" AND e.name like :name ") + } + if (args.containsKey("description")) { + sql.append(" AND e.description like :description ") + } + if (args.containsKey("equipmentTypeId")) { + sql.append(" AND e.equipmentTypeId like :equipmentTypeId ") } + return jdbcDao.queryForList(sql.toString(), args) +} open fun findById(id: Long): Equipment? { return equipmentRepository.findByIdAndDeletedFalse(id) diff --git a/src/main/java/com/ffii/fpsms/modules/master/web/EquipmentDetailController.kt b/src/main/java/com/ffii/fpsms/modules/master/web/EquipmentDetailController.kt index bfa06d3..b62cc14 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/web/EquipmentDetailController.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/web/EquipmentDetailController.kt @@ -10,6 +10,8 @@ import jakarta.validation.Valid import org.springframework.web.bind.annotation.* import java.util.Collections.emptyList import com.ffii.fpsms.modules.master.web.models.NewEquipmentDetailRequest +import com.ffii.fpsms.modules.master.web.models.UpdateMaintenanceRequest + @RestController @RequestMapping("/EquipmentDetail") class EquipmentDetailController( @@ -43,31 +45,38 @@ fun getAllEquipmentDetailByPage( .addStringLike("code") .addStringLike("description") .addStringLike("id") + .addStringLike("equipmentCode") + .addBoolean("repairAndMaintenanceStatus") .build() val pageSize = request.getParameter("pageSize")?.toIntOrNull() ?: 10 val pageNum = request.getParameter("pageNum")?.toIntOrNull() ?: 1 - // 方法名和变量名都要和 Service 保持一致 val fullList = equipmentDetailService.getEquipmentDetailsByPage(criteriaArgs) ?: emptyList() val paginatedList = PagingUtils.getPaginatedList(fullList, pageSize, pageNum) return RecordsRes(paginatedList as List>, fullList.size) } - // 详情 @GetMapping("/details/{id}") fun getEquipmentDetail(@PathVariable id: Long): EquipmentDetail? { return equipmentDetailService.findById(id) } + + @PutMapping("/update/{id}") + fun updateMaintenanceAndRepair( + @PathVariable id: Long, + @RequestBody request: UpdateMaintenanceRequest + ): EquipmentDetail { + return equipmentDetailService.updateMaintenanceAndRepair(id, request) + } /* - // 新增/编辑 @PostMapping("/save") fun saveEquipmentDetail(@Valid @RequestBody equipmentDetail: NewEquipmentDetailRequest): EquipmentDetail { return equipmentDetailService.saveEquipmentDetail(equipmentDetail) } */ - // 逻辑删除 + @DeleteMapping("/delete/{id}") fun deleteEquipmentDetail(@PathVariable id: Long) { equipmentDetailService.deleteEquipmentDetail(id) diff --git a/src/main/java/com/ffii/fpsms/modules/master/web/UpdateMaintenanceRequest.kt b/src/main/java/com/ffii/fpsms/modules/master/web/UpdateMaintenanceRequest.kt new file mode 100644 index 0000000..bed17d5 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/master/web/UpdateMaintenanceRequest.kt @@ -0,0 +1,6 @@ +package com.ffii.fpsms.modules.master.web.models + +data class UpdateMaintenanceRequest( + val repairAndMaintenanceStatus: Boolean?, + val repairAndMaintenanceRemarks: String? +) \ No newline at end of file