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>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>17</java.version>
|
||||
<kotlin.version>1.9.10</kotlin.version>
|
||||
</properties>
|
||||
@ -69,6 +70,10 @@
|
||||
<artifactId>fastjson2-kotlin</artifactId>
|
||||
<version>2.0.40</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<!-- Other -->
|
||||
<dependency>
|
||||
<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.RestController
|
||||
|
||||
@RestController
|
||||
@SpringBootApplication
|
||||
class FruitableApplication {
|
||||
@RequestMapping("/")
|
||||
fun home(): String {
|
||||
return "Hello World!"
|
||||
}
|
||||
}
|
||||
class FruitableApplication
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
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 team8.fruitable.constant.UserType
|
||||
import team8.fruitable.datebase.entity.User
|
||||
import team8.fruitable.datebase.repository.UserRepository
|
||||
import team8.fruitable.util.ResultBuilder
|
||||
import team8.fruitable.datebase.repository.AccountRepository
|
||||
import team8.fruitable.util.ResultBuilderJson
|
||||
|
||||
@RestController
|
||||
class Account(private val repository: UserRepository) {
|
||||
@RequestMapping("/api/v1/account")
|
||||
class AccountApi(private val repository: AccountRepository) {
|
||||
private fun getCurrentUser(token: String?): User? {
|
||||
return token?.let(repository::findByToken)
|
||||
}
|
||||
@ -25,50 +26,50 @@ class Account(private val repository: UserRepository) {
|
||||
response.addCookie(cookie)
|
||||
}
|
||||
|
||||
@GetMapping("/api/v1/account/info", produces = ["application/json"])
|
||||
@GetMapping("/info", produces = ["application/json"])
|
||||
fun infoMe(
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?
|
||||
): String {
|
||||
val user = this.getCurrentUser(token) ?: return ResultBuilder<Any>("账户未登录").toJson()
|
||||
return ResultBuilder(user.asMap(UserType.User)).toJson()
|
||||
val user = this.getCurrentUser(token) ?: return ResultBuilderJson<Any>("账户未登录").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(
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?, @PathVariable id: Long
|
||||
): 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)
|
||||
return ResultBuilder(
|
||||
return ResultBuilderJson(
|
||||
queryUser.asMap(if (currentUser != null && (currentUser.id == id || currentUser.isAdmin)) UserType.User else UserType.Guest)
|
||||
).toJson()
|
||||
}
|
||||
|
||||
//@PostMapping
|
||||
@RequestMapping("/api/v1/account/login", produces = ["application/json"])
|
||||
@RequestMapping("/login", produces = ["application/json"])
|
||||
fun login(
|
||||
response: HttpServletResponse,
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||
@RequestParam(name = "name") name: String,
|
||||
@RequestParam(name = "password") password: String
|
||||
): String {
|
||||
if (this.getCurrentUser(token) != null) return ResultBuilder<Any>("当前已登录账户").toJson()
|
||||
val user = repository.findByName(name) ?: return ResultBuilder<Any>("账户不存在").toJson()
|
||||
if (!user.testPassword(password)) return ResultBuilder<Any>("密码错误").toJson()
|
||||
if (this.getCurrentUser(token) != null) return ResultBuilderJson<Any>("当前已登录账户").toJson()
|
||||
val user = repository.findByName(name) ?: return ResultBuilderJson<Any>("账户不存在").toJson()
|
||||
if (!user.testPassword(password)) return ResultBuilderJson<Any>("密码错误").toJson()
|
||||
user.updateToken()
|
||||
user.updateLoginTime()
|
||||
repository.save(user)
|
||||
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 {
|
||||
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(
|
||||
response: HttpServletResponse,
|
||||
@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 = "address", required = false) address: 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))
|
||||
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(
|
||||
response: HttpServletResponse,
|
||||
@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 = "address", required = false) address: 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)
|
||||
repository.save(user)
|
||||
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(
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||
@PathVariable id: Long,
|
||||
): String {
|
||||
if (this.hasAdminPermissions(token)) return ResultBuilder<Any>("无管理员权限").toJson()
|
||||
return ResultBuilder(repository.findById(id)).toJson()
|
||||
if (this.hasAdminPermissions(token)) return ResultBuilderJson<Any>("无管理员权限").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(
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||
@PathVariable id: Long,
|
||||
): String {
|
||||
if (this.hasAdminPermissions(token)) return ResultBuilder<Any>("无管理员权限").toJson()
|
||||
if (this.hasAdminPermissions(token)) return ResultBuilderJson<Any>("无管理员权限").toJson()
|
||||
// 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(
|
||||
@CookieValue(value = "TOKEN", required = false) token: String?,
|
||||
@PathVariable id: Long,
|
||||
@ -136,8 +137,8 @@ class Account(private val repository: UserRepository) {
|
||||
@RequestParam(name = "email", required = false) email: String?,
|
||||
@RequestParam(name = "address", required = false) address: String?
|
||||
): String {
|
||||
if (this.hasAdminPermissions(token)) return ResultBuilder<Any>("无管理员权限").toJson()
|
||||
if (this.hasAdminPermissions(token)) return ResultBuilderJson<Any>("无管理员权限").toJson()
|
||||
// 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 team8.fruitable.datebase.entity.User
|
||||
import team8.fruitable.datebase.repository.ItemRepository
|
||||
import team8.fruitable.datebase.repository.UserRepository
|
||||
import team8.fruitable.util.ResultBuilder
|
||||
import team8.fruitable.datebase.repository.AccountRepository
|
||||
import team8.fruitable.util.ResultBuilderJson
|
||||
|
||||
@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? {
|
||||
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"])
|
||||
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
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonView
|
||||
import jakarta.persistence.*
|
||||
import team8.fruitable.constant.UserType
|
||||
import team8.fruitable.util.Util
|
||||
@ -13,47 +14,65 @@ class User(
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id", nullable = false)
|
||||
@JsonView(UserView::class)
|
||||
var id: Long? = null,
|
||||
|
||||
@Column(name = "name", length = 16, nullable = false)
|
||||
@JsonView(GuestView::class)
|
||||
var name: String? = null,
|
||||
|
||||
@Column(name = "password", length = 64, nullable = false)
|
||||
@JsonView(AdminView::class)
|
||||
var password: String? = null,
|
||||
|
||||
@Column(name = "time_create", nullable = false)
|
||||
@JsonView(UserView::class)
|
||||
var createTime: LocalDateTime = LocalDateTime.now(),
|
||||
|
||||
@Column(name = "time_login", nullable = false)
|
||||
@JsonView(UserView::class)
|
||||
var loginTime: LocalDateTime = LocalDateTime.now(),
|
||||
|
||||
@Column(name = "token", length = 36)
|
||||
@JsonView(AdminView::class)
|
||||
var token: String = UUID.randomUUID().toString(),
|
||||
|
||||
@Column(name = "age")
|
||||
@JsonView(GuestView::class)
|
||||
var age: Int? = null,
|
||||
|
||||
@Column(name = "gender", length = 1)
|
||||
@JsonView(GuestView::class)
|
||||
var gender: String? = null,
|
||||
|
||||
@Column(name = "phone", length = 11)
|
||||
@JsonView(UserView::class)
|
||||
var phone: String? = null,
|
||||
|
||||
@Column(name = "email", length = 64)
|
||||
@JsonView(GuestView::class)
|
||||
var email: String? = null,
|
||||
|
||||
@Column(name = "address", length = 64)
|
||||
@JsonView(UserView::class)
|
||||
var address: String? = null,
|
||||
|
||||
@Column(name = "is_admin", nullable = false)
|
||||
@JsonView(AdminView::class)
|
||||
var isAdmin: Boolean = false,
|
||||
|
||||
@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")
|
||||
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() {
|
||||
this.name = name
|
||||
this.password = this.genPassword(password)
|
||||
|
@ -3,7 +3,7 @@ package team8.fruitable.datebase.repository
|
||||
import org.springframework.data.repository.CrudRepository
|
||||
import team8.fruitable.datebase.entity.User
|
||||
|
||||
interface UserRepository : CrudRepository<User, Long> {
|
||||
interface AccountRepository : CrudRepository<User, Long> {
|
||||
fun findByName(name: String): User?
|
||||
fun findByToken(token: String): User?
|
||||
}
|
@ -4,7 +4,7 @@ import com.alibaba.fastjson2.toJSONString
|
||||
import java.time.LocalDateTime
|
||||
import java.util.*
|
||||
|
||||
class ResultBuilder<T> {
|
||||
class ResultBuilderJson<T> {
|
||||
var status: String = "auto"
|
||||
var message: String = ""
|
||||
val timestamp: LocalDateTime = LocalDateTime.now()
|
@ -7,3 +7,8 @@ spring:
|
||||
show-sql: true
|
||||
hibernate:
|
||||
ddl-auto: update
|
||||
server:
|
||||
servlet:
|
||||
encoding:
|
||||
charset: UTF-8
|
||||
force-response: true
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- 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"
|
||||
y="0px" viewBox="0 0 503.945 503.945" style="enable-background:new 0 0 503.945 503.945;" xml:space="preserve">
|
||||
<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">
|
||||
<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
|
||||
c8.8,0,16.8-5.6,20-14.4l20.8-66.4L455.173,345.073z M73.573,285.073h356.8l-12,37.6h-333.6L73.573,285.073z M455.173,206.673
|
||||
|
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"?>
|
||||
<!-- 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"
|
||||
y="0px" viewBox="0 0 495 495" style="enable-background:new 0 0 495 495;" xml:space="preserve">
|
||||
<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">
|
||||
<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 " />
|
||||
<polygon style="fill:#005ECE;" points="446.663,81.833 313.888,81.833 326.258,166.012 326.258,222.068 483.774,222.068
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- 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"
|
||||
y="0px" viewBox="0 0 512.001 512.001" style="enable-background:new 0 0 512.001 512.001;" xml:space="preserve">
|
||||
<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">
|
||||
<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,27.221-10.201,37.421,0l23.986,23.984c3.163,3.162,8.293,3.163,11.455-0.001c3.163-3.163,3.163-8.293,0-11.455
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- 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"
|
||||
y="0px" viewBox="0 0 503.945 503.945" style="enable-background:new 0 0 503.945 503.945;" xml:space="preserve">
|
||||
<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">
|
||||
<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
|
||||
c8.8,0,16.8-5.6,20-14.4l20.8-66.4L455.173,345.073z M73.573,285.073h356.8l-12,37.6h-333.6L73.573,285.073z M455.173,206.673
|
||||
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- 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">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
||||
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">
|
||||
<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"
|
||||
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
|
||||
c-1.683,1.43-4.208,1.225-5.639-0.459c-1.43-1.686-1.224-4.208,0.46-5.64l11.01-9.351c1.493-1.269,3.686-1.269,5.178,0
|
||||
l11.011,9.351C30.294,18.068,30.499,20.591,29.069,22.276z" />
|
||||
|
Before Width: | Height: | Size: 800 B After Width: | Height: | Size: 765 B |
@ -7,7 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
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));
|
||||
// 源数据
|
||||
let rawBanners = [];
|
||||
@ -135,7 +136,7 @@ function updateItems() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let ID = this.getAttribute("item_id");
|
||||
if (ID != null) {
|
||||
window.location.href = `item.jsp?item_id=${ID}`;
|
||||
window.location.href = `item/${ID}`;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -7,7 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
import { getItem, loadItem } from "./items.js";
|
||||
import {getItem, loadItem} from "./items.js";
|
||||
|
||||
let ID;
|
||||
let TheItem;
|
||||
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) => {
|
||||
let contants = v.querySelector(".Contants");
|
||||
let contants = v.querySelector(".Contents");
|
||||
Array.from(contants.children).forEach((v) => {
|
||||
v.addEventListener("click", function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
|
@ -7,7 +7,7 @@
|
||||
width: 140px;
|
||||
color: rgb(0, 255, 90);
|
||||
text-align: center;
|
||||
font-family: "LcdD";
|
||||
font-family: "LcdD", serif;
|
||||
border: 3px solid black;
|
||||
border-radius: 5px;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
|
@ -20,7 +20,7 @@ div {
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
#Contents > .Editor {
|
||||
#Contents > .Editors {
|
||||
flex: 4 0 0;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
@ -32,31 +32,31 @@ div {
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
#Contents > .Editor > .Title {
|
||||
#Contents > .Editors > .Title {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#Contents > .Editor > .Result {
|
||||
#Contents > .Editors > .Result {
|
||||
color: wheat;
|
||||
border: 3px solid skyblue;
|
||||
border-spacing: 0;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#Contents > .Editor > .Result td {
|
||||
#Contents > .Editors > .Result td {
|
||||
white-space: nowrap;
|
||||
border: 1px solid cornflowerblue;
|
||||
}
|
||||
|
||||
#Contents > .Editor > .Result > thead {
|
||||
#Contents > .Editors > .Result > thead {
|
||||
background-color: #044488;
|
||||
}
|
||||
|
||||
#Contents > .Editor > .Result > tbody {
|
||||
#Contents > .Editors > .Result > tbody {
|
||||
background-color: #008080;
|
||||
}
|
||||
|
||||
#Contents > .Editor > .Pages > * {
|
||||
#Contents > .Editors > .Pages > * {
|
||||
color: wheat;
|
||||
margin-right: 3px;
|
||||
border: 3px solid skyblue;
|
||||
@ -64,15 +64,15 @@ div {
|
||||
background-color: cadetblue;
|
||||
}
|
||||
|
||||
#Contents > .Editor > .Pages > *:last-child {
|
||||
#Contents > .Editors > .Pages > *:last-child {
|
||||
margin-right: inherit;
|
||||
}
|
||||
|
||||
#Contents > .Editor > .Pages > span {
|
||||
#Contents > .Editors > .Pages > span {
|
||||
color: green;
|
||||
}
|
||||
|
||||
#Contents > .UserEditor {
|
||||
#Contents > .EditPanel {
|
||||
flex: 1 0 0;
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
@ -81,8 +81,8 @@ div {
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
#Contents > .UserEditor > .Displayer {
|
||||
border: 0px;
|
||||
#Contents > .EditPanel > .Panel {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
|
@ -35,7 +35,7 @@ div {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
color: wheat;
|
||||
font-family: "Normal";
|
||||
font-family: "Normal", system-ui;
|
||||
}
|
||||
|
||||
.ErrorTitle {
|
||||
@ -46,7 +46,7 @@ div {
|
||||
|
||||
.ErrorRedirectButton {
|
||||
margin: 20px 15px;
|
||||
padding: 8px 0px;
|
||||
padding: 8px 0;
|
||||
border: 3px solid skyblue;
|
||||
border-radius: 10px;
|
||||
font-size: 18px;
|
||||
|
@ -47,23 +47,23 @@ div {
|
||||
}
|
||||
|
||||
.Item .Infos > * {
|
||||
margin: 10px 0px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.Item .Infos > .Title {
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
font-family: "Normal";
|
||||
font-family: "Normal", system-ui;
|
||||
}
|
||||
|
||||
.Item .Infos .Description {
|
||||
font-size: 20px;
|
||||
font-family: "Normal";
|
||||
font-family: "Normal", system-ui;
|
||||
}
|
||||
|
||||
.Item .Infos .Prices {
|
||||
align-items: baseline;
|
||||
font-family: "Normal";
|
||||
font-family: "Normal", system-ui;
|
||||
}
|
||||
|
||||
.Item .Infos .Prices .VipPrice {
|
||||
@ -79,7 +79,7 @@ div {
|
||||
}
|
||||
|
||||
.Item .Infos .Prices .Price[has_vip_price] {
|
||||
color: gray;
|
||||
color: grey;
|
||||
font-size: 16px;
|
||||
font-weight: lighter;
|
||||
font-style: italic;
|
||||
@ -92,32 +92,32 @@ div {
|
||||
|
||||
.Item .Infos .Options > .Option {
|
||||
flex-direction: row;
|
||||
margin: 5px 0px;
|
||||
margin: 5px 0;
|
||||
border: 1px solid rgba(0, 120, 255, 0.8);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.Item .Infos .Options > .Option .Title {
|
||||
font-weight: bold;
|
||||
padding: 0px 10px;
|
||||
border-radius: 5px 0px 0px 5px;
|
||||
padding: 0 10px;
|
||||
border-radius: 5px 0 0 5px;
|
||||
background: green;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.Item .Infos .Options > .Option .Contants {
|
||||
.Item .Infos .Options > .Option .Contents {
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.Item .Infos .Options > .Option .Contants .Option {
|
||||
.Item .Infos .Options > .Option .Contents .Option {
|
||||
font-size: 18px;
|
||||
padding: 0px 5px;
|
||||
padding: 0 5px;
|
||||
align-items: center;
|
||||
background-color: #355ae8;
|
||||
}
|
||||
|
||||
.Item .Infos .Options > .Option .Contants .Option[selected] {
|
||||
.Item .Infos .Options > .Option .Contents .Option[selected] {
|
||||
font-weight: bold;
|
||||
background-color: #489dff;
|
||||
}
|
||||
|
0
src/main/resources/templates/cart.mustache
Normal file
@ -65,14 +65,14 @@
|
||||
|
||||
<!-- 页面内容 -->
|
||||
<div id="Contents">
|
||||
<div class="Editor">
|
||||
<div class="Editors">
|
||||
<div class="Title">
|
||||
<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:textfield name="search" placeholder="请在此处输入你想要搜索的内容..." value="%{#EditInfo.Search}" />
|
||||
<button type="submit">搜索</button>
|
||||
</form>
|
||||
|
||||
|
||||
<button onclick="javascript:location.reload();">刷新</button>
|
||||
</div>
|
||||
|
||||
@ -109,7 +109,7 @@
|
||||
</s:iterator>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<div class="Pages">
|
||||
<a href="edit.jsp?page=0">首页</a>
|
||||
<s:iterator begin="%{#EditInfo.StartPage}" end="%{#EditInfo.StopPage}" var="PageNumber">
|
||||
@ -123,9 +123,9 @@
|
||||
<a href="edit.jsp?page=<s:property value="%{#EditInfo.EndPage}" />">尾页</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="UserEditor">
|
||||
<iframe id="Displayer" class="Displayer" name="displayer"></iframe>
|
||||
|
||||
<div class="EditPanel">
|
||||
<iframe id="Displayer" class="Panel" name="displayer"></iframe>
|
||||
</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 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="Contents">
|
||||
<span>只做高质量商品销售~</span>
|
||||
@ -28,6 +28,3 @@
|
||||
"
|
||||
></canvas>
|
||||
</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 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>
|
||||
</div>
|
||||
<div class="List Link" href="activity.jsp">
|
||||
<span class="Text">活动</span>
|
||||
<div class="List Link" {{#isItem}}this{{/isItem}}{{^isItem}}href="/items"{{/isItem}}>
|
||||
<span class="Text">商品</span>
|
||||
</div>
|
||||
<div class="List Blank"></div>
|
||||
<div class="List Special SearchBar">
|
||||
<input class="InputBar" type="text"/>
|
||||
<label>
|
||||
<input class="InputBar" type="text"/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="List Blank"></div>
|
||||
<div class="List Button"><span class="Text">历史记录</span></div>
|
||||
<div class="List Button"><span class="Text">购物车</span></div>
|
||||
{{#isLogined}}
|
||||
<div class="List Button Link" href="logout.action"><span class="Text">注销</span></div>
|
||||
{{#user}}
|
||||
<div class="List Button Link" {{#isCart}}this{{/isCart}}{{^isCart}}href="/cart"{{/isCart}}><span class="Text">购物车</span></div>
|
||||
<div class="List Button Link" href="/action/account/logout"><span class="Text">注销</span></div>
|
||||
{{#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}}
|
||||
<div class="List Button Link" href="account.jsp"><span class="Text">账户</span></div>
|
||||
{{/isLogined}}
|
||||
{{^isLogined}}
|
||||
<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>
|
||||
{{/isLogined}}
|
||||
<div class="List Button Link" {{#isAccount}}this{{/isAccount}}{{^isAccount}}href="/account"{{/isAccount}}><span class="Text">账户</span></div>
|
||||
{{/user}}
|
||||
{{^user}}
|
||||
<div class="List Button Link" {{#isLogin}}this{{/isLogin}}{{^isLogin}}href="/login"{{/isLogin}}><span class="Text">登录</span></div>
|
||||
<div class="List Button Link" {{#isRegister}}this{{/isRegister}}{{^isRegister}}href="/register"{{/isRegister}}><span class="Text">注册</span></div>
|
||||
{{/user}}
|
||||
<div class="List Special Clock">
|
||||
<span class="CLOCK"></span>
|
||||
</div>
|
||||
<div class="List Special PinHeader">
|
||||
<img class="PIN" src="images/pin.svg" checked/>
|
||||
<img class="PIN" src="images/pin.svg" alt="固定图标" checked/>
|
||||
</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,4 +1,31 @@
|
||||
{{> header}}
|
||||
<!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 }}
|
||||
|
||||
<!-- 页面内容 -->
|
||||
<div id="Contents">
|
||||
@ -7,7 +34,7 @@
|
||||
<!-- 滚动横幅 -->
|
||||
<div class="RollingBanner">
|
||||
<div class="BannerImage">
|
||||
<img />
|
||||
<img alt="滚动横幅图片" src=""/>
|
||||
</div>
|
||||
<div class="Infos">
|
||||
<span class="Title"></span>
|
||||
@ -33,4 +60,7 @@
|
||||
</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() {
|
||||
}
|
||||
|
||||
}
|