基于Spring Boot + Vue.js构建的前后端分离的学生社团管理系

系列文章目录

本项目是学生社团管理系统一个基于Spring Boot + Vue.js构建的一个前后端分离项目框架的后端项目代码部分。
前端是基于Vue+elementUI+bootstrap(仅活动展示页面)+axios 的开发框架。

前言

本项目是学生社团管理系统一个基于Spring Boot + Vue.js构建的一个前后端分离项目框架的后端项目代码部分。
前端是基于Vue+elementUI+bootstrap(仅活动展示页面)+axios 的开发框架。


功能

管理员功能
  1. 管理社团:增加新社团(设置社长)、修改社长、删除社团、社团活动管理(报名活动查询、结束活动查询、活动删除)、社团活动报名者的管理(查看、删除)
  2. 成员管理:成员信息管理(成员条件查询、删除)
  3. 社团申请:审批社团申请(同意、不同意)
  4. 活动审批:审批活动申请(同意、不同意)
  5. 个人信息修改:用户名、密码、电话号码、个性签名、性别
  6. 系统公告:修改系统公告
社长功能
  1. 社团报名:查看社团已有活动、报名社团
  2. 社长中心:社团成员管理(条件查询、删除)、审批成员申请社团(同意、不同意)
  3. 活动管理:活动管理(新增活动、活动报名通知展示、活动结束通知展示、活动名单(成员管理(审批通过、审批不通过、删除))、新增结束活动通知、报名结束)
  4. 我的中心:活动记录、我的社团(活动报名、社团公告)
  5. 个人信息修改:用户名、密码、电话号码、个性签名、性别
  6. 公告:系统公告、社团公告编辑
成员功能
  1. 社团成立:新增社团等待审批
  2. 社团报名:查看社团已有活动、报名社团、活动查询(报名活动、结束通知)
  3. 活动记录:活动信息(报名活动、结束通知)
  4. 我的社团:社团公告、社团活动(查看报名活动、查看结束通知、申请活动)
  5. 个人信息修改:用户名、密码、电话号码、个性签名、性别
  6. 系统公告查看
登录、注册功能

运行截图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、使用步骤

1.pom文件

代码如下(示例):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.edu.shu.xj</groupId>
    <artifactId>ser</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ser</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </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.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.0</version>
        </dependency>


        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.29</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.4</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>2.0.4</version>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
            <version>1.9.6</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>

        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.10.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>

        <!-- 验证码 -->
        <dependency>
            <groupId>com.github.axet</groupId>
            <artifactId>kaptcha</artifactId>
            <version>0.0.9</version>
        </dependency>

<!--        <dependency>-->
<!--            <groupId>org.thymeleaf.extras</groupId>-->
<!--            <artifactId>thymeleaf-extras-springsecurity5</artifactId>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-security</artifactId>-->
<!--        </dependency>-->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>aliyun</id>
            <name>aliyun</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <layout>default</layout>
            <releases>
                <enabled>true</enabled>
                <updatePolicy>never</updatePolicy>
            </releases>
            <snapshots>
                <enabled>true</enabled>
                <updatePolicy>never</updatePolicy>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>aliyun</id>
            <name>aliyun</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

前端登录页面

<template>
  <!--登录表单的容器-->
  <div class="login_container">
    <div class="video-container">
      <div :style="fixStyle" class="filter">
        <div class="title">
          <span>学生社团管理系统</span>
        </div>
        <!--登录区域-->
        <div class="login_box" style="margin-top: 50px">
          <!--头像-->
          <div class="avatar_box">
            <img src="../assets/img/timg.jpg">
          </div>
          <!--表单-->
          <el-form :model="loginForm" :rules="loginRules" ref="loginForm" label- width="0px" class="login_form">
            <el-form-item prop="number">
              <el-input v-model="loginForm.number" placeholder="请输入学号" prefix-icon="el-icon-user-solid"></el-input>
            </el-form-item>
            <el-form-item prop="password">
              <el-input type="password" v-model="loginForm.password" placeholder="请输入登录密码" prefix-icon="el-icon-lock"></el-input>
            </el-form-item>
            <el-form-item prop="verifyCode">
              <div class="verifyCode_box">
                <el-input v-model="loginForm.verifyCode" placeholder="请输入计算结果" prefix-icon="el-icon-mobile" class="verifyCode"></el-input>
                <img src="../assets/img/mskKPg.png" alt="" class="verifyCode_img">
              </div>
            </el-form-item>
            <el-form-item class="login_btn">
              <el-button type="warning" @click="back">返回</el-button>
              <el-button type="primary" @click="submitForm('loginForm')">登录</el-button>
              <el-button @click="resetForm('loginForm')">重置</el-button>
            </el-form-item>
          </el-form>
        </div>
      </div>
      <video :style="fixStyle" autoplay loop muted class="fillWidth" v-on:canplay="canplay">
        <source src="../assets/video/background.mp4" type="video/mp4"/>
        浏览器不支持 video 标签,建议升级浏览器。
      </video>
    </div>
  </div>
