• 基于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/
                <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/
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </pluginRepository>
        </pluginRepositories>
    </project>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179

    前端登录页面

    <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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324

    源码下载

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

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

  • 相关阅读:
    华为AP升级操作记录
    RAII技术学习
    form表单组件与小程序前后端通信
    设计模式之访问者模式(下)
    485. 最大连续 1 的个数(javascript)485. Max Consecutive Ones
    [linux]信号处理:信号编码、基本API、自定义函数和集合操作的详解
    strcpy库函数初步实现到完美优化
    手把手带你开发你的第一个前端脚手架
    Qt·事件处理机制
    【Azure K8S | AKS】在不丢失文件/不影响POD运行的情况下增加PVC的大小
  • 原文地址:https://blog.csdn.net/m0_46108627/article/details/127995023