| @@ -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<Long>() { | |||
| @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) | |||
| @@ -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<String, Any>): List<Map<String, Any>> { | |||
| 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 { | |||
| @@ -18,26 +18,40 @@ open class EquipmentService( | |||
| } | |||
| open fun getEquipmentsByPage(args: Map<String, Any>): List<Map<String, Any>> { | |||
| 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) | |||
| @@ -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<Map<String, Any>>, 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) | |||
| @@ -0,0 +1,6 @@ | |||
| package com.ffii.fpsms.modules.master.web.models | |||
| data class UpdateMaintenanceRequest( | |||
| val repairAndMaintenanceStatus: Boolean?, | |||
| val repairAndMaintenanceRemarks: String? | |||
| ) | |||