diff --git a/src/main/resources/static/fonts/FiraCode-Regular.woff2 b/src/main/resources/static/fonts/FiraCode-Regular.woff2 new file mode 100644 index 0000000..f8b63fb Binary files /dev/null and b/src/main/resources/static/fonts/FiraCode-Regular.woff2 differ diff --git a/src/main/resources/static/fonts/LcdD.ttf b/src/main/resources/static/fonts/LcdD.ttf new file mode 100644 index 0000000..6928f9b Binary files /dev/null and b/src/main/resources/static/fonts/LcdD.ttf differ diff --git a/src/main/resources/static/fonts/SmileySans-Oblique.otf.woff2 b/src/main/resources/static/fonts/SmileySans-Oblique.otf.woff2 new file mode 100644 index 0000000..ebef92c Binary files /dev/null and b/src/main/resources/static/fonts/SmileySans-Oblique.otf.woff2 differ diff --git a/src/main/resources/static/fonts/华文圆体-Regular.ttf b/src/main/resources/static/fonts/华文圆体-Regular.ttf new file mode 100644 index 0000000..2c8ddf2 Binary files /dev/null and b/src/main/resources/static/fonts/华文圆体-Regular.ttf differ diff --git a/src/main/resources/static/images/add_to_cart.svg b/src/main/resources/static/images/add_to_cart.svg new file mode 100644 index 0000000..46d6be4 --- /dev/null +++ b/src/main/resources/static/images/add_to_cart.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/static/images/favicon.ico b/src/main/resources/static/images/favicon.ico new file mode 100644 index 0000000..4a14d5f Binary files /dev/null and b/src/main/resources/static/images/favicon.ico differ diff --git a/src/main/resources/static/images/icon.svg b/src/main/resources/static/images/icon.svg new file mode 100644 index 0000000..b4dce61 --- /dev/null +++ b/src/main/resources/static/images/icon.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/static/images/item/0.jpeg b/src/main/resources/static/images/item/0.jpeg new file mode 100644 index 0000000..dbe0a7c Binary files /dev/null and b/src/main/resources/static/images/item/0.jpeg differ diff --git a/src/main/resources/static/images/item/1.jpeg b/src/main/resources/static/images/item/1.jpeg new file mode 100644 index 0000000..728a4f8 Binary files /dev/null and b/src/main/resources/static/images/item/1.jpeg differ diff --git a/src/main/resources/static/images/item/10.jpeg b/src/main/resources/static/images/item/10.jpeg new file mode 100644 index 0000000..7bf9293 Binary files /dev/null and b/src/main/resources/static/images/item/10.jpeg differ diff --git a/src/main/resources/static/images/item/11.jpeg b/src/main/resources/static/images/item/11.jpeg new file mode 100644 index 0000000..3dc0aa2 Binary files /dev/null and b/src/main/resources/static/images/item/11.jpeg differ diff --git a/src/main/resources/static/images/item/12.jpeg b/src/main/resources/static/images/item/12.jpeg new file mode 100644 index 0000000..d9402e1 Binary files /dev/null and b/src/main/resources/static/images/item/12.jpeg differ diff --git a/src/main/resources/static/images/item/13.jpeg b/src/main/resources/static/images/item/13.jpeg new file mode 100644 index 0000000..cb9b7ff Binary files /dev/null and b/src/main/resources/static/images/item/13.jpeg differ diff --git a/src/main/resources/static/images/item/14.jpeg b/src/main/resources/static/images/item/14.jpeg new file mode 100644 index 0000000..f547ea2 Binary files /dev/null and b/src/main/resources/static/images/item/14.jpeg differ diff --git a/src/main/resources/static/images/item/2.jpeg b/src/main/resources/static/images/item/2.jpeg new file mode 100644 index 0000000..b6d97f1 Binary files /dev/null and b/src/main/resources/static/images/item/2.jpeg differ diff --git a/src/main/resources/static/images/item/3.jpeg b/src/main/resources/static/images/item/3.jpeg new file mode 100644 index 0000000..eb93649 Binary files /dev/null and b/src/main/resources/static/images/item/3.jpeg differ diff --git a/src/main/resources/static/images/item/4.jpeg b/src/main/resources/static/images/item/4.jpeg new file mode 100644 index 0000000..175494b Binary files /dev/null and b/src/main/resources/static/images/item/4.jpeg differ diff --git a/src/main/resources/static/images/item/5.jpeg b/src/main/resources/static/images/item/5.jpeg new file mode 100644 index 0000000..0d328e1 Binary files /dev/null and b/src/main/resources/static/images/item/5.jpeg differ diff --git a/src/main/resources/static/images/item/6.jpeg b/src/main/resources/static/images/item/6.jpeg new file mode 100644 index 0000000..007336d Binary files /dev/null and b/src/main/resources/static/images/item/6.jpeg differ diff --git a/src/main/resources/static/images/item/7.jpeg b/src/main/resources/static/images/item/7.jpeg new file mode 100644 index 0000000..cf605ce Binary files /dev/null and b/src/main/resources/static/images/item/7.jpeg differ diff --git a/src/main/resources/static/images/item/8.jpeg b/src/main/resources/static/images/item/8.jpeg new file mode 100644 index 0000000..40f150b Binary files /dev/null and b/src/main/resources/static/images/item/8.jpeg differ diff --git a/src/main/resources/static/images/item/9.jpeg b/src/main/resources/static/images/item/9.jpeg new file mode 100644 index 0000000..e1b4864 Binary files /dev/null and b/src/main/resources/static/images/item/9.jpeg differ diff --git a/src/main/resources/static/images/item/placeholder.png b/src/main/resources/static/images/item/placeholder.png new file mode 100644 index 0000000..e469b8a Binary files /dev/null and b/src/main/resources/static/images/item/placeholder.png differ diff --git a/src/main/resources/static/images/pin.svg b/src/main/resources/static/images/pin.svg new file mode 100644 index 0000000..2fd8981 --- /dev/null +++ b/src/main/resources/static/images/pin.svg @@ -0,0 +1,21 @@ + + + + + diff --git a/src/main/resources/static/images/place_an_order.svg b/src/main/resources/static/images/place_an_order.svg new file mode 100644 index 0000000..296c70f --- /dev/null +++ b/src/main/resources/static/images/place_an_order.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/static/images/top.svg b/src/main/resources/static/images/top.svg new file mode 100644 index 0000000..706c24e --- /dev/null +++ b/src/main/resources/static/images/top.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/src/main/resources/static/resources/banner.json b/src/main/resources/static/resources/banner.json new file mode 100644 index 0000000..b486de8 --- /dev/null +++ b/src/main/resources/static/resources/banner.json @@ -0,0 +1,14 @@ +[ + { + "Name": "排浊泡沫沐浴露", + "Picture": "images/item/13.jpeg" + }, + { + "Name": "辣椒酱 风味豆豉油制辣椒", + "Picture": "images/item/8.jpeg" + }, + { + "Name": "小麦漱口杯", + "Picture": "images/item/5.jpeg" + } +] diff --git a/src/main/resources/static/resources/item.json b/src/main/resources/static/resources/item.json new file mode 100644 index 0000000..33a05be --- /dev/null +++ b/src/main/resources/static/resources/item.json @@ -0,0 +1,790 @@ +[ + { + "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" + } +] diff --git a/src/main/resources/static/resources/recommend.json b/src/main/resources/static/resources/recommend.json new file mode 100644 index 0000000..eee5e44 --- /dev/null +++ b/src/main/resources/static/resources/recommend.json @@ -0,0 +1 @@ +[1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14] diff --git a/src/main/resources/static/scripts/back.js b/src/main/resources/static/scripts/back.js new file mode 100644 index 0000000..5b9de84 --- /dev/null +++ b/src/main/resources/static/scripts/back.js @@ -0,0 +1,11 @@ +/** + * 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")); + }); + }); +}); diff --git a/src/main/resources/static/scripts/clock.js b/src/main/resources/static/scripts/clock.js new file mode 100644 index 0000000..a1eea3e --- /dev/null +++ b/src/main/resources/static/scripts/clock.js @@ -0,0 +1,33 @@ +"use strict"; +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()); + }); +}; +function genTime() { + return __awaiter(this, void 0, void 0, function* () { + return new Date().toLocaleString(undefined, { hour12: false }); + }); +} +function updateTime() { + return __awaiter(this, void 0, void 0, function* () { + let nowTime = null; + let clocks = Array.from(document.getElementsByClassName("CLOCK")); + clocks.forEach((v) => __awaiter(this, void 0, void 0, function* () { + if (nowTime == null) { + nowTime = yield genTime(); + } + v.innerText = nowTime; + })); + }); +} +window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () { + console.info("[Clock] initializing"); + yield updateTime(); + window.setInterval(updateTime, 500); + console.info("[Clock] initialization completed"); +})); diff --git a/src/main/resources/static/scripts/edit.js b/src/main/resources/static/scripts/edit.js new file mode 100644 index 0000000..f110995 --- /dev/null +++ b/src/main/resources/static/scripts/edit.js @@ -0,0 +1,23 @@ +/** + * edit.js by Puqns_67 + */ + +function getID(element) { + return element.parentElement.parentElement.getAttribute("id"); +} + +window.addEventListener("DOMContentLoaded", () => { + let displayer = document.getElementById("Displayer"); + + Array.from(document.getElementsByClassName("update")).forEach((v) => { + v.addEventListener("click", function () { + displayer.src = `info.action?as=update.jsp&id=${getID(this)}`; + }); + }); + + Array.from(document.getElementsByClassName("remove")).forEach((v) => { + v.addEventListener("click", function () { + displayer.src = `info.action?as=remove.jsp&id=${getID(this)}`; + }); + }); +}); diff --git a/src/main/resources/static/scripts/footer.js b/src/main/resources/static/scripts/footer.js new file mode 100644 index 0000000..0915fbe --- /dev/null +++ b/src/main/resources/static/scripts/footer.js @@ -0,0 +1,26 @@ +let footer = null; + +// 页面长度无法填满整个页面时挂起页尾 +function updatePinState() { + let contextHight = (footer.hasAttribute("pined")) + ? document.body.clientHeight + footer.clientHeight + : document.body.clientHeight; + let result = contextHight < window.innerHeight; + if (footer.hasAttribute("pined") != result) + footer.toggleAttribute("pined", result); +} + +window.addEventListener("DOMContentLoaded", () => { + console.info("[Footer] initializing"); + + // 初始化变量 + footer = document.getElementById("Footer"); + + // 在页面大小重置时更新挂起状态 + window.addEventListener("resize", updatePinState); + + // 手动更新一次挂起状态 + updatePinState(); + + console.info("[Footer] initialization completed"); +}); diff --git a/src/main/resources/static/scripts/header.js b/src/main/resources/static/scripts/header.js new file mode 100644 index 0000000..7d14edc --- /dev/null +++ b/src/main/resources/static/scripts/header.js @@ -0,0 +1,86 @@ +"use strict"; +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()); + }); +}; +function setPin(n, body, header) { + if (body === undefined) { + body = document.querySelector("body"); + } + if (header === undefined) { + header = document.getElementById("Header"); + } + if (n) { + console.info("[Header] Pining the header"); + body.toggleAttribute("headerPined", true); + header.toggleAttribute("pined", true); + } + else { + console.info("[Header] Unpining the header"); + body.removeAttribute("headerPined"); + header.removeAttribute("pined"); + } +} +window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () { + console.info("[Header] initializing"); + let body = document.getElementsByTagName("body")[0]; + let header = document.getElementById("Header"); + // 初始化动画 + let lists = Array.from(header.getElementsByClassName("List")); + lists.forEach((v) => { + if (v.classList.contains("Button") || v.classList.contains("Link")) { + let text = Array.from(v.getElementsByClassName("Text")); + text.forEach((v) => { + v.addEventListener("mouseenter", function () { + return __awaiter(this, void 0, void 0, function* () { + this.style.animationName = "BackgroundBlur"; + }); + }); + v.addEventListener("mouseleave", function () { + return __awaiter(this, void 0, void 0, function* () { + this.style.animationName = "BackgroundUnblur"; + }); + }); + v.addEventListener("animationend", function () { + return __awaiter(this, void 0, void 0, function* () { + if (this.style.animationName == "BackgroundBlur") { + this.toggleAttribute("blured", true); + } + else { + this.removeAttribute("blured"); + } + this.style.animation = ""; + }); + }); + }); + } + }); + // 初始化链接 + let links = Array.from(header.getElementsByClassName("Link")); + links.forEach((v) => { + v.addEventListener("click", function () { + return __awaiter(this, void 0, void 0, function* () { + if (!this.hasAttribute("this")) { + let href = this.getAttribute("href"); + window.location.replace(href ? href : "index.jsp"); + } + }); + }); + }); + // 初始化 PIN + let pins = Array.from(document.getElementsByClassName("PIN")); + pins.forEach((v) => { + v.addEventListener("click", function () { + return __awaiter(this, void 0, void 0, function* () { + setPin(this.toggleAttribute("checked"), body, header); + }); + }); + setPin(v.hasAttribute("checked"), body, header); + }); + console.info("[Header] initialization completed"); +})); diff --git a/src/main/resources/static/scripts/index.js b/src/main/resources/static/scripts/index.js new file mode 100644 index 0000000..7a36a8e --- /dev/null +++ b/src/main/resources/static/scripts/index.js @@ -0,0 +1,248 @@ +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()); + }); +}; +import { getItems, getNextItem, hasNextItem, indexOf, loadItem, } from "./items.js"; +const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); +// 源数据 +let rawBanners = []; +// 图片与标题与选择器 +let BannerImageDisplayer; +let BannerTitleDisplayer; +let BannerSelectersDisplayer; +let BannerSelecters = []; +let Items; +let LoadingDisplayer; +let LoadingInfoDisplayer; +// 变量 +let Modifyed = false; +let LastetBanner = -1; +let BannerIntervalID; +let UpdatingItemFlag = false; +let IsEnd = false; +function switchBanner(bannerIndex = 0, isAuto = false) { + return __awaiter(this, void 0, void 0, function* () { + console.info(`[Index] switch banner to ${bannerIndex}`); + // 替换图片与标题 + BannerImageDisplayer.src = rawBanners[bannerIndex].Picture; + BannerTitleDisplayer.innerText = rawBanners[bannerIndex].Name; + // 更改 Seleters 的状态 + BannerSelecters.forEach((v, i) => { + i == bannerIndex + ? v.toggleAttribute("selected", true) + : v.removeAttribute("selected"); + }); + // 记录状态 + LastetBanner = bannerIndex; + Modifyed = !isAuto; + }); +} +function nextBanner() { + return __awaiter(this, void 0, void 0, function* () { + // 如果状态为手动修改则多暂停一会儿 + if (Modifyed) { + window.clearInterval(BannerIntervalID); + yield sleep(10000); + Modifyed = false; + BannerIntervalID = window.setInterval(nextBanner, 5000); + } + let newBannerIndex = LastetBanner + 1; + if (newBannerIndex >= rawBanners.length) { + newBannerIndex = 0; + } + yield switchBanner(newBannerIndex, true); + }); +} +function isContain(element) { + return __awaiter(this, void 0, void 0, function* () { + // 获取可视窗口的盖度 + 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* () { + UpdatingItemFlag = true; + do { + 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"); + // 图片部分 + let newPictureDisplayer = document.createElement("div"); + 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.jsp?item_id=${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* () { + console.info("[Index] initializing"); + let Contants = document.getElementById("Contents"); + let ContantsHeader = Contants.querySelector(".ContentHeader"); + Items = Contants.querySelector(".Items"); + let ContentFooter = Contants.querySelector(".ContentFooter"); + // + // 滚动屏幕部分 + // + rawBanners = yield window + .fetch("resources/banner.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 banner.json failed with response ${response.status}: ${response.statusText}`); + return []; + } + })); + 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* () { + yield switchBanner(Number(this.innerText) - 1); + }); + }); + BannerSelectersDisplayer.append(newSelecter); + BannerSelecters.push(newSelecter); + }); + // 手动运行一次 + yield switchBanner(undefined, true); + // 设置定时器 + BannerIntervalID = window.setInterval(nextBanner, 8000); + } + // + // 推荐项目部分 + // + 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"); +})); diff --git a/src/main/resources/static/scripts/item.js b/src/main/resources/static/scripts/item.js new file mode 100644 index 0000000..55b0d89 --- /dev/null +++ b/src/main/resources/static/scripts/item.js @@ -0,0 +1,80 @@ +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()); + }); +}; +import { getItem, loadItem } from "./items.js"; +let ID; +let TheItem; +window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () { + let rawID = new URLSearchParams(window.location.search).get("item_id"); + if (rawID == null || rawID == "") + window.location.replace("index.jsp"); + ID = Number(rawID); + yield loadItem(); + let rawItem = yield getItem(ID); + if (rawItem == null) + window.location.replace("index.jsp"); + TheItem = rawItem; + let ItemDisplayer = document.querySelector(".Item"); + let PictureDisplayer = ItemDisplayer.querySelector(".Picture"); + let InfoDisplayer = ItemDisplayer.querySelector(".Infos"); + // 图片部分 + let Image = PictureDisplayer.querySelector("img"); + Image.src = TheItem.Picture; + // 说明文字部分 + let TitleDisplayer = InfoDisplayer.querySelector(".Title"); + let DescriptionDisplayer = InfoDisplayer.querySelector(".Description"); + let OptionDisplayer = InfoDisplayer.querySelector(".Options"); + TitleDisplayer.innerText = TheItem.Name; + if (TheItem.Description != null) + DescriptionDisplayer.innerText = TheItem.Description; + // 价格文字部分 + let PriceDisplayer = InfoDisplayer.querySelector(".Prices"); + let Price = PriceDisplayer.querySelector(".Price"); + Price.innerText = `¥${TheItem.Price}`; + if (TheItem.VipPrice != null) { + let VipPrice = PriceDisplayer.querySelector(".VipPrice"); + VipPrice.innerText = `¥${TheItem.VipPrice}`; + Price.toggleAttribute("has_vip_price", true); + } + // 选项部分 + TheItem.Options.forEach((v) => { + let newOptionElement = document.createElement("div"); + let newOptionTitle = document.createElement("div"); + let newOptionSelecter = document.createElement("div"); + v.Contants.forEach((v, i) => { + let newOption = document.createElement("div"); + newOption.innerHTML = v; + newOption.classList.add("Option"); + if (i == 0) + newOption.toggleAttribute("selected", true); + newOptionSelecter.append(newOption); + }); + newOptionTitle.innerText = v.Name; + newOptionSelecter.classList.add("Contants"); + newOptionTitle.classList.add("Title"); + newOptionElement.classList.add("Option"); + newOptionElement.append(newOptionTitle, newOptionSelecter); + OptionDisplayer.append(newOptionElement); + }); + // 为选项添加点击事件 + Array.from(OptionDisplayer.children).forEach((v) => { + let contants = v.querySelector(".Contants"); + Array.from(contants.children).forEach((v) => { + v.addEventListener("click", function () { + return __awaiter(this, void 0, void 0, function* () { + Array.from(this.parentElement + .children).forEach((v) => { + v.removeAttribute("selected"); + }); + this.toggleAttribute("selected", true); + }); + }); + }); + }); +})); diff --git a/src/main/resources/static/scripts/items.js b/src/main/resources/static/scripts/items.js new file mode 100644 index 0000000..3f23a57 --- /dev/null +++ b/src/main/resources/static/scripts/items.js @@ -0,0 +1,71 @@ +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; + } + }); +} diff --git a/src/main/resources/static/scripts/lib/anime.min.js b/src/main/resources/static/scripts/lib/anime.min.js new file mode 100644 index 0000000..c399324 --- /dev/null +++ b/src/main/resources/static/scripts/lib/anime.min.js @@ -0,0 +1,33 @@ +/* + 2017 Julian Garnier + Released under the MIT license +*/ +var $jscomp={scope:{}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(e,r,p){if(p.get||p.set)throw new TypeError("ES3 does not support getters and setters.");e!=Array.prototype&&e!=Object.prototype&&(e[r]=p.value)};$jscomp.getGlobal=function(e){return"undefined"!=typeof window&&window===e?e:"undefined"!=typeof global&&null!=global?global:e};$jscomp.global=$jscomp.getGlobal(this);$jscomp.SYMBOL_PREFIX="jscomp_symbol_"; +$jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol)};$jscomp.symbolCounter_=0;$jscomp.Symbol=function(e){return $jscomp.SYMBOL_PREFIX+(e||"")+$jscomp.symbolCounter_++}; +$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();var e=$jscomp.global.Symbol.iterator;e||(e=$jscomp.global.Symbol.iterator=$jscomp.global.Symbol("iterator"));"function"!=typeof Array.prototype[e]&&$jscomp.defineProperty(Array.prototype,e,{configurable:!0,writable:!0,value:function(){return $jscomp.arrayIterator(this)}});$jscomp.initSymbolIterator=function(){}};$jscomp.arrayIterator=function(e){var r=0;return $jscomp.iteratorPrototype(function(){return rb&&(b+=1);1b?c:b<2/3?a+(c-a)*(2/3-b)*6:a}var d=/hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(a)||/hsla\((\d+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)/g.exec(a);a=parseInt(d[1])/360;var b=parseInt(d[2])/100,f=parseInt(d[3])/100,d=d[4]||1;if(0==b)f=b=a=f;else{var n=.5>f?f*(1+b):f+b-f*b,k=2*f-n,f=c(k,n,a+1/3),b=c(k,n,a);a=c(k,n,a-1/3)}return"rgba("+ +255*f+","+255*b+","+255*a+","+d+")"}function y(a){if(a=/([\+\-]?[0-9#\.]+)(%|px|pt|em|rem|in|cm|mm|ex|ch|pc|vw|vh|vmin|vmax|deg|rad|turn)?$/.exec(a))return a[2]}function V(a){if(-1=g.currentTime)for(var G=0;G=w||!k)g.began||(g.began=!0,f("begin")),f("run");if(q>n&&q=k&&r!==k||!k)b(k),x||e();f("update");a>=k&&(g.remaining?(t=h,"alternate"===g.direction&&(g.reversed=!g.reversed)):(g.pause(),g.completed||(g.completed=!0,f("complete"),"Promise"in window&&(p(),m=c()))),l=0)}a=void 0===a?{}:a;var h,t,l=0,p=null,m=c(),g=fa(a);g.reset=function(){var a=g.direction,c=g.loop;g.currentTime= +0;g.progress=0;g.paused=!0;g.began=!1;g.completed=!1;g.reversed="reverse"===a;g.remaining="alternate"===a&&1===c?2:c;b(0);for(a=g.children.length;a--;)g.children[a].reset()};g.tick=function(a){h=a;t||(t=h);k((l+h-t)*q.speed)};g.seek=function(a){k(d(a))};g.pause=function(){var a=v.indexOf(g);-1=c&&0<=b&&1>=b){var e=new Float32Array(11);if(c!==d||b!==f)for(var k=0;11>k;++k)e[k]=a(.1*k,c,b);return function(k){if(c===d&&b===f)return k;if(0===k)return 0;if(1===k)return 1;for(var h=0,l=1;10!==l&&e[l]<=k;++l)h+=.1;--l;var l=h+(k-e[l])/(e[l+1]-e[l])*.1,n=3*(1-3*b+3*c)*l*l+2*(3*b-6*c)*l+3*c;if(.001<=n){for(h=0;4>h;++h){n=3*(1-3*b+3*c)*l*l+2*(3*b-6*c)*l+3*c;if(0===n)break;var m=a(l,c,b)-k,l=l-m/n}k=l}else if(0=== +n)k=l;else{var l=h,h=h+.1,g=0;do m=l+(h-l)/2,n=a(m,c,b)-k,0++g);k=m}return a(k,d,f)}}}}(),Q=function(){function a(a,b){return 0===a||1===a?a:-Math.pow(2,10*(a-1))*Math.sin(2*(a-1-b/(2*Math.PI)*Math.asin(1))*Math.PI/b)}var c="Quad Cubic Quart Quint Sine Expo Circ Back Elastic".split(" "),d={In:[[.55,.085,.68,.53],[.55,.055,.675,.19],[.895,.03,.685,.22],[.755,.05,.855,.06],[.47,0,.745,.715],[.95,.05,.795,.035],[.6,.04,.98,.335],[.6,-.28,.735,.045],a],Out:[[.25, +.46,.45,.94],[.215,.61,.355,1],[.165,.84,.44,1],[.23,1,.32,1],[.39,.575,.565,1],[.19,1,.22,1],[.075,.82,.165,1],[.175,.885,.32,1.275],function(b,c){return 1-a(1-b,c)}],InOut:[[.455,.03,.515,.955],[.645,.045,.355,1],[.77,0,.175,1],[.86,0,.07,1],[.445,.05,.55,.95],[1,0,0,1],[.785,.135,.15,.86],[.68,-.55,.265,1.55],function(b,c){return.5>b?a(2*b,c)/2:1-a(-2*b+2,c)/2}]},b={linear:A(.25,.25,.75,.75)},f={},e;for(e in d)f.type=e,d[f.type].forEach(function(a){return function(d,f){b["ease"+a.type+c[f]]=h.fnc(d)? +d:A.apply($jscomp$this,d)}}(f)),f={type:f.type};return b}(),ha={css:function(a,c,d){return a.style[c]=d},attribute:function(a,c,d){return a.setAttribute(c,d)},object:function(a,c,d){return a[c]=d},transform:function(a,c,d,b,f){b[f]||(b[f]=[]);b[f].push(c+"("+d+")")}},v=[],B=0,ia=function(){function a(){B=requestAnimationFrame(c)}function c(c){var b=v.length;if(b){for(var d=0;db&&(c.duration=d.duration);c.children.push(d)});c.seek(0);c.reset();c.autoplay&&c.restart();return c};return c};q.random=function(a,c){return Math.floor(Math.random()*(c-a+1))+a};return q}); \ No newline at end of file diff --git a/src/main/resources/static/scripts/lib/explosion.min.js b/src/main/resources/static/scripts/lib/explosion.min.js new file mode 100644 index 0000000..cb967a5 --- /dev/null +++ b/src/main/resources/static/scripts/lib/explosion.min.js @@ -0,0 +1 @@ +"use strict";function updateCoords(e){pointerX=(e.clientX||e.touches[0].clientX)-canvasEl.getBoundingClientRect().left,pointerY=e.clientY||e.touches[0].clientY-canvasEl.getBoundingClientRect().top}function setParticuleDirection(e){var t=anime.random(0,360)*Math.PI/180,a=anime.random(50,180),n=[-1,1][anime.random(0,1)]*a;return{x:e.x+n*Math.cos(t),y:e.y+n*Math.sin(t)}}function createParticule(e,t){var a={};return a.x=e,a.y=t,a.color=colors[anime.random(0,colors.length-1)],a.radius=anime.random(16,32),a.endPos=setParticuleDirection(a),a.draw=function(){ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.fillStyle=a.color,ctx.fill()},a}function createCircle(e,t){var a={};return a.x=e,a.y=t,a.color="#F00",a.radius=.1,a.alpha=.5,a.lineWidth=6,a.draw=function(){ctx.globalAlpha=a.alpha,ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.lineWidth=a.lineWidth,ctx.strokeStyle=a.color,ctx.stroke(),ctx.globalAlpha=1},a}function renderParticule(e){for(var t=0;t { + v.style.display = ""; + }); + } + else { + topButtons.forEach((v) => { + v.style.display = "none"; + }); + } + }); +} +window.addEventListener("scroll", () => __awaiter(void 0, void 0, void 0, function* () { + lastScrollPosition = window.scrollY; + if (!ticking) { + window.requestAnimationFrame(() => __awaiter(void 0, void 0, void 0, function* () { + yield setDisplay(); + // 设置 flag + ticking = false; + })); + ticking = true; + } +})); +window.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () { + console.info("[Top] initializing"); + topButtons = Array.from(document.getElementsByClassName("TOP")); + topButtons.forEach((v) => { + v.addEventListener("click", () => __awaiter(void 0, void 0, void 0, function* () { + console.info("[Top] scrolling to top"); + window.scrollTo(window.innerWidth / 2, 0); + })); + }); + yield setDisplay(); + console.info("[Top] initialization completed"); +})); diff --git a/src/main/resources/static/styles/clock.css b/src/main/resources/static/styles/clock.css new file mode 100644 index 0000000..8359889 --- /dev/null +++ b/src/main/resources/static/styles/clock.css @@ -0,0 +1,14 @@ +@font-face { + font-family: "LcdD"; + src: url("../fonts/LcdD.ttf"); +} + +.CLOCK { + width: 140px; + color: rgb(0, 255, 90); + text-align: center; + font-family: "LcdD"; + border: 3px solid black; + border-radius: 5px; + background-color: rgba(0, 0, 0, 0.5); +} diff --git a/src/main/resources/static/styles/edit.css b/src/main/resources/static/styles/edit.css new file mode 100644 index 0000000..857a729 --- /dev/null +++ b/src/main/resources/static/styles/edit.css @@ -0,0 +1,92 @@ +@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: row; + width: 100%; + height: 500px; +} + +#Contents > .Editor { + flex: 4 0 0; + flex-direction: column; + justify-content: space-between; + width: auto; + margin: 5px; + padding: 5px; + background-color: rgba(0, 60, 130, 0.8); + border: 3px solid rgba(0, 120, 255, 0.8); + border-radius: 15px; +} + +#Contents > .Editor > .Title { + justify-content: space-between; +} + +#Contents > .Editor > .Result { + color: wheat; + border: 3px solid skyblue; + border-spacing: 0; + border-radius: 10px; +} + +#Contents > .Editor > .Result td { + white-space: nowrap; + border: 1px solid cornflowerblue; +} + +#Contents > .Editor > .Result > thead { + background-color: #044488; +} + +#Contents > .Editor > .Result > tbody { + background-color: #008080; +} + +#Contents > .Editor > .Pages > * { + color: wheat; + margin-right: 3px; + border: 3px solid skyblue; + border-radius: 10px; + background-color: cadetblue; +} + +#Contents > .Editor > .Pages > *:last-child { + margin-right: inherit; +} + +#Contents > .Editor > .Pages > span { + color: green; +} + +#Contents > .UserEditor { + flex: 1 0 0; + margin: 5px; + padding: 5px; + background-color: rgba(0, 60, 130, 0.8); + border: 3px solid rgba(0, 120, 255, 0.8); + border-radius: 15px; +} + +#Contents > .UserEditor > .Displayer { + border: 0px; +} + +@media (min-width: 1280px) { + #Contents { + width: 1280px; + } +} diff --git a/src/main/resources/static/styles/error.css b/src/main/resources/static/styles/error.css new file mode 100644 index 0000000..b0e4ccd --- /dev/null +++ b/src/main/resources/static/styles/error.css @@ -0,0 +1,60 @@ +@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%; + justify-content: center; + align-items: center; +} + +.ErrorInfo { + flex-direction: column; + width: 480px; + margin: 5px; + padding: 26px 48px; + background-color: rgba(0, 60, 130, 0.8); + border: 3px solid rgba(0, 120, 255, 0.8); + border-radius: 15px; +} + +.ErrorTitle, .ErrorMessage, .ErrorRedirectMessage { + margin-top: 10px; + margin-bottom: 10px; + color: wheat; + font-family: "Normal"; +} + +.ErrorTitle { + margin-top: 20px; + margin-bottom: 20px; + font-size: 32px; +} + +.ErrorRedirectButton { + margin: 20px 15px; + padding: 8px 0px; + border: 3px solid skyblue; + border-radius: 10px; + font-size: 18px; + background: aqua; +} + +@media (min-width: 640px) { + #Contents { + width: 640px; + } +} \ No newline at end of file diff --git a/src/main/resources/static/styles/footer.css b/src/main/resources/static/styles/footer.css new file mode 100644 index 0000000..c9379fb --- /dev/null +++ b/src/main/resources/static/styles/footer.css @@ -0,0 +1,44 @@ +#Footer { + display: flex; + flex-direction: row; + height: 150px; + width: 100%; + border-top: 2px solid #3bfeff; + background-image: linear-gradient(#489dff, #355ae8, #702CF5); +} + +#Footer[pined] { + position: fixed; + bottom: 0px; +} + +#Footer div { + display: flex; +} + +#Footer .Infos { + flex: 1 0; + flex-direction: column; + justify-content: space-evenly; + align-items: flex-start; + padding: 10px 50px 10px 50px; +} + +#Footer .Infos .Icon { + height: 80px; + width: 80px; +} + +#Footer .Contents { + flex-direction: column; + padding-left: 15px; + font-size: 8px; +} + +#Footer .Links { + flex: 1 0; + flex-direction: column; + justify-content: space-evenly; + align-items: flex-end; + padding: 10px 50px 10px 50px; +} diff --git a/src/main/resources/static/styles/form.css b/src/main/resources/static/styles/form.css new file mode 100644 index 0000000..4c301df --- /dev/null +++ b/src/main/resources/static/styles/form.css @@ -0,0 +1,49 @@ +.TabForm { + display: flex; + flex-direction: column; + justify-content: center; +} + +.TabForm > .TabTitle { + margin: 20px 0px; + font-weight: bold; + font-size: 32px; +} + +.TabForm > .TabFormItems { + flex-direction: column; +} + +.TabForm > .TabFormItems > .TabFormItem { + margin-top: 10px; + margin-bottom: 10px; +} + +.TabForm > .TabFormItems > .TabFormItem > .ItemName { + flex: 1 0 0; +} + +.TabForm > .TabFormItems > .TabFormItem > .ItemInput { + flex: 1 0 0; + margin-left: 20px; + border-radius: 10px; + border: 3px solid skyblue; +} + +.TabForm > .TabButtons > .TabButton { + flex: 1; + margin: 20px 15px; + padding: 8px 0px; + border: 3px solid skyblue; + border-radius: 10px; + font-size: 18px; + background: unset; +} + +.TabForm > .TabButtons > .TabButton[type="reset"] { + background: cornflowerblue; +} + +.TabForm > .TabButtons > .TabButton[type="submit"] { + background: aqua; +} diff --git a/src/main/resources/static/styles/header.css b/src/main/resources/static/styles/header.css new file mode 100644 index 0000000..f611d8f --- /dev/null +++ b/src/main/resources/static/styles/header.css @@ -0,0 +1,131 @@ +@font-face { + font-family: "SmileySans"; + src: url("../fonts/SmileySans-Oblique.otf.woff2") format("woff2"); +} + +@keyframes BackgroundBlur { + from { + border-radius: 0px; + background-color: rgba(0, 0, 0, 0); + } + + to { + border-radius: 8px; + background-color: rgba(0, 0, 0, 0.25); + } +} + +@keyframes BackgroundUnblur { + from { + border-radius: 8px; + background-color: rgba(0, 0, 0, 0.25); + } + + to { + border-radius: 0px; + background-color: rgba(0, 0, 0, 0); + } +} + +body[headerPined] { + padding-top: 58px; +} + +#Header { + display: flex; + height: 56px; + width: 100%; + flex-direction: row; + border-bottom: 2px solid #3bfeff; + background-image: linear-gradient(#355ae8, #489dff); +} + +#Header[pined] { + position: fixed; + top: 0px; +} + +#Header .List { + flex: 0 0 auto; + padding-left: 5px; + padding-right: 5px; + + display: flex; + justify-content: space-around; + align-items: center; + color: wheat; +} + +#Header .List .Text { + padding: 3px; + animation-duration: 0.3s; +} + +#Header .List .Text[blured] { + border-radius: 8px; + background-color: rgba(0, 0, 0, 0.25); +} + +#Header .Blank { + flex: 1 0 auto; +} + +#Header .Title { + padding-left: 15px; + padding-right: 15px; + font-size: 32px; + font-family: "SmileySans"; +} + +#Header .Link .Text { + font-size: 22px; +} + +#Header .Link[this] { + background-color: rgba(0, 0, 0, 0.1); +} + +#Header .Button .Text { + font-size: 18px; +} + +#Header .SearchBar { + flex-grow: 1; +} + +#Header .SearchBar .InputBar { + flex-grow: 1; + + height: 30px; + border: 2px solid #3bfeff; + border-radius: 15px; + background-image: linear-gradient(#489dff, #355ae8); + padding-left: 10px; + padding-right: 10px; +} + +#Header .Clock { + font-size: 16px; +} + +#Header .PinHeader .PIN { + padding: 10px; + height: 25px; + width: 25px; +} + +#Header .PinHeader .PIN { + animation-duration: 0.3s; + animation-name: BackgroundUnblur; + + border-radius: 0px; + background-color: rgba(0, 0, 0, 0); +} + +#Header .PinHeader .PIN[checked] { + animation-duration: 0.3s; + animation-name: BackgroundBlur; + + border-radius: 8px; + background-color: rgba(0, 0, 0, 0.25); +} diff --git a/src/main/resources/static/styles/index.css b/src/main/resources/static/styles/index.css new file mode 100644 index 0000000..d5670b2 --- /dev/null +++ b/src/main/resources/static/styles/index.css @@ -0,0 +1,267 @@ +@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"; + 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-color: rgba(0, 60, 130, 0.8); + background: unset; + border: unset; + font-family: "Normal"; + 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"; + 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"; +} + +.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: gray; + 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; + } +} diff --git a/src/main/resources/static/styles/item.css b/src/main/resources/static/styles/item.css new file mode 100644 index 0000000..ef2c564 --- /dev/null +++ b/src/main/resources/static/styles/item.css @@ -0,0 +1,141 @@ +@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%; +} + +.Item { + flex-direction: row; + width: auto; + border-radius: 15px; + margin: 5px; + padding: 15px; + background-color: rgba(0, 60, 130, 0.8); + border: 3px solid rgba(0, 120, 255, 0.8); +} + +.Item .Picture { + flex: 1 0; + justify-content: center; +} + +.Item .Picture img { + width: 400px; + height: 400px; +} + +.Item .Infos { + flex: 1 0; + margin: 10px; + flex-direction: column; + color: wheat; +} + +.Item .Infos > * { + margin: 10px 0px; +} + +.Item .Infos > .Title { + font-size: 30px; + font-weight: bold; + font-family: "Normal"; +} + +.Item .Infos .Description { + font-size: 20px; + font-family: "Normal"; +} + +.Item .Infos .Prices { + align-items: baseline; + font-family: "Normal"; +} + +.Item .Infos .Prices .VipPrice { + color: gold; + font-size: 20px; + font-weight: bold; +} + +.Item .Infos .Prices .Price { + color: red; + font-size: 20px; + font-weight: bold; +} + +.Item .Infos .Prices .Price[has_vip_price] { + color: gray; + font-size: 16px; + font-weight: lighter; + font-style: italic; + text-decoration: line-through; +} + +.Item .Infos .Options { + flex-direction: column; +} + +.Item .Infos .Options > .Option { + flex-direction: row; + margin: 5px 0px; + 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; + background: green; + font-size: 20px; +} + +.Item .Infos .Options > .Option .Contants { + flex-wrap: wrap; + align-items: stretch; +} + +.Item .Infos .Options > .Option .Contants .Option { + font-size: 18px; + padding: 0px 5px; + align-items: center; + background-color: #355ae8; +} + +.Item .Infos .Options > .Option .Contants .Option[selected] { + font-weight: bold; + background-color: #489dff; +} + +.Item .Infos .Buttons { + justify-content: space-evenly; + text-align: center; +} + +.Item .Infos .Buttons .Button { + width: 90px; + padding: 10px 30px; + border-radius: 15px; + background-color: darkgreen; +} + +@media (min-width: 1280px) { + #Contents { + width: 1280px; + } +} diff --git a/src/main/resources/static/styles/loading.css b/src/main/resources/static/styles/loading.css new file mode 100644 index 0000000..d45bef8 --- /dev/null +++ b/src/main/resources/static/styles/loading.css @@ -0,0 +1,65 @@ +@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; +} + +.Loading 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; +} + +.Loading div:nth-child(1) { + left: 0px; + animation-name: loading-zoom-in; +} + +.Loading div:nth-child(2) { + left: 0px; + animation-name: loading-move; +} + +.Loading div:nth-child(3) { + left: 24px; + animation-name: loading-move; +} + +.Loading div:nth-child(4) { + left: 48px; + animation-name: loading-zoom-out; +} diff --git a/src/main/resources/static/styles/remove.css b/src/main/resources/static/styles/remove.css new file mode 100644 index 0000000..6efcfdf --- /dev/null +++ b/src/main/resources/static/styles/remove.css @@ -0,0 +1,9 @@ +@font-face { + font-family: "Normal"; + src: url("../fonts/华文圆体-Regular.ttf") format("ttf"); +} + +h3, p { + font: "Normal"; + color: wheat; +} diff --git a/src/main/resources/static/styles/success.css b/src/main/resources/static/styles/success.css new file mode 100644 index 0000000..6d58562 --- /dev/null +++ b/src/main/resources/static/styles/success.css @@ -0,0 +1,9 @@ +@font-face { + font-family: "Normal"; + src: url("../fonts/华文圆体-Regular.ttf") format("ttf"); +} + +h2 { + font: "Normal"; + color: wheat; +} diff --git a/src/main/resources/static/styles/top.css b/src/main/resources/static/styles/top.css new file mode 100644 index 0000000..500ffd2 --- /dev/null +++ b/src/main/resources/static/styles/top.css @@ -0,0 +1,13 @@ +.TOP { + position: fixed; + right: 30px; + bottom: 30px; + height: 50px; + width: 50px; + border: 2px solid black; + border-radius: 30px; + background-position: center; + background-repeat: no-repeat; + background-color: rgba(0, 0, 0, 0.2); + background-image: url("../images/top.svg"); +} diff --git a/src/main/resources/static/styles/update.css b/src/main/resources/static/styles/update.css new file mode 100644 index 0000000..bc96dd9 --- /dev/null +++ b/src/main/resources/static/styles/update.css @@ -0,0 +1,27 @@ +h3, label { + color: wheat; +} + +form { + display: flex; + flex-direction: column; +} + +form > div { + margin-top: 5px; + margin-bottom: 5px; +} + +.i { + display: flex; + justify-content: space-between; +} + +.i > input, select { + width: 200px; +} + +.formButton { + display: flex; + flex-direction: column; +} diff --git a/src/main/resources/static/styles/user.css b/src/main/resources/static/styles/user.css new file mode 100644 index 0000000..6ad6d77 --- /dev/null +++ b/src/main/resources/static/styles/user.css @@ -0,0 +1,41 @@ +@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%; + justify-content: center; + align-items: center; +} + +.TabForm { + margin: 5px; + padding: 26px 48px; + background-color: rgba(0, 60, 130, 0.8); + border: 3px solid rgba(0, 120, 255, 0.8); + border-radius: 15px; +} + +.TabTitle, .TabFormItem > .ItemName { + color: wheat; + font-family: "Normal"; +} + +@media (min-width: 640px) { + #Contents { + width: 640px; + } +} \ No newline at end of file diff --git a/src/main/resources/templates/account.jsp b/src/main/resources/templates/account.jsp new file mode 100644 index 0000000..e734688 --- /dev/null +++ b/src/main/resources/templates/account.jsp @@ -0,0 +1,147 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="s" uri="/struts-tags" %> + + + + + + 账户 - 67购物网站 + + + + + + + + + + + + + + + + + + + + + +
+
+
账户
+ + " /> + +
+
+ + +
+ +
+ + " /> +
+ +
+ + +
+ +
+ + +
+ +
+ + " /> +
+ +
+ + " /> +
+ +
+ checked /> + + checked /> + + checked /> + +
+
+ +
+ +
+
+
+ + + + + +
+ +
+ +
+ + diff --git a/src/main/resources/templates/activity.jsp b/src/main/resources/templates/activity.jsp new file mode 100644 index 0000000..409216c --- /dev/null +++ b/src/main/resources/templates/activity.jsp @@ -0,0 +1,96 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="s" uri="/struts-tags" %> + + + + + + 活动 - 67购物网站 + + + + + + + + + + + + + + + + + + + + + +
此处由于时间不足,不完善,请见谅
+ + + + + +
+ +
+ +
+ + diff --git a/src/main/resources/templates/edit.jsp b/src/main/resources/templates/edit.jsp new file mode 100644 index 0000000..600b39b --- /dev/null +++ b/src/main/resources/templates/edit.jsp @@ -0,0 +1,163 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="s" uri="/struts-tags" %> + + + + + + + + + + 编辑 - 67购物网站 + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID用户名帐户创建时间最后登录时间年龄性别邮箱管理员操作
+ + +
+ +
+ 首页 + + + + + + ">第 + + + ">尾页 +
+
+ +
+ +
+
+ + + + + +
+ +
+ +
+ + diff --git a/src/main/resources/templates/error.jsp b/src/main/resources/templates/error.jsp new file mode 100644 index 0000000..8c72f70 --- /dev/null +++ b/src/main/resources/templates/error.jsp @@ -0,0 +1,109 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="s" uri="/struts-tags" %> + + + + + + + "> + + 出错啦! - 67购物网站 + + + + + + + + + + + + + + + + + + + + +
+
+
失败
+ +
原因:
+ + +
将在三秒后跳转至页面:
+ +
+
+
+ + + + + +
+ +
+ +
+ + diff --git a/src/main/resources/templates/footer.mustache b/src/main/resources/templates/footer.mustache index 691287b..713fbe7 100644 --- a/src/main/resources/templates/footer.mustache +++ b/src/main/resources/templates/footer.mustache @@ -1,2 +1,33 @@ + + + + +
+ +
+ +
+ \ No newline at end of file diff --git a/src/main/resources/templates/header.mustache b/src/main/resources/templates/header.mustache index 71e0b08..78da228 100644 --- a/src/main/resources/templates/header.mustache +++ b/src/main/resources/templates/header.mustache @@ -1,5 +1,58 @@ - + + - {{title}} + + 主页 - 67购物网站 + + + + + + + + + + + + + + + + - \ No newline at end of file + + + + diff --git a/src/main/resources/templates/index.jsp b/src/main/resources/templates/index.jsp new file mode 100644 index 0000000..1738c51 --- /dev/null +++ b/src/main/resources/templates/index.jsp @@ -0,0 +1,128 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="s" uri="/struts-tags" %> + + + + + + 主页 - 67购物网站 + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+
+ +
+
+
+ +
+
+ + +
+ + + +
+ + + + + +
+ +
+ +
+ + diff --git a/src/main/resources/templates/index.mustache b/src/main/resources/templates/index.mustache index f759f54..37faef7 100644 --- a/src/main/resources/templates/index.mustache +++ b/src/main/resources/templates/index.mustache @@ -1,5 +1,36 @@ {{> header}} -

