@@ -4,6 +4,7 @@ plugins { | |||||
id 'io.spring.dependency-management' version '1.1.0' | id 'io.spring.dependency-management' version '1.1.0' | ||||
id 'org.jetbrains.kotlin.jvm' | id 'org.jetbrains.kotlin.jvm' | ||||
id 'org.jetbrains.kotlin.plugin.serialization' version '1.8.0' | id 'org.jetbrains.kotlin.plugin.serialization' version '1.8.0' | ||||
} | } | ||||
group = 'com.ffii' | group = 'com.ffii' | ||||
@@ -2,8 +2,10 @@ package com.ffii.fpsms; | |||||
import org.springframework.boot.SpringApplication; | import org.springframework.boot.SpringApplication; | ||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
import org.springframework.context.annotation.ComponentScan; | |||||
@SpringBootApplication | @SpringBootApplication | ||||
@ComponentScan(basePackages = {"com.ffii.fpsms", "com.ffii.core"}) | |||||
public class FpsmsApplication { | public class FpsmsApplication { | ||||
public static void main(String[] args) { | public static void main(String[] args) { | ||||
@@ -6,6 +6,13 @@ import java.util.Optional | |||||
@Repository | @Repository | ||||
interface EquipmentRepository : AbstractRepository<Equipment, Long> { | interface EquipmentRepository : AbstractRepository<Equipment, Long> { | ||||
fun findByNameAndDeletedIsFalse(name: String): Equipment? | |||||
fun findByCodeAndDeletedIsFalse(code: String): Equipment? | |||||
fun findAllByDeletedFalse(): List<Equipment>; | |||||
fun findByCodeAndDeletedFalse(code: String): Equipment? | |||||
fun findByIdAndDeletedFalse(id: Long): Equipment?; | |||||
fun findByCodeAndDeletedIsFalse(code: String): Equipment?; | |||||
fun findByNameAndDeletedIsFalse(name: String): Equipment?; | |||||
fun findByDescriptionAndDeletedIsFalse(description: String): Equipment?; | |||||
} | } |
@@ -24,4 +24,6 @@ open class EquipmentType : BaseEntity<Long>() { | |||||
@NotNull | @NotNull | ||||
@Column(name = "description", nullable = false, length = 500) | @Column(name = "description", nullable = false, length = 500) | ||||
open var description: String? = null | open var description: String? = null | ||||
} | } |
@@ -5,4 +5,13 @@ import org.springframework.stereotype.Repository | |||||
@Repository | @Repository | ||||
interface EquipmentTypeRepository : AbstractRepository<EquipmentType, Long> { | interface EquipmentTypeRepository : AbstractRepository<EquipmentType, Long> { | ||||
fun findAllByDeletedFalse(): List<EquipmentType>; | |||||
fun findByCodeAndDeletedFalse(code: String): EquipmentType? | |||||
fun findByIdAndDeletedFalse(id: Long): EquipmentType?; | |||||
fun findByCodeAndDeletedIsFalse(code: String): EquipmentType?; | |||||
fun findByNameAndDeletedIsFalse(name: String): EquipmentType?; | |||||
fun findByDescriptionAndDeletedIsFalse(description: String): EquipmentType?; | |||||
} | } |
@@ -0,0 +1,94 @@ | |||||
package com.ffii.fpsms.modules.master.service | |||||
import com.ffii.core.support.AbstractBaseEntityService | |||||
import com.ffii.core.support.JdbcDao | |||||
import com.ffii.fpsms.modules.master.entity.Equipment | |||||
import com.ffii.fpsms.modules.master.entity.EquipmentRepository | |||||
import org.springframework.stereotype.Service | |||||
import org.springframework.transaction.annotation.Transactional | |||||
import com.ffii.fpsms.modules.master.web.models.NewEquipmentRequest | |||||
@Service | |||||
open class EquipmentService( | |||||
private val jdbcDao: JdbcDao, | |||||
private val equipmentRepository: EquipmentRepository, | |||||
) : AbstractBaseEntityService<Equipment, Long, EquipmentRepository>(jdbcDao, equipmentRepository) { | |||||
open fun allEquipments(): List<Equipment> { | |||||
return equipmentRepository.findAll() | |||||
} | |||||
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) | |||||
} | |||||
open fun findById(id: Long): Equipment? { | |||||
return equipmentRepository.findByIdAndDeletedFalse(id) | |||||
} | |||||
open fun findByCode(code: String): Equipment? { | |||||
return equipmentRepository.findByCodeAndDeletedIsFalse(code) | |||||
} | |||||
open fun findByName(name: String): Equipment? { | |||||
return equipmentRepository.findByNameAndDeletedIsFalse(name) | |||||
} | |||||
open fun findByDescription(description: String): Equipment? { | |||||
return equipmentRepository.findByDescriptionAndDeletedIsFalse(description) | |||||
} | |||||
@Transactional | |||||
open fun saveEquipment(request: NewEquipmentRequest): Equipment { | |||||
if (request.code.isNullOrBlank()) { | |||||
throw IllegalArgumentException("Equipment type code cannot be null or blank") | |||||
} | |||||
val duplicated = equipmentRepository.findByCodeAndDeletedFalse(request.code!!) | |||||
if (duplicated != null && duplicated.id != request.id) { | |||||
throw IllegalArgumentException("Equipment type code already exists") | |||||
} | |||||
val entity = if (request.id != null && request.id > 0) { | |||||
equipmentRepository.findByIdAndDeletedFalse(request.id) ?: Equipment() | |||||
} else { | |||||
Equipment() | |||||
} | |||||
entity.code = request.code | |||||
entity.name = request.name | |||||
entity.description = request.description | |||||
entity.equipmentType= request.equipmentType | |||||
return equipmentRepository.saveAndFlush(entity) | |||||
} | |||||
@Transactional | |||||
open fun deleteEquipment(id: Long) { | |||||
val Equipment = equipmentRepository.findByIdAndDeletedFalse(id) | |||||
Equipment?.let { et -> | |||||
et.deleted = true | |||||
equipmentRepository.saveAndFlush(et) | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,90 @@ | |||||
package com.ffii.fpsms.modules.master.service | |||||
import com.ffii.core.support.AbstractBaseEntityService | |||||
import com.ffii.core.support.JdbcDao | |||||
import com.ffii.fpsms.modules.master.entity.EquipmentType | |||||
import com.ffii.fpsms.modules.master.entity.EquipmentTypeRepository | |||||
import org.springframework.stereotype.Service | |||||
import org.springframework.transaction.annotation.Transactional | |||||
import com.ffii.fpsms.modules.master.web.models.NewEquipmentTypeRequest | |||||
@Service | |||||
open class EquipmentTypeService( | |||||
private val jdbcDao: JdbcDao, | |||||
private val equipmentTypeRepository: EquipmentTypeRepository, | |||||
) : AbstractBaseEntityService<EquipmentType, Long, EquipmentTypeRepository>(jdbcDao, equipmentTypeRepository) { | |||||
open fun allEquipmentTypes(): List<EquipmentType> { | |||||
return equipmentTypeRepository.findAll() | |||||
} | |||||
open fun getEquipmentTypesByPage(args: Map<String, Any>): List<Map<String, Any>> { | |||||
val sql = StringBuilder( | |||||
"SELECT e.id, e.code, e.name, e.description FROM equipment_type 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 ") | |||||
} | |||||
return jdbcDao.queryForList(sql.toString(), args) | |||||
} | |||||
open fun findById(id: Long): EquipmentType? { | |||||
return equipmentTypeRepository.findByIdAndDeletedFalse(id) | |||||
} | |||||
open fun findByCode(code: String): EquipmentType? { | |||||
return equipmentTypeRepository.findByCodeAndDeletedIsFalse(code) | |||||
} | |||||
open fun findByName(name: String): EquipmentType? { | |||||
return equipmentTypeRepository.findByNameAndDeletedIsFalse(name) | |||||
} | |||||
open fun findByDescription(description: String): EquipmentType? { | |||||
return equipmentTypeRepository.findByDescriptionAndDeletedIsFalse(description) | |||||
} | |||||
@Transactional | |||||
open fun saveEquipmentType(request: NewEquipmentTypeRequest): EquipmentType { | |||||
if (request.code.isNullOrBlank()) { | |||||
throw IllegalArgumentException("Equipment type code cannot be null or blank") | |||||
} | |||||
val duplicated = equipmentTypeRepository.findByCodeAndDeletedFalse(request.code!!) | |||||
if (duplicated != null && duplicated.id != request.id) { | |||||
throw IllegalArgumentException("Equipment type code already exists") | |||||
} | |||||
val entity = if (request.id != null && request.id > 0) { | |||||
equipmentTypeRepository.findByIdAndDeletedFalse(request.id) ?: EquipmentType() | |||||
} else { | |||||
EquipmentType() | |||||
} | |||||
entity.code = request.code | |||||
entity.name = request.name | |||||
entity.description = request.description | |||||
return equipmentTypeRepository.saveAndFlush(entity) | |||||
} | |||||
@Transactional | |||||
open fun deleteEquipmentType(id: Long) { | |||||
val equipmentType = equipmentTypeRepository.findByIdAndDeletedFalse(id) | |||||
equipmentType?.let { et -> | |||||
et.deleted = true | |||||
equipmentTypeRepository.saveAndFlush(et) | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,76 @@ | |||||
package com.ffii.fpsms.modules.master.web | |||||
import com.ffii.core.response.RecordsRes | |||||
import com.ffii.core.utils.CriteriaArgsBuilder | |||||
import com.ffii.core.utils.PagingUtils | |||||
import com.ffii.fpsms.modules.master.entity.Equipment | |||||
import com.ffii.fpsms.modules.master.service.EquipmentService | |||||
import jakarta.servlet.http.HttpServletRequest | |||||
import jakarta.validation.Valid | |||||
import org.springframework.web.bind.annotation.* | |||||
import java.util.Collections.emptyList | |||||
import com.ffii.fpsms.modules.master.web.models.NewEquipmentRequest | |||||
@RestController | |||||
@RequestMapping("/Equipment") | |||||
class EquipmentController( | |||||
private val equipmentService: EquipmentService | |||||
) { | |||||
@GetMapping | |||||
fun allEquipment(): List<Equipment> { | |||||
return equipmentService.allEquipments() | |||||
} | |||||
// @GetMapping("/getRecordByPage") | |||||
// fun getAllItemsByPage(@RequestBody filterRequest: HttpServletRequest): RecordsRes<Map<String, Any>> { | |||||
// val pageSize = filterRequest.getParameter("pageSize").toString().toInt(); // Default to 10 if not provided | |||||
// val pageNumber = filterRequest.getParameter("pageNum").toString().toInt(); // Default to 0 if not provided | |||||
// val criteriaArgs = CriteriaArgsBuilder.withRequest(filterRequest) | |||||
// .addStringLike("name") | |||||
// .build(); | |||||
// | |||||
// val fullList = itemsService.getItemsByPage(criteriaArgs)?.subList(pageSize*pageNumber+1, pageSize*pageNumber+pageSize) | |||||
// val outputList = fullList?.subList(pageSize*pageNumber+1, pageSize*pageNumber+pageSize) | |||||
// | |||||
// return RecordsRes(outputList as List<Map<String, Any>>?, fullList?.size) | |||||
// } | |||||
@GetMapping("/getRecordByPage") | |||||
fun getAllEquipmentByPage( | |||||
request: HttpServletRequest | |||||
): RecordsRes<Map<String, Any>> { | |||||
val criteriaArgs = CriteriaArgsBuilder.withRequest(request) | |||||
.addStringLike("name") | |||||
.addStringLike("code") | |||||
.addStringLike("description") | |||||
.addStringLike("id") | |||||
.build() | |||||
val pageSize = request.getParameter("pageSize")?.toIntOrNull() ?: 10 | |||||
val pageNum = request.getParameter("pageNum")?.toIntOrNull() ?: 1 | |||||
// 方法名和变量名都要和 Service 保持一致 | |||||
val fullList = equipmentService.getEquipmentsByPage(criteriaArgs) ?: emptyList() | |||||
val paginatedList = PagingUtils.getPaginatedList(fullList, pageSize, pageNum) | |||||
return RecordsRes(paginatedList as List<Map<String, Any>>, fullList.size) | |||||
} | |||||
// 详情 | |||||
@GetMapping("/details/{id}") | |||||
fun getEquipment(@PathVariable id: Long): Equipment? { | |||||
return equipmentService.findById(id) | |||||
} | |||||
// 新增/编辑 | |||||
@PostMapping("/save") | |||||
fun saveEquipment(@Valid @RequestBody equipment: NewEquipmentRequest): Equipment { | |||||
return equipmentService.saveEquipment(equipment) | |||||
} | |||||
// 逻辑删除 | |||||
@DeleteMapping("/delete/{id}") | |||||
fun deleteEquipment(@PathVariable id: Long) { | |||||
equipmentService.deleteEquipment(id) | |||||
} | |||||
} |
@@ -0,0 +1,76 @@ | |||||
package com.ffii.fpsms.modules.master.web | |||||
import com.ffii.core.response.RecordsRes | |||||
import com.ffii.core.utils.CriteriaArgsBuilder | |||||
import com.ffii.core.utils.PagingUtils | |||||
import com.ffii.fpsms.modules.master.entity.EquipmentType | |||||
import com.ffii.fpsms.modules.master.service.EquipmentTypeService | |||||
import jakarta.servlet.http.HttpServletRequest | |||||
import jakarta.validation.Valid | |||||
import org.springframework.web.bind.annotation.* | |||||
import java.util.Collections.emptyList | |||||
import com.ffii.fpsms.modules.master.web.models.NewEquipmentTypeRequest | |||||
@RestController | |||||
@RequestMapping("/EquipmentType") | |||||
class EquipmentTypeController( | |||||
private val equipmentTypeService: EquipmentTypeService | |||||
) { | |||||
@GetMapping | |||||
fun allEquipmentType(): List<EquipmentType> { | |||||
return equipmentTypeService.allEquipmentTypes() | |||||
} | |||||
// @GetMapping("/getRecordByPage") | |||||
// fun getAllItemsByPage(@RequestBody filterRequest: HttpServletRequest): RecordsRes<Map<String, Any>> { | |||||
// val pageSize = filterRequest.getParameter("pageSize").toString().toInt(); // Default to 10 if not provided | |||||
// val pageNumber = filterRequest.getParameter("pageNum").toString().toInt(); // Default to 0 if not provided | |||||
// val criteriaArgs = CriteriaArgsBuilder.withRequest(filterRequest) | |||||
// .addStringLike("name") | |||||
// .build(); | |||||
// | |||||
// val fullList = itemsService.getItemsByPage(criteriaArgs)?.subList(pageSize*pageNumber+1, pageSize*pageNumber+pageSize) | |||||
// val outputList = fullList?.subList(pageSize*pageNumber+1, pageSize*pageNumber+pageSize) | |||||
// | |||||
// return RecordsRes(outputList as List<Map<String, Any>>?, fullList?.size) | |||||
// } | |||||
@GetMapping("/getRecordByPage") | |||||
fun getAllEquipmentTypeByPage( | |||||
request: HttpServletRequest | |||||
): RecordsRes<Map<String, Any>> { | |||||
val criteriaArgs = CriteriaArgsBuilder.withRequest(request) | |||||
.addStringLike("name") | |||||
.addStringLike("code") | |||||
.addStringLike("description") | |||||
.addStringLike("id") | |||||
.build() | |||||
val pageSize = request.getParameter("pageSize")?.toIntOrNull() ?: 10 | |||||
val pageNum = request.getParameter("pageNum")?.toIntOrNull() ?: 1 | |||||
// 方法名和变量名都要和 Service 保持一致 | |||||
val fullList = equipmentTypeService.getEquipmentTypesByPage(criteriaArgs) ?: emptyList() | |||||
val paginatedList = PagingUtils.getPaginatedList(fullList, pageSize, pageNum) | |||||
return RecordsRes(paginatedList as List<Map<String, Any>>, fullList.size) | |||||
} | |||||
// 详情 | |||||
@GetMapping("/details/{id}") | |||||
fun getEquipmentType(@PathVariable id: Long): EquipmentType? { | |||||
return equipmentTypeService.findById(id) | |||||
} | |||||
// 新增/编辑 | |||||
@PostMapping("/save") | |||||
fun saveEquipmentType(@Valid @RequestBody equipmentType: NewEquipmentTypeRequest): EquipmentType { | |||||
return equipmentTypeService.saveEquipmentType(equipmentType) | |||||
} | |||||
// 逻辑删除 | |||||
@DeleteMapping("/delete/{id}") | |||||
fun deleteEquipmentType(@PathVariable id: Long) { | |||||
equipmentTypeService.deleteEquipmentType(id) | |||||
} | |||||
} |
@@ -0,0 +1,28 @@ | |||||
package com.ffii.fpsms.modules.master.web.models | |||||
import com.ffii.fpsms.modules.master.entity.EquipmentType | |||||
import jakarta.validation.constraints.NotBlank | |||||
import jakarta.validation.constraints.NotNull | |||||
import java.time.LocalDateTime | |||||
/* | |||||
enum class EquipmentType(val type: String) { | |||||
MATERIAL("mat"), | |||||
BY_PRODUCT("byp"), | |||||
PRODUCT("product"), | |||||
CONSUMABLE("consumables"), | |||||
} | |||||
*/ | |||||
data class NewEquipmentRequest( | |||||
@field:NotBlank(message = "material code cannot be empty") | |||||
val code: String, | |||||
@field:NotBlank(message = "material name cannot be empty") | |||||
val name: String, | |||||
val id: Long?, | |||||
val description: String?, | |||||
val equipmentType: EquipmentType?, | |||||
// val type: List<NewTypeRequest>?, | |||||
// val uom: List<NewUomRequest>?, | |||||
// val weightUnit: List<NewWeightUnitRequest>?, | |||||
) | |||||
@@ -0,0 +1,26 @@ | |||||
package com.ffii.fpsms.modules.master.web.models | |||||
import jakarta.validation.constraints.NotBlank | |||||
import jakarta.validation.constraints.NotNull | |||||
import java.time.LocalDateTime | |||||
/* | |||||
enum class EquipmentType(val type: String) { | |||||
MATERIAL("mat"), | |||||
BY_PRODUCT("byp"), | |||||
PRODUCT("product"), | |||||
CONSUMABLE("consumables"), | |||||
} | |||||
*/ | |||||
data class NewEquipmentTypeRequest( | |||||
@field:NotBlank(message = "material code cannot be empty") | |||||
val code: String, | |||||
@field:NotBlank(message = "material name cannot be empty") | |||||
val name: String, | |||||
val id: Long?, | |||||
val description: String?, | |||||
// val type: List<NewTypeRequest>?, | |||||
// val uom: List<NewUomRequest>?, | |||||
// val weightUnit: List<NewWeightUnitRequest>?, | |||||
) | |||||
@@ -69,4 +69,5 @@ class PurchaseOrderController( | |||||
fun checkPolAndCompletePo(@PathVariable id: Long): MessageResponse { | fun checkPolAndCompletePo(@PathVariable id: Long): MessageResponse { | ||||
return purchaseOrderService.checkPolAndCompletePo(id) | return purchaseOrderService.checkPolAndCompletePo(id) | ||||
} | } | ||||
} | } |
@@ -1,5 +1,5 @@ | |||||
spring: | spring: | ||||
datasource: | datasource: | ||||
jdbc-url: jdbc:mysql://127.0.0.1:3306/fpsmsdb?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
jdbc-url: jdbc:mysql://127.0.0.1:3308/fpsmsdb?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
username: root | username: root | ||||
password: secret | password: secret |
@@ -0,0 +1,10 @@ | |||||
-- liquibase formatted sql | |||||
-- changeset enson:add_EquipmentType_column | |||||
ALTER TABLE `equipment_type` | |||||
ADD COLUMN `equipmentTypeID` VARCHAR(30) NULL AFTER `description`, | |||||
ADD COLUMN `equipmentTypeCapacity` INT(11) NULL AFTER `EquipmentTypeID`, | |||||
ADD COLUMN `equipmentTypeUom` VARCHAR(30) NULL AFTER `equipmentTypeCapacity` | |||||
; |
@@ -14,4 +14,5 @@ Configutation: | |||||
Root: | Root: | ||||
level: info | level: info | ||||
AppenderRef: | AppenderRef: | ||||
- ref: Console_Appender | |||||
- ref: Console_Appender | |||||