refactor: new SQL and API

This commit is contained in:
SOR
2026-08-06 16:26:46 +08:00
parent b56f7bd9bf
commit f13aef29b3
22 changed files with 27 additions and 685 deletions
@@ -1,49 +0,0 @@
package club.itstudio.itmanager.controller.v1
import club.itstudio.itmanager.utils.Const
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import reactor.core.publisher.Mono
@Validated
@RestController
@RequestMapping("/api/v1/evaluation-records")
class EvaluationRecordsController {
// evaluation-records/ GET/POST/PUT/DELETE 考评记录 CRUD 操作
@GetMapping("", "/")
fun getRecords(): Mono<String> = Const.INTERNAL_ERROR_MONO
@PostMapping("", "/")
fun createRecord(): Mono<String> = Const.INTERNAL_ERROR_MONO
@PutMapping("", "/")
fun updateRecord(): Mono<String> = Const.INTERNAL_ERROR_MONO
@DeleteMapping("", "/")
fun deleteRecord(@RequestParam(required = false) id: String?): Mono<String> = Const.INTERNAL_ERROR_MONO
// evaluation-records/personnel-summary/ GET 获取人员考评汇总
@GetMapping("/personnel-summary", "/personnel-summary/")
fun getPersonnelSummary(): Mono<String> = Const.INTERNAL_ERROR_MONO
// evaluation-records/personnel-records/ GET 获取某个人员的所有考评记录
@GetMapping("/personnel-records", "/personnel-records/")
fun getPersonnelRecords(@RequestParam(required = false) personId: String?): Mono<String> = Const.INTERNAL_ERROR_MONO
// evaluation-records/delete-personnel/ DELETE 删除某个人员的所有考评记录
@DeleteMapping("/delete-personnel", "/delete-personnel/")
fun deletePersonnelRecords(@RequestParam(required = false) personId: String?): Mono<String> = Const.INTERNAL_ERROR_MONO
// evaluation-records/export/ GET 导出考评记录为 Excel
@GetMapping("/export", "/export/")
fun exportRecords(): Mono<String> = Const.INTERNAL_ERROR_MONO
// evaluation-records/download-template/ GET 下载人员导入样表
@GetMapping("/download-template", "/download-template/")
fun downloadTemplate(): Mono<String> = Const.INTERNAL_ERROR_MONO
// evaluation-records/import/ POST 导入考评记录
@PostMapping("/import", "/import/")
fun importRecords(): Mono<String> = Const.INTERNAL_ERROR_MONO
}
@@ -1,33 +0,0 @@
package club.itstudio.itmanager.controller.v1
import club.itstudio.itmanager.utils.Const
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import reactor.core.publisher.Mono
@Validated
@RestController
@RequestMapping("/api/v1/memos")
class MemosController {
// memos/ GET/POST/PUT/DELETE 备忘录 CRUD 操作
@GetMapping("", "/")
fun getMemos(): Mono<String> = Const.INTERNAL_ERROR_MONO
@PostMapping("", "/")
fun createMemo(): Mono<String> = Const.INTERNAL_ERROR_MONO
@PutMapping("", "/")
fun updateMemo(): Mono<String> = Const.INTERNAL_ERROR_MONO
@DeleteMapping("", "/")
fun deleteMemo(@RequestParam(required = false) id: String?): Mono<String> = Const.INTERNAL_ERROR_MONO
// memos/{id}/upload_image/ POST 上传备忘录图片
@PostMapping("/{id}/upload_image", "/{id}/upload_image/")
fun uploadImage(@PathVariable("id") id: String): Mono<String> = Const.INTERNAL_ERROR_MONO
// memos/{id}/delete_image/ DELETE 删除备忘录图片
@DeleteMapping("/{id}/delete_image", "/{id}/delete_image/")
fun deleteImage(@PathVariable("id") id: String): Mono<String> = Const.INTERNAL_ERROR_MONO
}
@@ -1,45 +0,0 @@
package club.itstudio.itmanager.controller.v1
import club.itstudio.itmanager.utils.Const
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import reactor.core.publisher.Mono
@Validated
@RestController
@RequestMapping("/api/v1/personnel")
class PersonnelController {
// personnel/ GET/POST/PUT/DELETE 人员信息 CRUD 操作
@GetMapping("", "/")
fun getPersonnel(): Mono<String> = Const.INTERNAL_ERROR_MONO
@PostMapping("", "/")
fun createPersonnel(): Mono<String> = Const.INTERNAL_ERROR_MONO
@PutMapping("", "/")
fun updatePersonnel(): Mono<String> = Const.INTERNAL_ERROR_MONO
@DeleteMapping("", "/")
fun deletePersonnel(@RequestParam(required = false) id: String?): Mono<String> = Const.INTERNAL_ERROR_MONO
// personnel/statistics/ GET 获取人员统计信息(按部门和职位)
@GetMapping("/statistics", "/statistics/")
fun getStatistics(): Mono<String> = Const.INTERNAL_ERROR_MONO
// personnel/{id}/set_inactive/ POST 设置人员为已卸任状态
@PostMapping("/{id}/set_inactive", "/{id}/set_inactive/")
fun setInactive(@PathVariable("id") id: String): Mono<String> = Const.INTERNAL_ERROR_MONO
// personnel/{id}/set_active/ POST 设置人员为在职状态
@PostMapping("/{id}/set_active", "/{id}/set_active/")
fun setActive(@PathVariable("id") id: String): Mono<String> = Const.INTERNAL_ERROR_MONO
// personnel/{id}/ DELETE 删除人员(发送邮件通知)
@DeleteMapping("/{id}", "/{id}/")
fun deleteById(@PathVariable("id") id: String): Mono<String> = Const.INTERNAL_ERROR_MONO
// personnel/check_expired/ POST 检查并更新已到期的人员状态
@PostMapping("/check_expired", "/check_expired/")
fun checkExpired(): Mono<String> = Const.INTERNAL_ERROR_MONO
}
@@ -1,33 +0,0 @@
package club.itstudio.itmanager.controller.v1
import club.itstudio.itmanager.utils.Const
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import reactor.core.publisher.Mono
@Validated
@RestController
@RequestMapping("/api/v1/project-groups")
class ProjectGroupsController {
// project-groups/ GET/POST/PUT/DELETE 项目组 CRUD 操作
@GetMapping("", "/")
fun getProjectGroups(): Mono<String> = Const.INTERNAL_ERROR_MONO
@PostMapping("", "/")
fun createProjectGroup(): Mono<String> = Const.INTERNAL_ERROR_MONO
@PutMapping("", "/")
fun updateProjectGroup(): Mono<String> = Const.INTERNAL_ERROR_MONO
@DeleteMapping("", "/")
fun deleteProjectGroup(@RequestParam(required = false) id: String?): Mono<String> = Const.INTERNAL_ERROR_MONO
// project-groups/by_department/ GET 按部门获取项目组
@GetMapping("/by_department", "/by_department/")
fun getByDepartment(@RequestParam(required = false) departmentId: String?): Mono<String> = Const.INTERNAL_ERROR_MONO
// project-groups/{id}/ DELETE 删除项目组(发送邮件通知)
@DeleteMapping("/{id}", "/{id}/")
fun deleteById(@PathVariable("id") id: String): Mono<String> = Const.INTERNAL_ERROR_MONO
}
@@ -13,13 +13,13 @@ data class BorrowRecord(
@TableId(type = IdType.AUTO)
val id: Long? = null,
val itemId: Long = 0,
val borrowerId: Long = 0,
val borrower: String = "",
val quantity: Int = 1,
val borrowDate: LocalDateTime? = null,
val dueDate: LocalDateTime? = null,
val returnDate: LocalDateTime? = null,
val status: String = "BORROWED", // BORROWED / RETURNED / OVERDUE / CANCELED
val approverId: Long? = null,
val approver: String? = null,
val note: String? = null,
val createdAt: LocalDateTime? = null,
val updatedAt: LocalDateTime? = null
@@ -1,20 +0,0 @@
package club.itstudio.itmanager.entity.dto
import com.baomidou.mybatisplus.annotation.IdType
import com.baomidou.mybatisplus.annotation.TableId
import com.baomidou.mybatisplus.annotation.TableName
import club.itstudio.itmanager.entity.DataCopy
import kotlinx.datetime.LocalDateTime
import kotlinx.serialization.Serializable
@Serializable
@TableName("evaluations")
data class Evaluation(
@TableId(type = IdType.AUTO)
val id: Long? = null,
val relatedItemId: Long? = null,
val evaluatorId: Long? = null,
val score: Short? = null, // 1-5
val comment: String? = null,
val createdAt: LocalDateTime? = null
) : DataCopy
@@ -1,22 +0,0 @@
package club.itstudio.itmanager.entity.dto
import com.baomidou.mybatisplus.annotation.IdType
import com.baomidou.mybatisplus.annotation.TableId
import com.baomidou.mybatisplus.annotation.TableName
import club.itstudio.itmanager.entity.DataCopy
import kotlinx.datetime.LocalDateTime
import kotlinx.serialization.Serializable
@Serializable
@TableName("memos")
data class Memo(
@TableId(type = IdType.AUTO)
val id: Long? = null,
val title: String? = null,
val content: String? = null,
val authorId: Long? = null,
val relatedItemId: Long? = null,
val isPublic: Boolean = false,
val createdAt: LocalDateTime? = null,
val updatedAt: LocalDateTime? = null
) : DataCopy
@@ -1,25 +0,0 @@
package club.itstudio.itmanager.entity.dto
import com.baomidou.mybatisplus.annotation.IdType
import com.baomidou.mybatisplus.annotation.TableId
import com.baomidou.mybatisplus.annotation.TableName
import club.itstudio.itmanager.entity.DataCopy
import kotlinx.datetime.LocalDateTime
import kotlinx.serialization.Serializable
@Serializable
@TableName("personnel")
data class Personnel(
@TableId(type = IdType.AUTO)
val id: Long? = null,
val userId: Long? = null,
val employeeNo: String? = null,
val name: String = "",
val departmentId: Long? = null,
val phone: String? = null,
val email: String? = null,
val role: String? = null,
val isActive: Boolean = true,
val createdAt: LocalDateTime? = null,
val updatedAt: LocalDateTime? = null
) : DataCopy
@@ -1,8 +0,0 @@
package club.itstudio.itmanager.mapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper
import club.itstudio.itmanager.entity.dto.Evaluation
import org.apache.ibatis.annotations.Mapper
@Mapper
interface EvaluationMapper : BaseMapper<Evaluation>
@@ -1,8 +0,0 @@
package club.itstudio.itmanager.mapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper
import club.itstudio.itmanager.entity.dto.Memo
import org.apache.ibatis.annotations.Mapper
@Mapper
interface MemoMapper : BaseMapper<Memo>
@@ -1,8 +0,0 @@
package club.itstudio.itmanager.mapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper
import club.itstudio.itmanager.entity.dto.Personnel
import org.apache.ibatis.annotations.Mapper
@Mapper
interface PersonnelMapper : BaseMapper<Personnel>
@@ -7,7 +7,7 @@ import reactor.core.publisher.Mono
interface BorrowRecordService : IService<BorrowRecord> {
fun getBorrowRecordById(id: Long): Mono<BorrowRecord>
fun listByItem(itemId: Long): Mono<List<BorrowRecord>>
fun listByBorrower(borrowerId: Long): Mono<List<BorrowRecord>>
fun listByBorrower(borrower: String): Mono<List<BorrowRecord>>
fun listByStatus(status: String): Mono<List<BorrowRecord>>
fun listOverdueRecords(): Mono<List<BorrowRecord>>
fun createBorrowRecord(record: BorrowRecord): Mono<Boolean>
@@ -1,17 +0,0 @@
package club.itstudio.itmanager.service
import com.baomidou.mybatisplus.extension.service.IService
import club.itstudio.itmanager.entity.dto.Evaluation
import reactor.core.publisher.Mono
interface EvaluationService : IService<Evaluation> {
fun getEvaluationById(id: Long): Mono<Evaluation>
fun listByEvaluator(evaluatorId: Long): Mono<List<Evaluation>>
fun listByRelatedItem(itemId: Long): Mono<List<Evaluation>>
fun listByScore(score: Short): Mono<List<Evaluation>>
fun createEvaluation(evaluation: Evaluation): Mono<Boolean>
fun updateEvaluation(evaluation: Evaluation): Mono<Boolean>
fun deleteEvaluation(id: Long): Mono<Boolean>
fun deleteByEvaluator(evaluatorId: Long): Mono<Boolean>
fun exportAllEvaluations(): Mono<List<Evaluation>>
}
@@ -1,17 +0,0 @@
package club.itstudio.itmanager.service
import com.baomidou.mybatisplus.extension.service.IService
import club.itstudio.itmanager.entity.dto.Memo
import reactor.core.publisher.Mono
interface MemoService : IService<Memo> {
fun getMemoById(id: Long): Mono<Memo>
fun searchMemos(keyword: String?): Mono<List<Memo>>
fun listByAuthor(authorId: Long): Mono<List<Memo>>
fun listByRelatedItem(itemId: Long): Mono<List<Memo>>
fun listPublicMemos(): Mono<List<Memo>>
fun createMemo(memo: Memo): Mono<Boolean>
fun updateMemo(memo: Memo): Mono<Boolean>
fun deleteMemo(id: Long): Mono<Boolean>
fun exportAllMemos(): Mono<List<Memo>>
}
@@ -1,17 +0,0 @@
package club.itstudio.itmanager.service
import com.baomidou.mybatisplus.extension.service.IService
import club.itstudio.itmanager.entity.dto.Personnel
import reactor.core.publisher.Mono
interface PersonnelService : IService<Personnel> {
fun getPersonnelById(id: Long): Mono<Personnel>
fun searchPersonnel(keyword: String?): Mono<List<Personnel>>
fun listByDepartment(departmentId: Long): Mono<List<Personnel>>
fun listByRole(role: String): Mono<List<Personnel>>
fun createPersonnel(personnel: Personnel): Mono<Boolean>
fun updatePersonnel(personnel: Personnel): Mono<Boolean>
fun deletePersonnel(id: Long): Mono<Boolean>
fun setActive(id: Long, active: Boolean): Mono<Boolean>
fun exportAllPersonnel(): Mono<List<Personnel>>
}
@@ -30,10 +30,10 @@ class BorrowRecordServiceImpl : ServiceImpl<BorrowRecordMapper, BorrowRecord>(),
ktQuery().eq(BorrowRecord::itemId, itemId).list()
}
override fun listByBorrower(borrowerId: Long): Mono<List<BorrowRecord>> =
override fun listByBorrower(borrower: String): Mono<List<BorrowRecord>> =
blockingCall {
logger.info("Searching borrow records by borrower id")
ktQuery().eq(BorrowRecord::borrowerId, borrowerId).list()
logger.info("Searching borrow records by borrower")
ktQuery().eq(BorrowRecord::borrower, borrower).list()
}
override fun listByStatus(status: String): Mono<List<BorrowRecord>> =
@@ -1,74 +0,0 @@
package club.itstudio.itmanager.service.impl
import club.itstudio.itmanager.entity.dto.Evaluation
import club.itstudio.itmanager.mapper.EvaluationMapper
import club.itstudio.itmanager.service.EvaluationService
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import reactor.core.publisher.Mono
import reactor.core.scheduler.Schedulers
import java.util.NoSuchElementException
@Service
class EvaluationServiceImpl : ServiceImpl<EvaluationMapper, Evaluation>(), EvaluationService {
private val logger = LoggerFactory.getLogger(this::class.java)
private fun <T : Any> blockingCall(block: () -> T?): Mono<T> =
Mono.fromCallable(block).subscribeOn(Schedulers.boundedElastic())
override fun getEvaluationById(id: Long): Mono<Evaluation> =
blockingCall {
logger.info("Searching evaluation by id")
ktQuery().eq(Evaluation::id, id).one()
}.switchIfEmpty(Mono.error(NoSuchElementException("Evaluation not found")))
override fun listByEvaluator(evaluatorId: Long): Mono<List<Evaluation>> =
blockingCall {
logger.info("Searching evaluations by evaluator id")
ktQuery().eq(Evaluation::evaluatorId, evaluatorId).list()
}
override fun listByRelatedItem(itemId: Long): Mono<List<Evaluation>> =
blockingCall {
logger.info("Searching evaluations by related item id")
ktQuery().eq(Evaluation::relatedItemId, itemId).list()
}
override fun listByScore(score: Short): Mono<List<Evaluation>> =
blockingCall {
logger.info("Searching evaluations by score")
ktQuery().eq(Evaluation::score, score).list()
}
override fun createEvaluation(evaluation: Evaluation): Mono<Boolean> =
blockingCall {
logger.info("Creating evaluation")
save(evaluation)
}
override fun updateEvaluation(evaluation: Evaluation): Mono<Boolean> =
blockingCall {
logger.info("Updating evaluation")
updateById(evaluation)
}
override fun deleteEvaluation(id: Long): Mono<Boolean> =
blockingCall {
logger.info("Deleting evaluation by id")
removeById(id)
}
override fun deleteByEvaluator(evaluatorId: Long): Mono<Boolean> =
blockingCall {
logger.info("Deleting evaluations by evaluator id")
remove(ktQuery().eq(Evaluation::evaluatorId, evaluatorId))
}
override fun exportAllEvaluations(): Mono<List<Evaluation>> =
blockingCall {
logger.info("Exporting all evaluations")
list()
}
}
@@ -1,80 +0,0 @@
package club.itstudio.itmanager.service.impl
import club.itstudio.itmanager.entity.dto.Memo
import club.itstudio.itmanager.mapper.MemoMapper
import club.itstudio.itmanager.service.MemoService
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import reactor.core.publisher.Mono
import reactor.core.scheduler.Schedulers
import java.util.NoSuchElementException
@Service
class MemoServiceImpl : ServiceImpl<MemoMapper, Memo>(), MemoService {
private val logger = LoggerFactory.getLogger(this::class.java)
private fun <T : Any> blockingCall(block: () -> T?): Mono<T> =
Mono.fromCallable(block).subscribeOn(Schedulers.boundedElastic())
override fun getMemoById(id: Long): Mono<Memo> =
blockingCall {
logger.info("Searching memo by id")
ktQuery().eq(Memo::id, id).one()
}.switchIfEmpty(Mono.error(NoSuchElementException("Memo not found")))
override fun searchMemos(keyword: String?): Mono<List<Memo>> =
blockingCall {
logger.info("Searching memos with keyword")
if (keyword.isNullOrBlank()) {
list()
} else {
ktQuery().and {
it.like(Memo::title, keyword).or().like(Memo::content, keyword)
}.list()
}
}
override fun listByAuthor(authorId: Long): Mono<List<Memo>> =
blockingCall {
logger.info("Searching memos by author id")
ktQuery().eq(Memo::authorId, authorId).list()
}
override fun listByRelatedItem(itemId: Long): Mono<List<Memo>> =
blockingCall {
logger.info("Searching memos by related item id")
ktQuery().eq(Memo::relatedItemId, itemId).list()
}
override fun listPublicMemos(): Mono<List<Memo>> =
blockingCall {
logger.info("Listing public memos")
ktQuery().eq(Memo::isPublic, true).list()
}
override fun createMemo(memo: Memo): Mono<Boolean> =
blockingCall {
logger.info("Creating memo")
save(memo)
}
override fun updateMemo(memo: Memo): Mono<Boolean> =
blockingCall {
logger.info("Updating memo")
updateById(memo)
}
override fun deleteMemo(id: Long): Mono<Boolean> =
blockingCall {
logger.info("Deleting memo by id")
removeById(id)
}
override fun exportAllMemos(): Mono<List<Memo>> =
blockingCall {
logger.info("Exporting all memos")
list()
}
}
@@ -1,83 +0,0 @@
package club.itstudio.itmanager.service.impl
import club.itstudio.itmanager.entity.dto.Personnel
import club.itstudio.itmanager.mapper.PersonnelMapper
import club.itstudio.itmanager.service.PersonnelService
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import reactor.core.publisher.Mono
import reactor.core.scheduler.Schedulers
import java.util.NoSuchElementException
@Service
class PersonnelServiceImpl : ServiceImpl<PersonnelMapper, Personnel>(), PersonnelService {
private val logger = LoggerFactory.getLogger(this::class.java)
private fun <T : Any> blockingCall(block: () -> T?): Mono<T> =
Mono.fromCallable(block).subscribeOn(Schedulers.boundedElastic())
override fun getPersonnelById(id: Long): Mono<Personnel> =
blockingCall {
logger.info("Searching personnel by id")
ktQuery().eq(Personnel::id, id).one()
}.switchIfEmpty(Mono.error(NoSuchElementException("Personnel not found")))
override fun searchPersonnel(keyword: String?): Mono<List<Personnel>> =
blockingCall {
logger.info("Searching personnel with keyword")
if (keyword.isNullOrBlank()) {
list()
} else {
ktQuery().and {
it.like(Personnel::name, keyword)
.or().like(Personnel::employeeNo, keyword)
.or().like(Personnel::phone, keyword)
.or().like(Personnel::email, keyword)
}.list()
}
}
override fun listByDepartment(departmentId: Long): Mono<List<Personnel>> =
blockingCall {
logger.info("Searching personnel by department id")
ktQuery().eq(Personnel::departmentId, departmentId).list()
}
override fun listByRole(role: String): Mono<List<Personnel>> =
blockingCall {
logger.info("Searching personnel by role")
ktQuery().eq(Personnel::role, role).list()
}
override fun createPersonnel(personnel: Personnel): Mono<Boolean> =
blockingCall {
logger.info("Creating personnel")
save(personnel)
}
override fun updatePersonnel(personnel: Personnel): Mono<Boolean> =
blockingCall {
logger.info("Updating personnel")
updateById(personnel)
}
override fun deletePersonnel(id: Long): Mono<Boolean> =
blockingCall {
logger.info("Deleting personnel by id")
removeById(id)
}
override fun setActive(id: Long, active: Boolean): Mono<Boolean> =
blockingCall {
logger.info("Setting personnel active status")
ktUpdate().eq(Personnel::id, id).set(Personnel::isActive, active).update()
}
override fun exportAllPersonnel(): Mono<List<Personnel>> =
blockingCall {
logger.info("Exporting all personnel")
list()
}
}