基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)

【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行!

博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、数据库、项目案例等相关知识点总结,感谢你的阅读和关注,希望我的博客能帮助到更多的人,分享获取新知,大家一起进步!

吾等采石之人,应怀大教堂之心,愿我们奔赴在各自的热爱里…

一、选题背景介绍

☕️

校园招聘管理系统:帮助企业招聘更好更优质的学生,帮助大学生更好的找工作

推荐理由:选题新颖,实用,基于SpringBoot+Vue的前后端分离项目

⚡️系统包含的技术

后端:SpringBoot(ssm)
前端:vue + element等
开发工具:IDEA
数据库:MySQL
JDK版本:jdk1.8

二、模块设计架构

  • 系统设计: 招聘端+管理端
  • 权限设计:有 管理员+用户+企业三种角色权限

招聘端:首页,招聘信息,求职者信息,友情链接,留言板,后台
管理,登录

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第1张图片

管理端:管理员功能截图如下

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第2张图片
管理端:分为 管理员+用户+企业 三种不同角色,每一种角色进入页面都不一样

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第3张图片

系统设计的类图

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第4张图片

用户登录时序图

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第5张图片
列表相关时序图

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第6张图片

如上时序图都可以用idea自动生成,节省时间和提高效率

手把手教学时序图:IDEA生成时序图和类图(案例超详解)


三、项目模块截图

备注:因为页面太多,本篇截取核心页面给大家展示

招聘端截图

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第7张图片

求职者信息

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第8张图片
留言板截图
基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第9张图片

个人中心页截图

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第10张图片

用户登录:

如下为求职者,及普通用户登录的相关页面
基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第11张图片
点击详情页,我们可以更新用户的信息等等

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第12张图片

企业登录

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第13张图片
新增招聘相关信息
基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第14张图片

管理员登录:系统管理员可以管理企业+普通用户

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第15张图片
企业管理
基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第16张图片

岗位管理

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第17张图片

学历管理
基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第18张图片

招聘信息管理

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第19张图片

求职者信息管理
基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第20张图片

本篇给大家分享相关系统的模块设计思路,欢迎留言沟通交流!


四、相关代码分享

文件上传的相关前端代码

<template>
  <div>
    <!-- 上传文件组件 -->
    <el-upload
      ref="upload"
      :action="getActionUrl"
      list-type="picture-card"
      :multiple="multiple"
      :limit="limit"
      :headers="myHeaders"
      :file-list="fileList"
      :on-exceed="handleExceed"
      :on-preview="handleUploadPreview"
      :on-remove="handleRemove"
      :on-success="handleUploadSuccess"
      :on-error="handleUploadErr"
      :before-upload="handleBeforeUpload"
    >
      <i class="el-icon-plus"></i>
      <div slot="tip" class="el-upload__tip" style="color:#838fa1;">{{tip}}</div>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible" size="tiny" append-to-body>
      <img width="100%" :src="dialogImageUrl" alt>
    </el-dialog>
  </div>
