rewrite index page, remove most of no needed resources

Signed-off-by: Puqns67 <me@puqns67.icu>
This commit is contained in:
Puqns67 2023-09-20 00:24:29 +08:00
parent 071c811664
commit a896edd6c6
Signed by: Puqns67
GPG Key ID: 9669DF042554F536
43 changed files with 438 additions and 1487 deletions

View File

@ -22,7 +22,7 @@ class OrderAction(
return token?.let(accountRepository::findByToken) return token?.let(accountRepository::findByToken)
} }
@RequestMapping("/create") @PostMapping("/create")
fun createForCart( fun createForCart(
attributes: RedirectAttributes, attributes: RedirectAttributes,
@CookieValue("TOKEN", required = false) token: String?, @CookieValue("TOKEN", required = false) token: String?,

View File

@ -20,8 +20,8 @@ class ErrorPage(private val repository: AccountRepository) : ErrorController {
@ModelAttribute("redirect") redirect: String @ModelAttribute("redirect") redirect: String
): String { ): String {
token?.let(repository::findByToken)?.let { model["user"] = it } token?.let(repository::findByToken)?.let { model["user"] = it }
model["title"] = title.ifEmpty { "页面" } model["title"] = title.ifEmpty { "加载页面" }
model["message"] = message.ifEmpty { "未知的页面" } model["message"] = message.ifEmpty { "内部错误,请联系网站管理员" }
model["redirect"] = redirect.ifEmpty { "/" } model["redirect"] = redirect.ifEmpty { "/" }
return "error" return "error"
} }

View File

@ -42,9 +42,17 @@ class OrderPage(
attributes: RedirectAttributes, attributes: RedirectAttributes,
@CookieValue("TOKEN", required = false) token: String?, @CookieValue("TOKEN", required = false) token: String?,
@RequestParam("items") itemIds: Array<Long>, @RequestParam("items") itemIds: Array<Long>,
@RequestParam("numbers") itemNumbers: Array<Long> @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 items: MutableList<Triple<Item, Int, Double>> = mutableListOf()
itemPairs.forEach {
val item = itemRepository.findById(it.first).orElse(null) ?: return error(attributes, "查看订单", "商品不存在")
items.add(Triple(item, it.second, item.price!! * it.second))
}
model["items"] = items
model["payTypes"] = payTypeRepository.findAll()
model["user"] = user model["user"] = user
return "order/create" return "order/create"
} }
@ -59,8 +67,8 @@ class OrderPage(
): String { ): String {
val user = this.getCurrentUser(token) ?: return error(attributes, "查看订单", "账户未登录", "/login") val user = this.getCurrentUser(token) ?: return error(attributes, "查看订单", "账户未登录", "/login")
val item = itemRepository.findById(id).orElse(null) ?: return error(attributes, "查看订单", "商品不存在") val item = itemRepository.findById(id).orElse(null) ?: return error(attributes, "查看订单", "商品不存在")
model["payTypes"] = payTypeRepository.findAll()
model["items"] = arrayOf(Triple(item, number ?: 1, item.price!! * (number ?: 1))) model["items"] = arrayOf(Triple(item, number ?: 1, item.price!! * (number ?: 1)))
model["payTypes"] = payTypeRepository.findAll()
model["user"] = user model["user"] = user
return "order/create" return "order/create"
} }

View File

@ -10,10 +10,17 @@ 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.AccountRepository
import team8.fruitable.datebase.repository.BannerRepository
import team8.fruitable.datebase.repository.ItemRepository import team8.fruitable.datebase.repository.ItemRepository
import team8.fruitable.datebase.repository.RecommendRepository
@Controller @Controller
class Pages(private val accountRepository: AccountRepository, private val itemRepository: ItemRepository) { class Pages(
private val accountRepository: AccountRepository,
private val itemRepository: ItemRepository,
private val bannerRepository: BannerRepository,
private val recommendRepository: RecommendRepository
) {
private fun getCurrentUser(token: String?): User? { private fun getCurrentUser(token: String?): User? {
return token?.let(accountRepository::findByToken) return token?.let(accountRepository::findByToken)
} }
@ -25,6 +32,9 @@ class Pages(private val accountRepository: AccountRepository, private val itemRe
): 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["banners"] = bannerRepository.findAll()
model["recommends"] = recommendRepository.findAll()
return "index" return "index"
} }

View File

@ -0,0 +1,19 @@
package team8.fruitable.datebase.entity
import jakarta.persistence.*
@Entity
@Table(name = "banners")
class Banner (
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
var id: Long? = null,
@OneToOne
@JoinColumn(name = "item", nullable = false)
var item: Item? = null,
@Column(name="description", length=32, nullable = false)
var description: String? = null,
)

View File

@ -12,8 +12,5 @@ class Recommend (
@OneToOne @OneToOne
@JoinColumn(name = "item", nullable = false) @JoinColumn(name = "item", nullable = false)
var item: Item? = null, var item: Item? = null
@Column(name="description", length=32, nullable = false)
var description: String? = null,
) )

View File

@ -0,0 +1,6 @@
package team8.fruitable.datebase.repository
import org.springframework.data.repository.CrudRepository
import team8.fruitable.datebase.entity.Banner
interface BannerRepository : CrudRepository<Banner, Long>

View File

@ -0,0 +1,6 @@
package team8.fruitable.datebase.repository
import org.springframework.data.repository.CrudRepository
import team8.fruitable.datebase.entity.Recommend
interface RecommendRepository : CrudRepository<Recommend, Long>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1,14 +0,0 @@
[
{
"Name": "排浊泡沫沐浴露",
"Picture": "images/item/13.jpeg"
},
{
"Name": "辣椒酱 风味豆豉油制辣椒",
"Picture": "images/item/8.jpeg"
},
{
"Name": "小麦漱口杯",
"Picture": "images/item/5.jpeg"
}
]

