add more Api for Account, add recommend entity for item
Signed-off-by: Puqns67 <me@puqns67.icu>
This commit is contained in:
parent
9b89dc93e6
commit
7514842f19
@ -5,7 +5,6 @@ import org.springframework.boot.runApplication
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
|
||||
@RestController
|
||||
@SpringBootApplication
|
||||
class FruitableApplication {
|
||||
|
7
src/main/kotlin/team8/fruitable/constant/UserType.kt
Normal file
7
src/main/kotlin/team8/fruitable/constant/UserType.kt
Normal file
@ -0,0 +1,7 @@
|
||||
package team8.fruitable.constant
|
||||
|
||||
enum class UserType {
|
||||
Admin,
|
||||
User,
|
||||
Guest
|
||||
}
|
@ -3,121 +3,128 @@ package team8.fruitable.controller.api
|
||||
import jakarta.servlet.http.Cookie
|
||||
import jakarta.servlet.http.HttpServletResponse
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import team8.fruitable.constant.UserType
|
||||
import team8.fruitable.datebase.entity.User
|
||||
import team8.fruitable.datebase.repository.UserRepository
|
||||
import team8.fruitable.util.ResultBuilder
|
||||
|
||||
|
||||
@RestController
|
||||
class Account(private val repository: UserRepository) {
|
||||
@GetMapping("/api/v1/account/info/{id}")
|
||||
fun info(
|
||||
@PathVariable id: Long,
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?
|
||||
): String {
|
||||
val queryUser = repository.findById(id).orElse(null) ?: return ResultBuilder<Any>("账户不存在").toJson()
|
||||
var currentUser: User? = null
|
||||
if (token != null) currentUser = repository.findByToken(token)
|
||||
val result = mapOf(
|
||||
"id" to queryUser.id,
|
||||
"name" to queryUser.name,
|
||||
"gender" to queryUser.gender,
|
||||
"createTime" to queryUser.createTime,
|
||||
"loginTime" to queryUser.loginTime
|
||||
)
|
||||
if (currentUser != null && (currentUser.id == id || currentUser.isAdmin)) result + mapOf(
|
||||
"address" to queryUser.address,
|
||||
"admin" to queryUser.isAdmin,
|
||||
"carts" to queryUser.carts,
|
||||
"orders" to queryUser.orders,
|
||||
"phone" to queryUser.phone
|
||||
)
|
||||
return ResultBuilder(result).toJson()
|
||||
private fun getCurrentUser(token: String?): User? {
|
||||
return token?.let(repository::findByToken)
|
||||
}
|
||||
|
||||
@PostMapping("/api/v1/account/login")
|
||||
private fun hasAdminPermissions(token: String?): Boolean {
|
||||
return this.getCurrentUser(token)?.isAdmin ?: false
|
||||
}
|
||||
|
||||
private fun updateToken(response: HttpServletResponse, token: String, path: String = "/", age: Int = 2678400) {
|
||||
val cookie = Cookie("TOKEN", token)
|
||||
cookie.path = path
|
||||
cookie.maxAge = age
|
||||
response.addCookie(cookie)
|
||||
}
|
||||
|
||||
@GetMapping("/api/v1/account/info", produces = ["application/json"])
|
||||
fun infoMe(
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?
|
||||
): String {
|
||||
val user = this.getCurrentUser(token) ?: return ResultBuilder<Any>("账户未登录").toJson()
|
||||
return ResultBuilder(user.asMap(UserType.User)).toJson()
|
||||
}
|
||||
|
||||
@GetMapping("/api/v1/account/info/{id}", produces = ["application/json"])
|
||||
fun info(
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?, @PathVariable id: Long
|
||||
): String {
|
||||
val queryUser = repository.findById(id).orElse(null) ?: return ResultBuilder<Any>("账户不存在").toJson()
|
||||
val currentUser = this.getCurrentUser(token)
|
||||
return ResultBuilder(
|
||||
queryUser.asMap(if (currentUser != null && (currentUser.id == id || currentUser.isAdmin)) UserType.User else UserType.Guest)
|
||||
).toJson()
|
||||
}
|
||||
|
||||
//@PostMapping
|
||||
@RequestMapping("/api/v1/account/login", produces = ["application/json"])
|
||||
fun login(
|
||||
response: HttpServletResponse,
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||
@RequestParam(name = "name") name: String,
|
||||
@RequestParam(name = "password") password: String
|
||||
): String {
|
||||
if (this.getCurrentUser(token) != null) return ResultBuilder<Any>("当前已登录账户").toJson()
|
||||
val user = repository.findByName(name) ?: return ResultBuilder<Any>("账户不存在").toJson()
|
||||
if (!user.testPassword(password)) {
|
||||
return ResultBuilder<Any>("密码错误").toJson()
|
||||
}
|
||||
if (!user.testPassword(password)) return ResultBuilder<Any>("密码错误").toJson()
|
||||
user.updateToken()
|
||||
val cookie = Cookie("TOKEN", user.token)
|
||||
cookie.maxAge = 2678400
|
||||
response.addCookie(cookie)
|
||||
user.updateLoginTime()
|
||||
repository.save(user)
|
||||
updateToken(response, user.token)
|
||||
return ResultBuilder<Any>("success", "登录成功").toJson()
|
||||
}
|
||||
|
||||
@PostMapping("/api/v1/account/logout")
|
||||
@RequestMapping("/api/v1/account/logout", produces = ["application/json"])
|
||||
fun logout(response: HttpServletResponse): String {
|
||||
val cookie = Cookie("TOKEN", "")
|
||||
cookie.maxAge = 0
|
||||
response.addCookie(cookie)
|
||||
updateToken(response, "", age = 0)
|
||||
return ResultBuilder<Any>("success", "注销成功").toJson()
|
||||
}
|
||||
|
||||
@PostMapping("/api/v1/account/register")
|
||||
@RequestMapping("/api/v1/account/register", produces = ["application/json"])
|
||||
fun register(
|
||||
response: HttpServletResponse,
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||
@RequestParam(name = "name") name: String,
|
||||
@RequestParam(name = "password") password: String,
|
||||
@RequestParam(name = "age", required = false) age: Int?,
|
||||
@RequestParam(name = "gender", required = false) gender: String?,
|
||||
@RequestParam(name = "phone", required = false) phone: String?,
|
||||
@RequestParam(name = "email", required = false) email: String?,
|
||||
@RequestParam(name = "address", required = false) address: String?,
|
||||
@RequestParam(name = "phone", required = false) phone: String?
|
||||
@RequestParam(name = "address", required = false) address: String?
|
||||
): String {
|
||||
// TODO: 完成注册方法
|
||||
return "TODO"
|
||||
if (this.getCurrentUser(token) != null) return ResultBuilder<Any>("当前已登录账户").toJson()
|
||||
val user = repository.save(User(name, password, age, gender, phone, email, address))
|
||||
updateToken(response, user.token)
|
||||
return ResultBuilder<Any>("success", "注册成功").toJson()
|
||||
}
|
||||
|
||||
@PostMapping("/api/v1/account/update")
|
||||
@RequestMapping("/api/v1/account/update", produces = ["application/json"])
|
||||
fun update(
|
||||
response: HttpServletResponse,
|
||||
@CookieValue(name = "TOKEN", required = false) token: String,
|
||||
@CookieValue(name = "TOKEN", required = false) token: String?,
|
||||
@RequestParam(name = "name") name: String,
|
||||
@RequestParam(name = "password") password: String,
|
||||
@RequestParam(name = "age", required = false) age: Int?,
|
||||
@RequestParam(name = "gender", required = false) gender: String?,
|
||||
@RequestParam(name = "phone", required = false) phone: String?,
|
||||
@RequestParam(name = "email", required = false) email: String?,
|
||||
@RequestParam(name = "address", required = false) address: String?,
|
||||
@RequestParam(name = "phone", required = false) phone: String?
|
||||
@RequestParam(name = "address", required = false) address: String?
|
||||
): String {
|
||||
// TODO: 完成更新账户数据方法
|
||||
return "TODO"
|
||||
val user = this.getCurrentUser(token) ?: return ResultBuilder<Any>("账户未登录").toJson()
|
||||
user.update(name, password, age, gender, phone, email, address)
|
||||
repository.save(user)
|
||||
updateToken(response, user.token)
|
||||
return ResultBuilder<Any>("success", "更新账户信息成功").toJson()
|
||||
}
|
||||
|
||||
@GetMapping("/api/v1/account/admin/info/{id}")
|
||||
@GetMapping("/api/v1/account/admin/info/{id}", produces = ["application/json"])
|
||||
fun infoAdmin(
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||
@PathVariable id: Long,
|
||||
): String {
|
||||
var currentUser: User? = null
|
||||
if (token != null) currentUser = repository.findByToken(token)
|
||||
if (currentUser == null) return ResultBuilder<Any>("账户未登录").toJson()
|
||||
if (!currentUser.isAdmin) return ResultBuilder<Any>("无管理员权限").toJson()
|
||||
if (this.hasAdminPermissions(token)) return ResultBuilder<Any>("无管理员权限").toJson()
|
||||
return ResultBuilder(repository.findById(id)).toJson()
|
||||
}
|
||||
|
||||
@DeleteMapping("/api/v1/account/admin/remove/{id}")
|
||||
@DeleteMapping("/api/v1/account/admin/remove/{id}", produces = ["application/json"])
|
||||
fun removeAdmin(
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||
@PathVariable id: Long,
|
||||
): String {
|
||||
var currentUser: User? = null
|
||||
if (token != null) currentUser = repository.findByToken(token)
|
||||
if (currentUser == null) return ResultBuilder<Any>("账户未登录").toJson()
|
||||
if (!currentUser.isAdmin) return ResultBuilder<Any>("无管理员权限").toJson()
|
||||
if (this.hasAdminPermissions(token)) return ResultBuilder<Any>("无管理员权限").toJson()
|
||||
// TODO: 完成管理员删除方法
|
||||
return ResultBuilder(repository.findById(id)).toJson()
|
||||
}
|
||||
|
||||
@PostMapping("/api/v1/account/admin/update/{id}")
|
||||
@PostMapping("/api/v1/account/admin/update/{id}", produces = ["application/json"])
|
||||
fun updateAdmin(
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||
@PathVariable id: Long,
|
||||
@ -125,14 +132,11 @@ class Account(private val repository: UserRepository) {
|
||||
@RequestParam(name = "password") password: String,
|
||||
@RequestParam(name = "age", required = false) age: Int?,
|
||||
@RequestParam(name = "gender", required = false) gender: String?,
|
||||
@RequestParam(name = "phone", required = false) phone: String?,
|
||||
@RequestParam(name = "email", required = false) email: String?,
|
||||
@RequestParam(name = "address", required = false) address: String?,
|
||||
@RequestParam(name = "phone", required = false) phone: String?
|
||||
@RequestParam(name = "address", required = false) address: String?
|
||||
): String {
|
||||
var currentUser: User? = null
|
||||
if (token != null) currentUser = repository.findByToken(token)
|
||||
if (currentUser == null) return ResultBuilder<Any>("账户未登录").toJson()
|
||||
if (!currentUser.isAdmin) return ResultBuilder<Any>("无管理员权限").toJson()
|
||||
if (this.hasAdminPermissions(token)) return ResultBuilder<Any>("无管理员权限").toJson()
|
||||
// TODO: 完成管理员更新账户数据方法
|
||||
return ResultBuilder(repository.findById(id)).toJson()
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package team8.fruitable.controller.api
|
||||
|
||||
class Cart {
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,26 @@
|
||||
package team8.fruitable.controller.api
|
||||
|
||||
class Item {
|
||||
}
|
||||
import org.springframework.web.bind.annotation.CookieValue
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import team8.fruitable.datebase.entity.User
|
||||
import team8.fruitable.datebase.repository.ItemRepository
|
||||
import team8.fruitable.datebase.repository.UserRepository
|
||||
import team8.fruitable.util.ResultBuilder
|
||||
|
||||
@RestController
|
||||
class Item(private val itemRepository: ItemRepository, private val userRepository: UserRepository) {
|
||||
private fun getCurrentUser(token: String?): User? {
|
||||
return token?.let(userRepository::findByToken)
|
||||
}
|
||||
|
||||
private fun hasAdminPermissions(token: String?): Boolean {
|
||||
return this.getCurrentUser(token)?.isAdmin ?: false
|
||||
}
|
||||
|
||||
@GetMapping("/api/v1/item/info/{id}", produces = ["application/json"])
|
||||
fun info(@PathVariable id: Long): String {
|
||||
return ResultBuilder(itemRepository.findById(id).orElse(null)).toJson()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package team8.fruitable.controller.api
|
||||
|
||||
class Order {
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package team8.fruitable.datebase.entity
|
||||
|
||||
import jakarta.persistence.*
|
||||
|
||||
|
||||
@Entity
|
||||
@Table(name = "items")
|
||||
class Item(
|
||||
@ -17,7 +16,7 @@ class Item(
|
||||
@Column(name="price", nullable = false)
|
||||
var price: Double? = null,
|
||||
|
||||
@Column(name="DESCRIPTION", length=320, nullable = true)
|
||||
@Column(name="description", length=320, nullable = true)
|
||||
var description: String? = null,
|
||||
|
||||
@ManyToOne
|
||||
@ -29,5 +28,8 @@ class Item(
|
||||
var ordered: Order? = null,
|
||||
|
||||
@OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.LAZY, mappedBy = "tagedItem")
|
||||
var tags: MutableList<Tag> = mutableListOf<Tag>()
|
||||
var tags: MutableList<Tag> = mutableListOf<Tag>(),
|
||||
|
||||
@OneToOne(mappedBy = "item")
|
||||
var recommend: Recommend? = null,
|
||||
)
|
||||
|
@ -3,7 +3,6 @@ package team8.fruitable.datebase.entity
|
||||
import jakarta.persistence.*
|
||||
import java.time.LocalDateTime
|
||||
|
||||
|
||||
@Entity
|
||||
@Table(name = "orders")
|
||||
class Order(
|
||||
|
@ -2,7 +2,6 @@ package team8.fruitable.datebase.entity
|
||||
|
||||
import jakarta.persistence.*
|
||||
|
||||
|
||||
@Entity
|
||||
@Table(name = "pay_type")
|
||||
class PayType(
|
||||
|
19
src/main/kotlin/team8/fruitable/datebase/entity/Recommend.kt
Normal file
19
src/main/kotlin/team8/fruitable/datebase/entity/Recommend.kt
Normal file
@ -0,0 +1,19 @@
|
||||
package team8.fruitable.datebase.entity
|
||||
|
||||
import jakarta.persistence.*
|
||||
|
||||
@Entity
|
||||
@Table(name = "recommends")
|
||||
class Recommend (
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id", nullable = false)
|
||||
var id: Long? = null,
|
||||
|
||||
@OneToOne
|
||||
@JoinColumn(name = "item")
|
||||
var item: Item,
|
||||
|
||||
@Column(name="description", length=32, nullable = false)
|
||||
var description: String? = null,
|
||||
)
|
@ -2,7 +2,6 @@ package team8.fruitable.datebase.entity
|
||||
|
||||
import jakarta.persistence.*
|
||||
|
||||
|
||||
@Entity
|
||||
@Table(name = "tags")
|
||||
class Tag(
|
||||
|
@ -1,6 +1,7 @@
|
||||
package team8.fruitable.datebase.entity
|
||||
|
||||
import jakarta.persistence.*
|
||||
import team8.fruitable.constant.UserType
|
||||
import team8.fruitable.util.Util
|
||||
import java.time.LocalDateTime
|
||||
import java.util.*
|
||||
@ -21,7 +22,7 @@ class User(
|
||||
var password: String? = null,
|
||||
|
||||
@Column(name = "time_create", nullable = false)
|
||||
val createTime: LocalDateTime = LocalDateTime.now(),
|
||||
var createTime: LocalDateTime = LocalDateTime.now(),
|
||||
|
||||
@Column(name = "time_login", nullable = false)
|
||||
var loginTime: LocalDateTime = LocalDateTime.now(),
|
||||
@ -53,15 +54,89 @@ class User(
|
||||
@OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.LAZY, mappedBy = "user")
|
||||
var orders: MutableList<Order> = mutableListOf<Order>()
|
||||
) {
|
||||
constructor(name: String, password: String) : this() {
|
||||
this.name = name
|
||||
this.password = this.genPassword(password)
|
||||
}
|
||||
|
||||
constructor(
|
||||
name: String,
|
||||
password: String,
|
||||
age: Int?,
|
||||
gender: String?,
|
||||
phone: String?,
|
||||
email: String?,
|
||||
address: String?
|
||||
) : this(name, password) {
|
||||
this.age = age
|
||||
this.gender = gender
|
||||
this.phone = phone
|
||||
this.email = email
|
||||
this.address = address
|
||||
}
|
||||
|
||||
final fun genPassword(password: String): String {
|
||||
return Util.hash(password)
|
||||
}
|
||||
|
||||
fun update(
|
||||
name: String,
|
||||
password: String,
|
||||
age: Int?,
|
||||
gender: String?,
|
||||
phone: String?,
|
||||
email: String?,
|
||||
address: String?,
|
||||
isAdmin: Boolean = false
|
||||
) {
|
||||
this.name = name
|
||||
this.updatePassword(password)
|
||||
this.age = age
|
||||
this.gender = gender
|
||||
this.phone = phone
|
||||
this.email = email
|
||||
this.address = address
|
||||
this.isAdmin = isAdmin
|
||||
this.updateToken()
|
||||
}
|
||||
|
||||
fun testPassword(password: String): Boolean {
|
||||
return Util.hash(password) == this.password
|
||||
}
|
||||
|
||||
fun updatePassword(password: String) {
|
||||
this.password = Util.hash(password)
|
||||
this.password = this.genPassword(password)
|
||||
}
|
||||
|
||||
fun updateLoginTime() {
|
||||
this.loginTime = LocalDateTime.now()
|
||||
}
|
||||
|
||||
fun updateToken() {
|
||||
this.token = UUID.randomUUID().toString()
|
||||
}
|
||||
|
||||
fun asMap(userType: UserType): Map<String, Any?> {
|
||||
val result: MutableMap<String, Any?> = mutableMapOf(
|
||||
"id" to this.id,
|
||||
"name" to this.name,
|
||||
"createTime" to this.createTime,
|
||||
"loginTime" to this.loginTime,
|
||||
"age" to this.age,
|
||||
"gender" to this.gender,
|
||||
"email" to this.email,
|
||||
)
|
||||
if (userType == UserType.User || userType == UserType.Admin) result += mapOf(
|
||||
"phone" to this.phone,
|
||||
"address" to this.address,
|
||||
"isAdmin" to this.isAdmin,
|
||||
"carts" to this.carts,
|
||||
"orders" to this.orders
|
||||
)
|
||||
if (userType == UserType.Admin) result += mapOf(
|
||||
"password" to this.password,
|
||||
"token" to this.token,
|
||||
)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
package team8.fruitable.datebase.repository
|
||||
|
||||
import org.springframework.data.repository.CrudRepository
|
||||
import team8.fruitable.datebase.entity.Item
|
||||
|
||||
interface ItemRepository : CrudRepository<Item, Long> {
|
||||
fun findByName(name: String): Item?
|
||||
}
|
@ -3,7 +3,6 @@ package team8.fruitable.datebase.repository
|
||||
import org.springframework.data.repository.CrudRepository
|
||||
import team8.fruitable.datebase.entity.User
|
||||
|
||||
|
||||
interface UserRepository : CrudRepository<User, Long> {
|
||||
fun findByName(name: String): User?
|
||||
fun findByToken(token: String): User?
|
||||
|
@ -4,7 +4,6 @@ import com.alibaba.fastjson2.toJSONString
|
||||
import java.time.LocalDateTime
|
||||
import java.util.*
|
||||
|
||||
|
||||
class ResultBuilder<T> {
|
||||
var status: String = "auto"
|
||||
var message: String = ""
|
||||
|
@ -2,12 +2,11 @@ package team8.fruitable.util
|
||||
|
||||
import java.security.MessageDigest
|
||||
|
||||
|
||||
class Util {
|
||||
companion object {
|
||||
fun hash(input: String, algorithm: String = "SHA-256"): String {
|
||||
return MessageDigest.getInstance(algorithm).digest(input.toByteArray())
|
||||
.fold("", { str, it -> str + "%02x".format(it) })
|
||||
.fold("") { str, it -> str + "%02x".format(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
|
||||
spring.datasource.url=jdbc:mariadb://localhost:3306/fruitable
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=password
|
||||
|
||||
#???????updata:????????????,?????????
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
#?????????? Unable to build Hibernate SessionFactory
|
||||
#spring.jpa.properties.hibernate.hbm2ddl.auto=validate
|
9
src/main/resources/application.yaml
Normal file
9
src/main/resources/application.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mariadb://localhost:3306/fruitable
|
||||
username: root
|
||||
password: password
|
||||
jpa:
|
||||
show-sql: true
|
||||
hibernate:
|
||||
ddl-auto: update
|
Loading…
x
Reference in New Issue
Block a user