</template>

<script>

import { userLogin } from '@/api/user'
import { findLeaderAss } from '@/api/assData'

export default {
  name: 'Login',
  data () {
    return {
      loginForm: {
        number: '',
        password: '',
        verifyCode: ''
      },
      loginRules: {
        number: [
          { required: true, message: '请输入学号', trigger: 'blur' },
          { min: 4, max: 9, message: '学号格式不正确', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入登录密码', trigger: 'blur' },
          { min: 1, max: 16, message: '长度在 1 到 16 个字符', trigger: 'blur' }
        ],
        verifyCode: [
          { required: true, message: '请输入计算结果', trigger: 'blur' }
        ]
      },
      vedioCanPlay: false,
      fixStyle: ''
    }
  },
  mounted: function () {
    window.onresize = () => {
      const windowWidth = document.body.clientWidth
      const windowHeight = document.body.clientHeight
      const windowAspectRatio = windowHeight / windowWidth
      let videoWidth
      let videoHeight
      if (windowAspectRatio < 0.5625) {
        videoWidth = windowWidth
        videoHeight = videoWidth * 0.5625
        this.fixStyle = {
          height: windowWidth * 0.5625 + 'px',
          width: windowWidth + 'px',
          'margin-bottom': (windowHeight - videoHeight) / 2 + 'px',
          'margin-left': 'initial'
        }
      } else {
        videoHeight = windowHeight
        videoWidth = videoHeight / 0.5625
        this.fixStyle = {
          height: windowHeight + 'px',
          width: windowHeight / 0.5625 + 'px',
          'margin-left': (windowWidth - videoWidth) / 2 + 'px',
          'margin-bottom': 'initial'
        }
      }
    }
    window.onresize()
  },
  methods: {
    canplay () {
      this.vedioCanPlay = true
    },
    submitForm (loginForm) {
      // eslint-disable-next-line no-unused-expressions
      this.$refs[loginForm].validate(valid => {
        if (!valid) {
          this.$notify({
            message: '请完整输入',
            type: 'warning',
            duration: 1200
          })
          return false
        }
      })
      this.getuserLogin()
      // 获取admin的信息
    },
    back () {
      this.$router.push('/home')
    },
    resetForm (formName) {
      this.$refs[formName].resetFields()
    },
    async getLeaderAss () {
      const { data } = await findLeaderAss(this.$root.USER.id)
      this.$root.ASS.assId = data.data.ass.assId
      this.$root.ASS.assName = data.data.ass.assName
      this.$root.ASS.assPosition = data.data.ass.assPositon
      this.$root.ASS.assTeacher = data.data.ass.assTeacher
      this.$root.ASS.assCapital = data.data.ass.assCapital
      this.$root.ASS.assNotice = data.data.ass.assNotice
      console.log(data)
      console.log(this.$root.ASS.assId)
    },
    async getuserLogin () {
      const { data } = await userLogin(this.loginForm.number, this.loginForm.password)
      console.log(data)

      if (data.code === 3012) {
        this.$notify({
          title: '警告',
          message: data.message,
          type: 'warning',
          duration: 2000
        })
      } else if (data.code === 3018) {
        this.$notify({
          title: '警告',
          message: data.message,
          type: 'warning',
          duration: 2000
        })
      } else if (data.code === 20000) {
        this.$root.USER.id = data.data.user.userId
        this.$root.USER.name = data.data.user.userName
        this.$root.USER.pwd = data.data.user.userPwd
        this.$root.USER.trueName = data.data.user.userTrueName
        this.$root.USER.authority = data.data.user.userAuthority
        this.$root.USER.score = data.data.user.userScore
        this.$root.USER.number = data.data.user.userNumber
        this.$root.USER.gender = data.data.user.userGender
        this.$root.USER.position = data.data.user.userPosition
        this.$root.USER.phone = data.data.user.userPhone
        this.$root.USER.pic = data.data.user.userPic
        this.$root.USER.token = data.data.token
        this.$root.USER.signature = data.data.user.userSignature
        console.log(this.$root.USER.id)
        console.log(this.$root.USER.name)
        console.log(this.$root.USER.signature)
        // eslint-disable-next-line eqeqeq
        this.$notify({
          title: '成功',
          message: '登录成功',
          type: 'success',
          duration: 2000,
          onClose: () => {
            // eslint-disable-next-line eqeqeq
            if (this.$root.USER.authority == 0) {
              this.$router.push('/main')
              // eslint-disable-next-line eqeqeq
            } else if (this.$root.USER.authority == 1) {
              // 获取社长的社团信息
              this.getLeaderAss()
              this.$router.push('/main1')
            } else {
              this.$router.push('/main2')
            }
          }
        })
      }
    }

    // async getadminLogin () {
    //   // eslint-disable-next-line no-unused-vars
    //   const { data } = await adminLogin(this.loginForm.admin, this.loginForm.password)
    //   console.log(data)
    //   // eslint-disable-next-line no-undef
    //   this.$store.commit('getToken', data.data.token)
    //   this.$store.commit('getData', data.data.shop)
    //   console.log(this.$store.state.token)
    //   console.log(this.$store.state.data)
    //   if (data.code === 4001) {
    //     this.$message({
    //       message: '本管理员用户名不存在',
    //       type: 'warning',
    //       duration: 2000
    //     })
    //   } else if (data.code === 4002) {
    //     this.$message({
    //       message: '管理员用户名对应密码错误',
    //       type: 'warning',
    //       duration: 2000
    //     })
    //   } else if (data.code === 20000) {
    //     this.$message({
    //       message: '登录成功',
    //       type: 'success',
    //       duration: 2000,
    //       onClose: () => {
    //         this.$router.push('/main')
    //       }
    //     })
    //   }
    // }
  }
}
</script>

<style lang="less" scoped>

.title {
  color: dimgray;
  -webkit-text-stroke: 1px black;
  letter-spacing: 0.04em;
  background-color: #FFFFFF;
  font-size: 50px;
  font-weight: bold;
  text-shadow: 1px -1px black, 2px -2px white;
  text-align: center;
  opacity: 0.55;
}

.login_box {
  width: 450px;
  height: 380px;
  background-color: #FFFFFF;
  border-radius: 3px;
  position: absolute;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);

  .avatar_box{
    width: 130px;
    height: 130px;
    border: 1px solid #EEEEEE;
    border-radius: 50%;
    padding: 10px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    margin: -65px auto;
    background-color: #FFFFFF;

    img{
      width: 100%;
      height: 100%;
      border-radius: 50%;
      background-color: #EEEEEE;
    }
  }

  .login_form{
    position: absolute;
    bottom: 0px;
    width: 100%;
    padding: 0px 20px;
    box-sizing: border-box;

    .login_btn{
      display: flex;
      justify-content: flex-end;
    }

    .verifyCode_box{
      display: flex;
      .verifyCode{
        width: 70%;
        justify-content: left;
      }

      .verifyCode_img{
        width: 30%;
        height: 45px;
        justify-content: flex-end;
      }
    }
  }
}
.login_container{
  background: url(../assets/img/pic3.jpg) no-repeat;
  background-size: 100% 770px;
  overflow: hidden;
  height: 100%;
}

.home,
.video-container {
  position: relative;
  height: 100vh;
  overflow: hidden;
}
.video-container .filter {
  z-index: 1;
  position: absolute;
  background: rgba(0, 0, 0, 0.4);
  width: 100%;
}
</style>

源码下载

提示:这里对文章进行总结:

https://pan.baidu.com/s/1HdmGCmAMFIQu37NKvZU0Bw?pwd=3212
提取码:3212

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小阿七Eason

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值