View File

@ -1,790 +0,0 @@
[
{
"Name": "电动牙刷",
"Description": "高频震动磁悬浮马达,刷得干净,智能过压提醒,不伤牙龈,个性定制洁齿模式,满足多种口腔需求,无锈无金属刷头,清洁卫生高效",
"Price": 159,
"VipPrice": 149,
"Tags": ["coupon", "price-break_discount"],
"Options": [
{
"Name": "颜色",
"Contants": ["白色", "粉色", "蓝色"]
}
],
"Picture": "images/item/0.jpeg"
},
{
"Name": "蓝牙耳机",
"Description": "主动降噪无线蓝牙耳机",
"Price": 1699,
"VipPrice": null,
"Tags": [],
"Options": [
{
"Name": "版本",
"Contants": ["公开版", "快充套装", "个性定制版"]
}
],
"Picture": "images/item/1.jpeg"
},
{
"Name": "花果香氛沐浴露套装",
"Description": "主动降噪无线蓝牙耳机",
"Price": 127,
"VipPrice": 125,
"Tags": ["coupon"],
"Options": [
{
"Name": "功效",
"Contants": [
"花果香氛三件套",
"花果香氛三件套",
"经典滋润三件套",
"经典滋润三件套",
"香氛美肌三件套",
"香氛美肌三件套",
"花香美肌三件套",
"花香美肌三件套",
"精油香氛三件套",
"精油香氛三件套",
"果萃香氛三件套",
"果萃香氛三件套",
"果萃滋润三件套",
"果萃滋润三件套"
]
}
],
"Picture": "images/item/2.jpeg"
},
{
"Name": "台式机内存条",
"Description": "【匠心淬炼高性能超频内存】电镀镜面外观不规则多层向切割技艺呈现出折射RGB灯效。内存中的皇者",
"Price": 1699,
"VipPrice": null,
"Tags": [],
"Options": [
{
"Name": "频率",
"Contants": ["3200Mhz", "3600Mhz", "3899MHz"]
}
],
"Picture": "images/item/3.jpeg"
},
{
"Name": "无线蓝牙键盘",
"Description": "办公键盘 超薄 带优联 深灰色 旗舰款",
"Price": 799,
"VipPrice": null,
"Tags": [],
"Options": [],
"Picture": "images/item/4.jpeg"
},
{
"Name": "小麦漱口杯",
"Description": "创意 环保 小麦秸秆 洗漱杯子 漱口杯 牙杯",
"Price": 20.76,
"VipPrice": 18.9,
"Tags": ["coupon", "price-break_discount"],
"Options": [],
"Picture": "images/item/5.jpeg"
},
{
"Name": "飞天 酱香型白酒 53度 500ml",
"Description": "单瓶装 收藏酒 陈年老酒",
"Price": 4529,
"VipPrice": null,
"Tags": [],
"Options": [
{
"Name": "年份",
"Contants": ["2010年", "2011年", "2012年"]
}
],
"Picture": "images/item/6.jpeg"
},
{
"Name": "MX Vertical 人体工学鼠标",
"Description": "【健康办公】人体工学鼠标,告别鼠标手!小手适用,柔软舒适!低噪点击,专注当下!",
"Price": 569,
"VipPrice": null,
"Tags": ["coupon"],
"Options": [
{
"Name": "颜色",
"Contants": ["黑色", "粉色", "白色"]
}
],
"Picture": "images/item/7.jpeg"
},
{
"Name": "辣椒酱 风味豆豉油制辣椒 280g",
"Description": null,
"Price": 13.9,
"VipPrice": 13.21,
"Tags": ["coupon"],
"Options": [],
"Picture": "images/item/8.jpeg"
},
{
"Name": "食用油",
"Description": "5S物理压榨 压榨一级 花生油 6.18L",
"Price": 189.8,
"VipPrice": null,
"Tags": [],
"Options": [],
"Picture": "images/item/9.jpeg"
},
{
"Name": "淡色拉格啤酒 450ml 整箱装",
"Description": null,
"Price": 49,
"VipPrice": null,
"Tags": ["coupon"],
"Options": [
{
"Name": "品种",
"Contants": ["12听", "18听", "24听"]
}
],
"Picture": "images/item/10.jpeg"
},
{
"Name": "运动鞋男鞋",
"Description": "秋冬季 轻便减震 慢跑鞋 透气休闲 旅游鞋 跑步 鞋子男",
"Price": 119,
"VipPrice": null,
"Tags": ["coupon"],
"Options": [
{
"Name": "颜色",
"Contants": ["曜石黑", "数字蓝", "宇宙灰", "烟灰", "皇冠金"]
}
],
"Picture": "images/item/11.jpeg"
},
{
"Name": "外套男羊羔绒夹克",
"Description": "加绒 加厚 上衣 男士 秋冬季新款 中青年 休闲 舒适 柔软 加厚 抗起球 休闲男装",
"Price": 139,
"VipPrice": null,
"Tags": ["coupon"],
"Options": [
{
"Name": "颜色",
"Contants": ["黑色", "卡其色", "深灰色", "灰色", "军绿色"]
},
{
"Name": "尺码",
"Contants": ["M", "L", "XL", "2XL", "3XL", "4XL", "5XL"]
}
],
"Picture": "images/item/12.jpeg"
},
{
"Name": "排浊泡沫沐浴露",
"Description": "疏通毛孔 焕活肌肤",
"Price": 64.9,
"VipPrice": null,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "功效",
"Contants": [
"红石榴 啫喱款",
"山茶花 啫喱款",
"红石榴 泡沫款",
"山茶花 泡沫款",
"山茶花+红石榴 啫喱款",
"山茶花+红石榴 泡沫款"
]
}
],
"Picture": "images/item/13.jpeg"
},
{
"Name": "狗玩具磨牙棒",
"Description": "狗狗磨牙玩具",
"Price": 26,
"VipPrice": null,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
}
],
"Picture": "images/item/14.jpeg"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
},
{
"Name": "虚拟商品",
"Description": "此商品的说明",
"Price": 100,
"VipPrice": 50,
"Tags": ["price-break_discount"],
"Options": [
{
"Name": "大小",
"Contants": ["小号", "中号", "大号"]
},
{
"Name": "颜色",
"Contants": ["黑色", "白色", "灰色"]
},
{
"Name": "语言",
"Contants": ["英语", "中文", "日语"]
}
],
"Picture": "images/item/placeholder.png"
}
]

