博主介绍:硕士研究生,专注于Java技术领域开发与管理,以及毕业项目实战✌
从事基于java BS架构、CS架构、c/c++ 编程工作近16年,拥有近12年的管理工作经验,拥有较丰富的技术架构思想、较扎实的技术功底和资深的项目管理经验。
先后担任过技术总监、部门经理、项目经理、开发组长、java高级工程师及c++工程师等职位,在工业互联网、国家标识解析体系、物联网、分布式集群架构、大数据通道处理、接口开发、远程教育、办公OA、财务软件(工资、记账、决策、分析、报表统计等方面)、企业内部管理软件(ERP、CRM等)、arggis地图等信息化建设领域有较丰富的实战工作经验;拥有BS分布式架构集群、数据库负载集群架构、大数据存储集群架构,以及高并发分布式集群架构的设计、开发和部署实战经验;拥有大并发访问、大数据存储、即时消息等瓶颈解决方案和实战经验。
拥有产品研发和发明专利申请相关工作经验,完成发明专利构思、设计、编写、申请等工作,并获得发明专利1枚。
大家在毕设选题、项目升级、论文写作,就业毕业等相关问题都可以给我留言咨询,非常乐意帮助更多的人或加w 908925859。
相关博客地址:
csdn专业技术博客:https://blog.csdn.net/mr_lili_1986?type=blog
Iteye博客: https://www.iteye.com/blog/user/mr-lili-1986-163-com
一、前言介绍:
二、系统功能结构:
三、功能设计:
功能模块设计
数据需求分析
四、功能实现:
登录模块的实现
注册模块的实现
用户子系统模块的实现
个人资料模块
用户首页模块
评论模块
剧本资讯模块
购买信息模块
玩家拼团管理模块
管理员子系统模块的实现
用户管理模块
公告信息模块
剧本资讯模块
优质店铺模块
剧本信息管理模块
剧本拼团管理模块
五、论文参考:
一、前言介绍:
随着社会生活节奏的加快和工作压力的增加,人们对于休闲娱乐的需求也越来越高,剧本杀作为一种新颖的娱乐方式,满足了人们对于沉浸式体验的追求。互联网和社交媒体的兴起,使得剧本杀游戏从线下逐步转移到线上,为更广泛的玩家群体提供了便捷的参与方式。在不少95后00后的眼里,“剧本杀”已经成为“Z世代”们交友聚会的新潮流。当前,年轻人休闲娱乐较为依赖线上的形式,而剧本杀也打开了线上社交市场,加上用户付费意愿较高,市场发展前景可期。因此在现实运用中,应用软件的工作规则和开发步骤,采用Java技术建设剧本杀服务平台。
本设计主要实现集人性化、高效率、便捷等优点于一身的剧本杀服务平台,完成公告消息管理、剧本资讯、、系统用户、优质店铺、剧本信息、购买信息、剧本拼团、玩家拼团、剧本拼团信息、玩家拼团信息等功能模块。系统通过浏览器与服务器进行通信,实现数据的交互与变更。只需通过一台电脑,动动手指就可以操作系统,实现数据通信管理。整个系统的设计过程都充分考虑了数据的安全、稳定及可靠等问题,而且操作过程简单。本系统通过科学的管理方式、便捷的服务提高了工作效率,减少了数据存储上的错误和遗漏。
剧本杀服务平台使用Java语言,采用基于B/S架构的SpringBoot技术进行开发,使用 IDEA编译器编写,数据方面主要采用的是MySQL关系型数据库来作为数据存储媒介,配合MyBatis等技术完成系统的开发。
二、系统功能结构:
剧本杀服务平台总体分为前台用户模块和后台管理员模块。
两个模块表现上是分别独立存在,但是访问的数据库是一样的。每一个模块的功能都是根据先前完成的需求分析,并查阅相关资料后整理制作的。
综上所述,系统功能结构图如下图所示
三、功能设计:
功能模块设计
用户管理模块
该模块是为所有用户登录设计的,如用户这种普通用户登录后只能进行自己的普通功能操作(如个人信息修改),管理员和超级管理员登录后有不同的权限,管理员不能超越权限。超级管理员能对整个系统的数据进行管理,主要是用户的登录权限以及用户登录后在系统里的操作权限。
登录模块:登录模块是进入系统的入口,所有用户必须登录后才能访问系统。登录需要输入用户名和密码,如果多次尝试登录需要输入验证码。登录时需要选择用户的角色,是一般用户还是管理员登录等。登录成功后,会通过数据库获取用户的权限,并跳转至用户的主页面。
评论模块:评论模块促进用户对剧本信息进行点评,查看某个剧本信息已存在的评论,发表评论可以达到真实描述剧本信息的效果。
公告数据模块:可分为公告数据浏览、公告数据检索、公告数据维护三个模块,管理员对公告数据有维护的权限,发布新的公告数据、更新已有的公告数据等。
剧本资讯模块:可分为剧本资讯浏览、剧本资讯检索、剧本资讯维护三个模块,管理员对剧本资讯有维护的权限,发布新的剧本资讯、更新已有的剧本资讯等。
剧本信息管理模块:剧本信息管理分为剧本信息添加、修改和剧本信息发布。剧本信息由管理员进行修改、添加、删除操作;剧本拼团由管理员来发布。
优质店铺管理模块:优质店铺管理分为优质店铺添加、修改和优质店铺发布。优质店铺信息由管理员进行修改、添加、删除操作。
玩家拼团模块:注册的用户可以浏览剧本信息并进行评论、点赞收藏操作。通过剧本信息查看玩家拼团活动,可以进行拼团购买;玩家拼团由用户来发布
数据需求分析
从前面可以分析到数据库中最重要的是用户信息、评论信息、剧本资讯信息、公告信息、优质店铺信息、剧本信息、剧本拼团信息、玩家拼团信息。分析可以得到如下数据描述:
平台用户:用于记录用户的各种信息,包括用户名、密码、姓名、性别、地址、邮箱、联系方式等数据项。
管理员:记录管理员的登录信息。包括用户名,密码,权限等数据项。
评论:存储用户的评论。包括评论内容,评论的信息,评论人,时间等数据项。
公告数据:存储平台内的公告数据内容。包括标题,公告数据内容,时间等数据项。
剧本资讯:存储平台内的剧本资讯内容。包括标题,资讯内容,图片、封面等数据项。
优质店铺:存储平台内的优质店铺信息。包括店铺名称、店铺地址、人均价格、店铺描述、店铺简介等数据项。
剧本信息:存储平台内的剧本信息内容。包括剧本名称、剧本类型、剧本价格、剧本评分、剧本排行、剧本描述等数据项。
剧本拼团:存储平台内的剧本拼团信息。包括剧本名称、剧本类型、剧本价格、拼团人数、剩余人数、拼团须知等数据项。
玩家拼团:存储平台内的玩家拼团信息。包括剧本名称、剧本类型、剧本价格、店铺地址、发布用户、拼团人数、剩余人数、剧本简介等数据项。
四、功能实现:
登录模块的实现
系统的登录窗口是用户的入口,用户只有在登录成功后才可以进入访问。通过在登录提交表单,后台处理判断是否为合法用户,进行页面跳转,进入系统中去。
登录合法性判断过程:用户输入账号和密码后,系统首先确定输入输入数据合法性,然后在login.JSP页面发送登录请求,调用登录验证方法来验证。
用户登录模块的IPO如下所示:
输入:用户名和密码。
处理:
1)检测用户输入的账号、密码是否正确及在数据库已对应存在。
2)从数据库中提取记录,并储存在本地的session中(timeout默认=30min)。
3)根据用户名,将其显示在系统首页上。
输出:是否成功的信息。
系统登录界面如下所示。
注册模块的实现
用户在填写数据的时候必须与注册页面上的验证相匹配否则会注册失败,注册页面的表单验证是通过JavaScript进行验证的,用户名的长度必须在6到18之间,邮箱必须带有@符号,密码和密码确认必须相同,你输入的密码,系统会根据你输入密码的强度给出指定的值,电话号码和身份证号码必须要求输入格式与生活相符合,当你前台验证通过的时候你点击注册,表单会将你输入的值通过name值传递给后台并保存到数据库中。
用户注册流程图如下图所示。
用户注册界面如下图所示。
用户子系统模块的实现
个人资料模块
用户点击登录填写账号信息登录后,会切换内容为“某某用户欢迎您”和历史订单,并给出注销链接。当用户登录成功后会将个人信息保存在session作用域中,点击自己的用户名时,会跳转到个人详细信息页面,由后台通过Freemarker取出session作用域中的用户信息进行动态渲染,例如,邮箱、电话号码、用户名等等。同时页面上会显示修改个人信息和修改密码的按钮,这时客户可以修改自己的登录密码以保障账号的安全性,防止被人窃取账号,通过updatePassword()实现,同时也可以根据自己的个人信息是否变动做出相应的修改,通过updateUserInfo()实现。
密码修改界面如下所示。
用户首页模块
系统呈现出一种简洁大方的首页:界面简约、鳞次栉比,用户能轻车熟路的使用。出于对系统使用群体广泛的顾虑,应有良好性能的后台。
如下图所示为系统的首页界面。
评论模块
用户可以对剧本资讯、优质店铺做出评论。点击按钮之后会跳转至评论填写页面,填写评论提交之后,后台通过PinglunController的publish方法将相关信息保存到数据库系统。
评论添加界面如下图所示。
剧本资讯模块
用户查看剧本资讯,可以进行查询相应的剧本资讯信息操作。查找剧本资讯时,输入需要查找的剧本资讯名,调用getData方法获取所有数据并且进行分页,把获取到的所有数据显示到视图上,这时候只需要用脚本方法便能快速查找,不涉及对数据库操作。
剧本资讯展示界面如图所示。
购买信息模块
用户添加剧本购买信息,在Goumai_list查看购买信息,点击新增,跳转至Goumai_add.Java,添加购买信息记录则将添加的购买信息记录数据封装在HashMap中,然后调用CommDAO的insert方法将购买信息记录内容插入购买信息记录表中。
剧本信息详情界面如图所示。
购买信息提交界面如图所示。
玩家拼团管理模块
添加玩家拼团时,输入必填字段后,表现层的WanjiapintuanController接受传过来的玩家拼团参数,再调用WanjiapintuanController类的addWanjiapintuan方法,经过WanjiapintuanService业务层到WanjiapintuanMapper持久层的处理,完成对整个添加玩家拼团的操作。addWanjiapintuan方法也和用户管理中的addUser方法类似,同时做添加和修改工作。
修改玩家拼团时,选择需要修改的玩家拼团进行修改,调用WanjiapintuanController控制器的editWanjiapintuan方法,拿到该产品原本的信息并显示到页面,管理员再对需要修改的玩家拼团字段进行修改,完成后调用addWanjiapintuan方法,调用业务层的updateByKey方法,更新数据库的玩家拼团表的数据。
玩家拼团添加界面如下图所示。
管理员子系统模块的实现
用户管理模块
管理员在yhzhgl查看用户信息,先使用sql语句查询出所有用户表的数据,然后调用mysql_query($sql),返回一个数组对象,在for循环里,将数据放入页面模板中,添加用户则将添加的用户数据封装在sql语句,中然后调用mysql_query($sql)方法将用户内容插入用户表中。
用户管理界面如下图所示。
公告信息模块
公告信息添加过程中,首先使用getmap(id,"xinxi"),通过公告信息ID得到公告信息数据,将公告信息数据赋值给公告信息管理,调用CommDAO的insert方法将公告数据插入公告信息表中,最后查看个人历史公告信息记录,可以销毁历史公告信息数据。
公告信息添加流程图如下所示。
公告信息添加界面如图所示。
公告信息管理界面如图所示。
剧本资讯模块
剧本资讯信息添加过程中。首先使用getmap(id,"xinxi"),通过剧本资讯ID得到剧本资讯信息数据,将剧本资讯数据赋值给剧本资讯管理,调用CommDAO的insert方法将剧本资讯数据插入剧本资讯信息表中,最后查看个人历史剧本资讯信息记录,可以销毁历史剧本资讯信息数据。
剧本资讯添加界面如下图所示。
剧本资讯管理界面如图所示。
优质店铺模块
管理员点击左侧菜单“优质店铺”,页面跳转到优质店铺外观,调用后台查询所有优质店铺信息,显示优质店铺列表。并将信息密封到数据集合List,绑定到请求对象,然后页面跳转到相应的jsp,显示出优质店铺信息,单击删除按钮完成优质店铺的删除。
优质店铺添加界面如下图所示。
剧本信息管理模块
如果剧本数据的信息需要修改,管理员可以通过查询剧本数据的基本信息来查询剧本数据,查询剧本数据是通过ajax技术来进行查询的,需要传递剧本数据的标题、编号等参数然后在返回到该页面中,可以选中要修改或删除的那条信息,如果选中了超过一条数据,页面会挑一个窗口提醒只能选择一条数,如果没有选中数据会挑一个窗口题型必须选择一条数据。当选择确认修改的时候,后台会根据传过来的id到数据库查询,并将结果返回到修改页面中,可以在修改页面中修改刚刚选中的信息当点击确认的时候from表单会将修改的数据提交到后台并保存到数据库中,就是说如果提交的数据数据库中存在就修改,否则就保存。
剧本信息添加界面如下图所示。
剧本信息管理界面如下图所示。
剧本拼团管理模块
添加剧本拼团时,输入必填字段后,表现层的JubenpintuanController接受传过来的剧本拼团参数,再调用JubenpintuanController类的addJubenpintuan方法,经过JubenpintuanService业务层到JubenpintuanMapper持久层的处理,完成对整个添加剧本拼团的操作。addJubenpintuan方法也和用户管理中的addUser方法类似,同时做添加和修改工作。
修改剧本拼团时,选择需要修改的剧本拼团进行修改,调用JubenpintuanController控制器的editJubenpintuan方法,拿到该产品原本的信息并显示到页面,管理员再对需要修改的剧本拼团字段进行修改,完成后调用addJubenpintuan方法,调用业务层的updateByKey方法,更新数据库的剧本拼团表的数据。
剧本拼团添加界面如下图所示。
五、关键代码:
/**
* 用户账户:用于保存用户登录信息(User)表控制层
*/
@Slf4j
@RestController
@RequestMapping("user")
public class UserController extends BaseController<User, UserService> {
/**
* 服务对象
*/
@Autowired
public UserController(UserService service) {
setService(service);
}
/**
* Token服务
*/
@Autowired
private AccessTokenService tokenService;
@Autowired
private UserGroupService userGroupService;
/**
* 注册
* @param user
* @return
*/
@PostMapping("register")
public Map<String, Object> signUp(@RequestBody User user) {
// 查询用户
Map<String, String> query = new HashMap<>();
query.put("username",user.getUsername());
List list = service.select(query, new HashMap<>()).getResultList();
if (list.size()>0){
return error(30000, "用户已存在");
}
user.setUserId(null);
user.setPassword(service.encryption(user.getPassword()));
service.save(user);
return success(1);
}
/**
* 找回密码
* @param form
* @return
*/
@PostMapping("forget_password")
public Map<String, Object> forgetPassword(@RequestBody User form,HttpServletRequest request) {
JSONObject ret = new JSONObject();
String username = form.getUsername();
String code = form.getCode();
String password = form.getPassword();
// 判断条件
if(code == null || code.length() == 0){
return error(30000, "验证码不能为空");
}
if(username == null || username.length() == 0){
return error(30000, "用户名不能为空");
}
if(password == null || password.length() == 0){
return error(30000, "密码不能为空");
}
// 查询用户
Map<String, String> query = new HashMap<>();
query.put("username",username);
Query select = service.select(query, service.readConfig(request));
List list = select.getResultList();
if (list.size() > 0) {
User o = (User) list.get(0);
JSONObject query2 = new JSONObject();
JSONObject form2 = new JSONObject();
// 修改用户密码
query2.put("user_id",o.getUserId());
form2.put("password",service.encryption(password));
service.update(query, service.readConfig(request), form2);
return success(1);
}
return error(70000,"用户不存在");
}
/**
* 登录
* @param data
* @param httpServletRequest
* @return
*/
@PostMapping("login")
public Map<String, Object> login(@RequestBody Map<String, String> data, HttpServletRequest httpServletRequest) {
log.info("[执行登录接口]");
String username = data.get("username");
String email = data.get("email");
String phone = data.get("phone");
String password = data.get("password");
List resultList = null;
Map<String, String> map = new HashMap<>();
if(username != null && "".equals(username) == false){
map.put("username", username);
resultList = service.select(map, new HashMap<>()).getResultList();
}
else if(email != null && "".equals(email) == false){
map.put("email", email);
resultList = service.select(map, new HashMap<>()).getResultList();
}
else if(phone != null && "".equals(phone) == false){
map.put("phone", phone);
resultList = service.select(map, new HashMap<>()).getResultList();
}else{
return error(30000, "账号或密码不能为空");
}
if (resultList == null || password == null) {
return error(30000, "账号或密码不能为空");
}
//判断是否有这个用户
if (resultList.size()<=0){
return error(30000,"用户不存在");
}
User byUsername = (User) resultList.get(0);
Map<String, String> groupMap = new HashMap<>();
groupMap.put("name",byUsername.getUserGroup());
List groupList = userGroupService.select(groupMap, new HashMap<>()).getResultList();
if (groupList.size()<1){
return error(30000,"用户组不存在");
}
UserGroup userGroup = (UserGroup) groupList.get(0);
//查询用户审核状态
if (!StringUtils.isEmpty(userGroup.getSourceTable())){
String sql = "select examine_state from "+ userGroup.getSourceTable() +" WHERE user_id = " + byUsername.getUserId();
String res = String.valueOf(service.runCountSql(sql).getSingleResult());
if (res==null){
return error(30000,"用户不存在");
}
if (!res.equals("已通过")){
return error(30000,"该用户审核未通过");
}
}
//查询用户状态
if (byUsername.getState()!=1){
return error(30000,"用户非可用状态,不能登录");
}
String md5password = service.encryption(password);
if (byUsername.getPassword().equals(md5password)) {
// 存储Token到数据库
AccessToken accessToken = new AccessToken();
accessToken.setToken(UUID.randomUUID().toString().replaceAll("-", ""));
accessToken.setUser_id(byUsername.getUserId());
tokenService.save(accessToken);
// 返回用户信息
JSONObject user = JSONObject.parseObject(JSONObject.toJSONString(byUsername));
user.put("token", accessToken.getToken());
JSONObject ret = new JSONObject();
ret.put("obj",user);
return success(ret);
} else {
return error(30000, "账号或密码不正确");
}
}
/**
* 修改密码
* @param data
* @param request
* @return
*/
@PostMapping("change_password")
public Map<String, Object> change_password(@RequestBody Map<String, String> data, HttpServletRequest request){
// 根据Token获取UserId
String token = request.getHeader("x-auth-token");
Integer userId = tokenGetUserId(token);
// 根据UserId和旧密码获取用户
Map<String, String> query = new HashMap<>();
String o_password = data.get("o_password");
query.put("user_id" ,String.valueOf(userId));
query.put("password" ,service.encryption(o_password));
Query ret = service.count(query, service.readConfig(request));
List list = ret.getResultList();
Object s = list.get(0);
int count = Integer.parseInt(list.get(0).toString());
if(count > 0){
// 修改密码
Map<String,Object> form = new HashMap<>();
form.put("password",service.encryption(data.get("password")));
service.update(query,service.readConfig(request),form);
return success(1);
}
return error(10000,"密码修改失败!");
}
/**
* 登录态
* @param request
* @return
*/
@GetMapping("state")
public Map<String, Object> state(HttpServletRequest request) {
JSONObject ret = new JSONObject();
// 获取状态
String token = request.getHeader("x-auth-token");
// 根据登录态获取用户ID
Integer userId = tokenGetUserId(token);
log.info("[返回userId] {}",userId);
if(userId == null || userId == 0){
return error(10000,"用户未登录!");
}
// 根据用户ID获取用户
Map<String,String> query = new HashMap<>();
query.put("user_id" ,String.valueOf(userId));
// 根据用户ID获取
Query select = service.select(query,service.readConfig(request));
List resultList = select.getResultList();
if (resultList.size() > 0) {
JSONObject user = JSONObject.parseObject(JSONObject.toJSONString(resultList.get(0)));
user.put("token",token);
ret.put("obj",user);
return success(ret);
} else {
return error(10000,"用户未登录!");
}
}
/**
* 登录态
* @param request
* @return
*/
@GetMapping("quit")
public Map<String, Object> quit(HttpServletRequest request) {
String token = request.getHeader("x-auth-token");
JSONObject ret = new JSONObject();
Map<String, String> query = new HashMap<>(16);
query.put("token", token);
try{
tokenService.delete(query,service.readConfig(request));
}catch (Exception e){
e.printStackTrace();
}
return success("退出登录成功!");
}
/**
* 获取登录用户ID
* @param token
* @return
*/
public Integer tokenGetUserId(String token) {
log.info("[获取的token] {}",token);
// 根据登录态获取用户ID
if(token == null || "".equals(token)){
return 0;
}
Map<String, String> query = new HashMap<>(16);
query.put("token", token);
AccessToken byToken = tokenService.findOne(query);
if(byToken == null){
return 0;
}
return byToken.getUser_id();
}
/**
* 重写add
* @return
*/
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
Map<String,Object> map = service.readBody(request.getReader());
map.put("password",service.encryption(String.valueOf(map.get("password"))));
service.insert(map);
return success(1);
}
}
六、论文参考:
七、其他案例: