| @@ -6,6 +6,7 @@ import jakarta.persistence.Entity | |||||
| import jakarta.persistence.Table | import jakarta.persistence.Table | ||||
| import jakarta.validation.constraints.NotNull | import jakarta.validation.constraints.NotNull | ||||
| import jakarta.validation.constraints.Size | import jakarta.validation.constraints.Size | ||||
| import java.time.LocalDateTime | |||||
| @Table(name = "equipment_detail") | @Table(name = "equipment_detail") | ||||
| @Entity | @Entity | ||||
| @@ -15,6 +16,19 @@ open class EquipmentDetail : BaseEntity<Long>() { | |||||
| @Column(name = "equipmentCode", nullable = true, length = 255) | @Column(name = "equipmentCode", nullable = true, length = 255) | ||||
| open var equipmentCode: String? = null | 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) | @Size(max = 30) | ||||
| @NotNull | @NotNull | ||||
| @Column(name = "code", nullable = false, length = 30) | @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.stereotype.Service | ||||
| import org.springframework.transaction.annotation.Transactional | import org.springframework.transaction.annotation.Transactional | ||||
| import com.ffii.fpsms.modules.master.web.models.NewEquipmentDetailRequest | import com.ffii.fpsms.modules.master.web.models.NewEquipmentDetailRequest | ||||
| import com.ffii.fpsms.modules.master.web.models.UpdateMaintenanceRequest | |||||
| import java.time.LocalDateTime | |||||
| @Service | @Service | ||||
| open class EquipmentDetailService( | open class EquipmentDetailService( | ||||
| private val jdbcDao: JdbcDao, | private val jdbcDao: JdbcDao, | ||||
| @@ -18,21 +21,54 @@ open class EquipmentDetailService( | |||||
| } | } | ||||
| open fun getEquipmentDetailsByPage(args: Map<String, Any>): List<Map<String, Any>> { | open fun getEquipmentDetailsByPage(args: Map<String, Any>): List<Map<String, Any>> { | ||||
| println("Search args: $args") | |||||
| val sql = StringBuilder( | 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")) { | if (args.containsKey("id")) { | ||||
| sql.append(" AND e.id like :id ") | sql.append(" AND e.id like :id ") | ||||
| } | } | ||||
| if (args.containsKey("name")) { | if (args.containsKey("name")) { | ||||
| sql.append(" AND e.name like :name ") | |||||
| sql.append(" AND LOWER(e.name) LIKE LOWER(:name) ") | |||||
| } | } | ||||
| if (args.containsKey("description")) { | if (args.containsKey("description")) { | ||||
| sql.append(" AND e.description like :description ") | sql.append(" AND e.description like :description ") | ||||
| } | } | ||||
| if (args.containsKey("repairAndMaintenanceStatus")) { | |||||
| sql.append(" AND e.repairAndMaintenanceStatus = :repairAndMaintenanceStatus ") | |||||
| } | |||||
| return jdbcDao.queryForList(sql.toString(), args) | return jdbcDao.queryForList(sql.toString(), args) | ||||
| } | } | ||||
| @@ -51,6 +87,42 @@ open class EquipmentDetailService( | |||||
| open fun findByDescription(description: String): EquipmentDetail? { | open fun findByDescription(description: String): EquipmentDetail? { | ||||
| return equipmentDetailRepository.findByDescriptionAndDeletedIsFalse(description) | 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 | @Transactional | ||||
| open fun saveEquipmentDetail(request: NewEquipmentDetailRequest): EquipmentDetail { | open fun saveEquipmentDetail(request: NewEquipmentDetailRequest): EquipmentDetail { | ||||
| @@ -18,26 +18,40 @@ open class EquipmentService( | |||||
| } | } | ||||
| open fun getEquipmentsByPage(args: Map<String, Any>): List<Map<String, Any>> { | 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? { | open fun findById(id: Long): Equipment? { | ||||
| return equipmentRepository.findByIdAndDeletedFalse(id) | return equipmentRepository.findByIdAndDeletedFalse(id) | ||||
| @@ -10,6 +10,8 @@ import jakarta.validation.Valid | |||||
| import org.springframework.web.bind.annotation.* | import org.springframework.web.bind.annotation.* | ||||
| import java.util.Collections.emptyList | import java.util.Collections.emptyList | ||||
| import com.ffii.fpsms.modules.master.web.models.NewEquipmentDetailRequest | import com.ffii.fpsms.modules.master.web.models.NewEquipmentDetailRequest | ||||
| import com.ffii.fpsms.modules.master.web.models.UpdateMaintenanceRequest | |||||
| @RestController | @RestController | ||||
| @RequestMapping("/EquipmentDetail") | @RequestMapping("/EquipmentDetail") | ||||
| class EquipmentDetailController( | class EquipmentDetailController( | ||||
| @@ -43,31 +45,38 @@ fun getAllEquipmentDetailByPage( | |||||
| .addStringLike("code") | .addStringLike("code") | ||||
| .addStringLike("description") | .addStringLike("description") | ||||
| .addStringLike("id") | .addStringLike("id") | ||||
| .addStringLike("equipmentCode") | |||||
| .addBoolean("repairAndMaintenanceStatus") | |||||
| .build() | .build() | ||||
| val pageSize = request.getParameter("pageSize")?.toIntOrNull() ?: 10 | val pageSize = request.getParameter("pageSize")?.toIntOrNull() ?: 10 | ||||
| val pageNum = request.getParameter("pageNum")?.toIntOrNull() ?: 1 | val pageNum = request.getParameter("pageNum")?.toIntOrNull() ?: 1 | ||||
| // 方法名和变量名都要和 Service 保持一致 | |||||
| val fullList = equipmentDetailService.getEquipmentDetailsByPage(criteriaArgs) ?: emptyList() | val fullList = equipmentDetailService.getEquipmentDetailsByPage(criteriaArgs) ?: emptyList() | ||||
| val paginatedList = PagingUtils.getPaginatedList(fullList, pageSize, pageNum) | val paginatedList = PagingUtils.getPaginatedList(fullList, pageSize, pageNum) | ||||
| return RecordsRes(paginatedList as List<Map<String, Any>>, fullList.size) | return RecordsRes(paginatedList as List<Map<String, Any>>, fullList.size) | ||||
| } | } | ||||
| // 详情 | |||||
| @GetMapping("/details/{id}") | @GetMapping("/details/{id}") | ||||
| fun getEquipmentDetail(@PathVariable id: Long): EquipmentDetail? { | fun getEquipmentDetail(@PathVariable id: Long): EquipmentDetail? { | ||||
| return equipmentDetailService.findById(id) | return equipmentDetailService.findById(id) | ||||
| } | } | ||||
| @PutMapping("/update/{id}") | |||||
| fun updateMaintenanceAndRepair( | |||||
| @PathVariable id: Long, | |||||
| @RequestBody request: UpdateMaintenanceRequest | |||||
| ): EquipmentDetail { | |||||
| return equipmentDetailService.updateMaintenanceAndRepair(id, request) | |||||
| } | |||||
| /* | /* | ||||
| // 新增/编辑 | |||||
| @PostMapping("/save") | @PostMapping("/save") | ||||
| fun saveEquipmentDetail(@Valid @RequestBody equipmentDetail: NewEquipmentDetailRequest): EquipmentDetail { | fun saveEquipmentDetail(@Valid @RequestBody equipmentDetail: NewEquipmentDetailRequest): EquipmentDetail { | ||||
| return equipmentDetailService.saveEquipmentDetail(equipmentDetail) | return equipmentDetailService.saveEquipmentDetail(equipmentDetail) | ||||
| } | } | ||||
| */ | */ | ||||
| // 逻辑删除 | |||||
| @DeleteMapping("/delete/{id}") | @DeleteMapping("/delete/{id}") | ||||
| fun deleteEquipmentDetail(@PathVariable id: Long) { | fun deleteEquipmentDetail(@PathVariable id: Long) { | ||||
| equipmentDetailService.deleteEquipmentDetail(id) | equipmentDetailService.deleteEquipmentDetail(id) | ||||
| @@ -0,0 +1,6 @@ | |||||
| package com.ffii.fpsms.modules.master.web.models | |||||
| data class UpdateMaintenanceRequest( | |||||
| val repairAndMaintenanceStatus: Boolean?, | |||||
| val repairAndMaintenanceRemarks: String? | |||||
| ) | |||||