View File

@ -1 +0,0 @@
[1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14]

View File

@ -1,11 +0,0 @@
/**
* back.js by Puqns_67
*/
window.addEventListener("DOMContentLoaded", () => {
Array.from(document.getElementsByClassName("back")).forEach((v) => {
v.addEventListener("click", function () {
window.location.replace(this.getAttribute("back_to"));
});
});
});

View File

@ -26,8 +26,6 @@ function updateTime() {
}); });
} }
window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () { window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () {
console.info("[Clock] initializing");
yield updateTime(); yield updateTime();
window.setInterval(updateTime, 500); window.setInterval(updateTime, 500);
console.info("[Clock] initialization completed");
})); }));

View File

@ -6,13 +6,11 @@ function updatePinState() {
? document.body.clientHeight + footer.clientHeight ? document.body.clientHeight + footer.clientHeight
: document.body.clientHeight; : document.body.clientHeight;
let result = contextHight < window.innerHeight; let result = contextHight < window.innerHeight;
if (footer.hasAttribute("pined") != result) if (footer.hasAttribute("pined") !== result)
footer.toggleAttribute("pined", result); footer.toggleAttribute("pined", result);
} }
window.addEventListener("DOMContentLoaded", () => { window.addEventListener("DOMContentLoaded", () => {
console.info("[Footer] initializing");
// 初始化变量 // 初始化变量
footer = document.getElementById("Footer"); footer = document.getElementById("Footer");
@ -21,6 +19,4 @@ window.addEventListener("DOMContentLoaded", () => {
// 手动更新一次挂起状态 // 手动更新一次挂起状态
updatePinState(); updatePinState();
console.info("[Footer] initialization completed");
}); });

View File

@ -16,18 +16,15 @@ function setPin(n, body, header) {
header = document.getElementById("Header"); header = document.getElementById("Header");
} }
if (n) { if (n) {
console.info("[Header] Pining the header");
body.toggleAttribute("headerPined", true); body.toggleAttribute("headerPined", true);
header.toggleAttribute("pined", true); header.toggleAttribute("pined", true);
} }
else { else {
console.info("[Header] Unpining the header");
body.removeAttribute("headerPined"); body.removeAttribute("headerPined");
header.removeAttribute("pined"); header.removeAttribute("pined");
} }
} }
window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () { window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () {
console.info("[Header] initializing");
let body = document.getElementsByTagName("body")[0]; let body = document.getElementsByTagName("body")[0];
let header = document.getElementById("Header"); let header = document.getElementById("Header");
// 初始化动画 // 初始化动画
@ -48,7 +45,7 @@ window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void
}); });
v.addEventListener("animationend", function () { v.addEventListener("animationend", function () {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
if (this.style.animationName == "BackgroundBlur") { if (this.style.animationName === "BackgroundBlur") {
this.toggleAttribute("blured", true); this.toggleAttribute("blured", true);
} }
else { else {
@ -82,5 +79,4 @@ window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void
}); });
setPin(v.hasAttribute("checked"), body, header); setPin(v.hasAttribute("checked"), body, header);
}); });
console.info("[Header] initialization completed");
})); }));

View File

