一、前端
- 环境准备
我的node是10.15.1建议直接使用nvm管理node版本不合适随时切换 - 代码
gitee地址:https://gitee.com/yin-xin666/mySport.git 下载源码
在这里插入图片描述
#登录代码
<template>
<div class="login_container">
<div class="login_box">
<div class="avatar_box">
<!--头像-->
<img src="../assets/touxiang.png" alt />
</div>
<!--添加表单-->
<el-form
ref="loginFormRef"
:model="loginForm"
:rules="loginRules"
class="login_form"
label-width="0px"
>
<el-form-item prop="username">
<el-input v-model="loginForm.username" prefix-icon="iconfont icondenglu"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="loginForm.password" prefix-icon="iconfont iconmima" type="password"></el-input>
</el-form-item>
<el-form-item class="btns">
<el-button type="primary" @click="login">登录</el-button>
<el-button type="info" @click="resetLoginForm">重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
export default {
data() {
return {
loginForm: {
username: "admin",
password: "123456"
},
loginRules: {
username: [
{ required: true, message: "请输入用户名", trigger: "blur" },
{ min: 5, max: 8, message: "长度在 5 到 8 个字符", trigger: "blur" }
],
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ min: 6, max: 8, message: "密码为 6~8 位", trigger: "blur" }
]
}
};
},
methods: {
resetLoginForm() {
this.$refs.loginFormRef.resetFields();
},
login() {
this.$refs.loginFormRef.validate(async valid => {
if (!valid) return;
// 调用get请求
const {data :res} = await this.$http.post("login", this.loginForm);
if (res == "ok" ) {
window.sessionStorage.setItem('flag','ok'); // session 放置
this.$message.success("登陆成功!!!");
this.$router.push({ path: "/home"});
}else{
this.$message.error("登录失败!!!");
}
});
}
}
};
</script>
<style lang="less" scoped>
// 跟节点样式
.login_container {
background-color: #2b4b6b;
height: 100%;
}
// 登录框
.login_box {
width: 450px;
height: 300px;
background-color: #fff;
border-radius: 3px;// 圆角
position: absolute;// 绝对定位
left: 50%;
top: 50%;
transform: translate(-50%, -50%);// 根据自己位置 以自己为长度位移
// 头像框
.avatar_box {
width: 130px;
height: 130px;
border: 1px solid #eee;
border-radius: 50%; // 加圆角
padding: 10px;
box-shadow: 0 0 10px #ddd;// 盒子阴影
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
background-color: #0ee;
img {
width: 100%;
height: 100%;
border-radius: 50%; // 加圆角
background-color: #eee;
}
}
.btns {
display: flex;// 弹性布局
justify-content: flex-end; // 尾部对齐
}
.login_form {
position: absolute;
bottom: 0%;
width: 100%;
padding: 0 10px;
box-sizing: border-box;// 设置边框
}
}
</style>
#管理模块
<template>
<el-container class="home-container">
<!--头部布局-->
<el-header>
<div>
<img src="../assets/logo.png" alt class="logo_img" />
<span>运动管理平台</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="toggleCollapase">|||</div>
<!--侧边栏菜单区 unique-opened="true" 只保持一个菜单展开 router开启路由 active-text-color 颜色-->
<el-menu background-color="#545c64" text-color="#fff" active-text-color="#409eff" unique-opened :collapse="isCollapse"
:collapse-transition="false" :router="true" :default-active="activePath">
<el-submenu :index="item.id+''" v-for="item in menuList" :key="item.id">
<template slot="title">
<i :class="iconsObject[item.id]"></i>
<span>{{item.title}}</span>
</template>
<el-menu-item :index="it.path+''" v-for="it in item.slist" :key="it.id" @click="saveNavState(it.path+'')">
<template slot="title" >
<i :class="iconsObject[it.id]"></i>
<span>{{it.title}}</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: [],
iconsObject: {
'100':'iconfont iconguanliyuan',
'200':'iconfont iconsport',
'101':'iconfont icondenglu',
'102':'iconfont iconmima',
'103':'iconfont iconsport',
'104':'iconfont iconshangpin',
'201':'iconfont iconshu',
'202':'iconfont iconkaluli',
'203':'iconfont iconshiwu',
'204':'iconfont icondenglu',
'205':'iconfont icondenglu',
},
isCollapse:false,
// 被激活的连接
activePath:'',
}
},
// 类似onload
created() {
this.getMenuList();
this.activePath = window.sessionStorage.getItem('activePath');// 取出session里的访问路径
},
methods: {
logout() {
window.sessionStorage.clear();
this.$router.push("/login");
},
// 获取所有的导航菜单
async getMenuList(){
const {data:res} = await this.$http.get("menus");
console.log(res.data);
if( res.status != 200) return this.$message.error("操作失败!!!");
this.menuList = res.data;
},
// 切换菜单折叠与展开
toggleCollapase(){
this.isCollapse = !this.isCollapse;
},
// 保存二级菜单的路径
saveNavState(activePath){
window.sessionStorage.setItem('activePath',activePath);// 存放点击的二级菜单
this.activePath = activePath;// 给点击的菜单添加高亮
},
}
};
</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 { //左侧div加布局
display: flex;
align-items: center;
span {
margin-left: 15px;
}
}
}
.el-aside {
background-color: #333744;
.el-menu{
border-right: none;// 对其右边框
}
}
.el-main {
background-color: #eaedf1;
}
.home-container {
height: 100%;
}
.logo_img {
width: 20%;
height: 100%;
}
.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>
我就不一 一列出来了,下载下来的代码很纯净基本只有一个架子,这也提供给广大的开发用户快速开发。
二、后端
实体类
import java.util.List;
public class MainMenu {
private int id;
private String title;
private String path;
List<SubMenu> slist;
public MainMenu() {
}
public MainMenu(int id, String title, String path, List<SubMenu> slist) {
this.id = id;
this.title = title;
this.path = path;
this.slist = slist;
}
public int getId() {
return id;
}
public String getTitle() {
return title;
}
public String getPath() {
return path;
}
public List<SubMenu> getSlist() {
return slist;
}
public void setId(int id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setPath(String path) {
this.path = path;
}
public void setSlist(List<SubMenu> slist) {
this.slist = slist;
}
@Override
public String toString() {
return "MainMenu{" +
"id=" + id +
", title='" + title + '\'' +
", path='" + path + '\'' +
", slist=" + slist +
'}';
}
}
public class SubMenu {
private int id;
private String title;
private String path;
public SubMenu() {
}
public SubMenu(int id, String title, String path) {
this.id = id;
this.title = title;
this.path = path;
}
public int getId() {
return id;
}
public String getTitle() {
return title;
}
public String getPath() {
return path;
}
public void setId(int id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setPath(String path) {
this.path = path;
}
@Override
public String toString() {
return "SubMenu{" +
"id=" + id +
", title='" + title + '\'' +
", path='" + path + '\'' +
'}';
}
}
public class User {
private int id;
private String username;
private String password;
private String email;
private String role;
private boolean state;
public User() {
}
public int getId() {
return id;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public boolean isState() {
return state;
}
public String getEmail() {
return email;
}
public String getRole() {
return role;
}
public void setId(int id) {
this.id = id;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setEmail(String email) {
this.email = email;
}
public void setRole(String role) {
this.role = role;
}
public void setState(boolean state) {
this.state = state;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
", role='" + role + '\'' +
", state=" + state +
'}';
}
}
public class QueryInfo {
private String query;
private int pageNum=1;
private int pageSize=1;
public QueryInfo() {
}
public QueryInfo(String query, int pageNum, int pageSize) {
this.query = query;
this.pageNum = pageNum;
this.pageSize = pageSize;
}
public String getQuery() {
return query;
}
public int getPageNum() {
return pageNum;
}
public int getPageSize() {
return pageSize;
}
public void setQuery(String query) {
this.query = query;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
@Override
public String toString() {
return "QueryInfo{" +
"query='" + query + '\'' +
", pageNum=" + pageNum +
", pageSize=" + pageSize +
'}';
}
}
controller层
@RestController
public class LoginController {
@Autowired
UserDao userDao;
@CrossOrigin
@RequestMapping("/login")
public String userLogin(@RequestBody User user) {
System.out.println("User : " + user);
String str = "error";
int count = userDao.getUserByMassage(user.getUsername(), user.getPassword());
if (count > 0) {
str = "ok";
}
return str;
}
}
@RestController
public class MenuController {
@Autowired
MenuDao menuDao;
@CrossOrigin
@RequestMapping("/menus")
public String getAllMenus(){
HashMap<String, Object> data = new HashMap<>();
List<MainMenu> mainMenus = menuDao.getMainMenus();
data.put("data",mainMenus);
data.put("status",200);
String data_json = JSON.toJSONString(data);
System.out.println("成功访问!!!");
return data_json;
}
}
@RestController
public class UserConteroller {
@Autowired
UserDao userDao;
@CrossOrigin
@RequestMapping("/allUser")
public String getUserList(QueryInfo queryInfo){
System.out.println(queryInfo);
int numbers = userDao.getUserCounts("%"+queryInfo.getQuery()+"%");// 获取数据总数
int pageStart = (queryInfo.getPageNum()-1)*queryInfo.getPageSize();
List<User> users = userDao.getAllUser("%"+queryInfo.getQuery()+"%",pageStart,queryInfo.getPageSize());
HashMap<String, Object> res = new HashMap<>();
res.put("numbers",numbers);
res.put("data",users);
System.out.println("总条数:"+numbers);
String users_json = JSON.toJSONString(res);
return users_json;
}
@RequestMapping("/userState")
public String updateUserState(@RequestParam("id") Integer id,
@RequestParam("state") Boolean state){
int i = userDao.updateState(id, state);
System.out.println("用户编号:"+id);
System.out.println("用户状态:"+state);
String str = i >0?"success":"error";
return str;
}
@RequestMapping("/addUser")
public String addUser(@RequestBody User user){
System.out.println(user);
user.setRole("普通用户");
user.setState(false);
int i = userDao.addUser(user);
String str = i >0?"success":"error";
return str;
}
@RequestMapping("/getUpdate")
public String getUpdateUser(int id){
System.out.println("编号:"+id);
User updateUser = userDao.getUpdateUser(id);
String users_json = JSON.toJSONString(updateUser);
return users_json;
}
@RequestMapping("/editUser")
public String editUser(@RequestBody User user){
System.out.println(user);
int i = userDao.editUser(user);
String str = i >0?"success":"error";
return str;
}
@RequestMapping("/deleteUser")
public String deleteUser(int id){
System.out.println(id);
int i = userDao.deleteUser(id);
String str = i >0?"success":"error";
return str;
}
}
dao层
@Repository
public interface MenuDao {
public List<MainMenu> getMainMenus();
}
@Repository
public interface UserDao {
public int getUserByMassage(@Param("username") String username, @Param("password") String password);
public List<User> getAllUser(@Param("username") String username,@Param("pageStart") int pageStart, @Param("pageSize") int pageSize);
public int getUserCounts(@Param("username") String username);
public int updateState(Integer id, Boolean state);
public int addUser(User user);
public User getUpdateUser(int id);
public int editUser(User user);
public int deleteUser(int id);
}
util
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080", "null")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.maxAge(3600)
.allowCredentials(true);
}
}
启动类
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080", "null")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.maxAge(3600)
.allowCredentials(true);
}
}
mapper的xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.naughty.userlogin02.dao.MenuDao">
<!--映射实体-->
<resultMap id="menuMap" type="com.naughty.userlogin02.bean.MainMenu">
<id column="id" property="id"></id>
<result column="title" property="title"></result>
<result column="path" property="path"></result>
<collection property="slist" ofType="com.naughty.userlogin02.bean.SubMenu">
<result column="sid" property="id"></result>
<result column="stitle" property="title"></result>
<result column="spath" property="path"></result>
</collection>
</resultMap>
<select id="getMainMenus" resultMap="menuMap">
SELECT mm.*,sm.id as sid ,sm.title as stitle,sm.path as spath FROM mainmenu mm ,submenu sm WHERE mm.id = sm.mid;
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.naughty.userlogin02.dao.UserDao">
<select id="getUserByMassage" resultType="java.lang.Integer">
SELECT count(id) FROM easyUser
WHERE username=#{username} AND password=#{password}
</select>
<select id="getAllUser" resultType="com.naughty.userlogin02.bean.User">
SELECT * FROM easyUser
<if test="username !=null ">
WHERE username like #{username}
</if>
LIMIT #{pageStart},#{pageSize}
</select>
<select id="getUserCounts" resultType="java.lang.Integer">
SELECT count(*) FROM `easyUser`
<if test="username !=null ">
WHERE username like #{username}
</if>
</select>
<select id="getUpdateUser" resultType="com.naughty.userlogin02.bean.User">
SELECT * FROM easyUser WHERE id = #{id}
</select>
<update id="updateState">
UPDATE easyUser SET state = #{state} WHERE id = #{id}
</update>
<insert id="addUser">
INSERT INTO easyUser
(username,password,email,role,state)
VALUE
(#{username},#{password},#{email},#{role},#{state})
</insert>
<update id="editUser">
UPDATE easyUser SET username = #{username} , password = #{password} ,
email = #{email} WHERE id = #{id}
</update>
<delete id="deleteUser">
DELETE FROM easyUser WHERE id = #{id}
</delete>
</mapper>
# mysql
spring:
datasource:
#MySQL配置
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.200.200:3306/easyproject?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
username: root
password: xxxxxx
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.demo.model
server:
port: 9000
入库sql
/*
Navicat Premium Data Transfer
Source Server : 192.168.200.200
Source Server Type : MySQL
Source Server Version : 50717
Source Host : 192.168.200.200:3306
Source Schema : easyproject
Target Server Type : MySQL
Target Server Version : 50717
File Encoding : 65001
Date: 25/10/2022 10:13:39
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for easyUser
-- ----------------------------
DROP TABLE IF EXISTS `easyUser`;
CREATE TABLE `easyUser` (
`id` int(24) NOT NULL AUTO_INCREMENT COMMENT '主键',
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`role` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`state` tinyint(255) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of easyUser
-- ----------------------------
INSERT INTO `easyUser` VALUES (1, 'admin', '123456', '123@qq.com', '超级管理员', 1);
INSERT INTO `easyUser` VALUES (2, 'naughty', '888888', '456@qq.com', '普通管理员', 0);
INSERT INTO `easyUser` VALUES (3, 'flysky01', '987654', 'qwe@qq.com', '普通用户', 1);
INSERT INTO `easyUser` VALUES (4, 'anglybirds', '321654', 'aaaa@163.com', '普通用户', 0);
INSERT INTO `easyUser` VALUES (7, 'admin003', 'q123456', 'c@qq.com', '普通用户', 1);
INSERT INTO `easyUser` VALUES (8, 'admin005', '123456', 'cxz@qq.com', '普通用户', 0);
INSERT INTO `easyUser` VALUES (9, 'admin007', '123456', 'rty@qq.com', '普通用户', 0);
SET FOREIGN_KEY_CHECKS = 1;
/*
Navicat MySQL Data Transfer
Source Server : Testblog
Source Server Version : 50556
Source Host : localhost:3306
Source Database : easyproject
Target Server Type : MYSQL
Target Server Version : 50556
File Encoding : 65001
Date: 2020-05-27 14:48:51
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for mainmenu
-- ----------------------------
DROP TABLE IF EXISTS `mainmenu`;
CREATE TABLE `mainmenu` (
`id` int(50) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`path` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of mainmenu
-- ----------------------------
INSERT INTO `mainmenu` VALUES ('100', '权限管理', '/admin');
INSERT INTO `mainmenu` VALUES ('200', '运动平台', '/use');
/*
Navicat MySQL Data Transfer
Source Server : Testblog
Source Server Version : 50556
Source Host : localhost:3306
Source Database : easyproject
Target Server Type : MYSQL
Target Server Version : 50556
File Encoding : 65001
Date: 2020-05-27 14:48:58
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for submenu
-- ----------------------------
DROP TABLE IF EXISTS `submenu`;
CREATE TABLE `submenu` (
`id` int(50) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`path` varchar(255) NOT NULL,
`mid` int(50) NOT NULL,
PRIMARY KEY (`id`),
KEY `mid` (`mid`),
CONSTRAINT `submenu_ibfk_1` FOREIGN KEY (`mid`) REFERENCES `mainmenu` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=204 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of submenu
-- ----------------------------
INSERT INTO `submenu` VALUES ('101', '用户列表', '/user', '100');
INSERT INTO `submenu` VALUES ('102', '修改权限', '/rights', '100');
INSERT INTO `submenu` VALUES ('103', ' 运动模块', '/sport', '100');
INSERT INTO `submenu` VALUES ('104', '商品模块', '/goods', '100');
INSERT INTO `submenu` VALUES ('201', '运动科普', '/Introduction', '200');
INSERT INTO `submenu` VALUES ('202', '卡路里', '/calories', '200');
INSERT INTO `submenu` VALUES ('203', '营养配餐', '/food', '200');
pom文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
</dependencies>
项目代码都在最上方gitee代码仓库中托管拉下去导入数据库即可运行。