add cart page, fix an error at index page

Signed-off-by: Puqns67 <me@puqns67.icu>
This commit is contained in:
Puqns67 2023-09-20 13:43:54 +08:00
parent a896edd6c6
commit 8ef4d78d56
Signed by: Puqns67
GPG Key ID: 9669DF042554F536
10 changed files with 140 additions and 11 deletions

View File

@ -36,6 +36,7 @@ class OrderAction(
): String { ): String {
val user = this.getCurrentUser(token) ?: return error(attributes, "创建订单", "账户未登录", "/login") val user = this.getCurrentUser(token) ?: return error(attributes, "创建订单", "账户未登录", "/login")
val itemPairs = itemIds zip itemNumbers val itemPairs = itemIds zip itemNumbers
if (itemPairs.isEmpty()) return error(attributes, "创建订单", "您还未选择商品", "/login")
val items: MutableList<Pair<Item, Int>> = mutableListOf() val items: MutableList<Pair<Item, Int>> = mutableListOf()
var priceSum = .0 var priceSum = .0
itemPairs.forEach { itemPairs.forEach {

View File

@ -44,11 +44,12 @@ class OrderPage(
@RequestParam("items") itemIds: Array<Long>, @RequestParam("items") itemIds: Array<Long>,
@RequestParam("numbers") itemNumbers: Array<Int> @RequestParam("numbers") itemNumbers: Array<Int>
): String { ): String {
val user = this.getCurrentUser(token) ?: return error(attributes, "更新", "账户未登录", "/login") val user = this.getCurrentUser(token) ?: return error(attributes, "创建订单", "账户未登录", "/login")
val itemPairs = itemIds zip itemNumbers val itemPairs = itemIds zip itemNumbers
if (itemPairs.isEmpty()) return error(attributes, "创建订单", "您还未选择商品", "/login")
val items: MutableList<Triple<Item, Int, Double>> = mutableListOf() val items: MutableList<Triple<Item, Int, Double>> = mutableListOf()
itemPairs.forEach { itemPairs.forEach {
val item = itemRepository.findById(it.first).orElse(null) ?: return error(attributes, "查看订单", "商品不存在") val item = itemRepository.findById(it.first).orElse(null) ?: return error(attributes, "创建订单", "商品不存在")
items.add(Triple(item, it.second, item.price!! * it.second)) items.add(Triple(item, it.second, item.price!! * it.second))
} }
model["items"] = items model["items"] = items

View File

@ -9,14 +9,12 @@ import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.servlet.mvc.support.RedirectAttributes import org.springframework.web.servlet.mvc.support.RedirectAttributes
import team8.fruitable.controller.util.error import team8.fruitable.controller.util.error
import team8.fruitable.datebase.entity.User import team8.fruitable.datebase.entity.User
import team8.fruitable.datebase.repository.AccountRepository import team8.fruitable.datebase.repository.*
import team8.fruitable.datebase.repository.BannerRepository
import team8.fruitable.datebase.repository.ItemRepository
import team8.fruitable.datebase.repository.RecommendRepository
@Controller @Controller
class Pages( class Pages(
private val accountRepository: AccountRepository, private val accountRepository: AccountRepository,
private val cartRepository: CartRepository,
private val itemRepository: ItemRepository, private val itemRepository: ItemRepository,
private val bannerRepository: BannerRepository, private val bannerRepository: BannerRepository,
private val recommendRepository: RecommendRepository private val recommendRepository: RecommendRepository
@ -32,7 +30,7 @@ class Pages(
): String { ): String {
model["isIndex"] = true model["isIndex"] = true
this.getCurrentUser(token)?.let { model["user"] = it } this.getCurrentUser(token)?.let { model["user"] = it }
model["items"] = itemRepository.findAll() model["items"] = itemRepository.findAll().filter { !it.isRevoked }
model["banners"] = bannerRepository.findAll() model["banners"] = bannerRepository.findAll()
model["recommends"] = recommendRepository.findAll() model["recommends"] = recommendRepository.findAll()
return "index" return "index"
@ -107,6 +105,15 @@ class Pages(
): String { ): String {
model["isCart"] = true model["isCart"] = true
val user = this.getCurrentUser(token) ?: return error(attributes, "更新", "账户未登录", "/login") val user = this.getCurrentUser(token) ?: return error(attributes, "更新", "账户未登录", "/login")
val carts = cartRepository.findByUser(user)
val prices: MutableList<Double> = mutableListOf()
var priceSum = .0
carts.forEach {
val price = it.item!!.price!! * it.number
prices.add(price)
priceSum += price
}
model["items"] = carts zip prices
model["user"] = user model["user"] = user
return "cart" return "cart"
} }

View File

@ -7,4 +7,6 @@ import team8.fruitable.datebase.entity.User
interface CartRepository : CrudRepository<CartedItem, Long> { interface CartRepository : CrudRepository<CartedItem, Long> {
fun findByUserAndItem(user: User, item: Item): CartedItem? fun findByUserAndItem(user: User, item: Item): CartedItem?
fun findByUser(user: User): List<CartedItem>
} }

View File

@ -2,10 +2,10 @@ let footer = null;
// 页面长度无法填满整个页面时挂起页尾 // 页面长度无法填满整个页面时挂起页尾
function updatePinState() { function updatePinState() {
let contextHight = (footer.hasAttribute("pined")) let contextHeight = (footer.hasAttribute("pined"))
? document.body.clientHeight + footer.clientHeight ? document.body.clientHeight + footer.clientHeight
: document.body.clientHeight; : document.body.clientHeight;
let result = contextHight < window.innerHeight; let result = contextHeight < window.innerHeight;
if (footer.hasAttribute("pined") !== result) if (footer.hasAttribute("pined") !== result)
footer.toggleAttribute("pined", result); footer.toggleAttribute("pined", result);
} }

View File

@ -0,0 +1,54 @@
.TabForm {
width: 640px;
}
.Item {
margin-top: 10px;
margin-bottom: 10px;
border-radius: 15px;
background-color: teal;
> .ItemCheckBox {
display: flex;
align-items: center;
justify-content: center;
> .ItemNumber {
display: none;
}
}
> .Picture {
display: flex;
align-items: center;
justify-content: center;
> img {
border-radius: 15px;
width: 100px;
height: 100px;
}
}
> .Infos {
display: flex;
flex: 1;
flex-direction: column;
padding: 5px 10px;
color: wheat;
> .Info {
display: flex;
flex-direction: row;
justify-content: space-between;
}
}
> .TabButtons {
> .TabButton {
border: none;
border-radius: 0 15px 15px 0;
background-color: wheat;
}
}
}

View File

@ -100,6 +100,10 @@ body[headerPined] {
background-image: linear-gradient(#489dff, #355ae8); background-image: linear-gradient(#489dff, #355ae8);
padding-left: 10px; padding-left: 10px;
padding-right: 10px; padding-right: 10px;
&::placeholder {
color: wheat;
}
} }
} }

View File

@ -7,7 +7,6 @@
border-radius: 15px; border-radius: 15px;
background-color: teal; background-color: teal;
> .Picture { > .Picture {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -11,12 +11,32 @@
<link type="text/css" rel="stylesheet/less" href="/styles/header.less"> <link type="text/css" rel="stylesheet/less" href="/styles/header.less">
<link type="text/css" rel="stylesheet" href="/styles/clock.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/top.css">
<link type="text/css" rel="stylesheet/less" href="/styles/form.less">
<link type="text/css" rel="stylesheet/less" href="/styles/base.less">
<!-- 页面特定的样式表 --> <!-- 页面特定的样式表 -->
<link type="text/css" rel="stylesheet/less" href="/styles/cart.less"> <link type="text/css" rel="stylesheet/less" href="/styles/cart.less">
<!-- 外部小组件 --> <!-- 外部小组件 -->
<script src="/scripts/lib/less.min.js"></script> <script src="/scripts/lib/less.min.js"></script>
<script src="/scripts/lib/anime.min.js"></script> <script src="/scripts/lib/anime.min.js"></script>
<script async src="/scripts/lib/explosion.min.js"></script> <script async src="/scripts/lib/explosion.min.js"></script>
<script>
window.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll("*[remove]").forEach((v) => {
v.addEventListener("click", function () {
window.location.href = `/action/cart/remove/${v.parentElement.parentElement.getAttribute("itemid")}`
})
});
document.querySelectorAll(".ItemCheckBox").forEach((v) => {
v.addEventListener("change", function (e) {
Array.from(this.getElementsByTagName("input")).forEach((v) => {
v.toggleAttribute("checked")
});
e.stopPropagation();
}, true);
});
});
</script>
</head> </head>
<body> <body>
@ -25,6 +45,47 @@
<!-- 页面内容 --> <!-- 页面内容 -->
<div id="Contents"> <div id="Contents">
<form class="TabForm" action="/order/create" method="post">
<div class="TabTitle">我的购物车</div>
<div class="TabFormItems Items">
{{#items}}
<div class="TabFormItem Item" itemid="{{first.item.id}}">
<label class="ItemCheckBox">
<input class="ItemId" type="checkbox" name="items" value="{{first.item.id}}"/>
<input class="ItemNumber" type="checkbox" name="numbers" value="{{first.number}}"/>
</label>
<div class="Picture">
<img alt="商品图片" src="{{first.item.pictureLink}}">
</div>
<div class="Infos">
<div class="Info">
<div class="Title">{{first.item.name}}</div>
<div class="Prices">
<span class="Price">{{first.item.price}}¥</span>
<span class="Number">x{{first.number}}</span>
<span class="PriceSum">= {{second}}¥</span>
</div>
</div>
<span class="Description">{{first.item.description}}</span>
</div>
<div class="TabButtons">
<button class="TabButton" type="button" remove>删除</button>
</div>
</div>
{{/items}}
</div>
<div class="TabFormItems Items">
<div class="TabFormItem">
</div>
</div>
<div class="TabButtons">
<button class="TabButton" type="submit">创建订单</button>
</div>
</form>
</div> </div>
</body> </body>

View File

@ -10,7 +10,7 @@
<div class="List Blank"></div> <div class="List Blank"></div>
<div class="List Special SearchBar"> <div class="List Special SearchBar">
<label> <label>
<input class="InputBar" type="text"/> <input class="InputBar" type="text" placeholder="输入你想要找的商品以搜素~"/>
</label> </label>
</div> </div>
<div class="List Blank"></div> <div class="List Blank"></div>