@ -1,249 +1,129 @@
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } function adopt(value) {
return value instanceof P ? value : new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) { return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function fulfilled(value) {
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } try {
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next()); step((generator = generator.apply(thisArg, _arguments || [])).next());
}); });
}; };
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 BannerImageDisplayer; let Banners;
let BannerTitleDisplayer; let BannerTitleDisplayPanel;
let BannerSelectersDisplayer; let BannerDescriptionDisplayPanel;
let BannerSelecters = []; let BannerSelectorsDisplayPanel;
let Items; let BannerSelectors = [];
let LoadingDisplayer;
let LoadingInfoDisplayer;
// 变量 // 变量
let Modifyed = false; let Modified = false;
let LastetBanner = -1; let LatestBanner = -1;
let BannerIntervalID; let BannerIntervalID;
let UpdatingItemFlag = false;
let IsEnd = false;
function switchBanner(bannerIndex = 0, isAuto = false) { function switchBanner(bannerIndex = 0, isAuto = false) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
console.info(`[Index] switch banner to ${bannerIndex}`); Banners.forEach((v, i) => {
// 替换图片与标题 v.style.display = i === bannerIndex ? "inherit" : "none"
BannerImageDisplayer.src = rawBanners[bannerIndex].Picture; });
BannerTitleDisplayer.innerText = rawBanners[bannerIndex].Name; // 替换标题与说明
// 更改 Seleters 的状态 BannerTitleDisplayPanel.innerText = Banners[bannerIndex].getAttribute("title");
BannerSelecters.forEach((v, i) => { BannerDescriptionDisplayPanel.innerText = Banners[bannerIndex].getAttribute("description");
i == bannerIndex // 更改 Selector 的状态
? v.toggleAttribute("selected", true) BannerSelectors.forEach((v, i) => {
: v.removeAttribute("selected"); i === bannerIndex ? v.toggleAttribute("selected", true) : v.removeAttribute("selected");
}); });
// 记录状态 // 记录状态
LastetBanner = bannerIndex; LatestBanner = bannerIndex;
Modifyed = !isAuto; Modified = !isAuto;
}); });
} }
function nextBanner() { function nextBanner() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
// 如果状态为手动修改则多暂停一会儿 // 如果状态为手动修改则多暂停一会儿
if (Modifyed) { if (Modified) {
window.clearInterval(BannerIntervalID); window.clearInterval(BannerIntervalID);
yield sleep(10000); yield sleep(10000);
Modifyed = false; Modified = false;
BannerIntervalID = window.setInterval(nextBanner, 5000); BannerIntervalID = window.setInterval(nextBanner, 5000);
} }
let newBannerIndex = LastetBanner + 1; let newBannerIndex = LatestBanner + 1;
if (newBannerIndex >= rawBanners.length) { if (newBannerIndex >= Banners.length) {
newBannerIndex = 0; newBannerIndex = 0;
} }
yield switchBanner(newBannerIndex, true); yield switchBanner(newBannerIndex, true);
}); });
} }
function isContain(element) {
return __awaiter(this, void 0, void 0, function* () { function redirectToItem() {
// 获取可视窗口的盖度 window.location.href = `/item/${this.getAttribute("itemid")}`;
let screenHeight = window.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight;
// 元素偏移的高度减去滚动条滚动的高度后与可视窗口的盖度比较
return (element.offsetTop - document.documentElement.scrollTop <= screenHeight);
});
} }
function updateItems() {
return __awaiter(this, void 0, void 0, function* () { function addToCartForItem(event) {
UpdatingItemFlag = true; window.location.href = `/action/cart/add/${this.parentElement.parentElement.getAttribute("itemid")}`;
do { event.stopPropagation();
let isNull = false;
let section = document.createElement("div");
for (var i = 0; i < 2; i++) {
let item = yield getNextItem("INDEX");
if (item == null) {
LoadingDisplayer.style.display = "none";
LoadingInfoDisplayer.innerText = "没有更多了";
LoadingInfoDisplayer.style.display = "block";
if (i == 0)
isNull = true;
IsEnd = true;
break;
} }
else {
let newItem = document.createElement("div"); function createOrderForItem(event) {
// 图片部分 window.location.href = `/order/create/${this.parentElement.parentElement.getAttribute("itemid")}`;
let newPictureDisplayer = document.createElement("div"); event.stopPropagation();
let newImageElement = document.createElement("img");
newImageElement.alt = item.Name;
newImageElement.src = item.Picture;
newPictureDisplayer.classList.add("Picture");
newPictureDisplayer.append(newImageElement);
// 价格文字部分
let newPriceDisplayer = document.createElement("div");
let newPriceText = document.createElement("span");
newPriceText.innerText = `${item.Price}`;
newPriceText.classList.add("Price");
newPriceDisplayer.classList.add("Prices");
newPriceDisplayer.append(newPriceText);
if (item.VipPrice != null) {
let newVipPriceText = document.createElement("span");
newVipPriceText.classList.add("VipPrice");
newVipPriceText.innerText = `${item.VipPrice}`;
newPriceDisplayer.append(newVipPriceText);
newPriceText.toggleAttribute("has_vip_price", true);
} }
// 说明文字部分
let newTextDisplayer = document.createElement("div");
let newTitleDisplayer = document.createElement("div");
let newTitleText = document.createElement("span");
let newDescriptionText = document.createElement("span");
if (item.Description)
newDescriptionText.innerText = item.Description;
newTitleText.innerText = item.Name;
newDescriptionText.classList.add("Description");
newTitleText.classList.add("Title");
newTitleDisplayer.classList.add("TitlePrices");
newTextDisplayer.classList.add("Descriptions");
newTitleDisplayer.append(newTitleText, newPriceDisplayer);
newTextDisplayer.append(newTitleDisplayer, newDescriptionText);
// 按钮部分
let newButtonDisplayer = document.createElement("div");
let newOrderButton = document.createElement("div");
let newCartButton = document.createElement("div");
newCartButton.classList.add("Button", "AddToCart");
newOrderButton.classList.add("Button", "PlaceAnOrder");
newButtonDisplayer.classList.add("Buttons");
newButtonDisplayer.append(newOrderButton, newCartButton);
// 触发器
newItem.addEventListener("click", function () {
return __awaiter(this, void 0, void 0, function* () {
let ID = this.getAttribute("item_id");
if (ID != null) {
window.location.href = `item/${ID}`;
}
});
});
newItem.setAttribute("item_id", String(yield indexOf(item)));
newItem.classList.add("Item");
newItem.append(newPictureDisplayer, newTextDisplayer, newButtonDisplayer);
section.append(newItem);
}
}
if (!isNull) {
section.classList.add("ItemSection");
Items.append(section);
}
} while ((yield hasNextItem("INDEX")) &&
(yield isContain(LoadingDisplayer)));
UpdatingItemFlag = false;
});
}
window.addEventListener("scroll", () => __awaiter(void 0, void 0, void 0, function* () {
if (!IsEnd && !UpdatingItemFlag && (yield isContain(LoadingDisplayer)))
yield updateItems();
}));
window.addEventListener("resize", () => __awaiter(void 0, void 0, void 0, function* () {
if (!IsEnd && !UpdatingItemFlag && (yield isContain(LoadingDisplayer)))
yield updateItems();
}));
window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () { window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () {
console.info("[Index] initializing"); let Contents = document.getElementById("Contents");
let Contants = document.getElementById("Contents"); let ContentsHeader = Contents.querySelector(".ContentHeader");
let ContantsHeader = Contants.querySelector(".ContentHeader");
Items = Contants.querySelector(".Items"); let BannerDisplayPanel = ContentsHeader.querySelector(".RollingBanner");
let ContentFooter = Contants.querySelector(".ContentFooter"); let Banner = BannerDisplayPanel.querySelector(".Banners");
// let Infos = BannerDisplayPanel.querySelector(".Infos");
// 滚动屏幕部分
// Banners = Banner.querySelectorAll(".Banner");
rawBanners = yield window BannerTitleDisplayPanel = Infos.querySelector(".Title");
.fetch("resources/banner.json") BannerDescriptionDisplayPanel = Infos.querySelector(".Description");
.then((response) => __awaiter(void 0, void 0, void 0, function* () { BannerSelectorsDisplayPanel = Infos.querySelector(".Selector");
if (response.ok) {
return yield response.json(); Banners.forEach((_, i) => {
} let newSelector = document.createElement("button");
else { newSelector.classList.add("Button");
console.warn(`[Index] Network request for banner.json failed with response ${response.status}: ${response.statusText}`); newSelector.innerText = String(i + 1);
return []; newSelector.addEventListener("click", function () {
}
}));
if (rawBanners.length != 0) {
let Banner = ContantsHeader.querySelector(".RollingBanner");
let Link = Banner.querySelector(".BannerImage");
let Infos = Banner.querySelector(".Infos");
BannerImageDisplayer = Link.querySelector("img");
BannerTitleDisplayer = Infos.querySelector(".Title");
BannerSelectersDisplayer = Infos.querySelector(".Selecter");
rawBanners.forEach((_, i) => {
let newSelecter = document.createElement("button");
newSelecter.classList.add("Button");
newSelecter.innerText = String(i + 1);
newSelecter.addEventListener("click", function () {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
yield switchBanner(Number(this.innerText) - 1); yield switchBanner(Number(this.innerText) - 1);
}); });
}); });
BannerSelectersDisplayer.append(newSelecter); BannerSelectorsDisplayPanel.append(newSelector);
BannerSelecters.push(newSelecter); BannerSelectors.push(newSelector);
}); });
// 手动运行一次 // 手动运行一次
yield switchBanner(undefined, true); yield switchBanner(undefined, true);
// 设置定时器 // 设置定时器
BannerIntervalID = window.setInterval(nextBanner, 8000); BannerIntervalID = window.setInterval(nextBanner, 8000);
}
// document.querySelectorAll("*[itemid]").forEach(v => v.addEventListener("click", redirectToItem));
// 推荐项目部分 Array.from(document.getElementsByClassName("AddToCart")).forEach(v => v.addEventListener("click", addToCartForItem));
// Array.from(document.getElementsByClassName("PlaceAnOrder")).forEach(v => v.addEventListener("click", createOrderForItem));
yield loadItem();
let rawItems = yield getItems();
let rawRecommends = yield window
.fetch("resources/recommend.json")
.then((response) => __awaiter(void 0, void 0, void 0, function* () {
if (response.ok) {
return yield response.json();
}
else {
console.warn(`[Index] Network request for recommend.json failed with response ${response.status}: ${response.statusText}`);
return [];
}
}));
let RecommendItemDisplayer = ContantsHeader.querySelector(".RecommendItems");
rawRecommends.forEach((v) => {
let newImageElement = document.createElement("img", {});
let newPictureDisplayer = document.createElement("div");
let newNameDisplayer = document.createElement("div");
let newItem = document.createElement("div");
newImageElement.src = rawItems[v].Picture;
newImageElement.alt = rawItems[v].Name;
newPictureDisplayer.classList.add("Picture");
newPictureDisplayer.append(newImageElement);
newNameDisplayer.innerText = rawItems[v].Name;
newNameDisplayer.classList.add("Title");
newItem.classList.add("Item");
newItem.append(newPictureDisplayer, newNameDisplayer);
RecommendItemDisplayer.append(newItem);
});
//
// 内容自动加载部分
//
LoadingDisplayer = ContentFooter.querySelector(".Loading");
LoadingInfoDisplayer = ContentFooter.querySelector(".Info");
yield updateItems();
console.info("[Index] initialization completed");
})); }));