</template>
<script>
import storage from "@/utils/storage";
import base from "@/utils/base";
export default {
  data() {
    return {
      // 查看大图
      dialogVisible: false,
      // 查看大图
      dialogImageUrl: "",
      // 组件渲染图片的数组字段,有特殊格式要求
      fileList: [],
      fileUrlList: [],
      myHeaders:{}
    };
  },
  props: ["tip", "action", "limit", "multiple", "fileUrls"],
  mounted() {
    this.init();
    this.myHeaders= {
      'Token':storage.get("Token")
    }
  },
  watch: {
    fileUrls: function(val, oldVal) {
      //   console.log("new: %s, old: %s", val, oldVal);
      this.init();
    }
  },
  computed: {
    // 计算属性的 getter
    getActionUrl: function() {
      // return base.url + this.action + "?token=" + storage.get("token");
      return `/${this.$base.name}/` + this.action;
    }
  },
  methods: {
    // 初始化
    init() {
      //   console.log(this.fileUrls);
      if (this.fileUrls) {
        this.fileUrlList = this.fileUrls.split(",");
        let fileArray = [];
        this.fileUrlList.forEach(function(item, index) {
          var url = item;
          var name = index;
          var file = {
            name: name,
            url: url
          };
          fileArray.push(file);
        });
        this.setFileList(fileArray);
      }
    },
    handleBeforeUpload(file) {
	
    },
    // 上传文件成功后执行
    handleUploadSuccess(res, file, fileList) {
      if (res && res.code === 0) {
        fileList[fileList.length - 1]["url"] =
          this.$base.url + "upload/" + file.response.file;
        this.setFileList(fileList);
        this.$emit("change", this.fileUrlList.join(","));
      } else {
        this.$message.error(res.msg);
      }
    },
    // 图片上传失败
    handleUploadErr(err, file, fileList) {
      this.$message.error("文件上传失败");
    },
    // 移除图片
    handleRemove(file, fileList) {
      this.setFileList(fileList);
      this.$emit("change", this.fileUrlList.join(","));
    },
    // 查看大图
    handleUploadPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    // 限制图片数量
    handleExceed(files, fileList) {
      this.$message.warning(`最多上传${this.limit}张图片`);
    },
    // 重新对fileList进行赋值
    setFileList(fileList) {
      var fileArray = [];
      var fileUrlArray = [];
      // 有些图片不是公开的,所以需要携带token信息做权限校验
      var token = storage.get("token");
      fileList.forEach(function(item, index) {
        var url = item.url.split("?")[0];
        var name = item.name;
        var file = {
          name: name,
          url: url + "?token=" + token
        };
        fileArray.push(file);
        fileUrlArray.push(url);
      });
      this.fileList = fileArray;
      this.fileUrlList = fileUrlArray;
    }
  }
};
</script>
<style lang="scss" scoped>
</style>

文件上传后端代码


/**
 * 上传文件映射表
 */
@RestController
@RequestMapping("file")
@SuppressWarnings({"unchecked","rawtypes"})
public class FileController{
	@Autowired
    private ConfigService configService;
	/**
	 * 上传文件
	 */
	@RequestMapping("/upload")
	public R upload(@RequestParam("file") MultipartFile file,String type) throws Exception {
		if (file.isEmpty()) {
			throw new EIException("上传文件不能为空");
		}
		String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
		File path = new File(ResourceUtils.getURL("classpath:static").getPath());
		if(!path.exists()) {
		    path = new File("");
		}
		File upload = new File(path.getAbsolutePath(),"/upload/");
		if(!upload.exists()) {
		    upload.mkdirs();
		}
		String fileName = new Date().getTime()+"."+fileExt;
		File dest = new File(upload.getAbsolutePath()+"/"+fileName);
		file.transferTo(dest);
		if(StringUtils.isNotBlank(type) && type.equals("1")) {
			ConfigEntity configEntity = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "faceFile"));
			if(configEntity==null) {
				configEntity = new ConfigEntity();
				configEntity.setName("faceFile");
				configEntity.setValue(fileName);
			} else {
				configEntity.setValue(fileName);
			}
			configService.insertOrUpdate(configEntity);
		}
		return R.ok().put("file", fileName);
	}
	
	/**
	 * 下载文件
	 */
	@IgnoreAuth
	@RequestMapping("/download")
	public ResponseEntity<byte[]> download(@RequestParam String fileName) {
		try {
			File path = new File(ResourceUtils.getURL("classpath:static").getPath());
			if(!path.exists()) {
			    path = new File("");
			}
			File upload = new File(path.getAbsolutePath(),"/upload/");
			if(!upload.exists()) {
			    upload.mkdirs();
			}
			File file = new File(upload.getAbsolutePath()+"/"+fileName);
			if(file.exists()){
				HttpHeaders headers = new HttpHeaders();
			    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);    
			    headers.setContentDispositionFormData("attachment", fileName);    
			    return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return new ResponseEntity<byte[]>(HttpStatus.INTERNAL_SERVER_ERROR);
	}
	
}

