From 906fccf6194b4f39bf5571074597272e1d16f006 Mon Sep 17 00:00:00 2001 From: Puqns67 Date: Mon, 18 Sep 2023 21:10:21 +0800 Subject: [PATCH] rename remove as revoke, update order logic Signed-off-by: Puqns67 --- .../fruitable/controller/action/Account.kt | 1 + .../fruitable/controller/action/Order.kt | 148 +++++++++++++++++- .../controller/action/editor/Item.kt | 35 +++-- .../controller/action/editor/User.kt | 21 +-- .../team8/fruitable/controller/page/Editor.kt | 14 +- .../team8/fruitable/datebase/entity/Item.kt | 16 +- .../team8/fruitable/datebase/entity/Order.kt | 55 ++++++- .../fruitable/datebase/entity/OrderedItem.kt | 6 +- .../fruitable/datebase/entity/PayType.kt | 4 - .../team8/fruitable/datebase/entity/User.kt | 7 + .../datebase/repository/OrderRepository.kt | 6 + .../repository/OrderedItemRepository.kt | 9 ++ .../datebase/repository/PayTypeRepository.kt | 6 + 13 files changed, 270 insertions(+), 58 deletions(-) create mode 100644 src/main/kotlin/team8/fruitable/datebase/repository/OrderRepository.kt create mode 100644 src/main/kotlin/team8/fruitable/datebase/repository/OrderedItemRepository.kt create mode 100644 src/main/kotlin/team8/fruitable/datebase/repository/PayTypeRepository.kt diff --git a/src/main/kotlin/team8/fruitable/controller/action/Account.kt b/src/main/kotlin/team8/fruitable/controller/action/Account.kt index 3fda1e2..4fb40ba 100644 --- a/src/main/kotlin/team8/fruitable/controller/action/Account.kt +++ b/src/main/kotlin/team8/fruitable/controller/action/Account.kt @@ -38,6 +38,7 @@ class Account(private val repository: AccountRepository) { if (this.getCurrentUser(token) != null) return error(attributes, "登录", "当前已登录账户") val user = repository.findByName(name) ?: return error(attributes, "登录", "账户不存在", "/login") if (!user.testPassword(password)) return error(attributes, "登录", "密码错误", "/login") + if (user.isRevoked) return error(attributes, "登录", "此账户已被吊销", "/login") user.updateToken() user.updateLoginTime() repository.save(user) diff --git a/src/main/kotlin/team8/fruitable/controller/action/Order.kt b/src/main/kotlin/team8/fruitable/controller/action/Order.kt index 4198fe1..ef3c5e0 100644 --- a/src/main/kotlin/team8/fruitable/controller/action/Order.kt +++ b/src/main/kotlin/team8/fruitable/controller/action/Order.kt @@ -1,4 +1,150 @@ package team8.fruitable.controller.action -class Order { +import org.springframework.stereotype.Controller +import org.springframework.web.bind.annotation.CookieValue +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestParam +import org.springframework.web.servlet.mvc.support.RedirectAttributes +import team8.fruitable.controller.util.error +import team8.fruitable.datebase.entity.Item +import team8.fruitable.datebase.entity.User +import team8.fruitable.datebase.entity.Order +import team8.fruitable.datebase.repository.* + +@Controller +@RequestMapping("/action/order") +class Order( + private val orderRepository: OrderRepository, + private val orderedItemRepository: OrderedItemRepository, + private val payTypeRepository: PayTypeRepository, + private val accountRepository: AccountRepository, + private val itemRepository: ItemRepository +) { + private fun getCurrentUser(token: String?): User? { + return token?.let(accountRepository::findByToken) + } + + @RequestMapping("/create/{item_id}/{item_number}") + fun create( + attributes: RedirectAttributes, + @CookieValue("TOKEN", required = false) token: String?, + @PathVariable("item_id") itemId: Long, + @PathVariable("item_number") itemNumber: Int, + @RequestParam("name") name: String, + @RequestParam("phone") phone: String, + @RequestParam("address") address: String, + @RequestParam("pay_type") payTypeId: Long, + @RequestParam("redirect", required = false) redirect: String? + ): String { + val user = this.getCurrentUser(token) ?: return error(attributes, "创建订单", "账户未登录", "/login") + val item = itemRepository.findById(itemId).orElse(null) ?: return error(attributes, "创建订单", "商品不存在") + val payType = + payTypeRepository.findById(payTypeId).orElse(null) ?: return error(attributes, "创建订单", "未知的支付类型") + val itemPrice = item.price?.times(itemNumber) ?: return error( + attributes, "创建订单", "错误的商品价格(可能是商品未添加对应的价格)" + ) + var order = Order(user, name, phone, address, payType, itemPrice, mutableListOf(item)) + order = orderRepository.save(order) + + // 更新 orders_to_items 表中的个数信息 + val orderedItem = orderedItemRepository.findByOrder(order)[0] + orderedItem.number = itemNumber + orderedItemRepository.save(orderedItem) + + redirect?.let { return "redirect:/${it}" } + return "redirect:/order/${order.id}" + } + + @RequestMapping("/create") + fun createForCart( + attributes: RedirectAttributes, + @CookieValue("TOKEN", required = false) token: String?, + @RequestParam("items") itemIds: Array, + @RequestParam("item_numbers") itemNumbers: Array, + @RequestParam("name") name: String, + @RequestParam("phone") phone: String, + @RequestParam("address") address: String, + @RequestParam("pay_type") payTypeId: Long, + @RequestParam("redirect", required = false) redirect: String? + ): String { + val user = this.getCurrentUser(token) ?: return error(attributes, "创建订单", "账户未登录", "/login") + val itemPairs = itemIds zip itemNumbers + val items: MutableList = mutableListOf() + var priceSum = .0 + itemPairs.forEach { + items.plus( + itemRepository.findById(it.first).orElse(null) ?: return error(attributes, "创建订单", "商品不存在") + ) + } + items.forEach { item -> + item.price?.let { + priceSum += it + } ?: return error(attributes, "创建订单", "错误的商品价格(可能是商品未添加对应的价格)") + } + val payType = + payTypeRepository.findById(payTypeId).orElse(null) ?: return error(attributes, "创建订单", "未知的支付类型") + val order = Order(user, name, phone, address, payType, priceSum, items) + orderRepository.save(order) + redirect?.let { return "redirect:/${it}" } + return "redirect:/order/${order.id}" + } + + @RequestMapping("/update/{id}") + fun update( + attributes: RedirectAttributes, + @CookieValue("TOKEN", required = false) token: String?, + @PathVariable("id") id: Long, + @RequestParam("name", required = false) name: String?, + @RequestParam("phone", required = false) phone: String?, + @RequestParam("address", required = false) address: String?, + @RequestParam("isPaid", required = false) isPaid: Boolean?, + @RequestParam("redirect", required = false) redirect: String? + ): String { + val user = this.getCurrentUser(token) ?: return error(attributes, "更新订单", "账户未登录", "/login") + val order = + orderRepository.findById(id).orElse(null) ?: return error(attributes, "更新订单", "订单不存在", "/orders") + if (order.user == null) return error(attributes, "更新订单", "此订单所指向的用户不存在", "/orders") + if (order.user!!.id != user.id) return error(attributes, "更新订单", "此订单不属于您", "/orders") + order.update(name, phone, address, isPaid) + orderRepository.save(order) + redirect?.let { return "redirect:/${it}" } + return "redirect:/order/${order.id}" + } + + @RequestMapping("/paid/{id}") + fun paid( + attributes: RedirectAttributes, + @CookieValue("TOKEN", required = false) token: String?, + @PathVariable("id") id: Long, + @RequestParam("redirect", required = false) redirect: String? + ): String { + val user = this.getCurrentUser(token) ?: return error(attributes, "支付订单", "账户未登录", "/login") + val order = + orderRepository.findById(id).orElse(null) ?: return error(attributes, "支付订单", "订单不存在", "/orders") + if (order.user == null) return error(attributes, "支付订单", "此订单所指向的用户不存在", "/orders") + if (order.user!!.id != user.id) return error(attributes, "支付订单", "此订单不属于您", "/orders") + order.update(isPaid = true) + orderRepository.save(order) + redirect?.let { return "redirect:/${it}" } + return "redirect:/order/${order.id}" + } + + @RequestMapping("/revoke/{id}") + fun revoke( + attributes: RedirectAttributes, + @CookieValue("TOKEN", required = false) token: String?, + @PathVariable("id") id: Long, + @RequestParam("redirect", required = false) redirect: String? + ): String { + val user = this.getCurrentUser(token) ?: return error(attributes, "撤销订单", "账户未登录", "/login") + val order = + orderRepository.findById(id).orElse(null) ?: return error(attributes, "撤销订单", "订单不存在", "/orders") + if (order.user == null) return error(attributes, "撤销订单", "此订单所指向的用户不存在", "/orders") + if (order.user!!.id != user.id) return error(attributes, "撤销订单", "此订单不属于您", "/orders") + order.revoke() + orderRepository.save(order) + redirect?.let { return "redirect:/${it}" } + return "redirect:/orders" + } } diff --git a/src/main/kotlin/team8/fruitable/controller/action/editor/Item.kt b/src/main/kotlin/team8/fruitable/controller/action/editor/Item.kt index d1ce98f..bc1839c 100644 --- a/src/main/kotlin/team8/fruitable/controller/action/editor/Item.kt +++ b/src/main/kotlin/team8/fruitable/controller/action/editor/Item.kt @@ -40,9 +40,9 @@ class Item( return this.hasAdminPermissions(this.getCurrentUser(token)) } - private fun autoCreateTag(tags: List): MutableList { + private fun autoCreateTag(tags: List?): MutableList { val result: MutableList = mutableListOf() - tags.forEach { + tags?.forEach { val oldTag = tagRepository.findByName(it) if (oldTag != null) { result.add(oldTag) @@ -55,12 +55,12 @@ class Item( return result } - private fun autoCreateTag(tags: String): MutableList { - return this.autoCreateTag(tags.split(" ")) + private fun autoCreateTag(tags: String?): MutableList { + return this.autoCreateTag(tags?.split(" ")) } - private fun uploadPicture(file: MultipartFile): String? { - if (file.isEmpty) return null + private fun uploadPicture(file: MultipartFile?): String? { + if (file == null || file.isEmpty) return null val hash = hash(file) val path = Path("${uploadPath}/picture/${hash.slice(0..1)}") if (!path.exists()) path.createDirectories() @@ -83,7 +83,11 @@ class Item( if (name.isBlank()) return error(attributes, "创建商品", "商品名不能为空") if (price == 0.0) return error(attributes, "创建商品", "商品价格不能为0") if (picture.isEmpty) return error(attributes, "创建商品", "必须上传商品图片") - itemRepository.save(Item(name, price, description, uploadPicture(picture), tag?.let { this.autoCreateTag(it) })) + itemRepository.save( + Item( + name, price, description, this.uploadPicture(picture), this.autoCreateTag(tag) + ) + ) redirect?.let { return "redirect:/${it}" } return "redirect:/editor?use=item" } @@ -105,26 +109,23 @@ class Item( if (price == 0.0) return error(attributes, "更新商品", "商品价格不能为0") val item = itemRepository.findById(id).orElse(null) ?: return error(attributes, "更新商品", "未找到目标商品") item.update( - name, - price, - description, - picture?.let { this.uploadPicture(it) }, - tag?.let { this.autoCreateTag(it) }) + name, price, description, this.uploadPicture(picture), this.autoCreateTag(tag) + ) itemRepository.save(item) redirect?.let { return "redirect:/${it}" } return "redirect:/editor?use=item" } - @PostMapping("/delete/{id}") - fun delete( + @PostMapping("/revoke/{id}") + fun revoke( attributes: RedirectAttributes, @CookieValue("TOKEN", required = false) token: String?, @PathVariable("id") id: Long, @RequestParam("redirect", required = false) redirect: String? ): String { - if (!this.hasAdminPermissions(token)) return error(attributes, "删除商品", "账户无权限") - val item = itemRepository.findById(id).orElse(null) ?: return error(attributes, "删除商品", "未找到目标商品") - item.update(isRemoved = true) + if (!this.hasAdminPermissions(token)) return error(attributes, "撤销商品", "账户无权限") + val item = itemRepository.findById(id).orElse(null) ?: return error(attributes, "撤销商品", "未找到目标商品") + item.revoke() itemRepository.save(item) redirect?.let { return "redirect:/${it}" } return "redirect:/editor?use=item" diff --git a/src/main/kotlin/team8/fruitable/controller/action/editor/User.kt b/src/main/kotlin/team8/fruitable/controller/action/editor/User.kt index d59ff77..c78d926 100644 --- a/src/main/kotlin/team8/fruitable/controller/action/editor/User.kt +++ b/src/main/kotlin/team8/fruitable/controller/action/editor/User.kt @@ -65,10 +65,7 @@ class User(private val accountRepository: AccountRepository) { val currentUser = this.getCurrentUser(token) ?: return error(attributes, "更新用户", "账户未登录") if (!this.hasAdminPermissions(currentUser)) return error(attributes, "更新用户", "账户无权限") val user = accountRepository.findById(id).orElse(null) ?: return error( - attributes, - "更新用户", - "未找到此用户", - "/editor?use=user" + attributes, "更新用户", "未找到此用户", "/editor?use=user" ) user.update(name, password, age, gender, phone, email, address, isAdmin) accountRepository.save(user) @@ -82,22 +79,20 @@ class User(private val accountRepository: AccountRepository) { return "redirect:/editor?use=user" } - @PostMapping("/delete/{id}") - fun delete( + @PostMapping("/revoke/{id}") + fun revoke( attributes: RedirectAttributes, @CookieValue("TOKEN", required = false) token: String?, @PathVariable("id") id: Long, @RequestParam("redirect", required = false) redirect: String? ): String { - val currentUser = this.getCurrentUser(token) ?: return error(attributes, "删除用户", "账户未登录") - if (!this.hasAdminPermissions(currentUser)) return error(attributes, "删除用户", "账户无权限") - if (currentUser.id == id) return error(attributes, "删除用户", "无法删除当前使用的账户", "/editor?use=user") + val currentUser = this.getCurrentUser(token) ?: return error(attributes, "禁用用户", "账户未登录") + if (!this.hasAdminPermissions(currentUser)) return error(attributes, "禁用用户", "账户无权限") + if (currentUser.id == id) return error(attributes, "禁用用户", "无法删除当前使用的账户", "/editor?use=user") val user = accountRepository.findById(id).orElse(null) ?: return error( - attributes, - "删除用户", - "未找到此用户", - "/editor?use=user" + attributes, "禁用用户", "未找到此用户", "/editor?use=user" ) + user.revoke() accountRepository.delete(user) redirect?.let { return "redirect:/${it}" } return "redirect:/editor?use=user" diff --git a/src/main/kotlin/team8/fruitable/controller/page/Editor.kt b/src/main/kotlin/team8/fruitable/controller/page/Editor.kt index 538be58..4ed684f 100644 --- a/src/main/kotlin/team8/fruitable/controller/page/Editor.kt +++ b/src/main/kotlin/team8/fruitable/controller/page/Editor.kt @@ -75,12 +75,12 @@ class Editor( @RequestParam("page", required = false) page: Int?, ): String { val user = this.getCurrentUser(token) ?: return error(attributes, "编辑", "账户未登录", "/login") - if (!this.hasAdminPermissions(user)) return error(attributes, "编辑", "账户无权限编辑网站") + if (!this.hasAdminPermissions(user)) return error(attributes, "编辑", "普通账户无权限编辑网站") model["isEditor"] = true model["user"] = user model["using"] = use model["tabs"] = editorTabs - if (searchContent != null) model["searching"] = searchContent + searchContent?.let { model["searching"] = it } val pageRequested = PageRequest.of(page ?: 0, 15) val data = when (use) { "item" -> pagingItemRepository.findAll(pageRequested) @@ -116,15 +116,17 @@ class Editor( model["target"] = when (use) { "item" -> { target?.let { - itemRepository.findById(it) - .orElse(null) ?: return error(attributes, "编辑", "无法找到目标商品") + itemRepository.findById(it).orElse(null) ?: return error(attributes, "编辑", "无法找到目标商品") } ?: return error(attributes, "编辑", "目标商品为空") } else -> { val targetUser = target?.let { - accountRepository.findById(it) - .orElse(null) ?: return error(attributes, "编辑", "无法找到目标用户") + accountRepository.findById(it).orElse(null) ?: return error( + attributes, + "编辑", + "无法找到目标用户" + ) } ?: return error(attributes, "编辑", "目标用户为空") if (action == "updating") when (targetUser.gender) { "M" -> model["isGenderAsMale"] = true diff --git a/src/main/kotlin/team8/fruitable/datebase/entity/Item.kt b/src/main/kotlin/team8/fruitable/datebase/entity/Item.kt index dc41e14..f5c82a9 100644 --- a/src/main/kotlin/team8/fruitable/datebase/entity/Item.kt +++ b/src/main/kotlin/team8/fruitable/datebase/entity/Item.kt @@ -30,8 +30,8 @@ class Item( @Column(name = "picture", length = 64, nullable = true) var picture: String? = null, - @Column(name = "is_removed", nullable = false) - var isRemoved: Boolean? = false, + @Column(name = "is_revoked", nullable = false) + var isRevoked: Boolean = false, @ManyToMany(cascade = [CascadeType.ALL], fetch = FetchType.LAZY) @JoinTable( @@ -67,13 +67,11 @@ class Item( price: Double, description: String? = null, picture: String? = null, - tags: MutableList? = null, - isRemoved: Boolean? = null + tags: MutableList? = null ) : this(name, price) { if (!description.isNullOrBlank()) this.description = description if (!picture.isNullOrBlank()) this.picture = picture tags?.let { this.tags.addAll(it) } - isRemoved?.let { this.isRemoved = it } } fun update( @@ -81,15 +79,13 @@ class Item( price: Double? = null, description: String? = null, picture: String? = null, - tags: MutableList? = null, - isRemoved: Boolean? = null + tags: MutableList? = null ) { if (!name.isNullOrBlank()) this.name = name this.price = price?.let { if (it <= 0) null else it } if (!description.isNullOrBlank()) this.description = description if (!picture.isNullOrBlank()) this.picture = picture tags?.let { this.tags = it } - isRemoved?.let { this.isRemoved = it } this.updateEditTime() } @@ -97,6 +93,10 @@ class Item( this.editTime = LocalDateTime.now() } + fun revoke() { + this.isRevoked = true + } + @Bean fun getTagPretty(): String { return this.tags.joinToString(", ") diff --git a/src/main/kotlin/team8/fruitable/datebase/entity/Order.kt b/src/main/kotlin/team8/fruitable/datebase/entity/Order.kt index 942c49e..992e7fc 100644 --- a/src/main/kotlin/team8/fruitable/datebase/entity/Order.kt +++ b/src/main/kotlin/team8/fruitable/datebase/entity/Order.kt @@ -17,6 +17,9 @@ class Order( @Column(name = "time_create", nullable = false) var createTime: LocalDateTime = LocalDateTime.now(), + @Column(name = "time_edit", nullable = false) + var editTime: LocalDateTime = LocalDateTime.now(), + @Column(name = "name", length = 16, nullable = false) var name: String? = null, @@ -26,16 +29,19 @@ class Order( @Column(name = "address", length = 64, nullable = false) var address: String? = null, - @ManyToOne - @JoinColumn(name = "order_id") + @ManyToOne(optional = false) + @JoinColumn(name = "pay_type", nullable = false) var payType: PayType? = null, - @Column(name = "pay_status", nullable = false) - var payStatus: Int = 1, - @Column(name = "price", nullable = false) var priceSum: Double = .0, + @Column(name = "is_paid", nullable = false) + var isPaid: Boolean = false, + + @Column(name = "is_revoked", nullable = false) + var isRevoked: Boolean = false, + @ManyToMany(cascade = [CascadeType.ALL], fetch = FetchType.LAZY) @JoinTable( name = "orders_to_items", @@ -43,4 +49,41 @@ class Order( inverseJoinColumns = [JoinColumn(name = "item_id", nullable = false)] ) var items: MutableList = mutableListOf() -) +) { + constructor(user: User) : this() { + this.user = user + } + + constructor( + user: User, + name: String, + phone: String, + address: String, + payType: PayType, + priceSum: Double, + items: MutableList + ) : this(user) { + this.name = name + this.phone = phone + this.address = address + this.payType = payType + this.priceSum = priceSum + this.items = items + } + + fun update(name: String? = null, phone: String? = null, address: String? = null, isPaid: Boolean? = null) { + if (!name.isNullOrBlank()) this.name = name + if (!phone.isNullOrBlank()) this.phone = phone + if (!address.isNullOrBlank()) this.address = address + isPaid?.let { this.isPaid = it } + this.updateEditTime() + } + + fun updateEditTime() { + this.editTime = LocalDateTime.now() + } + + fun revoke() { + this.isRevoked = true + } +} diff --git a/src/main/kotlin/team8/fruitable/datebase/entity/OrderedItem.kt b/src/main/kotlin/team8/fruitable/datebase/entity/OrderedItem.kt index 0dae231..641749a 100644 --- a/src/main/kotlin/team8/fruitable/datebase/entity/OrderedItem.kt +++ b/src/main/kotlin/team8/fruitable/datebase/entity/OrderedItem.kt @@ -11,13 +11,13 @@ class OrderedItem( var id: Long? = null, @ManyToOne - @JoinColumn(name = "order_id") + @JoinColumn(name = "order_id", nullable = false) var order: Order? = null, @ManyToOne - @JoinColumn(name = "item_id") + @JoinColumn(name = "item_id", nullable = false) var item: Item? = null, - @Column(name = "number", nullable = false) + @Column(name = "number") var number: Int? = 0 ) diff --git a/src/main/kotlin/team8/fruitable/datebase/entity/PayType.kt b/src/main/kotlin/team8/fruitable/datebase/entity/PayType.kt index 5e4990a..1c6cced 100644 --- a/src/main/kotlin/team8/fruitable/datebase/entity/PayType.kt +++ b/src/main/kotlin/team8/fruitable/datebase/entity/PayType.kt @@ -12,8 +12,4 @@ class PayType( @Column(name = "NAME", length = 16, nullable = false) var name: String? = null, - - @OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.LAZY) - @JoinColumn(name = "pay_type", nullable = false) - var orders: MutableList = mutableListOf() ) diff --git a/src/main/kotlin/team8/fruitable/datebase/entity/User.kt b/src/main/kotlin/team8/fruitable/datebase/entity/User.kt index 964f895..51de8ad 100644 --- a/src/main/kotlin/team8/fruitable/datebase/entity/User.kt +++ b/src/main/kotlin/team8/fruitable/datebase/entity/User.kt @@ -47,6 +47,9 @@ class User( @Column(name = "is_admin", nullable = false) var isAdmin: Boolean = false, + @Column(name = "is_revoked", nullable = false) + var isRevoked: Boolean = false, + @ManyToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.LAZY) @JoinTable( name = "carts", @@ -124,6 +127,10 @@ class User( this.token = UUID.randomUUID().toString() } + fun revoke() { + this.isRevoked = true + } + @Bean fun getGenderPretty(): String { return when (this.gender) { diff --git a/src/main/kotlin/team8/fruitable/datebase/repository/OrderRepository.kt b/src/main/kotlin/team8/fruitable/datebase/repository/OrderRepository.kt new file mode 100644 index 0000000..d8b6e99 --- /dev/null +++ b/src/main/kotlin/team8/fruitable/datebase/repository/OrderRepository.kt @@ -0,0 +1,6 @@ +package team8.fruitable.datebase.repository + +import org.springframework.data.repository.CrudRepository +import team8.fruitable.datebase.entity.Order + +interface OrderRepository : CrudRepository diff --git a/src/main/kotlin/team8/fruitable/datebase/repository/OrderedItemRepository.kt b/src/main/kotlin/team8/fruitable/datebase/repository/OrderedItemRepository.kt new file mode 100644 index 0000000..d22cfbb --- /dev/null +++ b/src/main/kotlin/team8/fruitable/datebase/repository/OrderedItemRepository.kt @@ -0,0 +1,9 @@ +package team8.fruitable.datebase.repository + +import org.springframework.data.repository.CrudRepository +import team8.fruitable.datebase.entity.Order +import team8.fruitable.datebase.entity.OrderedItem + +interface OrderedItemRepository : CrudRepository { + fun findByOrder(order: Order): List +} diff --git a/src/main/kotlin/team8/fruitable/datebase/repository/PayTypeRepository.kt b/src/main/kotlin/team8/fruitable/datebase/repository/PayTypeRepository.kt new file mode 100644 index 0000000..fd67c58 --- /dev/null +++ b/src/main/kotlin/team8/fruitable/datebase/repository/PayTypeRepository.kt @@ -0,0 +1,6 @@ +package team8.fruitable.datebase.repository + +import org.springframework.data.repository.CrudRepository +import team8.fruitable.datebase.entity.PayType + +interface PayTypeRepository : CrudRepository