fix build error and index page
Signed-off-by: Puqns67 <me@puqns67.icu>
5
pom.xml
@ -11,6 +11,7 @@
|
|||||||
<description>A demo project for fruit and vegetable store using Spring Boot.</description>
|
<description>A demo project for fruit and vegetable store using Spring Boot.</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
<kotlin.version>1.9.10</kotlin.version>
|
<kotlin.version>1.9.10</kotlin.version>
|
||||||
</properties>
|
</properties>
|
||||||
@ -69,6 +70,10 @@
|
|||||||
<artifactId>fastjson2-kotlin</artifactId>
|
<artifactId>fastjson2-kotlin</artifactId>
|
||||||
<version>2.0.40</version>
|
<version>2.0.40</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
</dependency>
|
||||||
<!-- Other -->
|
<!-- Other -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mariadb.jdbc</groupId>
|
<groupId>org.mariadb.jdbc</groupId>
|
||||||
|
@ -5,14 +5,8 @@ import org.springframework.boot.runApplication
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
|
||||||
@RestController
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
class FruitableApplication {
|
class FruitableApplication
|
||||||
@RequestMapping("/")
|
|
||||||
fun home(): String {
|
|
||||||
return "Hello World!"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
runApplication<FruitableApplication>(*args)
|
runApplication<FruitableApplication>(*args)
|
||||||
|
90
src/main/kotlin/team8/fruitable/controller/action/Account.kt
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package team8.fruitable.controller.action
|
||||||
|
|
||||||
|
import jakarta.servlet.http.Cookie
|
||||||
|
import jakarta.servlet.http.HttpServletResponse
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.web.bind.annotation.CookieValue
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping
|
||||||
|
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.datebase.entity.User
|
||||||
|
import team8.fruitable.datebase.repository.AccountRepository
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/action/account")
|
||||||
|
class Account(private val repository: AccountRepository) {
|
||||||
|
private fun getCurrentUser(token: String?): User? {
|
||||||
|
return token?.let(repository::findByToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun error(
|
||||||
|
redirectAttributes: RedirectAttributes,
|
||||||
|
title: String,
|
||||||
|
message: String,
|
||||||
|
redirect: String = "redirect:/"
|
||||||
|
): String {
|
||||||
|
redirectAttributes.addFlashAttribute("title", title)
|
||||||
|
redirectAttributes.addFlashAttribute("message", message)
|
||||||
|
redirectAttributes.addFlashAttribute("redirect", redirect)
|
||||||
|
return "redirect:/error"
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/login")
|
||||||
|
fun login(
|
||||||
|
response: HttpServletResponse,
|
||||||
|
attributes: RedirectAttributes,
|
||||||
|
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||||
|
@RequestParam(name = "name") name: String,
|
||||||
|
@RequestParam(name = "password") password: String
|
||||||
|
): String {
|
||||||
|
if (this.getCurrentUser(token) != null) return error(attributes, "登录", "当前已登录账户")
|
||||||
|
val user = repository.findByName(name) ?: return error(attributes, "登录", "账户不存在")
|
||||||
|
if (!user.testPassword(password)) return error(attributes, "登录", "密码错误")
|
||||||
|
user.updateToken()
|
||||||
|
user.updateLoginTime()
|
||||||
|
repository.save(user)
|
||||||
|
updateToken(response, user.token)
|
||||||
|
return "redirect:/";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/register")
|
||||||
|
fun register(
|
||||||
|
response: HttpServletResponse,
|
||||||
|
attributes: RedirectAttributes,
|
||||||
|
@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?
|
||||||
|
): String {
|
||||||
|
if (this.getCurrentUser(token) != null) return error(attributes, "登录", "当前已登录账户")
|
||||||
|
val user = repository.save(User(name, password, age, gender, phone, email, address))
|
||||||
|
updateToken(response, user.token)
|
||||||
|
return "redirect:/";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/logout")
|
||||||
|
fun logout(
|
||||||
|
response: HttpServletResponse,
|
||||||
|
@RequestParam("redirect", required = false) redirect: String?
|
||||||
|
): String {
|
||||||
|
updateToken(response, "", age = 0)
|
||||||
|
redirect?.let { return it }
|
||||||
|
return "redirect:/"
|
||||||
|
}
|
||||||
|
}
|
@ -5,11 +5,12 @@ import jakarta.servlet.http.HttpServletResponse
|
|||||||
import org.springframework.web.bind.annotation.*
|
import org.springframework.web.bind.annotation.*
|
||||||
import team8.fruitable.constant.UserType
|
import team8.fruitable.constant.UserType
|
||||||
import team8.fruitable.datebase.entity.User
|
import team8.fruitable.datebase.entity.User
|
||||||
import team8.fruitable.datebase.repository.UserRepository
|
import team8.fruitable.datebase.repository.AccountRepository
|
||||||
import team8.fruitable.util.ResultBuilder
|
import team8.fruitable.util.ResultBuilderJson
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
class Account(private val repository: UserRepository) {
|
@RequestMapping("/api/v1/account")
|
||||||
|
class AccountApi(private val repository: AccountRepository) {
|
||||||
private fun getCurrentUser(token: String?): User? {
|
private fun getCurrentUser(token: String?): User? {
|
||||||
return token?.let(repository::findByToken)
|
return token?.let(repository::findByToken)
|
||||||
}
|
}
|
||||||
@ -25,50 +26,50 @@ class Account(private val repository: UserRepository) {
|
|||||||
response.addCookie(cookie)
|
response.addCookie(cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/api/v1/account/info", produces = ["application/json"])
|
@GetMapping("/info", produces = ["application/json"])
|
||||||
fun infoMe(
|
fun infoMe(
|
||||||
@CookieValue(value = "TOKEN", required = false) token: String?
|
@CookieValue(value = "TOKEN", required = false) token: String?
|
||||||
): String {
|
): String {
|
||||||
val user = this.getCurrentUser(token) ?: return ResultBuilder<Any>("账户未登录").toJson()
|
val user = this.getCurrentUser(token) ?: return ResultBuilderJson<Any>("账户未登录").toJson()
|
||||||
return ResultBuilder(user.asMap(UserType.User)).toJson()
|
return ResultBuilderJson(user.asMap(UserType.User)).toJson()
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/api/v1/account/info/{id}", produces = ["application/json"])
|
@GetMapping("/info/{id}", produces = ["application/json"])
|
||||||
fun info(
|
fun info(
|
||||||
@CookieValue(value = "TOKEN", required = false) token: String?, @PathVariable id: Long
|
@CookieValue(value = "TOKEN", required = false) token: String?, @PathVariable id: Long
|
||||||
): String {
|
): String {
|
||||||
val queryUser = repository.findById(id).orElse(null) ?: return ResultBuilder<Any>("账户不存在").toJson()
|
val queryUser = repository.findById(id).orElse(null) ?: return ResultBuilderJson<Any>("账户不存在").toJson()
|
||||||
val currentUser = this.getCurrentUser(token)
|
val currentUser = this.getCurrentUser(token)
|
||||||
return ResultBuilder(
|
return ResultBuilderJson(
|
||||||
queryUser.asMap(if (currentUser != null && (currentUser.id == id || currentUser.isAdmin)) UserType.User else UserType.Guest)
|
queryUser.asMap(if (currentUser != null && (currentUser.id == id || currentUser.isAdmin)) UserType.User else UserType.Guest)
|
||||||
).toJson()
|
).toJson()
|
||||||
}
|
}
|
||||||
|
|
||||||
//@PostMapping
|
//@PostMapping
|
||||||
@RequestMapping("/api/v1/account/login", produces = ["application/json"])
|
@RequestMapping("/login", produces = ["application/json"])
|
||||||
fun login(
|
fun login(
|
||||||
response: HttpServletResponse,
|
response: HttpServletResponse,
|
||||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||||
@RequestParam(name = "name") name: String,
|
@RequestParam(name = "name") name: String,
|
||||||
@RequestParam(name = "password") password: String
|
@RequestParam(name = "password") password: String
|
||||||
): String {
|
): String {
|
||||||
if (this.getCurrentUser(token) != null) return ResultBuilder<Any>("当前已登录账户").toJson()
|
if (this.getCurrentUser(token) != null) return ResultBuilderJson<Any>("当前已登录账户").toJson()
|
||||||
val user = repository.findByName(name) ?: return ResultBuilder<Any>("账户不存在").toJson()
|
val user = repository.findByName(name) ?: return ResultBuilderJson<Any>("账户不存在").toJson()
|
||||||
if (!user.testPassword(password)) return ResultBuilder<Any>("密码错误").toJson()
|
if (!user.testPassword(password)) return ResultBuilderJson<Any>("密码错误").toJson()
|
||||||
user.updateToken()
|
user.updateToken()
|
||||||
user.updateLoginTime()
|
user.updateLoginTime()
|
||||||
repository.save(user)
|
repository.save(user)
|
||||||
updateToken(response, user.token)
|
updateToken(response, user.token)
|
||||||
return ResultBuilder<Any>("success", "登录成功").toJson()
|
return ResultBuilderJson<Any>("success", "登录成功").toJson()
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/api/v1/account/logout", produces = ["application/json"])
|
@RequestMapping("/logout", produces = ["application/json"])
|
||||||
fun logout(response: HttpServletResponse): String {
|
fun logout(response: HttpServletResponse): String {
|
||||||
updateToken(response, "", age = 0)
|
updateToken(response, "", age = 0)
|
||||||
return ResultBuilder<Any>("success", "注销成功").toJson()
|
return ResultBuilderJson<Any>("success", "注销成功").toJson()
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/api/v1/account/register", produces = ["application/json"])
|
@RequestMapping("/register", produces = ["application/json"])
|
||||||
fun register(
|
fun register(
|
||||||
response: HttpServletResponse,
|
response: HttpServletResponse,
|
||||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||||
@ -80,13 +81,13 @@ class Account(private val repository: UserRepository) {
|
|||||||
@RequestParam(name = "email", required = false) email: String?,
|
@RequestParam(name = "email", required = false) email: String?,
|
||||||
@RequestParam(name = "address", required = false) address: String?
|
@RequestParam(name = "address", required = false) address: String?
|
||||||
): String {
|
): String {
|
||||||
if (this.getCurrentUser(token) != null) return ResultBuilder<Any>("当前已登录账户").toJson()
|
if (this.getCurrentUser(token) != null) return ResultBuilderJson<Any>("当前已登录账户").toJson()
|
||||||
val user = repository.save(User(name, password, age, gender, phone, email, address))
|
val user = repository.save(User(name, password, age, gender, phone, email, address))
|
||||||
updateToken(response, user.token)
|
updateToken(response, user.token)
|
||||||
return ResultBuilder<Any>("success", "注册成功").toJson()
|
return ResultBuilderJson<Any>("success", "注册成功").toJson()
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/api/v1/account/update", produces = ["application/json"])
|
@RequestMapping("/update", produces = ["application/json"])
|
||||||
fun update(
|
fun update(
|
||||||
response: HttpServletResponse,
|
response: HttpServletResponse,
|
||||||
@CookieValue(name = "TOKEN", required = false) token: String?,
|
@CookieValue(name = "TOKEN", required = false) token: String?,
|
||||||
@ -98,33 +99,33 @@ class Account(private val repository: UserRepository) {
|
|||||||
@RequestParam(name = "email", required = false) email: String?,
|
@RequestParam(name = "email", required = false) email: String?,
|
||||||
@RequestParam(name = "address", required = false) address: String?
|
@RequestParam(name = "address", required = false) address: String?
|
||||||
): String {
|
): String {
|
||||||
val user = this.getCurrentUser(token) ?: return ResultBuilder<Any>("账户未登录").toJson()
|
val user = this.getCurrentUser(token) ?: return ResultBuilderJson<Any>("账户未登录").toJson()
|
||||||
user.update(name, password, age, gender, phone, email, address)
|
user.update(name, password, age, gender, phone, email, address)
|
||||||
repository.save(user)
|
repository.save(user)
|
||||||
updateToken(response, user.token)
|
updateToken(response, user.token)
|
||||||
return ResultBuilder<Any>("success", "更新账户信息成功").toJson()
|
return ResultBuilderJson<Any>("success", "更新账户信息成功").toJson()
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/api/v1/account/admin/info/{id}", produces = ["application/json"])
|
@GetMapping("/admin/info/{id}", produces = ["application/json"])
|
||||||
fun infoAdmin(
|
fun infoAdmin(
|
||||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||||
@PathVariable id: Long,
|
@PathVariable id: Long,
|
||||||
): String {
|
): String {
|
||||||
if (this.hasAdminPermissions(token)) return ResultBuilder<Any>("无管理员权限").toJson()
|
if (this.hasAdminPermissions(token)) return ResultBuilderJson<Any>("无管理员权限").toJson()
|
||||||
return ResultBuilder(repository.findById(id)).toJson()
|
return ResultBuilderJson(repository.findById(id)).toJson()
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/api/v1/account/admin/remove/{id}", produces = ["application/json"])
|
@DeleteMapping("/admin/remove/{id}", produces = ["application/json"])
|
||||||
fun removeAdmin(
|
fun removeAdmin(
|
||||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||||
@PathVariable id: Long,
|
@PathVariable id: Long,
|
||||||
): String {
|
): String {
|
||||||
if (this.hasAdminPermissions(token)) return ResultBuilder<Any>("无管理员权限").toJson()
|
if (this.hasAdminPermissions(token)) return ResultBuilderJson<Any>("无管理员权限").toJson()
|
||||||
// TODO: 完成管理员删除方法
|
// TODO: 完成管理员删除方法
|
||||||
return ResultBuilder(repository.findById(id)).toJson()
|
return ResultBuilderJson(repository.findById(id)).toJson()
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/api/v1/account/admin/update/{id}", produces = ["application/json"])
|
@PostMapping("/admin/update/{id}", produces = ["application/json"])
|
||||||
fun updateAdmin(
|
fun updateAdmin(
|
||||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||||
@PathVariable id: Long,
|
@PathVariable id: Long,
|
||||||
@ -136,8 +137,8 @@ class Account(private val repository: UserRepository) {
|
|||||||
@RequestParam(name = "email", required = false) email: String?,
|
@RequestParam(name = "email", required = false) email: String?,
|
||||||
@RequestParam(name = "address", required = false) address: String?
|
@RequestParam(name = "address", required = false) address: String?
|
||||||
): String {
|
): String {
|
||||||
if (this.hasAdminPermissions(token)) return ResultBuilder<Any>("无管理员权限").toJson()
|
if (this.hasAdminPermissions(token)) return ResultBuilderJson<Any>("无管理员权限").toJson()
|
||||||
// TODO: 完成管理员更新账户数据方法
|
// TODO: 完成管理员更新账户数据方法
|
||||||
return ResultBuilder(repository.findById(id)).toJson()
|
return ResultBuilderJson(repository.findById(id)).toJson()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,11 +5,11 @@ import org.springframework.web.bind.annotation.PathVariable
|
|||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
import team8.fruitable.datebase.entity.User
|
import team8.fruitable.datebase.entity.User
|
||||||
import team8.fruitable.datebase.repository.ItemRepository
|
import team8.fruitable.datebase.repository.ItemRepository
|
||||||
import team8.fruitable.datebase.repository.UserRepository
|
import team8.fruitable.datebase.repository.AccountRepository
|
||||||
import team8.fruitable.util.ResultBuilder
|
import team8.fruitable.util.ResultBuilderJson
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
class Item(private val itemRepository: ItemRepository, private val userRepository: UserRepository) {
|
class Item(private val itemRepository: ItemRepository, private val userRepository: AccountRepository) {
|
||||||
private fun getCurrentUser(token: String?): User? {
|
private fun getCurrentUser(token: String?): User? {
|
||||||
return token?.let(userRepository::findByToken)
|
return token?.let(userRepository::findByToken)
|
||||||
}
|
}
|
||||||
@ -20,6 +20,6 @@ class Item(private val itemRepository: ItemRepository, private val userRepositor
|
|||||||
|
|
||||||
@GetMapping("/api/v1/item/info/{id}", produces = ["application/json"])
|
@GetMapping("/api/v1/item/info/{id}", produces = ["application/json"])
|
||||||
fun info(@PathVariable id: Long): String {
|
fun info(@PathVariable id: Long): String {
|
||||||
return ResultBuilder(itemRepository.findById(id).orElse(null)).toJson()
|
return ResultBuilderJson(itemRepository.findById(id).orElse(null)).toJson()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
32
src/main/kotlin/team8/fruitable/controller/page/Error.kt
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package team8.fruitable.controller.page
|
||||||
|
|
||||||
|
import org.springframework.boot.web.servlet.error.ErrorController
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.ui.Model
|
||||||
|
import org.springframework.ui.set
|
||||||
|
import org.springframework.web.bind.annotation.CookieValue
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import team8.fruitable.datebase.repository.AccountRepository
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
class Error(private val repository: AccountRepository) : ErrorController {
|
||||||
|
@RequestMapping("/error")
|
||||||
|
fun error(
|
||||||
|
model: Model,
|
||||||
|
@CookieValue("TOKEN", required = false) token: String?,
|
||||||
|
@ModelAttribute("title") title: String?,
|
||||||
|
@ModelAttribute("message") message: String?,
|
||||||
|
@ModelAttribute("redirect") redirect: String?
|
||||||
|
): Model {
|
||||||
|
token?.let(repository::findByToken)?.let { model["user"] = it }
|
||||||
|
|
||||||
|
model["error"] = mapOf(
|
||||||
|
"title" to title,
|
||||||
|
"message" to message,
|
||||||
|
"redirect" to redirect
|
||||||
|
)
|
||||||
|
|
||||||
|
return model
|
||||||
|
}
|
||||||
|
}
|
52
src/main/kotlin/team8/fruitable/controller/page/Pages.kt
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package team8.fruitable.controller.page
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.ui.Model
|
||||||
|
import org.springframework.ui.set
|
||||||
|
import org.springframework.web.bind.annotation.CookieValue
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
import org.springframework.web.servlet.ModelAndView
|
||||||
|
import team8.fruitable.datebase.entity.User
|
||||||
|
import team8.fruitable.datebase.repository.AccountRepository
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
class Pages(private val repository: AccountRepository) {
|
||||||
|
private fun getCurrentUser(token: String?): User? {
|
||||||
|
return token?.let(repository::findByToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hasAdminPermissions(token: String?): Boolean {
|
||||||
|
return this.getCurrentUser(token)?.isAdmin ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/")
|
||||||
|
fun index(
|
||||||
|
model: Model,
|
||||||
|
@CookieValue("TOKEN", required = false) token: String?
|
||||||
|
): String {
|
||||||
|
model["isIndex"] = true
|
||||||
|
this.getCurrentUser(token)?.let { model["user"] = it }
|
||||||
|
return "index"
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/login")
|
||||||
|
fun login(
|
||||||
|
model: Model,
|
||||||
|
@CookieValue("TOKEN", required = false) token: String?
|
||||||
|
): String {
|
||||||
|
model["isLogin"] = true
|
||||||
|
this.getCurrentUser(token)?.let { model["user"] = it }
|
||||||
|
return "login"
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/register")
|
||||||
|
fun register(
|
||||||
|
model: Model,
|
||||||
|
@CookieValue("TOKEN", required = false) token: String?
|
||||||
|
): String {
|
||||||
|
model["isRegister"] = true
|
||||||
|
this.getCurrentUser(token)?.let { model["user"] = it }
|
||||||
|
return "register"
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package team8.fruitable.datebase.entity
|
package team8.fruitable.datebase.entity
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonView
|
||||||
import jakarta.persistence.*
|
import jakarta.persistence.*
|
||||||
import team8.fruitable.constant.UserType
|
import team8.fruitable.constant.UserType
|
||||||
import team8.fruitable.util.Util
|
import team8.fruitable.util.Util
|
||||||
@ -13,47 +14,65 @@ class User(
|
|||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Column(name = "id", nullable = false)
|
@Column(name = "id", nullable = false)
|
||||||
|
@JsonView(UserView::class)
|
||||||
var id: Long? = null,
|
var id: Long? = null,
|
||||||
|
|
||||||
@Column(name = "name", length = 16, nullable = false)
|
@Column(name = "name", length = 16, nullable = false)
|
||||||
|
@JsonView(GuestView::class)
|
||||||
var name: String? = null,
|
var name: String? = null,
|
||||||
|
|
||||||
@Column(name = "password", length = 64, nullable = false)
|
@Column(name = "password", length = 64, nullable = false)
|
||||||
|
@JsonView(AdminView::class)
|
||||||
var password: String? = null,
|
var password: String? = null,
|
||||||
|
|
||||||
@Column(name = "time_create", nullable = false)
|
@Column(name = "time_create", nullable = false)
|
||||||
|
@JsonView(UserView::class)
|
||||||
var createTime: LocalDateTime = LocalDateTime.now(),
|
var createTime: LocalDateTime = LocalDateTime.now(),
|
||||||
|
|
||||||
@Column(name = "time_login", nullable = false)
|
@Column(name = "time_login", nullable = false)
|
||||||
|
@JsonView(UserView::class)
|
||||||
var loginTime: LocalDateTime = LocalDateTime.now(),
|
var loginTime: LocalDateTime = LocalDateTime.now(),
|
||||||
|
|
||||||
@Column(name = "token", length = 36)
|
@Column(name = "token", length = 36)
|
||||||
|
@JsonView(AdminView::class)
|
||||||
var token: String = UUID.randomUUID().toString(),
|
var token: String = UUID.randomUUID().toString(),
|
||||||
|
|
||||||
@Column(name = "age")
|
@Column(name = "age")
|
||||||
|
@JsonView(GuestView::class)
|
||||||
var age: Int? = null,
|
var age: Int? = null,
|
||||||
|
|
||||||
@Column(name = "gender", length = 1)
|
@Column(name = "gender", length = 1)
|
||||||
|
@JsonView(GuestView::class)
|
||||||
var gender: String? = null,
|
var gender: String? = null,
|
||||||
|
|
||||||
@Column(name = "phone", length = 11)
|
@Column(name = "phone", length = 11)
|
||||||
|
@JsonView(UserView::class)
|
||||||
var phone: String? = null,
|
var phone: String? = null,
|
||||||
|
|
||||||
@Column(name = "email", length = 64)
|
@Column(name = "email", length = 64)
|
||||||
|
@JsonView(GuestView::class)
|
||||||
var email: String? = null,
|
var email: String? = null,
|
||||||
|
|
||||||
@Column(name = "address", length = 64)
|
@Column(name = "address", length = 64)
|
||||||
|
@JsonView(UserView::class)
|
||||||
var address: String? = null,
|
var address: String? = null,
|
||||||
|
|
||||||
@Column(name = "is_admin", nullable = false)
|
@Column(name = "is_admin", nullable = false)
|
||||||
|
@JsonView(AdminView::class)
|
||||||
var isAdmin: Boolean = false,
|
var isAdmin: Boolean = false,
|
||||||
|
|
||||||
@OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.LAZY, mappedBy = "carted")
|
@OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.LAZY, mappedBy = "carted")
|
||||||
var carts: MutableList<Item> = mutableListOf<Item>(),
|
@JsonView(UserView::class)
|
||||||
|
var carts: MutableList<Item> = mutableListOf(),
|
||||||
|
|
||||||
@OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.LAZY, mappedBy = "user")
|
@OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.LAZY, mappedBy = "user")
|
||||||
var orders: MutableList<Order> = mutableListOf<Order>()
|
@JsonView(UserView::class)
|
||||||
|
var orders: MutableList<Order> = mutableListOf()
|
||||||
) {
|
) {
|
||||||
|
interface GuestView
|
||||||
|
interface UserView : GuestView
|
||||||
|
interface AdminView : UserView
|
||||||
|
|
||||||
constructor(name: String, password: String) : this() {
|
constructor(name: String, password: String) : this() {
|
||||||
this.name = name
|
this.name = name
|
||||||
this.password = this.genPassword(password)
|
this.password = this.genPassword(password)
|
||||||
|
@ -3,7 +3,7 @@ package team8.fruitable.datebase.repository
|
|||||||
import org.springframework.data.repository.CrudRepository
|
import org.springframework.data.repository.CrudRepository
|
||||||
import team8.fruitable.datebase.entity.User
|
import team8.fruitable.datebase.entity.User
|
||||||
|
|
||||||
interface UserRepository : CrudRepository<User, Long> {
|
interface AccountRepository : CrudRepository<User, Long> {
|
||||||
fun findByName(name: String): User?
|
fun findByName(name: String): User?
|
||||||
fun findByToken(token: String): User?
|
fun findByToken(token: String): User?
|
||||||
}
|
}
|
@ -4,7 +4,7 @@ import com.alibaba.fastjson2.toJSONString
|
|||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class ResultBuilder<T> {
|
class ResultBuilderJson<T> {
|
||||||
var status: String = "auto"
|
var status: String = "auto"
|
||||||
var message: String = ""
|
var message: String = ""
|
||||||
val timestamp: LocalDateTime = LocalDateTime.now()
|
val timestamp: LocalDateTime = LocalDateTime.now()
|
@ -7,3 +7,8 @@ spring:
|
|||||||
show-sql: true
|
show-sql: true
|
||||||
hibernate:
|
hibernate:
|
||||||
ddl-auto: update
|
ddl-auto: update
|
||||||
|
server:
|
||||||
|
servlet:
|
||||||
|
encoding:
|
||||||
|
charset: UTF-8
|
||||||
|
force-response: true
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px"
|
||||||
y="0px" viewBox="0 0 503.945 503.945" style="enable-background:new 0 0 503.945 503.945;" xml:space="preserve">
|
y="0px" viewBox="0 0 503.945 503.945" style="enable-background:new 0 0 503.945 503.945;" xml:space="preserve">
|
||||||
<path style="fill:#18456D;" d="M455.173,345.073l48-152.8c1.6-6.4,0.8-12.8-3.2-18.4s-10.4-8.8-16.8-8.8h-462.4
|
<path style="fill:#18456D;" d="M455.173,345.073l48-152.8c1.6-6.4,0.8-12.8-3.2-18.4s-10.4-8.8-16.8-8.8h-462.4
|
||||||
c-6.4,0-12.8,3.2-16.8,8.8s-4.8,12-3.2,18.4l48,152.8c0,3.2,0.8,5.6,2.4,8.8l20.8,66.4c2.4,8.8,10.4,14.4,20,14.4h320
|
c-6.4,0-12.8,3.2-16.8,8.8s-4.8,12-3.2,18.4l48,152.8c0,3.2,0.8,5.6,2.4,8.8l20.8,66.4c2.4,8.8,10.4,14.4,20,14.4h320
|
||||||
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px"
|
||||||
y="0px" viewBox="0 0 495 495" style="enable-background:new 0 0 495 495;" xml:space="preserve">
|
y="0px" viewBox="0 0 495 495" style="enable-background:new 0 0 495 495;" xml:space="preserve">
|
||||||
<polygon style="fill:#004FAC;" points="181.112,81.833 168.742,166.012 168.742,222.068 326.258,222.068 326.258,166.012
|
<polygon style="fill:#004FAC;" points="181.112,81.833 168.742,166.012 168.742,222.068 326.258,222.068 326.258,166.012
|
||||||
313.888,81.833 " />
|
313.888,81.833 " />
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<svg version="1.1" id="Pin" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
<svg version="1.1" id="Pin" xmlns="http://www.w3.org/2000/svg" x="0px"
|
||||||
y="0px" viewBox="0 0 512.001 512.001" style="enable-background:new 0 0 512.001 512.001;" xml:space="preserve">
|
y="0px" viewBox="0 0 512.001 512.001" style="enable-background:new 0 0 512.001 512.001;" xml:space="preserve">
|
||||||
<path d="M499.505,128.508l-72.045-72.045c-3.163-3.162-8.293-3.162-11.455,0c-3.163,3.164-3.163,8.293,0,11.456l72.045,72.044
|
<path d="M499.505,128.508l-72.045-72.045c-3.163-3.162-8.293-3.162-11.455,0c-3.163,3.164-3.163,8.293,0,11.456l72.045,72.044
|
||||||
c10.2,10.201,10.2,27.222,0,37.422c-10.201,10.2-27.221,10.2-37.421-0.001L334.614,61.371c-10.2-10.199-10.2-27.22,0-37.419
|
c10.2,10.201,10.2,27.222,0,37.422c-10.201,10.2-27.221,10.2-37.421-0.001L334.614,61.371c-10.2-10.199-10.2-27.22,0-37.419
|
||||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px"
|
||||||
y="0px" viewBox="0 0 503.945 503.945" style="enable-background:new 0 0 503.945 503.945;" xml:space="preserve">
|
y="0px" viewBox="0 0 503.945 503.945" style="enable-background:new 0 0 503.945 503.945;" xml:space="preserve">
|
||||||
<path style="fill:#18456D;" d="M455.173,345.073l48-152.8c1.6-6.4,0.8-12.8-3.2-18.4s-10.4-8.8-16.8-8.8h-462.4
|
<path style="fill:#18456D;" d="M455.173,345.073l48-152.8c1.6-6.4,0.8-12.8-3.2-18.4s-10.4-8.8-16.8-8.8h-462.4
|
||||||
c-6.4,0-12.8,3.2-16.8,8.8s-4.8,12-3.2,18.4l48,152.8c0,3.2,0.8,5.6,2.4,8.8l20.8,66.4c2.4,8.8,10.4,14.4,20,14.4h320
|
c-6.4,0-12.8,3.2-16.8,8.8s-4.8,12-3.2,18.4l48,152.8c0,3.2,0.8,5.6,2.4,8.8l20.8,66.4c2.4,8.8,10.4,14.4,20,14.4h320
|
||||||
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px"
|
||||||
y="0px" width="30.021px" height="30.021px" viewBox="0 0 30.021 30.021"
|
y="0px" width="30.021px" height="30.021px" viewBox="0 0 30.021 30.021"
|
||||||
style="enable-background:new 0 0 30.021 30.021;" xml:space="preserve">
|
style="enable-background:new 0 0 30.021 30.021;" xml:space="preserve">
|
||||||
<path d="M29.069,22.276c-0.791,0.932-1.917,1.409-3.052,1.409c-0.913,0-1.834-0.312-2.587-0.949l-8.42-7.152l-8.42,7.151
|
<path d="M29.069,22.276c-0.791,0.932-1.917,1.409-3.052,1.409c-0.913,0-1.834-0.312-2.587-0.949l-8.42-7.152l-8.42,7.151
|
||||||
|
Before Width: | Height: | Size: 800 B After Width: | Height: | Size: 765 B |
@ -8,6 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
import {getItems, getNextItem, hasNextItem, indexOf, loadItem,} from "./items.js";
|
import {getItems, getNextItem, hasNextItem, indexOf, loadItem,} from "./items.js";
|
||||||
|
|
||||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||||
// 源数据
|
// 源数据
|
||||||
let rawBanners = [];
|
let rawBanners = [];
|
||||||
@ -135,7 +136,7 @@ function updateItems() {
|
|||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
let ID = this.getAttribute("item_id");
|
let ID = this.getAttribute("item_id");
|
||||||
if (ID != null) {
|
if (ID != null) {
|
||||||
window.location.href = `item.jsp?item_id=${ID}`;
|
window.location.href = `item/${ID}`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -8,6 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
import {getItem, loadItem} from "./items.js";
|
import {getItem, loadItem} from "./items.js";
|
||||||
|
|
||||||
let ID;
|
let ID;
|
||||||
let TheItem;
|
let TheItem;
|
||||||
window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () {
|
window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () {
|
||||||
@ -64,7 +65,7 @@ window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void
|
|||||||
});
|
});
|
||||||
// 为选项添加点击事件
|
// 为选项添加点击事件
|
||||||
Array.from(OptionDisplayer.children).forEach((v) => {
|
Array.from(OptionDisplayer.children).forEach((v) => {
|
||||||
let contants = v.querySelector(".Contants");
|
let contants = v.querySelector(".Contents");
|
||||||
Array.from(contants.children).forEach((v) => {
|
Array.from(contants.children).forEach((v) => {
|
||||||
v.addEventListener("click", function () {
|
v.addEventListener("click", function () {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
width: 140px;
|
width: 140px;
|
||||||
color: rgb(0, 255, 90);
|
color: rgb(0, 255, 90);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-family: "LcdD";
|
font-family: "LcdD", serif;
|
||||||
border: 3px solid black;
|
border: 3px solid black;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
@ -20,7 +20,7 @@ div {
|
|||||||
height: 500px;
|
height: 500px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#Contents > .Editor {
|
#Contents > .Editors {
|
||||||
flex: 4 0 0;
|
flex: 4 0 0;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -32,31 +32,31 @@ div {
|
|||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#Contents > .Editor > .Title {
|
#Contents > .Editors > .Title {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
#Contents > .Editor > .Result {
|
#Contents > .Editors > .Result {
|
||||||
color: wheat;
|
color: wheat;
|
||||||
border: 3px solid skyblue;
|
border: 3px solid skyblue;
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#Contents > .Editor > .Result td {
|
#Contents > .Editors > .Result td {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
border: 1px solid cornflowerblue;
|
border: 1px solid cornflowerblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#Contents > .Editor > .Result > thead {
|
#Contents > .Editors > .Result > thead {
|
||||||
background-color: #044488;
|
background-color: #044488;
|
||||||
}
|
}
|
||||||
|
|
||||||
#Contents > .Editor > .Result > tbody {
|
#Contents > .Editors > .Result > tbody {
|
||||||
background-color: #008080;
|
background-color: #008080;
|
||||||
}
|
}
|
||||||
|
|
||||||
#Contents > .Editor > .Pages > * {
|
#Contents > .Editors > .Pages > * {
|
||||||
color: wheat;
|
color: wheat;
|
||||||
margin-right: 3px;
|
margin-right: 3px;
|
||||||
border: 3px solid skyblue;
|
border: 3px solid skyblue;
|
||||||
@ -64,15 +64,15 @@ div {
|
|||||||
background-color: cadetblue;
|
background-color: cadetblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#Contents > .Editor > .Pages > *:last-child {
|
#Contents > .Editors > .Pages > *:last-child {
|
||||||
margin-right: inherit;
|
margin-right: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#Contents > .Editor > .Pages > span {
|
#Contents > .Editors > .Pages > span {
|
||||||
color: green;
|
color: green;
|
||||||
}
|
}
|
||||||
|
|
||||||
#Contents > .UserEditor {
|
#Contents > .EditPanel {
|
||||||
flex: 1 0 0;
|
flex: 1 0 0;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@ -81,8 +81,8 @@ div {
|
|||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#Contents > .UserEditor > .Displayer {
|
#Contents > .EditPanel > .Panel {
|
||||||
border: 0px;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1280px) {
|
@media (min-width: 1280px) {
|
||||||
|
@ -35,7 +35,7 @@ div {
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
color: wheat;
|
color: wheat;
|
||||||
font-family: "Normal";
|
font-family: "Normal", system-ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ErrorTitle {
|
.ErrorTitle {
|
||||||
@ -46,7 +46,7 @@ div {
|
|||||||
|
|
||||||
.ErrorRedirectButton {
|
.ErrorRedirectButton {
|
||||||
margin: 20px 15px;
|
margin: 20px 15px;
|
||||||
padding: 8px 0px;
|
padding: 8px 0;
|
||||||
border: 3px solid skyblue;
|
border: 3px solid skyblue;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
|
@ -47,23 +47,23 @@ div {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.Item .Infos > * {
|
.Item .Infos > * {
|
||||||
margin: 10px 0px;
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Item .Infos > .Title {
|
.Item .Infos > .Title {
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-family: "Normal";
|
font-family: "Normal", system-ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Item .Infos .Description {
|
.Item .Infos .Description {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-family: "Normal";
|
font-family: "Normal", system-ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Item .Infos .Prices {
|
.Item .Infos .Prices {
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
font-family: "Normal";
|
font-family: "Normal", system-ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Item .Infos .Prices .VipPrice {
|
.Item .Infos .Prices .VipPrice {
|
||||||
@ -79,7 +79,7 @@ div {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.Item .Infos .Prices .Price[has_vip_price] {
|
.Item .Infos .Prices .Price[has_vip_price] {
|
||||||
color: gray;
|
color: grey;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
@ -92,32 +92,32 @@ div {
|
|||||||
|
|
||||||
.Item .Infos .Options > .Option {
|
.Item .Infos .Options > .Option {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
margin: 5px 0px;
|
margin: 5px 0;
|
||||||
border: 1px solid rgba(0, 120, 255, 0.8);
|
border: 1px solid rgba(0, 120, 255, 0.8);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Item .Infos .Options > .Option .Title {
|
.Item .Infos .Options > .Option .Title {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 0px 10px;
|
padding: 0 10px;
|
||||||
border-radius: 5px 0px 0px 5px;
|
border-radius: 5px 0 0 5px;
|
||||||
background: green;
|
background: green;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Item .Infos .Options > .Option .Contants {
|
.Item .Infos .Options > .Option .Contents {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Item .Infos .Options > .Option .Contants .Option {
|
.Item .Infos .Options > .Option .Contents .Option {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
padding: 0px 5px;
|
padding: 0 5px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: #355ae8;
|
background-color: #355ae8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Item .Infos .Options > .Option .Contants .Option[selected] {
|
.Item .Infos .Options > .Option .Contents .Option[selected] {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
background-color: #489dff;
|
background-color: #489dff;
|
||||||
}
|
}
|
||||||
|
0
src/main/resources/templates/cart.mustache
Normal file
@ -65,7 +65,7 @@
|
|||||||
|
|
||||||
<!-- 页面内容 -->
|
<!-- 页面内容 -->
|
||||||
<div id="Contents">
|
<div id="Contents">
|
||||||
<div class="Editor">
|
<div class="Editors">
|
||||||
<div class="Title">
|
<div class="Title">
|
||||||
<form class="Search" action="edit.jsp" method="post">
|
<form class="Search" action="edit.jsp" method="post">
|
||||||
<s:select name="type" list="#{'ALL': '搜索全部', 'ID': '以ID搜索', 'USERNAME': '以用户名搜索', 'CREATE_DATE': '以帐户注册时间搜索', 'LAST_LOGIN_DATE': '以最后登录时间搜索', 'AGE': '以年龄搜索', 'GENDER': '以性别搜索', 'EMAIL': '以邮箱搜索', 'IS_ADMIN': '以管理员状态搜索'}" value="%{#EditInfo.SearchType}" />
|
<s:select name="type" list="#{'ALL': '搜索全部', 'ID': '以ID搜索', 'USERNAME': '以用户名搜索', 'CREATE_DATE': '以帐户注册时间搜索', 'LAST_LOGIN_DATE': '以最后登录时间搜索', 'AGE': '以年龄搜索', 'GENDER': '以性别搜索', 'EMAIL': '以邮箱搜索', 'IS_ADMIN': '以管理员状态搜索'}" value="%{#EditInfo.SearchType}" />
|
||||||
@ -124,8 +124,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="UserEditor">
|
<div class="EditPanel">
|
||||||
<iframe id="Displayer" class="Displayer" name="displayer"></iframe>
|
<iframe id="Displayer" class="Panel" name="displayer"></iframe>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
19
src/main/resources/templates/edit.mustache
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{{> header }}
|
||||||
|
|
||||||
|
<!-- 页面内容 -->
|
||||||
|
<div id="Contents">
|
||||||
|
<div class="Editors">
|
||||||
|
{{# userEditor }}
|
||||||
|
{{> editor/user }}
|
||||||
|
{{/ userEditor }}
|
||||||
|
{{# itemEditor }}
|
||||||
|
{{> editor/item }}
|
||||||
|
{{/ itemEditor }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="EditPanel">
|
||||||
|
<iframe id="Panel" class="Panel" name="panel"></iframe>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{> footer }}
|
37
src/main/resources/templates/editor/item.mustache
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{{> header }}
|
||||||
|
|
||||||
|
<!-- 页面内容 -->
|
||||||
|
<div id="Contents">
|
||||||
|
<div class="Item">
|
||||||
|
<div class="Picture">
|
||||||
|
<img alt="商品图片" src=""/>
|
||||||
|
</div>
|
||||||
|
<div class="Infos">
|
||||||
|
<span class="Title"></span>
|
||||||
|
<div class="Prices">
|
||||||
|
<div class="VipPrice"></div>
|
||||||
|
<div class="Price"></div>
|
||||||
|
</div>
|
||||||
|
<span class="Description"></span>
|
||||||
|
<div class="Options">
|
||||||
|
<div class="Option">
|
||||||
|
<div class="Title">数量</div>
|
||||||
|
<div class="Contents">
|
||||||
|
<div class="Option" selected> 1 </div>
|
||||||
|
<div class="Option"> 2 </div>
|
||||||
|
<div class="Option"> 3 </div>
|
||||||
|
<div class="Option"> 4 </div>
|
||||||
|
<div class="Option"> 5 </div>
|
||||||
|
<div class="Option"> 6 </div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="Buttons">
|
||||||
|
<span class="Button">立即购买</span>
|
||||||
|
<span class="Button">加入购物车</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{> footer }}
|
69
src/main/resources/templates/editor/user.mustache
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<div class="Title">
|
||||||
|
<form class="Search" action="edit" method="post">
|
||||||
|
<input type="hidden" name="edit" value="user"/>
|
||||||
|
{{!
|
||||||
|
list="#{'ALL': '搜索全部', 'ID': '以ID搜索', 'USERNAME': '以用户名搜索', 'CREATE_DATE': '以帐户注册时间搜索', 'LAST_LOGIN_DATE': '以最后登录时间搜索', 'AGE': '以年龄搜索', 'GENDER': '以性别搜索', 'EMAIL': '以邮箱搜索', 'IS_ADMIN': '以管理员状态搜索'}"
|
||||||
|
}}
|
||||||
|
<select name="type">
|
||||||
|
{{#Editor.Selects}}
|
||||||
|
<option value="{{key}}">{{value}}</option>
|
||||||
|
{{/Editor.Selects}}
|
||||||
|
</select>
|
||||||
|
<label>
|
||||||
|
<input name="search" placeholder="请在此处输入你想要搜索的内容..." value="{{Editor.Searching}}"/>
|
||||||
|
</label>
|
||||||
|
<button type="submit">搜索</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<button onclick="location.reload();">刷新</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="Result">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>ID</td>
|
||||||
|
<td>用户名</td>
|
||||||
|
<td>帐户创建时间</td>
|
||||||
|
<td>最后登录时间</td>
|
||||||
|
<td>年龄</td>
|
||||||
|
<td>性别</td>
|
||||||
|
<td>邮箱</td>
|
||||||
|
<td>管理员</td>
|
||||||
|
<td>操作</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#Users}}
|
||||||
|
<tr id="{{ Id }}">
|
||||||
|
<td>{{ Id }}</td>
|
||||||
|
<td>{{ UserName }}</td>
|
||||||
|
<td>{{ CreateDate }}</td>
|
||||||
|
<td>{{ LastLoginDate }}</td>
|
||||||
|
<td>{{ Age }}</td>
|
||||||
|
<td>{{ Gender }}</td>
|
||||||
|
<td>{{ Phone }}</td>
|
||||||
|
<td>{{ Email }}</td>
|
||||||
|
<td>{{ Address }}</td>
|
||||||
|
<td>{{ IsAdmin }}</td>
|
||||||
|
<td>
|
||||||
|
<button class="update">编辑</button>
|
||||||
|
<button class="remove">删除</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{/Users}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="Pages">
|
||||||
|
<a href="edit?page=0">首页</a>
|
||||||
|
<s:iterator begin="%{#EditInfo.StartPage}" end="%{#EditInfo.StopPage}" var="PageNumber">
|
||||||
|
<s:if test="%{#PageNumber == #EditInfo.NowPageStr}">
|
||||||
|
<span>第 <s:property value="%{#PageNumber + 1}" 页</span>
|
||||||
|
</s:if>
|
||||||
|
<s:else>
|
||||||
|
<a href=" edit.jsp?page=<s:property value="%{#PageNumber} }}">第 <s:property
|
||||||
|
value="%{#PageNumber + 1}"/> 页</a>
|
||||||
|
</s:else>
|
||||||
|
</s:iterator>
|
||||||
|
<a href="edit.jsp?page=<s:property value=" %{#EditInfo.EndPage} }}">尾页</a>
|
||||||
|
</div>
|
@ -1,109 +0,0 @@
|
|||||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
|
||||||
pageEncoding="UTF-8"%>
|
|
||||||
<%@ taglib prefix="s" uri="/struts-tags" %>
|
|
||||||
<s:action name="auth" var="AuthInfo" />
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-Hans">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<s:if test="%{#ErrorRedirectTo != \"none\"}">
|
|
||||||
<meta http-equiv="refresh" content="3;url=<s:property value="ErrorRedirectTo" />">
|
|
||||||
</s:if>
|
|
||||||
<title>出错啦! - 67购物网站</title>
|
|
||||||
<script type="text/javascript" src="../static/scripts/header.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/clock.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/top.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/footer.js"></script>
|
|
||||||
<link type="image/x-icon" rel="icon" href="../static/images/favicon.ico">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/header.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/clock.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/top.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/footer.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/error.css">
|
|
||||||
<!-- 外部小组件 -->
|
|
||||||
<script src="../static/scripts/lib/anime.min.js"></script>
|
|
||||||
<script async src="../static/scripts/lib/explosion.min.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!-- 头部内容 -->
|
|
||||||
<div id="Header">
|
|
||||||
<div class="List Special Title">67购物网站</div>
|
|
||||||
<div class="List Link" href="index.jsp">
|
|
||||||
<span class="Text">首页</span>
|
|
||||||
</div>
|
|
||||||
<div class="List Link" this>
|
|
||||||
<span class="Text">活动</span>
|
|
||||||
</div>
|
|
||||||
<div class="List Blank"></div>
|
|
||||||
<div class="List Special SearchBar">
|
|
||||||
<input class="InputBar" type="text" />
|
|
||||||
</div>
|
|
||||||
<div class="List Blank"></div>
|
|
||||||
<div class="List Button"><span class="Text">历史记录</span></div>
|
|
||||||
<div class="List Button"><span class="Text">购物车</span></div>
|
|
||||||
<s:if test="%{#AuthInfo.IsLogined}">
|
|
||||||
<div class="List Button Link" href="logout.action"><span class="Text">注销</span></div>
|
|
||||||
<s:if test="%{#AuthInfo.UserInfo.IsAdmin}">
|
|
||||||
<div class="List Button Link" href="edit.jsp"><span class="Text">编辑</span></div>
|
|
||||||
</s:if>
|
|
||||||
<div class="List Button Link" href="account.jsp"><span class="Text">账户</span></div>
|
|
||||||
</s:if>
|
|
||||||
<s:else>
|
|
||||||
<div class="List Button Link" href="login.jsp"><span class="Text">登录</span></div>
|
|
||||||
<div class="List Button Link" href="register.jsp"><span class="Text">注册</span></div>
|
|
||||||
</s:else>
|
|
||||||
<div class="List Special Clock">
|
|
||||||
<span class="CLOCK"></span>
|
|
||||||
</div>
|
|
||||||
<div class="List Special PinHeader">
|
|
||||||
<img class="PIN" src="../static/images/pin.svg" checked />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 页面内容 -->
|
|
||||||
<div id="Contents">
|
|
||||||
<div class="ErrorInfo">
|
|
||||||
<div class="ErrorTitle"><s:property value="ErrorFrom" />失败</div>
|
|
||||||
|
|
||||||
<div class="ErrorMessage">原因: <s:property value="ErrorMessage" /></div>
|
|
||||||
|
|
||||||
<s:if test="%{#ErrorRedirectTo != \"none\"}">
|
|
||||||
<div class="ErrorRedirectMessage">将在三秒后跳转至页面: <s:property value="ErrorRedirectTo" /></div>
|
|
||||||
<button class="ErrorRedirectButton" onclick="javascript:window.location.replace('<s:property value="ErrorRedirectTo" />')">点此立即跳转</button>
|
|
||||||
</s:if>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 页尾内容 -->
|
|
||||||
<div id="Footer">
|
|
||||||
<div class="Infos">
|
|
||||||
<div class="Icon"><img src="../static/images/icon.svg" /></div>
|
|
||||||
<div class="Title">67购物网站</div>
|
|
||||||
<div class="Contents">
|
|
||||||
<span>只做高质量商品销售~</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="Links">
|
|
||||||
<div class="Title"></div>
|
|
||||||
<div class="Contents"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 浮动内容 -->
|
|
||||||
<div id="Floater">
|
|
||||||
<!-- 回到顶层 -->
|
|
||||||
<div class="TOP"></div>
|
|
||||||
<canvas
|
|
||||||
class="fireworks"
|
|
||||||
style="
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
z-index: 1;
|
|
||||||
pointer-events: none;
|
|
||||||
"
|
|
||||||
></canvas>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
42
src/main/resources/templates/error.mustache
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>主页 - 在线果蔬商城</title>
|
||||||
|
<script type="text/javascript" src="scripts/header.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/clock.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/top.js"></script>
|
||||||
|
<script type="module" src="scripts/resources.js"></script>
|
||||||
|
<script type="module" src="scripts/items.js"></script>
|
||||||
|
<script type="module" src="scripts/index.js"></script>
|
||||||
|
<link type="image/x-icon" rel="icon" href="images/favicon.ico">
|
||||||
|
<!-- 页面公共的样式表 -->
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/header.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/clock.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/top.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/footer.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/loading.css">
|
||||||
|
<!-- 页面特定的样式表 -->
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/error.css">
|
||||||
|
<!-- 外部小组件 -->
|
||||||
|
<script src="scripts/lib/anime.min.js"></script>
|
||||||
|
<script async src="scripts/lib/explosion.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
{{> header }}
|
||||||
|
|
||||||
|
<div class="ErrorInfo">
|
||||||
|
<div class="ErrorTitle">{{ title }} 失败</div>
|
||||||
|
<div class="ErrorMessage">原因: {{ message }}</div>
|
||||||
|
{{# redirect }}
|
||||||
|
<div class="ErrorRedirectMessage">将在三秒后跳转至页面: {{ redirect }}</div>
|
||||||
|
<button class="ErrorRedirectButton" onclick="window.location.replace('{{ redirect }}')">点此立即跳转</button>
|
||||||
|
{{/ redirect }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{> footer }}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,7 +1,7 @@
|
|||||||
<!-- 页尾内容 -->
|
<!-- 页尾内容 -->
|
||||||
<div id="Footer">
|
<div id="Footer">
|
||||||
<div class="Infos">
|
<div class="Infos">
|
||||||
<div class="Icon"><img src="../static/images/icon.svg" /></div>
|
<div class="Icon"><img alt="图标" src="images/icon.svg" /></div>
|
||||||
<div class="Title">果蔬销售商城</div>
|
<div class="Title">果蔬销售商城</div>
|
||||||
<div class="Contents">
|
<div class="Contents">
|
||||||
<span>只做高质量商品销售~</span>
|
<span>只做高质量商品销售~</span>
|
||||||
@ -28,6 +28,3 @@
|
|||||||
"
|
"
|
||||||
></canvas>
|
></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,58 +1,35 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>主页 - 67购物网站</title>
|
|
||||||
<script type="text/javascript" src="scripts/header.js"></script>
|
|
||||||
<script type="text/javascript" src="scripts/clock.js"></script>
|
|
||||||
<script type="text/javascript" src="scripts/top.js"></script>
|
|
||||||
<script type="module" src="scripts/resources.js"></script>
|
|
||||||
<script type="module" src="scripts/items.js"></script>
|
|
||||||
<script type="module" src="scripts/index.js"></script>
|
|
||||||
<link type="image/x-icon" rel="icon" href="images/favicon.ico">
|
|
||||||
<link type="text/css" rel="stylesheet" href="styles/header.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="styles/clock.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="styles/top.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="styles/footer.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="styles/loading.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="styles/index.css">
|
|
||||||
<!-- 外部小组件 -->
|
|
||||||
<script src="scripts/lib/anime.min.js"></script>
|
|
||||||
<script async src="scripts/lib/explosion.min.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!-- 头部内容 -->
|
<!-- 头部内容 -->
|
||||||
<div id="Header">
|
<div id="Header">
|
||||||
<div class="List Special Title">67购物网站</div>
|
<div class="List Special Title">67购物网站</div>
|
||||||
<div class="List Link" this>
|
<div class="List Link" {{#isIndex}}this{{/isIndex}}{{^isIndex}}href="/"{{/isIndex}}>
|
||||||
<span class="Text">首页</span>
|
<span class="Text">首页</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="List Link" href="activity.jsp">
|
<div class="List Link" {{#isItem}}this{{/isItem}}{{^isItem}}href="/items"{{/isItem}}>
|
||||||
<span class="Text">活动</span>
|
<span class="Text">商品</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="List Blank"></div>
|
<div class="List Blank"></div>
|
||||||
<div class="List Special SearchBar">
|
<div class="List Special SearchBar">
|
||||||
|
<label>
|
||||||
<input class="InputBar" type="text"/>
|
<input class="InputBar" type="text"/>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="List Blank"></div>
|
<div class="List Blank"></div>
|
||||||
<div class="List Button"><span class="Text">历史记录</span></div>
|
{{#user}}
|
||||||
<div class="List Button"><span class="Text">购物车</span></div>
|
<div class="List Button Link" {{#isCart}}this{{/isCart}}{{^isCart}}href="/cart"{{/isCart}}><span class="Text">购物车</span></div>
|
||||||
{{#isLogined}}
|
<div class="List Button Link" href="/action/account/logout"><span class="Text">注销</span></div>
|
||||||
<div class="List Button Link" href="logout.action"><span class="Text">注销</span></div>
|
|
||||||
{{#isAdmin}}
|
{{#isAdmin}}
|
||||||
<div class="List Button Link" href="edit.jsp"><span class="Text">编辑</span></div>
|
<div class="List Button Link" {{#isEditor}}this{{/isEditor}}{{^isEditor}}href="/editor"{{/isEditor}}><span class="Text">编辑</span></div>
|
||||||
{{/isAdmin}}
|
{{/isAdmin}}
|
||||||
<div class="List Button Link" href="account.jsp"><span class="Text">账户</span></div>
|
<div class="List Button Link" {{#isAccount}}this{{/isAccount}}{{^isAccount}}href="/account"{{/isAccount}}><span class="Text">账户</span></div>
|
||||||
{{/isLogined}}
|
{{/user}}
|
||||||
{{^isLogined}}
|
{{^user}}
|
||||||
<div class="List Button Link" href="login.jsp"><span class="Text">登录</span></div>
|
<div class="List Button Link" {{#isLogin}}this{{/isLogin}}{{^isLogin}}href="/login"{{/isLogin}}><span class="Text">登录</span></div>
|
||||||
<div class="List Button Link" href="register.jsp"><span class="Text">注册</span></div>
|
<div class="List Button Link" {{#isRegister}}this{{/isRegister}}{{^isRegister}}href="/register"{{/isRegister}}><span class="Text">注册</span></div>
|
||||||
{{/isLogined}}
|
{{/user}}
|
||||||
<div class="List Special Clock">
|
<div class="List Special Clock">
|
||||||
<span class="CLOCK"></span>
|
<span class="CLOCK"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="List Special PinHeader">
|
<div class="List Special PinHeader">
|
||||||
<img class="PIN" src="images/pin.svg" checked/>
|
<img class="PIN" src="images/pin.svg" alt="固定图标" checked/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,128 +0,0 @@
|
|||||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
|
||||||
pageEncoding="UTF-8"%>
|
|
||||||
<%@ taglib prefix="s" uri="/struts-tags" %>
|
|
||||||
<s:action name="auth" var="AuthInfo" />
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>主页 - 67购物网站</title>
|
|
||||||
<script type="text/javascript" src="../static/scripts/header.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/clock.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/top.js"></script>
|
|
||||||
<script type="module" src="../static/scripts/resources.js"></script>
|
|
||||||
<script type="module" src="../static/scripts/items.js"></script>
|
|
||||||
<script type="module" src="../static/jss/index.js"></script>
|
|
||||||
<link type="image/x-icon" rel="icon" href="../static/images/favicon.ico">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/header.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/clock.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/top.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/footer.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/loading.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/index.css">
|
|
||||||
<!-- 外部小组件 -->
|
|
||||||
<script src="../static/scripts/lib/anime.min.js"></script>
|
|
||||||
<script async src="../static/scripts/lib/explosion.min.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!-- 头部内容 -->
|
|
||||||
<div id="Header">
|
|
||||||
<div class="List Special Title">67购物网站</div>
|
|
||||||
<div class="List Link" this>
|
|
||||||
<span class="Text">首页</span>
|
|
||||||
</div>
|
|
||||||
<div class="List Link" href="activity.jsp">
|
|
||||||
<span class="Text">活动</span>
|
|
||||||
</div>
|
|
||||||
<div class="List Blank"></div>
|
|
||||||
<div class="List Special SearchBar">
|
|
||||||
<input class="InputBar" type="text" />
|
|
||||||
</div>
|
|
||||||
<div class="List Blank"></div>
|
|
||||||
<div class="List Button"><span class="Text">历史记录</span></div>
|
|
||||||
<div class="List Button"><span class="Text">购物车</span></div>
|
|
||||||
<s:if test="%{#AuthInfo.IsLogined}">
|
|
||||||
<div class="List Button Link" href="logout.action"><span class="Text">注销</span></div>
|
|
||||||
<s:if test="%{#AuthInfo.UserInfo.IsAdmin}">
|
|
||||||
<div class="List Button Link" href="edit.jsp"><span class="Text">编辑</span></div>
|
|
||||||
</s:if>
|
|
||||||
<div class="List Button Link" href="account.jsp"><span class="Text">账户</span></div>
|
|
||||||
</s:if>
|
|
||||||
<s:else>
|
|
||||||
<div class="List Button Link" href="login.jsp"><span class="Text">登录</span></div>
|
|
||||||
<div class="List Button Link" href="register.jsp"><span class="Text">注册</span></div>
|
|
||||||
</s:else>
|
|
||||||
<div class="List Special Clock">
|
|
||||||
<span class="CLOCK"></span>
|
|
||||||
</div>
|
|
||||||
<div class="List Special PinHeader">
|
|
||||||
<img class="PIN" src="../static/images/pin.svg" checked />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 页面内容 -->
|
|
||||||
<div id="Contents">
|
|
||||||
<!-- 内容头 -->
|
|
||||||
<div class="ContentHeader">
|
|
||||||
<!-- 滚动横幅 -->
|
|
||||||
<div class="RollingBanner">
|
|
||||||
<div class="BannerImage">
|
|
||||||
<img />
|
|
||||||
</div>
|
|
||||||
<div class="Infos">
|
|
||||||
<span class="Title"></span>
|
|
||||||
<div class="Selecter"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 推荐商品集 -->
|
|
||||||
<div class="RecommendItems"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 内容本身 -->
|
|
||||||
<div class="Items"></div>
|
|
||||||
|
|
||||||
<!-- 内容为尾 -->
|
|
||||||
<div class="ContentFooter">
|
|
||||||
<div class="Loading">
|
|
||||||
<div></div>
|
|
||||||
<div></div>
|
|
||||||
<div></div>
|
|
||||||
<div></div>
|
|
||||||
</div>
|
|
||||||
<span class="Info">恭喜你找到了一个彩蛋!</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 页尾内容 -->
|
|
||||||
<div id="Footer">
|
|
||||||
<div class="Infos">
|
|
||||||
<div class="Icon"><img src="../static/images/icon.svg" /></div>
|
|
||||||
<div class="Title">67购物网站</div>
|
|
||||||
<div class="Contents">
|
|
||||||
<span>只做高质量商品销售~</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="Links">
|
|
||||||
<div class="Title"></div>
|
|
||||||
<div class="Contents"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 浮动内容 -->
|
|
||||||
<div id="Floater">
|
|
||||||
<!-- 回到顶层 -->
|
|
||||||
<div class="TOP"></div>
|
|
||||||
<canvas
|
|
||||||
class="fireworks"
|
|
||||||
style="
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
z-index: 1;
|
|
||||||
pointer-events: none;
|
|
||||||
"
|
|
||||||
></canvas>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,3 +1,30 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>主页 - 在线果蔬商城</title>
|
||||||
|
<script type="text/javascript" src="scripts/header.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/clock.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/top.js"></script>
|
||||||
|
<script type="module" src="scripts/resources.js"></script>
|
||||||
|
<script type="module" src="scripts/items.js"></script>
|
||||||
|
<script type="module" src="scripts/index.js"></script>
|
||||||
|
<link type="image/x-icon" rel="icon" href="images/favicon.ico">
|
||||||
|
<!-- 页面公共的样式表 -->
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/header.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/clock.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/top.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/footer.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/loading.css">
|
||||||
|
<!-- 页面特定的样式表 -->
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/index.css">
|
||||||
|
<!-- 外部小组件 -->
|
||||||
|
<script src="scripts/lib/anime.min.js"></script>
|
||||||
|
<script async src="scripts/lib/explosion.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
{{> header }}
|
{{> header }}
|
||||||
|
|
||||||
<!-- 页面内容 -->
|
<!-- 页面内容 -->
|
||||||
@ -7,7 +34,7 @@
|
|||||||
<!-- 滚动横幅 -->
|
<!-- 滚动横幅 -->
|
||||||
<div class="RollingBanner">
|
<div class="RollingBanner">
|
||||||
<div class="BannerImage">
|
<div class="BannerImage">
|
||||||
<img />
|
<img alt="滚动横幅图片" src=""/>
|
||||||
</div>
|
</div>
|
||||||
<div class="Infos">
|
<div class="Infos">
|
||||||
<span class="Title"></span>
|
<span class="Title"></span>
|
||||||
@ -34,3 +61,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{> footer }}
|
{{> footer }}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,129 +0,0 @@
|
|||||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
|
||||||
pageEncoding="UTF-8"%>
|
|
||||||
<%@ taglib prefix="s" uri="/struts-tags" %>
|
|
||||||
<s:action name="auth" var="AuthInfo" />
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>商品 - 67购物网站</title>
|
|
||||||
<script type="text/javascript" src="../static/scripts/header.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/clock.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/top.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/footer.js"></script>
|
|
||||||
<script type="module" src="../static/scripts/resources.js"></script>
|
|
||||||
<script type="module" src="../static/scripts/items.js"></script>
|
|
||||||
<script type="module" src="../static/scripts/item.js"></script>
|
|
||||||
<link type="image/x-icon" rel="icon" href="../static/images/favicon.ico">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/header.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/clock.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/top.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/footer.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/item.css">
|
|
||||||
<!-- 外部小组件 -->
|
|
||||||
<script src="../static/scripts/lib/anime.min.js"></script>
|
|
||||||
<script async src="../static/scripts/lib/explosion.min.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!-- 头部内容 -->
|
|
||||||
<div id="Header">
|
|
||||||
<div class="List Special Title">67购物网站</div>
|
|
||||||
<div class="List Link" href="index.jsp">
|
|
||||||
<span class="Text">首页</span>
|
|
||||||
</div>
|
|
||||||
<div class="List Link" href="activity.jsp">
|
|
||||||
<span class="Text">活动</span>
|
|
||||||
</div>
|
|
||||||
<div class="List Blank"></div>
|
|
||||||
<div class="List Special SearchBar">
|
|
||||||
<input class="InputBar" type="text" />
|
|
||||||
</div>
|
|
||||||
<div class="List Blank"></div>
|
|
||||||
<div class="List Button"><span class="Text">历史记录</span></div>
|
|
||||||
<div class="List Button"><span class="Text">购物车</span></div>
|
|
||||||
<s:if test="%{#AuthInfo.IsLogined}">
|
|
||||||
<div class="List Button Link" href="logout.action"><span class="Text">注销</span></div>
|
|
||||||
<s:if test="%{#AuthInfo.UserInfo.IsAdmin}">
|
|
||||||
<div class="List Button Link" href="edit.jsp"><span class="Text">编辑</span></div>
|
|
||||||
</s:if>
|
|
||||||
<div class="List Button Link" href="account.jsp"><span class="Text">账户</span></div>
|
|
||||||
</s:if>
|
|
||||||
<s:else>
|
|
||||||
<div class="List Button Link" href="login.jsp"><span class="Text">登录</span></div>
|
|
||||||
<div class="List Button Link" href="register.jsp"><span class="Text">注册</span></div>
|
|
||||||
</s:else>
|
|
||||||
<div class="List Special Clock">
|
|
||||||
<span class="CLOCK"></span>
|
|
||||||
</div>
|
|
||||||
<div class="List Special PinHeader">
|
|
||||||
<img class="PIN" src="../static/images/pin.svg" checked />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 页面内容 -->
|
|
||||||
<div id="Contents">
|
|
||||||
<div class="Item">
|
|
||||||
<div class="Picture">
|
|
||||||
<img />
|
|
||||||
</div>
|
|
||||||
<div class="Infos">
|
|
||||||
<span class="Title"></span>
|
|
||||||
<div class="Prices">
|
|
||||||
<div class="VipPrice"></div>
|
|
||||||
<div class="Price"></div>
|
|
||||||
</div>
|
|
||||||
<span class="Description"></span>
|
|
||||||
<div class="Options">
|
|
||||||
<div class="Option">
|
|
||||||
<div class="Title">数量</div>
|
|
||||||
<div class="Contants">
|
|
||||||
<div class="Option" selected> 1 </div>
|
|
||||||
<div class="Option"> 2 </div>
|
|
||||||
<div class="Option"> 3 </div>
|
|
||||||
<div class="Option"> 4 </div>
|
|
||||||
<div class="Option"> 5 </div>
|
|
||||||
<div class="Option"> 6 </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="Buttons">
|
|
||||||
<span class="Button">立即购买</span>
|
|
||||||
<span class="Button">加入购物车</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 页尾内容 -->
|
|
||||||
<div id="Footer">
|
|
||||||
<div class="Infos">
|
|
||||||
<div class="Icon"><img src="../static/images/icon.svg" /></div>
|
|
||||||
<div class="Title">67购物网站</div>
|
|
||||||
<div class="Contents">
|
|
||||||
<span>只做高质量商品销售~</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="Links">
|
|
||||||
<div class="Title"></div>
|
|
||||||
<div class="Contents"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 浮动内容 -->
|
|
||||||
<div id="Floater">
|
|
||||||
<!-- 回到顶层 -->
|
|
||||||
<div class="TOP"></div>
|
|
||||||
<canvas
|
|
||||||
class="fireworks"
|
|
||||||
style="
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
z-index: 1;
|
|
||||||
pointer-events: none;
|
|
||||||
"
|
|
||||||
></canvas>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
68
src/main/resources/templates/item.mustache
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>主页 - 在线果蔬商城</title>
|
||||||
|
<script type="text/javascript" src="scripts/header.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/clock.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/top.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/footer.js"></script>
|
||||||
|
<script type="module" src="scripts/resources.js"></script>
|
||||||
|
<script type="module" src="scripts/items.js"></script>
|
||||||
|
<script type="module" src="scripts/item.js"></script>
|
||||||
|
<link type="image/x-icon" rel="icon" href="images/favicon.ico">
|
||||||
|
<!-- 页面公共的样式表 -->
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/header.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/clock.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/top.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/footer.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/loading.css">
|
||||||
|
<!-- 页面特定的样式表 -->
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/item.css">
|
||||||
|
<!-- 外部小组件 -->
|
||||||
|
<script src="scripts/lib/anime.min.js"></script>
|
||||||
|
<script async src="scripts/lib/explosion.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
{{> header }}
|
||||||
|
|
||||||
|
<!-- 页面内容 -->
|
||||||
|
<div id="Contents">
|
||||||
|
<div class="Item">
|
||||||
|
<div class="Picture">
|
||||||
|
<img alt="商品图片" src=""/>
|
||||||
|
</div>
|
||||||
|
<div class="Infos">
|
||||||
|
<span class="Title"></span>
|
||||||
|
<div class="Prices">
|
||||||
|
<div class="VipPrice"></div>
|
||||||
|
<div class="Price"></div>
|
||||||
|
</div>
|
||||||
|
<span class="Description"></span>
|
||||||
|
<div class="Options">
|
||||||
|
<div class="Option">
|
||||||
|
<div class="Title">数量</div>
|
||||||
|
<div class="Contents">
|
||||||
|
<div class="Option" selected> 1 </div>
|
||||||
|
<div class="Option"> 2 </div>
|
||||||
|
<div class="Option"> 3 </div>
|
||||||
|
<div class="Option"> 4 </div>
|
||||||
|
<div class="Option"> 5 </div>
|
||||||
|
<div class="Option"> 6 </div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="Buttons">
|
||||||
|
<span class="Button">立即购买</span>
|
||||||
|
<span class="Button">加入购物车</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{> footer }}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
0
src/main/resources/templates/items.mustache
Normal file
@ -1,116 +0,0 @@
|
|||||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
|
||||||
pageEncoding="UTF-8"%>
|
|
||||||
<%@ taglib prefix="s" uri="/struts-tags" %>
|
|
||||||
<s:action name="auth" var="AuthInfo" />
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-Hans">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>登录 - 67购物网站</title>
|
|
||||||
<script type="text/javascript" src="../static/scripts/header.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/clock.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/top.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/footer.js"></script>
|
|
||||||
<link type="image/x-icon" rel="icon" href="../static/images/favicon.ico">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/header.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/clock.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/top.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/footer.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/form.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/user.css">
|
|
||||||
<!-- 外部小组件 -->
|
|
||||||
<script src="../static/scripts/lib/anime.min.js"></script>
|
|
||||||
<script async src="../static/scripts/lib/explosion.min.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!-- 头部内容 -->
|
|
||||||
<div id="Header">
|
|
||||||
<div class="List Special Title">67购物网站</div>
|
|
||||||
<div class="List Link" href="index.jsp">
|
|
||||||
<span class="Text">首页</span>
|
|
||||||
</div>
|
|
||||||
<div class="List Link" href="activity.jsp">
|
|
||||||
<span class="Text">活动</span>
|
|
||||||
</div>
|
|
||||||
<div class="List Blank"></div>
|
|
||||||
<div class="List Special SearchBar">
|
|
||||||
<input class="InputBar" type="text" />
|
|
||||||
</div>
|
|
||||||
<div class="List Blank"></div>
|
|
||||||
<div class="List Button"><span class="Text">历史记录</span></div>
|
|
||||||
<div class="List Button"><span class="Text">购物车</span></div>
|
|
||||||
<s:if test="%{#AuthInfo.IsLogined}">
|
|
||||||
<div class="List Button Link" href="logout.action"><span class="Text">注销</span></div>
|
|
||||||
<s:if test="%{#AuthInfo.UserInfo.IsAdmin}">
|
|
||||||
<div class="List Button Link" href="edit.jsp"><span class="Text">编辑</span></div>
|
|
||||||
</s:if>
|
|
||||||
<div class="List Button Link" href="account.jsp"><span class="Text">账户</span></div>
|
|
||||||
</s:if>
|
|
||||||
<s:else>
|
|
||||||
<div class="List Button Link" this><span class="Text">登录</span></div>
|
|
||||||
<div class="List Button Link" href="register.jsp"><span class="Text">注册</span></div>
|
|
||||||
</s:else>
|
|
||||||
<div class="List Special Clock">
|
|
||||||
<span class="CLOCK"></span>
|
|
||||||
</div>
|
|
||||||
<div class="List Special PinHeader">
|
|
||||||
<img class="PIN" src="../static/images/pin.svg" checked />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 页面内容 -->
|
|
||||||
<div id="Contents">
|
|
||||||
<form class="TabForm" action="login.action" method="post">
|
|
||||||
<div class="TabTitle">登录</div>
|
|
||||||
|
|
||||||
<div class="TabFormItems">
|
|
||||||
<div class="TabFormItem">
|
|
||||||
<label class="ItemName" for="username">用户名</label>
|
|
||||||
<input class="ItemInput" id="username" type="text" name="username" placeholder="请输入用户名" required />
|
|
||||||
</div>
|
|
||||||
<div class="TabFormItem">
|
|
||||||
<label class="ItemName" for="password">密码</label>
|
|
||||||
<input class="ItemInput" id="password" type="password" name="password" placeholder="请输入密码" required />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="TabButtons">
|
|
||||||
<button class="TabButton" type="reset">重置</button>
|
|
||||||
<button class="TabButton" type="submit">登录</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 页尾内容 -->
|
|
||||||
<div id="Footer">
|
|
||||||
<div class="Infos">
|
|
||||||
<div class="Icon"><img src="../static/images/icon.svg" /></div>
|
|
||||||
<div class="Title">67购物网站</div>
|
|
||||||
<div class="Contents">
|
|
||||||
<span>只做高质量商品销售~</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="Links">
|
|
||||||
<div class="Title"></div>
|
|
||||||
<div class="Contents"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 浮动内容 -->
|
|
||||||
<div id="Floater">
|
|
||||||
<!-- 回到顶层 -->
|
|
||||||
<div class="TOP"></div>
|
|
||||||
<canvas
|
|
||||||
class="fireworks"
|
|
||||||
style="
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
z-index: 1;
|
|
||||||
pointer-events: none;
|
|
||||||
"
|
|
||||||
></canvas>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
58
src/main/resources/templates/login.mustache
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>主页 - 在线果蔬商城</title>
|
||||||
|
<script type="text/javascript" src="scripts/header.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/clock.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/top.js"></script>
|
||||||
|
<script type="module" src="scripts/resources.js"></script>
|
||||||
|
<script type="module" src="scripts/items.js"></script>
|
||||||
|
<script type="module" src="scripts/index.js"></script>
|
||||||
|
<link type="image/x-icon" rel="icon" href="images/favicon.ico">
|
||||||
|
<!-- 页面公共的样式表 -->
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/header.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/clock.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/top.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/footer.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/loading.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/form.css">
|
||||||
|
<!-- 页面特定的样式表 -->
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/user.css">
|
||||||
|
<!-- 外部小组件 -->
|
||||||
|
<script src="scripts/lib/anime.min.js"></script>
|
||||||
|
<script async src="scripts/lib/explosion.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
{{> header}}
|
||||||
|
|
||||||
|
<!-- 页面内容 -->
|
||||||
|
<div id="Contents">
|
||||||
|
<form class="TabForm" action="action/account/login" method="post">
|
||||||
|
<div class="TabTitle">登录</div>
|
||||||
|
|
||||||
|
<div class="TabFormItems">
|
||||||
|
<div class="TabFormItem">
|
||||||
|
<label class="ItemName" for="name">用户名</label>
|
||||||
|
<input class="ItemInput" id="name" type="text" name="name" placeholder="请输入用户名" required/>
|
||||||
|
</div>
|
||||||
|
<div class="TabFormItem">
|
||||||
|
<label class="ItemName" for="password">密码</label>
|
||||||
|
<input class="ItemInput" id="password" type="password" name="password" placeholder="请输入密码"
|
||||||
|
required/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="TabButtons">
|
||||||
|
<button class="TabButton" type="reset">重置</button>
|
||||||
|
<button class="TabButton" type="submit">登录</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{> footer}}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,141 +0,0 @@
|
|||||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
|
||||||
pageEncoding="UTF-8"%>
|
|
||||||
<%@ taglib prefix="s" uri="/struts-tags" %>
|
|
||||||
<s:action name="auth" var="AuthInfo" />
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-Hans">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>注册 - 67购物网站</title>
|
|
||||||
<script type="text/javascript" src="../static/scripts/header.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/clock.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/top.js"></script>
|
|
||||||
<script type="text/javascript" src="../static/scripts/footer.js"></script>
|
|
||||||
<link type="image/x-icon" rel="icon" href="../static/images/favicon.ico">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/header.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/clock.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/top.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/footer.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/form.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="../static/styles/user.css">
|
|
||||||
<!-- 外部小组件 -->
|
|
||||||
<script src="../static/scripts/lib/anime.min.js"></script>
|
|
||||||
<script async src="../static/scripts/lib/explosion.min.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!-- 头部内容 -->
|
|
||||||
<div id="Header">
|
|
||||||
<div class="List Special Title">67购物网站</div>
|
|
||||||
<div class="List Link" href="index.jsp">
|
|
||||||
<span class="Text">首页</span>
|
|
||||||
</div>
|
|
||||||
<div class="List Link" href="activity.jsp">
|
|
||||||
<span class="Text">活动</span>
|
|
||||||
</div>
|
|
||||||
<div class="List Blank"></div>
|
|
||||||
<div class="List Special SearchBar">
|
|
||||||
<input class="InputBar" type="text" />
|
|
||||||
</div>
|
|
||||||
<div class="List Blank"></div>
|
|
||||||
<div class="List Button"><span class="Text">历史记录</span></div>
|
|
||||||
<div class="List Button"><span class="Text">购物车</span></div>
|
|
||||||
<s:if test="%{#AuthInfo.IsLogined}">
|
|
||||||
<div class="List Button Link" href="logout.action"><span class="Text">注销</span></div>
|
|
||||||
<s:if test="%{#AuthInfo.UserInfo.IsAdmin}">
|
|
||||||
<div class="List Button Link" href="edit.jsp"><span class="Text">编辑</span></div>
|
|
||||||
</s:if>
|
|
||||||
<div class="List Button Link" href="account.jsp"><span class="Text">账户</span></div>
|
|
||||||
</s:if>
|
|
||||||
<s:else>
|
|
||||||
<div class="List Button Link" href="login.jsp"><span class="Text">登录</span></div>
|
|
||||||
<div class="List Button Link" this><span class="Text">注册</span></div>
|
|
||||||
</s:else>
|
|
||||||
<div class="List Special Clock">
|
|
||||||
<span class="CLOCK"></span>
|
|
||||||
</div>
|
|
||||||
<div class="List Special PinHeader">
|
|
||||||
<img class="PIN" src="../static/images/pin.svg" checked />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 页面内容 -->
|
|
||||||
<div id="Contents">
|
|
||||||
<form class="TabForm" action="register.action" method="post">
|
|
||||||
<div class="TabTitle">注册</div>
|
|
||||||
|
|
||||||
<div class="TabFormItems">
|
|
||||||
<div class="TabFormItem">
|
|
||||||
<label class="ItemName" for="username">用户名</label>
|
|
||||||
<input class="ItemInput" id="username" type="text" name="username" placeholder="请输入用户名" required />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="TabFormItem">
|
|
||||||
<label class="ItemName" for="password">密码</label>
|
|
||||||
<input class="ItemInput" id="password" type="password" name="password" placeholder="请输入密码" required />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="TabFormItem">
|
|
||||||
<label class="ItemName" for="passwrod">确认密码</label>
|
|
||||||
<input class="ItemInput" id="password_confirm" type="password" name="password_confirm" placeholder="请输入确认密码" required />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="TabFormItem">
|
|
||||||
<label class="ItemName" for="age">年龄</label>
|
|
||||||
<input class="ItemInput" id="age" type="number" name="age" placeholder="请输入年龄" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="TabFormItem">
|
|
||||||
<label class="ItemName" for="email">邮箱</label>
|
|
||||||
<input class="ItemInput" id="email" type="email" name="email" placeholder="请输入邮箱" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="TabFormItem">
|
|
||||||
<input class="ItemInput" id="gender_null" type="radio" name="gender" value="N" checked />
|
|
||||||
<label class="ItemName" for="gender_null">未知</label>
|
|
||||||
<input class="ItemInput"id="gender_male" type="radio" name="gender" value="M" />
|
|
||||||
<label class="ItemName" for="gender_male">男性</label>
|
|
||||||
<input class="ItemInput"id="gender_female" type="radio" name="gender" value="F" />
|
|
||||||
<label class="ItemName" for="gender_female">女性</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="TabButtons">
|
|
||||||
<button class="TabButton" type="reset">重置</button>
|
|
||||||
<button class="TabButton" type="submit">注册并登录</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 页尾内容 -->
|
|
||||||
<div id="Footer">
|
|
||||||
<div class="Infos">
|
|
||||||
<div class="Icon"><img src="../static/images/icon.svg" /></div>
|
|
||||||
<div class="Title">67购物网站</div>
|
|
||||||
<div class="Contents">
|
|
||||||
<span>只做高质量商品销售~</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="Links">
|
|
||||||
<div class="Title"></div>
|
|
||||||
<div class="Contents"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 浮动内容 -->
|
|
||||||
<div id="Floater">
|
|
||||||
<!-- 回到顶层 -->
|
|
||||||
<div class="TOP"></div>
|
|
||||||
<canvas
|
|
||||||
class="fireworks"
|
|
||||||
style="
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
z-index: 1;
|
|
||||||
pointer-events: none;
|
|
||||||
"
|
|
||||||
></canvas>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
94
src/main/resources/templates/register.mustache
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>主页 - 在线果蔬商城</title>
|
||||||
|
<script type="text/javascript" src="scripts/header.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/clock.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/top.js"></script>
|
||||||
|
<script type="module" src="scripts/resources.js"></script>
|
||||||
|
<script type="module" src="scripts/items.js"></script>
|
||||||
|
<script type="module" src="scripts/index.js"></script>
|
||||||
|
<link type="image/x-icon" rel="icon" href="images/favicon.ico">
|
||||||
|
<!-- 页面公共的样式表 -->
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/header.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/clock.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/top.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/footer.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/loading.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/form.css">
|
||||||
|
<!-- 页面特定的样式表 -->
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/user.css">
|
||||||
|
<!-- 外部小组件 -->
|
||||||
|
<script src="scripts/lib/anime.min.js"></script>
|
||||||
|
<script async src="scripts/lib/explosion.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
{{> header }}
|
||||||
|
|
||||||
|
<!-- 页面内容 -->
|
||||||
|
<div id="Contents">
|
||||||
|
<form class="TabForm" action="action/account/register" method="post">
|
||||||
|
<div class="TabTitle">注册</div>
|
||||||
|
|
||||||
|
<div class="TabFormItems">
|
||||||
|
<div class="TabFormItem">
|
||||||
|
<label class="ItemName" for="name">用户名</label>
|
||||||
|
<input class="ItemInput" id="name" type="text" name="username" placeholder="请输入用户名" required/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="TabFormItem">
|
||||||
|
<label class="ItemName" for="password">密码</label>
|
||||||
|
<input class="ItemInput" id="password" type="password" name="password" placeholder="请输入密码"
|
||||||
|
required/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="TabFormItem">
|
||||||
|
<label class="ItemName" for="password_confirm">确认密码</label>
|
||||||
|
<input class="ItemInput" id="password_confirm" type="password" name="password_confirm"
|
||||||
|
placeholder="请输入确认密码" required/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="TabFormItem">
|
||||||
|
<label class="ItemName" for="age">年龄</label>
|
||||||
|
<input class="ItemInput" id="age" type="number" name="age" placeholder="请输入年龄"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="TabFormItem">
|
||||||
|
<label class="ItemName" for="phone">邮箱</label>
|
||||||
|
<input class="ItemInput" id="phone" type="text" name="phone" placeholder="请输入手机号"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="TabFormItem">
|
||||||
|
<label class="ItemName" for="email">邮箱</label>
|
||||||
|
<input class="ItemInput" id="email" type="email" name="email" placeholder="请输入邮箱"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="TabFormItem">
|
||||||
|
<label class="ItemName" for="address">邮箱</label>
|
||||||
|
<input class="ItemInput" id="address" type="text" name="address" placeholder="请输入邮箱"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="TabFormItem">
|
||||||
|
<input class="ItemInput" id="gender_null" type="radio" name="gender" value="N" checked/>
|
||||||
|
<label class="ItemName" for="gender_null">未知</label>
|
||||||
|
<input class="ItemInput" id="gender_male" type="radio" name="gender" value="M"/>
|
||||||
|
<label class="ItemName" for="gender_male">男性</label>
|
||||||
|
<input class="ItemInput" id="gender_female" type="radio" name="gender" value="F"/>
|
||||||
|
<label class="ItemName" for="gender_female">女性</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="TabButtons">
|
||||||
|
<button class="TabButton" type="reset">重置</button>
|
||||||
|
<button class="TabButton" type="submit">注册并登录</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{> footer }}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,13 +0,0 @@
|
|||||||
package team8.fruitable
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest
|
|
||||||
|
|
||||||
@SpringBootTest
|
|
||||||
class FruitableApplicationTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun contextLoads() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|