登录功能相关代码

<template>
    <div>
        <img class="bg" src="@/assets/img/bg.jpg">
        <el-form :model="rulesForm" :rules="rules" ref="rulesForm" class="login-form">
            <h1 class="h1">校园招聘系统登录</h1>
            <el-form-item label="账号" prop="username">
                <el-input type="text" v-model="rulesForm.username"></el-input>
            </el-form-item>
            <el-form-item label="密码" prop="password">
                <el-input type="password" v-model="rulesForm.password"></el-input>
            </el-form-item>
            <el-form-item label="" prop="role">
                <el-radio v-for="item in menus" v-bind:key="item.roleName" v-model="rulesForm.role"
                          :label="item.roleName">{{item.roleName}}
                </el-radio>
            </el-form-item>
            <el-form-item label="">
                <a style="margin-right:10px" href="javascript:void(0)" @click="register('yonghu')">注册用户</a>
                <a style="margin-right:10px" href="javascript:void(0)" @click="register('qiyexinxi')">注册企业信息</a>
            </el-form-item>
            <el-button @click="login()" class="btn-login" type="primary">登录</el-button>
        </el-form>
    </div>
</template>
<script>
    import menu from '@/utils/menu'

    export default {
        data() {
            return {
                rulesForm: {
                    username: "",
                    password: "",
                    role: ""
                },
                menus: [],
                tableName: "",
                rules: {
                    username: [{required: true, message: "请输入账号", trigger: "blur"}],
                    password: [{required: true, message: "请输入密码", trigger: "blur"}],
                    role: [{required: true, message: "请选择角色", trigger: "blur"}]
                }
            };
        },
        mounted() {
            let menus = menu.list();
            this.menus = menus;
        },
        methods: {
            register(tableName) {
                this.$storage.set("loginTable", tableName);
                this.$router.push({path: '/register'})
            },
            // 登录
            login() {
                this.$refs["rulesForm"].validate(valid => {
                    let menus = this.menus;
                    for (let i = 0; i < menus.length; i++) {
                        if (menus[i].roleName == this.rulesForm.role) {
                            this.tableName = menus[i].tableName
                        }
                    }
                    if (valid) {
                        this.$http({
                            url: `${this.tableName}/login?username=${this.rulesForm.username}&password=${this.rulesForm.password}`,
                            method: "post"
                        }).then(({data}) => {
                            if (data && data.code === 0) {
                                this.$storage.set("Token", data.token);
                                this.$storage.set("role", this.rulesForm.role);
                                this.$storage.set("sessionTable", this.tableName);
                                this.$storage.set("adminName", this.rulesForm.username);
                                this.$router.replace({path: "/index/"});
                            } else {
                                this.$message.error(data.msg);
                            }
                        });
                    }
                });
            }
        }
    };
</script>
<style lang="scss" scoped>
</style>

登录成功的时候会将token,role,sessionTable,adminName相关信息放入到storage缓存中

基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)_第21张图片

有源码 有源码 有源码


五、毕设专栏介绍

☕️最近开设的专栏整理了很多优秀Java项目,详细的分享了设计思路,计算机毕业生可以参考学习数据库设计,论文写作,项目优化等,每一篇博文均整理了相关系统可以设计的具体模块,以及详细的业务讲解,祝大家学业进步!

Java项目精选:点击进入Java毕设专栏 关注走一波

分享的所有Java项目源码均包含(前端+后台+数据库),可做毕业设计课程设计

论文写作指南:计算机专业毕业论文写作指导(案例超详解)


非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞 关注❤️ 分享 留言thanks!!!

愿我们奔赴在各自的热爱里!

你可能感兴趣的