View File

@ -1,12 +0,0 @@
window.addEventListener("DOMContentLoaded", () => {
Array.from(document.querySelector(".Options").children).forEach((v) => {
Array.from(v.querySelector(".Contents").children).forEach((vv) => {
vv.addEventListener("click", function () {
Array.from(this.parentElement.children).forEach((v) => {
v.removeAttribute("selected");
});
this.toggleAttribute("selected", true);
});
});
});
});

View File

@ -1,71 +0,0 @@
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const NextMap = new Map();
let isItemLoaded = false;
let Items = [];
export function loadItem(force = false) {
return __awaiter(this, void 0, void 0, function* () {
if (!force && isItemLoaded) {
return;
}
Items = yield window.fetch("resources/item.json").then((response) => __awaiter(this, void 0, void 0, function* () {
if (response.ok) {
return yield response.json();
}
else {
console.warn(`[Index] Network request for item.json failed with response ${response.status}: ${response.statusText}`);
return [];
}
}));
isItemLoaded = true;
});
}
export function getItem(ID) {
return __awaiter(this, void 0, void 0, function* () {
return ID < Items.length ? Items[ID] : null;
});
}
export function getItems() {
return __awaiter(this, void 0, void 0, function* () {
return Items;
});
}
export function indexOf(item) {
return __awaiter(this, void 0, void 0, function* () {
return Items.indexOf(item);
});
}
export function hasNextItem(ID) {
return __awaiter(this, void 0, void 0, function* () {
if (!NextMap.has(ID))
NextMap.set(ID, -1);
let next = NextMap.get(ID) + 1;
if (next < Items.length) {
return true;
}
else {
return false;
}
});
}
export function getNextItem(ID) {
return __awaiter(this, void 0, void 0, function* () {
if (!NextMap.has(ID))
NextMap.set(ID, -1);
let next = NextMap.get(ID) + 1;
if (next < Items.length) {
NextMap.set(ID, next);
return Items[next];
}
else {
return null;
}
});
}

