作者主页:编程指南针
作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、腾讯课堂常驻讲师
主要内容:Java项目、Python项目、前端项目、人工智能与大数据、简历模板、学习资料、面试题库、技术互助
收藏点赞不迷路 关注作者有好处
文末获取源码
项目编号:BS-XCX-021
一,环境介绍
语言环境:Java: jdk1.8
数据库:Mysql: mysql5.7
应用服务器:Tomcat: tomcat8.5.31
开发工具:IDEA或eclipse
前端开发技术:Uniapp生成微信小程序+vue+nodejs
后台开发技术:springboot+mybatisplus
二,项目简介
2.1 需求分析
本课题主要是要实现一个基于微信小程序的比赛编排管理系统,主要是为了方便于当下各类小型比赛的赛制活动安排,减少人力的投入,提升比赛管理系统效率。系统基于微信小程序开发,后台采用Java技术平台来完成服务接口和业务逻辑的开发处理。主要实现在小程序端的比赛信息展示,比赛的编排结果展示,体育新的展示,对比赛的点赞、评论、收藏和在线报名操作,以及个人中心管理功能。后台管理主要实现对于基本信息的管理,包含用户管理、赛事管理、赛事编排管理、体育新闻管理等相关数据管理模块。比赛管理的相关业务数据采用MySQL5.7来进行管理,程序整设计采用三层架构,完成一个前后端分离的比赛编排管理系统。系统整体设计功能完整,结构清晰,用户体验效果较好。
在对小型比赛自动编排系统进行开发时,首要任务就是对系统的需求进行分析,包含功能性需求分析和非功能性需求分析。系统最终实现的目标是,实现比赛赛事的信息化管理,通过计算机信息化来替代原来的人工操作,简化赛事管理和编排的工作量,提升工作效率。经过对举办过赛事的人群进行走访了解和调查分析,得出本系统主要两类用户,一个是小程序端用户,一类是后台管理员用户。
下面分别展示一下各个角色对应的用例图。
前端用户的主要功能如图1所示。
图1 前端用例图
后台管理用户主要的功能用例如图2所示。
图2 教师用例图
系统管理员的主要功能如下图3所示。
图3 管理员用例图
2.2 功能设计
微信小程序端的选手用户的业务功能模块根据以上的需求分析,主要包含以下几个业务模块,具体的功能展示如下图4所示功能结构图。
图4 选手功能模块
(1)注册登陆:小型比赛自动编排系统中的选手用户,需要注册后才可以登陆系统进行相关的业务操作。
(2)新闻浏览:选手用户可以在线进行新闻信息的浏览操作,并可以对新闻进行点赞和评论操作。
(3)公告浏览:可以在微信小程序端查看系统发布的平台公告信息。
(4)赛事浏览:可以查看系统管理员发布的比赛信息。
(5)赛事编排查看:可以查看平台对于举办的赛事编排的情况。
(6)在线报名:可以实现用户在线报名操作,用户进入赛事详情中查看时可以点击报名进行在线报名操作。
(7)在线互动:可以在赛事详情中进行点赞、收藏和评论等互动操作。
(8)个人中心:可以在个人中心处管理个人的信息、收藏的信息、个人报名的信息等。
管理员用户登陆赛事管理系统的后台主要进行一些基础数据的管理操作,包含用户管理、赛事管理、编排管理、新闻管理等模块,具体本用户角色的的业务功能模块如图5所示。
图5管理员功能模块
(1)用户管理:小型比赛自动编排系统中的选手用户,注册后的信息可以在后台由管理员进行相应的管理操作。
(2)管理员管理:可以在后台管理管理员用户信息。
(3)新闻管理:主要管理微信小程序端查看的体育新闻信息。
(4)新闻类型管理:主要是为方便用户分类查看新闻设置的分类信息。
(5)公告管理:系统的公告管理包含公告的增删改查,数据在微信小程序端可以看到。
(6)赛事管理:主要管理系统中安排的比赛赛事情况信息。
(7)赛事编排管理:赛事的编排操作由管理员在后台进行实现。
(8)报名管理:选择在前端进行的报名信息,可由管理员在后台进行相应的管理操作。
(9)比赛结果管理:主要对每场比赛的结果名次进行数据处理操作。
(10)轮播图管理:前端小程序展示的广告轮播图片,可以在后台由管理员进行管理操作。
2.3 数据库表结构设计
根据以上的逻辑结构的数据分析,可初步得到系统的基本数据架构,在和用户进行充分的沟通和修改后,最终确定了本系统中用的数据库表结构,下面展示一下小型比赛自动编排系统中具体的表结构信息。
(1)用户信息表:此表主要用来存储系统中参与管理的用户信息,包含管理员用户、教师用户、学生用户,不同的用户通过外键关联的身份信息来表示不同的身份,具体的表结构如下表1所示。
表1 用户信息表(users)
名称 |
类型 |
空 |
备注 |
user_id |
mediumint(8) |
否 |
用户ID:[0,8388607]用户获取其他与用户相关的数据 |
state |
smallint(1) |
否 |
账户状态:[0,10](1可用|2异常|3已冻结|4已注销) |
user_group |
varchar(32) |
是 |
所在用户组:[0,32767]决定用户身份和权限 |
login_time |
timestamp |
否 |
上次登录时间: |
phone |
varchar(11) |
是 |
手机号码:[0,11]用户的手机号码,用于找回密码时或登录时 |
phone_state |
smallint(1) |
否 |
手机认证:[0,1](0未认证|1审核中|2已认证) |
username |
varchar(16) |
否 |
用户名:[0,16]用户登录时所用的账户名称 |
nickname |
varchar(16) |
是 |
昵称:[0,16] |
password |
varchar(64) |
否 |
密码:[0,32]用户登录所需的密码,由6-16位数字或英文组成 |
|
varchar(64) |
是 |
邮箱:[0,64]用户的邮箱,用于找回密码时或登录时 |
email_state |
smallint(1) |
否 |
邮箱认证:[0,1](0未认证|1审核中|2已认证) |
avatar |
varchar(255) |
是 |
头像地址:[0,255] |
create_time |
timestamp |
否 |
创建时间: |
(2)用户身份信息表:此表主要用来存储系统中不同用户的角色身分信息,具体的表结构如下表2所示。
表2 用户信息表(users_group)
名称 |
类型 |
空 |
备注 |
group_id |
mediumint(8) unsigned |
否 |
用户组ID:[0,8388607] |
display |
smallint(4) unsigned |
否 |
显示顺序:[0,1000] |
name |
varchar(16) |
否 |
名称:[0,16] |
description |
varchar(255) |
是 |
描述:[0,255]描述该用户组的特点或权限范围 |
source_table |
varchar(255) |
是 |
来源表: |
source_field |
varchar(255) |
是 |
来源字段: |
source_id |
int(10) unsigned |
否 |
来源ID: |
register |
smallint(1) unsigned |
是 |
注册位置: |
create_time |
timestamp |
否 |
创建时间: |
update_time |
timestamp |
否 |
更新时间: |
(3)赛事信息表:此表主要用来存储系统中设计的比赛赛事信息,具体的表结构如下表3所示。
表3 赛事信息表(event)
名称 |
类型 |
空 |
备注 |
event_id |
int(11) |
否 |
比赛项目ID |
event |
varchar(64) |
是 |
比赛项目 |
project_code |
varchar(64) |
是 |
项目代号 |
competition_format |
varchar(64) |
是 |
比赛赛制 |
event_location |
varchar(64) |
是 |
赛事地点 |
competition_schedule |
date |
是 |
比赛日程 |
event_cover |
varchar(255) |
是 |
赛事封面 |
event_details |
text |
是 |
赛事详情 |
hits |
int(11) |
否 |
点击数 |
praise_len |
int(11) |
否 |
点赞数 |
recommend |
int(11) |
否 |
智能推荐 |
create_time |
datetime |
否 |
创建时间 |
update_time |
timestamp |
否 |
更新时间 |
(4)选手报名信息表:此表主要用来存储系统中选手报名比赛的信息,具体的表结构如下表4所示。
表4 比赛报名信息表(contestant_registration)
名称 |
类型 |
空 |
备注 |
contestant_registration_id |
int(11) |
否 |
选手报名ID |
event |
varchar(64) |
是 |
比赛项目 |
project_code |
varchar(64) |
是 |
项目代号 |
competition_format |
varchar(64) |
是 |
比赛赛制 |
event_location |
varchar(64) |
是 |
赛事地点 |
competition_schedule |
date |
是 |
比赛日程 |
player_user |
int(11) |
是 |
选手用户 |
player_name |
varchar(64) |
是 |
选手姓名 |
recommend |
int(11) |
否 |
智能推荐 |
create_time |
datetime |
否 |
创建时间 |
update_time |
timestamp |
否 |
更新时间 |
(5)赛事编排结果信息表:此表主要用来存储系统中对比赛赛事的编排信息,具体的表结构如下表5所示。
表5 比赛赛事编排信息表(arrange_results)
名称 |
类型 |
空 |
默认值 |
其他 |
备注 |
arrange_results_id |
int(11) |
否 |
<auto_increment> |
编排结果ID |
|
event |
varchar(64) |
是 |
<空> |
比赛项目 |
|
project_code |
varchar(64) |
是 |
<空> |
项目代号 |
|
competition_format |
varchar(64) |
是 |
<空> |
比赛赛制 |
|
player_user |
int(11) |
是 |
0 |
选手用户 |
|
player_name |
varchar(64) |
是 |
<空> |
选手姓名 |
|
arrange_results |
text |
是 |
编排结果 |
||
recommend |
int(11) |
否 |
0 |
智能推荐 |
|
create_time |
datetime |
否 |
<INSERT-TimeStamp> |
创建时间 |
|
update_time |
timestamp |
否 |
<INSERT-TimeStamp> |
更新时间 |
(6)比赛结果信息表:此表主要用来存储系统中各个场次的比赛结果信息,具体的表结构如下表6所示。
表6 比赛信息表(competition_results)
名称 |
类型 |
空 |
备注 |
competition_results_id |
int(11) |
否 |
比赛结果ID |
event |
varchar(64) |
是 |
比赛项目 |
project_code |
varchar(64) |
是 |
项目代号 |
competition_format |
varchar(64) |
是 |
比赛赛制 |
player_user |
int(11) |
是 |
选手用户 |
player_name |
varchar(64) |
是 |
选手姓名 |
ranking_of_contestants |
varchar(64) |
是 |
选手名次 |
number_of_victories |
int(11) |
是 |
胜利场数 |
number_of_failed_events |
int(11) |
是 |
失败场数 |
recommend |
int(11) |
否 |
智能推荐 |
create_time |
datetime |
否 |
创建时间 |
update_time |
timestamp |
否 |
更新时间 |
(7)新闻类型信息表:此表主要用来存储系统中存储的新闻类型信息,具体的表结构如下表7所示。
表7 新闻类型信息表(article_type)
名称 |
类型 |
空 |
备注 |
type_id |
smallint(5) unsigned |
否 |
分类ID:[0,10000] |
display |
smallint(4) unsigned |
否 |
显示顺序:[0,1000]决定分类显示的先后顺序 |
name |
varchar(16) |
否 |
分类名称:[2,16] |
father_id |
smallint(5) unsigned |
否 |
上级分类ID:[0,32767] |
description |
varchar(255) |
是 |
描述:[0,255]描述该分类的作用 |
icon |
text |
是 |
分类图标: |
url |
varchar(255) |
是 |
外链地址:[0,255]如果该分类是跳转到其他网站的情况下,就在该URL上设置 |
create_time |
timestamp |
否 |
创建时间: |
update_time |
timestamp |
否 |
更新时间: |
(8)新闻信息表:此表主要用来存储系统中添加的体育新闻相关信息,具体的表结构如下表8所示。
表8 新闻信息表(article)
名称 |
类型 |
空 |
备注 |
article_id |
mediumint(8) |
否 |
文章id:[0,8388607] |
title |
varchar(125) |
否 |
标题:[0,125]用于文章和html的title标签中 |
type |
varchar(64) |
否 |
文章分类:[0,1000]用来搜索指定类型的文章 |
hits |
int(10) |
否 |
点击数:[0,1000000000]访问这篇文章的人次 |
praise_len |
int(11) |
否 |
点赞数 |
create_time |
timestamp |
否 |
创建时间: |
update_time |
timestamp |
否 |
更新时间: |
source |
varchar(255) |
是 |
来源:[0,255]文章的出处 |
url |
varchar(255) |
是 |
来源地址:[0,255]用于跳转到发布该文章的网站 |
tag |
varchar(255) |
是 |
标签:[0,255]用于标注文章所属相关内容,多个标签用空格隔开 |
content |
longtext |
是 |
正文:文章的主体内容 |
img |
varchar(255) |
是 |
封面图 |
description |
text |
是 |
文章描述 |
(9)评论信息表:此表主要用来存储系统中用户对赛事的评论基本信息,具体的表结构如下表9所示。
表9 评论信息表(comment)
名称 |
类型 |
空 |
备注 |
comment_id |
int(11) |
否 |
评论ID: |
user_id |
int(11) |
否 |
评论人ID: |
reply_to_id |
int(11) |
否 |
回复评论ID:空为0 |
content |
longtext |
是 |
内容: |
nickname |
varchar(255) |
是 |
昵称: |
avatar |
varchar(255) |
是 |
头像地址:[0,255] |
create_time |
timestamp |
否 |
创建时间: |
update_time |
timestamp |
否 |
更新时间: |
source_table |
varchar(255) |
是 |
来源表: |
source_field |
varchar(255) |
是 |
来源字段: |
source_id |
int(10) unsigned |
否 |
来源ID: |
(10)收藏信息表:此表主要用来存储系统中用户对赛事的收藏基本信息,具体的表结构如下表10所示。
表10 收藏信息表(collect)
名称 |
类型 |
空 |
备注 |
collect_id |
int(10) unsigned |
否 |
收藏ID: |
user_id |
int(10) unsigned |
否 |
收藏人ID: |
source_table |
varchar(255) |
是 |
来源表: |
source_field |
varchar(255) |
是 |
来源字段: |
source_id |
int(10) unsigned |
否 |
来源ID: |
title |
varchar(255) |
是 |
标题: |
img |
varchar(255) |
是 |
封面: |
create_time |
timestamp |
否 |
创建时间: |
update_time |
timestamp |
否 |
更新时间: |
三,系统展示
用户注册登录
比赛赛事浏览
赛事编排
比赛结果
赛事资讯
后台管理功能模块
赛事管理
用户管理
比赛编排管理
选手报名管理
四,核心代码展示
package com.project.demo.controller.base;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.project.demo.service.base.BaseService;
import com.project.demo.utils.IdWorker;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*/
@Slf4j
public class BaseController<E, S extends BaseService<E>> {
@Setter
protected S service;
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
service.insert(service.readBody(request.getReader()));
return success(1);
}
@Transactional
public Map<String, Object> addMap(Map<String,Object> map){
service.insert(map);
return success(1);
}
@PostMapping("/set")
@Transactional
public Map<String, Object> set(HttpServletRequest request) throws IOException {
service.update(service.readQuery(request), service.readConfig(request), service.readBody(request.getReader()));
return success(1);
}
@RequestMapping(value = "/del")
@Transactional
public Map<String, Object> del(HttpServletRequest request) {
service.delete(service.readQuery(request), service.readConfig(request));
return success(1);
}
@RequestMapping("/get_obj")
public Map<String, Object> obj(HttpServletRequest request) {
List resultList = service.selectBaseList(service.select(service.readQuery(request), service.readConfig(request)));
if (resultList.size() > 0) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("obj",resultList.get(0));
return success(jsonObject);
} else {
return success(null);
}
}
@RequestMapping("/get_list")
public Map<String, Object> getList(HttpServletRequest request) {
Map<String, Object> map = service.selectToPage(service.readQuery(request), service.readConfig(request));
return success(map);
}
@RequestMapping("/list_group")
public Map<String, Object> listGroup(HttpServletRequest request) {
Map<String,Object> map = service.selectToList(service.readQuery(request), service.readConfig(request));
Map<String,Object> result = new HashMap<>();
result.put("result",map);
return result;
}
@RequestMapping("/bar_group")
public Map<String, Object> barGroup(HttpServletRequest request) {
Map<String, Object> map = service.selectBarGroup(service.readQuery(request), service.readConfig(request));
return success(map);
}
@RequestMapping(value = {"/count_group", "/count"})
public Map<String, Object> count(HttpServletRequest request) {
Integer value= service.selectSqlToInteger(service.groupCount(service.readQuery(request), service.readConfig(request)));
return success(value);
}
@RequestMapping(value = {"/sum_group", "/sum"})
public Map<String, Object> sum(HttpServletRequest request) {
Integer value = service.selectSqlToInteger(service.sum(service.readQuery(request), service.readConfig(request)));
return success(value);
}
@RequestMapping(value = {"/avg_group", "/avg"})
public Map<String, Object> avg(HttpServletRequest request) {
Integer value = service.selectSqlToInteger(service.avg(service.readQuery(request), service.readConfig(request)));
return success(value);
}
// @RequestMapping(value = {"/count_group", "/count"})
// public Map<String, Object> count(HttpServletRequest request) {
// Query count = service.count(service.readQuery(request), service.readConfig(request));
// return success(count.getResultList());
// }
//
// @RequestMapping(value = {"/sum_group", "/sum"})
// public Map<String, Object> sum(HttpServletRequest request) {
// Query count = service.sum(service.readQuery(request), service.readConfig(request));
// return success(count.getResultList());
// }
//
// @RequestMapping(value = {"/avg_group", "/avg"})
// public Map<String, Object> avg(HttpServletRequest request) {
// Query count = service.avg(service.readQuery(request), service.readConfig(request));
// return success(count.getResultList());
// }
@PostMapping("/upload")
public Map<String, Object> upload(@RequestParam(value = "file",required=false) MultipartFile file,HttpServletRequest request) {
log.info("进入方法");
if (file.isEmpty()) {
return error(30000, "没有选择文件");
}
try {
//判断有没路径,没有则创建
String filePath = request.getSession().getServletContext().getRealPath("\\") +"\\upload\\";
// String filePath = System.getProperty("user.dir") + "\\target\\classes\\static\\upload\\";
File targetDir = new File(filePath);
if (!targetDir.exists() && !targetDir.isDirectory()) {
if (targetDir.mkdirs()) {
log.info("创建目录成功");
} else {
log.error("创建目录失败");
}
}
// String path = ResourceUtils.getURL("classpath:").getPath() + "static/upload/";
// String filePath = path.replace('/', '\\').substring(1, path.length());
String fileName = file.getOriginalFilename();
int lastIndexOf = fileName.lastIndexOf(".");
//获取文件的后缀名 .jpg
String suffix = fileName.substring(lastIndexOf);
fileName = IdWorker.getId()+suffix;
File dest = new File(filePath + fileName);
log.info("文件路径:{}", dest.getPath());
log.info("文件名:{}", dest.getName());
file.transferTo(dest);
JSONObject jsonObject = new JSONObject();
jsonObject.put("url", "/api/upload/" + fileName);
return success(jsonObject);
} catch (IOException e) {
log.info("上传失败:{}", e.getMessage());
}
return error(30000, "上传失败");
}
// @PostMapping("/import_db")
// public Map<String, Object> importDb(@RequestParam("file") MultipartFile file) throws IOException {
// service.importDb(file);
// return success(1);
// }
//
// @RequestMapping("/export_db")
// public void exportDb(HttpServletRequest request, HttpServletResponse response) throws IOException {
// HSSFWorkbook sheets = service.exportDb(service.readQuery(request), service.readConfig(request));
// response.setContentType("application/octet-stream");
// response.setHeader("Content-disposition", "attachment;filename=employee.xls");
// response.flushBuffer();
// sheets.write(response.getOutputStream());
// sheets.close();
// }
public Map<String, Object> success(Object o) {
Map<String, Object> map = new HashMap<>();
if (o == null) {
map.put("result", null);
return map;
}
if (o instanceof List) {
if (((List) o).size() == 1) {
o = ((List) o).get(0);
map.put("result", o);
}else {
String jsonString = JSONObject.toJSONString(o);
JSONArray objects = service.covertArray(JSONObject.parseArray(jsonString));
map.put("result", objects);
}
} else if (o instanceof Integer || o instanceof String) {
map.put("result", o);
} else {
String jsonString = JSONObject.toJSONString(o);
JSONObject jsonObject = JSONObject.parseObject(jsonString);
JSONObject j = service.covertObject(jsonObject);
map.put("result", j);
}
return map;
}
public Map<String, Object> error(Integer code, String message) {
Map<String, Object> map = new HashMap<>();
map.put("error", new HashMap<String, Object>(4) {{
put("code", code);
put("message", message);
}});
return map;
}
}
五,相关作品展示
基于Java开发、Python开发、PHP开发、C#开发等相关语言开发的实战项目
基于Nodejs、Vue等前端技术开发的前端实战项目
基于微信小程序和安卓APP应用开发的相关作品
基于51单片机等嵌入式物联网开发应用
基于各类算法实现的AI智能应用
基于大数据实现的各类数据管理和推荐系统
文章来源:https://www.toymoban.com/news/detail-513009.html
文章来源地址https://www.toymoban.com/news/detail-513009.html
到了这里,关于uniapp小程序开发|基于微信小程序实现小型比赛自动编排系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!