{{title}}

+ +
+ +
+ +
+
+ +
+
+ +
+
+
+ +
+
+ + +
+ + + +
{{> footer}} \ No newline at end of file diff --git a/src/main/resources/templates/item.jsp b/src/main/resources/templates/item.jsp new file mode 100644 index 0000000..59cda37 --- /dev/null +++ b/src/main/resources/templates/item.jsp @@ -0,0 +1,129 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="s" uri="/struts-tags" %> + + + + + + 商品 - 67购物网站 + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+ +
+
+
数量
+
+
 1 
+
 2 
+
 3 
+
 4 
+
 5 
+
 6 
+
+
+
+
+ 立即购买 + 加入购物车 +
+
+
+
+ + + + + +
+ +
+ +
+ + diff --git a/src/main/resources/templates/login.jsp b/src/main/resources/templates/login.jsp new file mode 100644 index 0000000..17f2a69 --- /dev/null +++ b/src/main/resources/templates/login.jsp @@ -0,0 +1,116 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="s" uri="/struts-tags" %> + + + + + + 登录 - 67购物网站 + + + + + + + + + + + + + + + + + + + + + +
+
+
登录
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+ + + + + +
+ +
+ +
+ + diff --git a/src/main/resources/templates/register.jsp b/src/main/resources/templates/register.jsp new file mode 100644 index 0000000..fd90f7f --- /dev/null +++ b/src/main/resources/templates/register.jsp @@ -0,0 +1,141 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="s" uri="/struts-tags" %> + + + + + + 注册 - 67购物网站 + + + + + + + + + + + + + + + + + + + + + +
+
+
注册
+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + + + + + +
+
+ +
+ + +
+
+
+ + + + + +
+ +
+ +
+ + diff --git a/src/main/resources/templates/remove.jsp b/src/main/resources/templates/remove.jsp new file mode 100644 index 0000000..e097e2d --- /dev/null +++ b/src/main/resources/templates/remove.jsp @@ -0,0 +1,23 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="s" uri="/struts-tags" %> + + + + + 移除用户 - 67购物网站 + + + + + +
+ " /> + +

确定移除此用户?

+

用户名:

+ + +
+ + diff --git a/src/main/resources/templates/success.jsp b/src/main/resources/templates/success.jsp new file mode 100644 index 0000000..db5aed3 --- /dev/null +++ b/src/main/resources/templates/success.jsp @@ -0,0 +1,15 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> + + + + + 成功 - 67购物网站 + + + + + +

操作已完成!

+ + diff --git a/src/main/resources/templates/update.jsp b/src/main/resources/templates/update.jsp new file mode 100644 index 0000000..37b8225 --- /dev/null +++ b/src/main/resources/templates/update.jsp @@ -0,0 +1,27 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="s" uri="/struts-tags" %> + + + + + 更新用户 - 67购物网站 + + + + + +

更新此用户的信息

+
+
+
+
+
+
+
+
+
+ + + +