View File

@ -1 +0,0 @@
export {};

View File

@ -37,7 +37,6 @@ window.addEventListener("scroll", () => __awaiter(void 0, void 0, void 0, functi
} }
})); }));
window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () { window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () {
console.info("[Top] initializing");
topButtons = Array.from(document.getElementsByClassName("TOP")); topButtons = Array.from(document.getElementsByClassName("TOP"));
topButtons.forEach((v) => { topButtons.forEach((v) => {
v.addEventListener("click", () => __awaiter(void 0, void 0, void 0, function* () { v.addEventListener("click", () => __awaiter(void 0, void 0, void 0, function* () {
@ -46,5 +45,4 @@ window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void
})); }));
}); });
yield setDisplay(); yield setDisplay();
console.info("[Top] initialization completed");
})); }));

View File

@ -1,260 +0,0 @@
@font-face {
font-family: "Normal";
src: url("../fonts/华文圆体-Regular.ttf") format("ttf");
}
body {
display: flex;
margin: auto;
flex-direction: column;
align-items: center;
}
div {
display: flex;
}
#Contents {
flex-direction: column;
width: 100%;
}
.ContentHeader {
height: 330px;
flex-direction: row;
}
.ContentHeader * {
margin: 5px;
}
.ContentHeader .RollingBanner {
flex: 1 1;
flex-direction: column;
background-color: rgba(0, 60, 130, 0.8);
border-radius: 10px;
}
.ContentHeader .RollingBanner .BannerImage {
flex: 4 1;
max-width: 100%;
max-height: 260px;
justify-content: center;
}
.ContentHeader .RollingBanner .BannerImage img {
max-width: 100%;
max-height: 100%;
object-fit: cover;
border-radius: 10px;
height: 100%;
}
.ContentHeader .RollingBanner .Infos {
flex: 1 1;
flex-direction: row;
align-items: center;
justify-content: center;
}
.ContentHeader .RollingBanner .Infos .Title {
flex: 2 1;
font-family: "Normal", system-ui;
color: rgba(21, 255, 172, 0.8);
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.ContentHeader .RollingBanner .Infos .Selecter {
border: 3px solid rgba(0, 120, 255, 0.8);
border-radius: 8px;
flex-direction: row;
}
.ContentHeader .RollingBanner .Infos .Selecter .Button {
flex: 1 1;
width: 22px;
background: rgba(0, 60, 130, 0.8);
border: unset;
font-family: "Normal", system-ui;
color: rgba(0, 225, 145, 0.8);
}
.ContentHeader .RollingBanner .Infos .Selecter .Button[selected] {
background-color: rgba(0, 84, 181, 0.8);
}
.ContentHeader .RecommendItems {
flex: 2 1;
flex-wrap: wrap;
overflow: hidden;
background-color: rgba(0, 60, 130, 0.8);
border-radius: 15px;
justify-content: space-around;
}
.ContentHeader .RecommendItems .Item {
margin: 5px;
width: 120px;
height: 150px;
border-radius: 15px;
flex-direction: column;
background-color: rgba(0, 84, 181, 0.8);
}
.ContentHeader .RecommendItems .Item .Picture {
flex: 3 1;
align-items: center;
justify-content: center;
padding: 5px;
max-width: 100%;
height: 100px;
}
.ContentHeader .RecommendItems .Item .Picture img {
max-width: 100%;
max-height: 100%;
object-fit: cover;
border-radius: 10px;
height: 100%;
}
.ContentHeader .RecommendItems .Item .Title {
flex: 1 1;
flex-direction: column;
align-items: start;
justify-content: center;
font-family: "Normal", system-ui;
text-decoration: none;
color: rgba(21, 255, 172, 0.8);
font-size: 12px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.Items {
flex-direction: column;
}
.Items .ItemSection {
flex-direction: row;
width: 100%;
justify-content: center;
align-items: center;
}
.Items .ItemSection .Item {
flex: 1 0;
flex-direction: row;
margin: 5px;
background-color: rgba(0, 60, 130, 0.8);
border-radius: 15px;
height: 110px;
}
.Items .ItemSection .Item .Picture {
height: 110px;
width: 110px;
}
.Items .ItemSection .Item .Picture img {
padding: 5px;
border-radius: 15px;
}
.Items .ItemSection .Item .Descriptions {
flex: 1 0;
flex-direction: column;
padding: 5px;
}
.Items .ItemSection .Item .Descriptions span {
font-family: "Normal", system-ui;
}
.Items .ItemSection .Item .Descriptions .TitlePrices {
justify-content: space-between;
height: 30px;
}
.Items .ItemSection .Item .Descriptions .TitlePrices .Title {
color: rgb(220, 220, 255);
font-size: 20px;
overflow: hidden;
text-overflow: ellipsis;
}
.Items .ItemSection .Item .Descriptions .TitlePrices .Prices {
align-items: center;
}
.Items .ItemSection .Item .Descriptions .TitlePrices .Prices .Price {
color: red;
font-size: 18px;
font-weight: bold;
}
.Items .ItemSection .Item .Descriptions .TitlePrices .Prices .Price[has_vip_price] {
color: grey;
font-weight: lighter;
font-style: italic;
text-decoration: line-through;
}
.Items .ItemSection .Item .Descriptions .TitlePrices .Prices .VipPrice {
color: gold;
font-size: 18px;
font-weight: bold;
}
.Items .ItemSection .Item .Descriptions .Description {
color: rgb(175, 175, 255);
font-size: 16px;
overflow: hidden;
text-overflow: ellipsis;
}
.Items .ItemSection .Item .Buttons {
padding-left: 10px;
padding-right: 10px;
flex-direction: column;
justify-content: space-around;
}
.Items .ItemSection .Item .Buttons .Button {
width: 40px;
height: 40px;
background-repeat: no-repeat;
background-color: rgba(40, 150, 40, 0.2);
border: 1px solid rgba(100, 255, 100, 0.8);
border-radius: 15px;
}
.Items .ItemSection .Item .Buttons .AddToCart {
background-image: url("../images/add_to_cart.svg");
}
.Items .ItemSection .Item .Buttons .PlaceAnOrder {
background-image: url("../images/place_an_order.svg");
}
.ContentFooter {
height: 48px;
margin: 5px;
justify-content: center;
align-items: center;
}
.ContentFooter .Info {
display: none;
}
@media (min-width: 1280px) {
#Contents {
width: 1280px;
}
}

View File

@ -0,0 +1,237 @@
@color_1: rgba(21, 255, 172, 0.8);
@color_2: rgba(0, 225, 145, 0.8);
@color_3: rgb(220, 220, 255);
@color_4: red;
@color_5: grey;
@color_6: gold;
@color_7: rgb(175, 175, 255);
@font_family_1: "Normal", system-ui;
@background_color_1: rgba(0, 60, 130, 0.8);
@background_color_2: rgba(0, 84, 181, 0.8);
@background_color_3: rgba(40, 150, 40, 0.2);
.ContentHeader {
height: 330px;
flex-direction: row;
> * {
margin: 5px;
}
> .RollingBanner {
flex: 1;
flex-direction: column;
background-color: @background_color_1;
border-radius: 10px;
> .Banners {
flex: 3;
width: calc(100% - 20px);
height: 220px;
margin: 10px;
> .Banner {
display: none;
width: 100%;
height: 100%;
justify-content: center;
> img {
max-width: 100%;
max-height: 100%;
object-fit: cover;
border-radius: 10px;
height: 100%;
}
}
}
> .Infos {
flex: 1;
flex-direction: row;
align-items: center;
justify-content: space-between;
> * {
margin-left: 20px;
margin-right: 20px;
}
> .Titles {
flex-direction: column;
> span {
font-family: @font_family_1;
color: @color_1;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
> .Selector {
border: 3px solid rgba(0, 120, 255, 0.8);
border-radius: 8px;
flex-direction: row;
> .Button {
flex: 1;
width: 22px;
background: rgba(0, 60, 130, 0.8);
border: unset;
font-family: @font_family_1;
color: @color_2;
&[selected] {
background-color: @background_color_2;
}
}
}
}
}
> .RecommendItems {
flex: 2 1;
flex-wrap: wrap;
overflow: hidden;
background-color: @background_color_1;
border-radius: 15px;
justify-content: space-around;
> .Item {
margin: 5px;
width: 120px;
height: 150px;
border-radius: 15px;
flex-direction: column;
background-color: @background_color_2;
> .Picture {
flex: 9;
align-items: center;
justify-content: center;
padding: 5px;
max-width: 100%;
height: 100px;
> img {
max-width: 100%;
max-height: 100%;
object-fit: cover;
border-radius: 10px;
height: 100%;
}
}
> .Title {
flex: 2;
flex-direction: column;
align-items: center;
justify-content: center;
font-family: @font_family_1;
font-size: 14px;
text-decoration: none;
color: @color_1;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
}
}
.Items {
flex-direction: row;
justify-content: center;
align-items: center;
flex-wrap: wrap;
> .Item {
flex: 0 0 49%;
flex-direction: row;
margin: 5px;
background-color: @background_color_1;
border-radius: 15px;
height: 110px;
> .Picture {
align-items: center;
justify-content: center;
height: 110px;
width: 110px;
> img {
max-width: 100px;
max-height: 100px;
object-fit: cover;
margin: 5px;
border-radius: 10px;
}
}
> .Descriptions {
flex: 1 0;
flex-direction: column;
padding: 5px;
> span {
font-family: @font_family_1;
}
> .TitlePrices {
justify-content: space-between;
height: 30px;
> .Title {
color: @color_3;
font-size: 20px;
overflow: hidden;
text-overflow: ellipsis;
}
> .Price {
color: @color_4;
font-size: 18px;
font-weight: bold;
}
}
> .Description {
color: @color_7;
font-size: 16px;
overflow: hidden;
text-overflow: ellipsis;
}
}
> .Buttons {
padding-left: 10px;
padding-right: 10px;
flex-direction: column;
justify-content: space-around;
> .Button {
width: 40px;
height: 40px;
background-repeat: no-repeat;
background-color: @background_color_3;
border: 1px solid rgba(100, 255, 100, 0.8);
border-radius: 15px;
}
> .AddToCart {
background-image: url("../images/add_to_cart.svg");
}
> .PlaceAnOrder {
background-image: url("../images/place_an_order.svg");
}
}
}
}
@media (min-width: 1280px) {
#Contents {
width: 1280px;
}
}

View File

@ -1,65 +0,0 @@
@keyframes loading-zoom-in {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
@keyframes loading-move {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(24px, 0);
}
}
@keyframes loading-zoom-out {
0% {
transform: scale(1);
}
100% {
transform: scale(0);
}
}
.Loading {
display: inline-block;
position: relative;
width: 62px;
height: 15px;
> div {
position: absolute;
top: 1px;
width: 13px;
height: 13px;
border-radius: 50%;
background: #3bfeff;
border: 1px solid black;
animation-duration: 0.6s;
animation-iteration-count: infinite;
&:nth-child(1) {
left: 0;
animation-name: loading-zoom-in;
}
&:nth-child(2) {
left: 0;
animation-name: loading-move;
}
&:nth-child(3) {
left: 24px;
animation-name: loading-move;
}
&:nth-child(4) {
left: 48px;
animation-name: loading-zoom-out;
}
}
}

View File

@ -1,3 +1,6 @@
.TabForm {
width: 640px;
}
.Item { .Item {
margin-top: 10px; margin-top: 10px;
margin-bottom: 10px; margin-bottom: 10px;
@ -19,6 +22,7 @@
> .Infos { > .Infos {
display: flex; display: flex;
flex: 1;
flex-direction: column; flex-direction: column;
padding: 5px 10px; padding: 5px 10px;
color: wheat; color: wheat;

View File

@ -6,18 +6,16 @@
<script type="text/javascript" src="/scripts/header.js"></script> <script type="text/javascript" src="/scripts/header.js"></script>
<script type="text/javascript" src="/scripts/clock.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/top.js"></script>
<script type="module" src="/scripts/resources.js"></script> <script type="text/javascript" src="/scripts/index.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="image/x-icon" rel="icon" href="/images/favicon.ico">
<!-- 页面公共的样式表 --> <!-- 页面公共的样式表 -->
<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/footer.less"> <link type="text/css" rel="stylesheet/less" href="/styles/footer.less">
<link type="text/css" rel="stylesheet/less" href="/styles/loading.less"> <link type="text/css" rel="stylesheet/less" href="/styles/base.less">
<!-- 页面特定的样式表 --> <!-- 页面特定的样式表 -->
<link type="text/css" rel="stylesheet" href="/styles/index.css"> <link type="text/css" rel="stylesheet/less" href="/styles/index.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>
@ -34,30 +32,54 @@
<div class="ContentHeader"> <div class="ContentHeader">
<!-- 滚动横幅 --> <!-- 滚动横幅 -->
<div class="RollingBanner"> <div class="RollingBanner">
<div class="BannerImage"> <div class="Banners">
<img alt="滚动横幅图片" src=""/> {{#banners}}
<div class="Banner" itemid="{{item.id}}" title="{{item.name}}" description="{{description}}">
<img alt="滚动横幅图片" src="{{item.pictureLink}}"/>
</div>
{{/banners}}
</div> </div>
<div class="Infos"> <div class="Infos">
<div class="Titles">
<span class="Title"></span> <span class="Title"></span>
<div class="Selecter"></div> <span class="Description"></span>
</div>
<div class="Selector"></div>
</div> </div>
</div> </div>
<!-- 推荐商品集 --> <!-- 推荐商品集 -->
<div class="RecommendItems"></div> <div class="RecommendItems">
{{#recommends}}
<div class="Item" itemid="{{item.id}}">
<div class="Picture">
<img alt="推荐商品" src="{{item.pictureLink}}"/>
</div>
<div class="Title">{{item.name}}</div>
</div>
{{/recommends}}
</div>
</div> </div>
<!-- 内容本身 --> <!-- 内容本身 -->
<div class="Items"></div> <div class="Items">
{{#items}}
<!-- 内容为尾 --> <div class="Item" itemid="{{id}}">
<div class="ContentFooter"> <div class="Picture">
<div class="Loading"> <img alt="商品图片" src="{{pictureLink}}"/>
<div></div>
<div></div>
<div></div>
<div></div>
</div> </div>
<span class="Info">恭喜你找到了一个彩蛋!</span> <div class="Descriptions">
<div class="TitlePrices">
<span class="Title">{{name}}</span>
<span class="Price">{{price}}¥</span>
</div>
<div class="Description">{{description}}</div>
</div>
<div class="Buttons">
<div class="Button PlaceAnOrder"></div>
<div class="Button AddToCart"></div>
</div>
</div>
{{/items}}
</div> </div>
</div> </div>

View File

@ -6,7 +6,6 @@
<script type="text/javascript" src="/scripts/header.js"></script> <script type="text/javascript" src="/scripts/header.js"></script>
<script type="text/javascript" src="/scripts/clock.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/top.js"></script>
<script type="text/javascript" src="/scripts/item.js"></script>
<link type="image/x-icon" rel="icon" href="/images/favicon.ico"> <link type="image/x-icon" rel="icon" href="/images/favicon.ico">
<!-- 页面公共的样式表 --> <!-- 页面公共的样式表 -->
<link type="text/css" rel="stylesheet/less" href="/styles/header.less"> <link type="text/css" rel="stylesheet/less" href="/styles/header.less">