目录
一、项目介绍 3
(一)项目背景及概况 3
(二)所选技术栈 3
二、功能介绍 3
(一)登录功能 4
(二)管理员功能 5
(三)买家用户功能 8
三、系统功能实现 10
(一)登录模块实现 10
(二)商品管理模块实现 10
(三)秒杀模块实现 12
(四)前端页面实现 13
四、性能优化策略及实现 15
(一)Redis 缓存优化及实现 16
(二)消息队列优化及实现 18
五、应用安全策略及实现 20
(一)登录页面校验 20
(二)权限角色管理 21
(三)统一的异常处理和状态返回 21
六、总结与反思 22
一、项目介绍
(一)项目背景及概况
随着各大电商平台,如淘宝、京东等的普及,网上购物这一形式逐渐走进我们的生活,现如今,人们购物的方式已经逐渐由线下购买逐渐转向线上购买的模式,而线上购物也凭借其方便、快捷、价格相对低廉等优点更容易被消费者所接受。
而在一众网上购物的方式中,秒杀这种形式通常以特定时间内较低的商品价格来吸引消费者抢购,商家通常对商品价格、购买时间以及库存数量等方面进行限制,以达到制造噱头和盈利的目的。
结合日常网站运维的相关经验我们可以知道,在短时间内大量的消费订单必然会增加系统对流量的承受难度,并且由于用户购买行为的并发性,也给系统提出了更多和更严格的要求,如如何防止多买,超卖,如何设计一个能够支撑短时间内高并发的系统,并且优化系统以降低数据库的压力等,都是设计一个秒杀系统时必须要考虑的问题。
这学期我选修了《互联网软件开发》这门课程,在张齐勋老师的指导下也逐渐接触并掌握了一些网站开发和系统设计的相关知识,正好借助这次期末项目的作业将自己所学到的知识加以运用。
本次项目实现的是一个商品秒杀系统,功能分为管理员端和用户端,支持商品添加、下单、修改等常见的商品售卖功能,并使用消息队列以及 Reddis 缓存实现高并发,并一定程度上减轻数据库压力,本文转载自http://www.biyezuopin.vip/onews.asp?id=14867并搭建了风格统一的前端页面以便管理和查看各类信息。
(二)所选技术栈
本次项目所选用的技术栈是目前比较流行的一些框架,具体来说:
开发语言:Java
后端:SpringBoot 框架搭建 MVC 框架
前端:Vue 框架 + Element UI 组件开发
数据库:MySQL + Redis 框架 + MyBatis 管理
消息队列:Apache RocketMQ
<template>
<el-container style="height:100vh">
<el-header>
<div>
<img src="../assets/logo.png" alt />
<span>t宝秒杀系统_LKT</span>
</div>
<el-button type="info" @click="logout">退出</el-button>
</el-header>
<el-container>
<el-aside :width="isCollapse ? '64px' : '200px'">
<div class="toggle-button" @click="toggleCollapse">|||</div>
<el-menu
router
background-color="#333744"
text-color="#fff"
active-text-color="#409EFF"
unique-opened
:collapse="isCollapse"
:collapse-transition="false"
:default-active="$route.path"
>
<el-submenu :index="item.id+''" v-for="item in menulist" :key="item.id">
<template slot="title">
<i :class="iconObj[item.id]"></i>
<span>{{item.authName}}</span>
</template>
<el-menu-item :index="'/'+subItem.path" v-for="subItem in item.children" :key="subItem.id">
<template slot="title">
<i class="el-icon-menu"></i>
<span>{{subItem.authName}}</span>
</template>
</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</template>
<script>
export default {
data() {
return {
menulist: [],
userMenulist: [
{"id":0,"authName":"个人信息","path":"","children":[{"id":100,"authName":"我的信息","path":"user","children":[],"order":null}, {"id":104,"authName":"历史订单","path":"orders","children":[],"order":null}],"order":1},
{"id":5,"authName":"秒杀商城","path":"","children":[{"id":105,"authName":"商品列表","path":"goods/show","children":[],"order":null}],"order":2},
],
administartorMenulist: [
{"id":0,"authName":"个人信息","path":"","children":[{"id":100,"authName":"我的信息","path":"user","children":[],"order":null}],"order":0},
{"id":1,"authName":"用户管理","path":"","children":[{"id":101,"authName":"用户列表","path":"users/list","children":[],"order":null}],"order":1},
{"id":2,"authName":"商品管理","path":"","children":[{"id":102,"authName":"商品列表","path":"goods","children":[],"order":null}],"order":2},
{"id":3,"authName":"订单管理","path":"","children":[{"id":103,"authName":"订单列表","path":"orders/list","children":[],"order":null},],"order":3},
{"id":4,"authName":"活动管理","path":"","children":[{"id":104,"authName":"活动列表","path":"promos","children":[],"order":null},],"order":4},
],
iconObj: {
"125": "iconfont icon-icon_user",
"103": "iconfont icon-tijikongjian",
"101": "iconfont icon-shangpin",
"102": "iconfont icon-danju",
"145": "iconfont icon-baobiao"
},
isCollapse: false,
};
},
methods: {
logout() {
window.sessionStorage.clear;
this.$router.push("/login");
},
async getMenuList() {
let params = new URLSearchParams();
params.append("token", window.sessionStorage.getItem("token"))
const { data:res } = await this.$http.post("/user/currentUser", params);
if (res.status === "success") {
var role = res.data.role;
if(role == "用户"){
this.menulist = this.userMenulist;
}
else if(role == "管理员") {
this.menulist = this.administartorMenulist;
}
} else {
this.$message({
type: "error",
message: res.msg
});
}
},
toggleCollapse() {
this.isCollapse = !this.isCollapse;
}
},
created() {
this.getMenuList();
}
};
</script>
<style lang="less" scoped>
.el-header {
background-color: #373d41;
display: flex;
justify-content: space-between;
padding-left: 0;
align-items: center;
color: #fff;
font-size: 20px;
> div {
display: flex;
align-items: center;
span {
margin-left: 15px;
}
}
img {
width: 50px;
height: 50px;
}
}
.el-aside {
background-color: #333744;
.el-menu {
border-right: none;
}
}
.el-main {
background-color: #eaedf1;
}
.iconfont {
margin-right: 10px;
}
.toggle-button {
background-color: #4a5064;
font-size: 10px;
line-height: 24px;
color: #fff;
text-align: center;
letter-spacing: 0.2em;
cursor: pointer;
}
</style>
保持更新