免费分享一套SpringBoot+Vue员工管理(职工管理,考勤管理,奖惩管理,合同管理)管理系统【论文+源码+SQL脚本】,帅呆了~~

news2024/11/17 23:46:14

大家好,我是java1234_小锋老师,看到一个不错的SpringBoot+Vue员工管理(职工管理,考勤管理,奖惩管理,合同管理)管理系统,分享下哈。

项目视频演示

【免费】SpringBoot+Vue员工管理(职工管理,考勤管理,奖惩管理,合同管理)管理系统 Java毕业设计_哔哩哔哩_bilibili

项目介绍

在数字化转型的浪潮中,员工业正积极采用先进的信息技术来优化客户体验和运营效率。本研究旨在开发一款基于Spring Boot后端框架和Vue.js前端框架的员工客房预订管理系统,以满足现代员工对高效、便捷、安全的预订管理需求。

系统采用Spring Boot作为后端技术栈的核心,负责处理业务逻辑、数据存储与安全控制。数据库采用关系型数据库MySQL,以确保数据的一致性和事务性。此外,使用Redis作为缓存层,提高数据读取速度,减少数据库压力。

前端界面采用Vue.js构建,提供直观、响应式的用户界面,包括客房查询、预订、取消、支付等功能。通过Axios与后端API进行交互,实现动态数据展示和实时更新。系统还集成了地图服务API,为用户提供员工位置信息及周边设施详情,增强用户体验。

安全性方面,系统采用JWT(JSON Web Token)进行身份验证,确保通信过程中的数据安全。

本系统的实施不仅提升了员工的预订管理效率,也极大地改善了顾客的在线预订体验。通过性能测试和用户反馈,证明了该系统在响应时间、易用性和安全性方面的优越性,为员工业提供了有力的技术支撑,推动了行业的数字化进程。

系统展示

部分代码

package com.rabbiter.staff.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rabbiter.staff.entity.Role;
import com.rabbiter.staff.entity.User;
import com.rabbiter.staff.entity.vo.UserInfoVo;
import com.rabbiter.staff.entity.vo.UserVo;
import com.rabbiter.staff.service.RoleService;
import com.rabbiter.staff.service.UserService;
import com.rabbiter.staff.utils.JwtUtils;
import com.rabbiter.staff.utils.MD5;
import com.rabbiter.staff.utils.R;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 */
@RestController
@RequestMapping("/staff/user")
@CrossOrigin
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @PostMapping("/login")
    public R login(@RequestBody UserVo userVo) {
        String token = userService.login(userVo);
        try {
            if (!StringUtils.isEmpty(token)) {
                return R.ok().data("token",token);
            } else {
                return R.error().message("用户名和密码不匹配");
            }
        } catch (Exception e){
            e.printStackTrace();
        }
        return R.error().message("用户名和密码不匹配");
    }
    
    @GetMapping("/info")
    public R info(@RequestParam("token") String token){
        //验证token是否合法
        String userId = JwtUtils.getMemberIdByToken(token);
        User byId = userService.getById(userId);
        UserInfoVo userInfoVo = new UserInfoVo();
        if (!StringUtils.isEmpty(byId)) {
            QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("userid",byId.getId());
            List<Role> list = roleService.list(queryWrapper);

            BeanUtils.copyProperties(byId,userInfoVo);
            List<String> roles = new ArrayList<>();
            for (Role role:list) {

                roles.add(role.getName());
            }
            userInfoVo.setRoles(roles);
            return R.ok().data("roles",roles).data("introduction",userInfoVo.getIntroduction()).data("avatar",userInfoVo.getAvatar()).data("name",userInfoVo.getName());
        } else {
            return R.error().message("请先登录");
        }
    }

    @PostMapping("/logout")
    public R logout(@RequestHeader("X-Token") String token) {
        boolean b = JwtUtils.checkToken(token);
        if (b){
            String id = JwtUtils.getMemberIdByToken(token);
            //移除redis中的标记
            return R.ok();
        }
        return R.error();
    }
    //修改信息
    //5.修改
    @PutMapping
    public R updateClerk(@RequestBody User user){
        boolean updateById = userService.updateById(user);
        if (updateById){
            return R.ok().message("修改成功");
        }
        return R.error().message("修改失败");
    }
    //查询自身密码是否与输入的相同
    @PostMapping("getPassword/{password}")
    public R getPassword(@RequestHeader("X-Token") String token,@PathVariable String password) {
        String id = JwtUtils.getMemberIdByToken(token);
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("id",id);
        userQueryWrapper.eq("password",MD5.encrypt(password));
        long count = userService.count(userQueryWrapper);
        if (count > 0){
            return R.ok();
        }
        return R.error().message("密码错误,请重新输入!");
    }
    //修改密码
    @PutMapping("putPassword/{newPassword}")
    public R putPassword(@PathVariable String newPassword,@RequestHeader("X-Token") String token) {
        String id = JwtUtils.getMemberIdByToken(token);
        User user = new User();
        user.setPassword(MD5.encrypt(newPassword));
        user.setId(id);
        userService.updateById(user);
        return R.ok();
    }
}

<template>
    <div class="login-container">
        <el-form
            ref="loginForm"
            :model="loginForm"
            :rules="loginRules"
            class="login-form"
            autocomplete="on"
            label-position="left"
        >
            <div class="title-container">
                <h3 class="title">职工管理系统</h3>
            </div>

            <el-form-item prop="username">
                <span class="svg-container">
                    <i
                        class="iconfont icon-r-user1"
                        style="font-size: 22px"
                    ></i>
                </span>
                <el-input
                    ref="username"
                    v-model="loginForm.username"
                    placeholder="用户名"
                    name="username"
                    type="text"
                    tabindex="1"
                />
            </el-form-item>

            <el-tooltip
                v-model="capsTooltip"
                content="Caps lock is On"
                placement="right"
                manual
            >
                <el-form-item prop="password">
                    <span class="svg-container">
                        <i
                            class="iconfont icon-r-lock"
                            style="font-size: 22px"
                        ></i>
                    </span>
                    <el-input
                        :key="passwordType"
                        ref="password"
                        v-model="loginForm.password"
                        :type="passwordType"
                        placeholder="密码"
                        name="password"
                        tabindex="2"
                        @keyup.native="checkCapslock"
                        @blur="capsTooltip = false"
                        @keyup.enter.native="handleLogin"
                    />
                    <span class="show-pwd" @click="showPwd">
                        <svg-icon
                            :icon-class="
                                passwordType === 'password' ? 'eye' : 'eye-open'
                            "
                        />
                    </span>
                </el-form-item>
            </el-tooltip>

            <el-button
                :loading="loading"
                type="primary"
                style="width: 100%; margin-bottom: 30px; font-size: 22px"
                @click.native.prevent="handleLogin"
                >
                 登录</el-button
            >

        </el-form>
    </div>
</template>

<script>
import { validUsername } from "@/utils/validate";
import SocialSign from "./components/SocialSignin";

export default {
    name: "Login",
    components: { SocialSign },
    data() {
        const validateUsername = (rule, value, callback) => {
            if (!validUsername(value)) {
                callback(new Error("Please enter the correct user name"));
            } else {
                callback();
            }
        };
        const validatePassword = (rule, value, callback) => {
            if (value.length < 6) {
                callback(
                    new Error("The password can not be less than 6 digits")
                );
            } else {
                callback();
            }
        };
        return {
            loginForm: {
                username: "",
                password: "",
            },
            loginRules: {
                // username: [{ required: true, trigger: 'blur', validator: validateUsername }],
                // password: [{ required: true, trigger: 'blur', validator: validatePassword }]
            },
            passwordType: "password",
            capsTooltip: false,
            loading: false,
            showDialog: false,
            redirect: undefined,
            otherQuery: {},
        };
    },
    watch: {
        $route: {
            handler: function (route) {
                const query = route.query;
                if (query) {
                    this.redirect = query.redirect;
                    this.otherQuery = this.getOtherQuery(query);
                }
            },
            immediate: true,
        },
    },
    created() {
        // window.addEventListener('storage', this.afterQRScan)
    },
    mounted() {
        if (this.loginForm.username === "") {
            this.$refs.username.focus();
        } else if (this.loginForm.password === "") {
            this.$refs.password.focus();
        }
    },
    destroyed() {
        // window.removeEventListener('storage', this.afterQRScan)
    },
    methods: {
        checkCapslock(e) {
            const { key } = e;
            this.capsTooltip =
                key && key.length === 1 && key >= "A" && key <= "Z";
        },
        showPwd() {
            if (this.passwordType === "password") {
                this.passwordType = "";
            } else {
                this.passwordType = "password";
            }
            this.$nextTick(() => {
                this.$refs.password.focus();
            });
        },
        handleLogin() {
            this.$refs.loginForm.validate((valid) => {
                if (valid) {
                    this.loading = true;
                    this.$store
                        .dispatch("user/login", this.loginForm)
                        .then(() => {
                            this.$router.push({
                                path: this.redirect || "/",
                                query: this.otherQuery,
                            });
                            this.loading = false;
                        })
                        .catch((e) => {
                            this.loading = false;
                            console.log(e);
                            if (
                                e.response == undefined ||
                                e.response.data == undefined
                            ) {
                                this.$message({
                                    showClose: true,
                                    message: e,
                                    type: "error",
                                    duration: 6000,
                                });
                            } else {
                                this.$message({
                                    showClose: true,
                                    message: e.response.data,
                                    type: "error",
                                    duration: 6000,
                                });
                            }
                        });
                } else {
                    console.log("error submit!!");
                    return false;
                }
            });
        },
        getOtherQuery(query) {
            return Object.keys(query).reduce((acc, cur) => {
                if (cur !== "redirect") {
                    acc[cur] = query[cur];
                }
                return acc;
            }, {});
        },
    },
};
</script>

<style lang="scss">
/* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */

$bg: #283443;
$light_gray: grey;
$cursor: black;

@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
    .login-container .el-input input {
        color: $cursor;
    }
}

/* reset element-ui css */
.login-container {
    background-image: url("../../assets/bg.png");
    background-size: cover;
    background-repeat: no-repeat;

    .el-input {
        display: inline-block;
        height: 47px;
        width: 85%;

        input {
            background: transparent;
            border: 0px;
            -webkit-appearance: none;
            border-radius: 0px;
            padding: 12px 5px 12px 15px;
            color: $light_gray;
            height: 47px;
            caret-color: $cursor;

            &:-webkit-autofill {
                box-shadow: 0 0 0px 1000px $bg inset !important;
                -webkit-text-fill-color: $cursor !important;
            }
        }
    }

    .el-form-item {
        border: 1px solid rgba(255, 255, 255, 0.1);
        background: white;
        border-radius: 5px;
        color: black;
    }
}
</style>

<style lang="scss" scoped>
$bg: #2d3a4b;
$dark_gray: black;
$light_gray: #eee;

.login-container {
    min-height: 100%;
    width: 100%;
    background-color: $bg;
    overflow: hidden;

    .login-form {
        position: relative;
        width: 520px;
        max-width: 100%;
        padding: 160px 35px 0;
        margin: 0 auto;
        overflow: hidden;
    }

    .tips {
        font-size: 14px;
        color: grey;
        margin-bottom: 10px;

        span {
            &:first-of-type {
                margin-right: 16px;
            }
        }
    }

    .svg-container {
        padding: 6px 5px 6px 15px;
        color: $dark_gray;
        vertical-align: middle;
        width: 30px;
        display: inline-block;
    }

    .title-container {
        position: relative;

        .title {
            font-size: 36px;
            color: black;
            margin: 0px auto 40px auto;
            text-align: center;
            -webkit-text-stroke: 0.5px green;
            font-weight: 600;
        }
    }

    .show-pwd {
        position: absolute;
        right: 10px;
        top: 7px;
        font-size: 16px;
        color: $dark_gray;
        cursor: pointer;
        user-select: none;
    }

    .thirdparty-button {
        position: absolute;
        right: 0;
        bottom: 6px;
    }

    @media only screen and (max-width: 470px) {
        .thirdparty-button {
            display: none;
        }
    }
}
</style>

源码代码

链接:https://pan.baidu.com/s/1qvymj7NI_jmgaZaTjnHNHA 
提取码:1234

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2052581.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis远程字典服务器(6) —— list类型详解

目录 一&#xff0c;基本情况 二&#xff0c;list常用命令 2.1 lpush&#xff0c;lrange 2.2 对于“下标越界”的思考 2.3 lpushx&#xff0c;rpush&#xff0c;rpushx 2.4 lpop&#xff0c;rpop 2.5 lindex&#xff0c;linsert&#xff0c;llen 2.6 lrem 2.7 ltrim…

基于B站的热门视频数据分析与情感分析【关联性、主题、情感分析】

目录 2 研究内容 2.1 主要研究内容 2.2 拟解决的关键问题 2.2.1热门视频特征的识别和提取 2.2.2情感分析与用户反馈 2.3技术路线 2.3.1数据收集 2.3.2数据预处理 2.3.3数据挖掘 2.3.4 数据可视化 2.4可行性分析 2.4.1技术可行性 2.4.2数据可行性 2.4.3经济可行性 2.5数据库设计…

vba发送邮件功能实现方法:如何调试测试?

vba发送邮件的配置步骤流程&#xff1f;vba发送邮件的安全指南&#xff1f; VBA是一种常用于自动化Office应用程序的编程语言。利用VBA发送邮件功能&#xff0c;用户可以实现自动化发送邮件的任务&#xff0c;无需手动操作。AokSend将详细探讨如何通过调试与测试来确保VBA发送…

ThreadLoad如何防止内存溢出

优质博文&#xff1a;IT-BLOG-CN 从 ThreadLocalMap看 ThreadLocal使用不当的内存泄漏问题 【1】基础概念 &#xff1a; 首先我们先看看ThreadLocalMap的类图&#xff0c;我们知道 ThreadLocal只是一个工具类&#xff0c;他为用户提供get、set、remove接口操作实际存放本地变…

MT7621+MT7915(MT7905)+MT7975 (W7621A6G-SDK)编译固件与升级固件方法

一、搭建开发环境&#xff0c;编译固件。 1、安装在Ubuntu 14.04.5 x86_64系统后&#xff0c;然后安装下面命令行。 $ sudo apt-get install git g make libncurses5-dev subversion libssl-dev gawk libxml-parser-perl unzip wget python xz-utils vim zlibc zlib1g zlib1g…

XSS---DOM破坏靶场复现

目录 一、OK&#xff0c;Boomer 一、网址&#xff1a; 二、源码分析&#xff1a; 三、 解决思路&#xff1a; 1.页面中的元素可以通过id和name直接取出来 2.覆盖 3.覆盖方法 四、ToString 五、setTimeout函数 六、使用框架白名单 七、成功绕过 ​编辑 二、案例分析…

才来鱼厂实习 1 个月,就转正了!

大家好&#xff0c;我是程序员鱼皮。昨天&#xff0c;我给才来我们公司 实习一个月 的前端开发同学转正了&#xff0c;直接发了正式 Offer&#xff01;这个转正速度&#xff0c;放眼到所有公司中&#xff0c;我相信也是炸裂的。 看小伙子那么激动&#xff0c;让我回想到了 19 年…

认识 bufferbloat

很多人并不理解 bufferbloat 的本质&#xff0c;我引用《计算机网络-自顶向下方法(第 8 版)》第四章的一个解释&#xff1a; 很形象的比喻&#xff0c;buffer 就像盐&#xff0c;不可或缺&#xff0c;适量增味&#xff0c;过量食物就不能吃了。高血压患者更有所感受&#xff…

STM32是基于ARM架构的,那么ARM究竟是什么呢?

一、什么是ARM 首先&#xff0c;ARM是一家英国公司&#xff0c;全称Advanced RISC Machines&#xff0c;高级精简指令集机器&#xff0c;RISC意味着是精简指令集的芯片。同时也有复杂指令集CSIC的芯片&#xff0c;如X86&#xff0c;常以Intel和AMD为主。 其次&#xff0c;之后…

如何跳过极狐GitLab 密钥推送保护功能?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门面向中国程序员和企业提供企业级一体化 DevOps 平台&#xff0c;用来帮助用户实现需求管理、源代码托管、CI/CD、安全合规&#xff0c;而且所有的操作都是在一个平台上进行&#xff0c;省事省心省钱。可以一键安装极狐GitL…

vue 子组件全局自动导入,不在需要每个组件import

main.js import vue from vue import App from ./App.vue import axios from axios axios.defaults.baseURL HTTP://LOCALHOST:3000/api/ Vue.prototype.$http axios; vue config.productionTip false; //子组件全局自动导入 const requireComponents require.cont…

MK米客方德推出新一代工业级SD NAND——更长寿命、更高速度、更优功耗

博客目录 关注我&#xff0c;不迷路&#xff0c;共学习&#xff0c;同进步一、产品封装与兼容性二、SLC 存储颗粒的使用三、高性能 IOPS 表现四、智能健康监测功能五、内嵌 ECC 校验、坏块管理和其他保护机制六、低功耗设计总结 作为 SD NAND 领域的领跑者&#xff0c;MK 米客方…

【Chromium】分享一个网址 Chromium Browser Snapshots

利用 Chromium Browser Snapshots 进行开发和调试 author: jwensh & chatgpt date:20240819 文章目录 利用 Chromium Browser Snapshots 进行开发和调试1. 获取最新的浏览器特性2. 测试和调试浏览器兼容性问题3. 开发和测试浏览器扩展4. 安全研究和漏洞分析5. 提前为新特性…

如何一键删除iPhone相册所有照片

拍照已成为我们记录日常生活的常态。但是&#xff0c;大量照片便会积累在设备上&#xff0c;这不仅占用了大量存储空间&#xff0c;而且随着时间的推移&#xff0c;管理这些照片也变得越来越困难。如果你决定清理旧照片&#xff0c;或者出于隐私考虑需要删除所有照片&#xff0…

2024:AI新纪元,轻松打造你的专属AI助手

引入 在数字化时代的潮流中&#xff0c;人工智能已经成为了我们生活中不可或缺的一部分。2024年被誉为“AI元年”&#xff0c;这不仅是因为人工智能技术的飞速发展&#xff0c;更是因为它已经渗透到我们的日常生活中&#xff0c;为我们带来了无数便利和可能性。在这个充满活力…

FPGA使用笔记:GPIO操作方式(用于测试设备io驱动性能)

一、前言 使用FPGA测试IO速率&#xff0c;用于后续驱动高速AD/DA等高速芯片做铺垫&#xff0c;很多芯片的驱动都是使用并行接口&#xff0c;不是使用专用接口的&#xff0c;这样采样速率的快慢就有CPU的时许周期决定了。 本文测试FPGA和STM32&#xff0c;后续如果用到更快的芯…

探索大模型时代:全面解析Agent智能体的奥秘

前言&#xff1a; 在2024年&#xff0c;大模型圈子的Agent是一个绝对热门的话题&#xff0c;agent也被各种各样的公众人物所追捧 Agent智能体能够最大化的激发大模型潜能还有人说agent智能体式大模型时代的APP&#xff0c;也有人说agent是在toB场景落地的主要方式之一 无论任…

信创(国产化)方案

信创 信创&#xff0c;即信息技术应用创新&#xff0c;旨在实现信息技术自主可控 openEuler openEuler是一款开源、免费的操作系统&#xff0c;由openEuler社区运作&#xff0c;前身为运行在华为公司通用服务器上的操作系统EulerOS。openEuler作为一款开源、免费的操作系统&…

QT6.0如何开启白名单保活

1. 概述 使用Qt开发android应用往往会存在这样一个问题:我们的android应用和后台需要时刻保持通信,但是往往我们在切换任务或者息屏,将我们开发的应用变更为后台应用的时候,由于android的电池策略,会将后台的应用关闭掉从而释放资源供其他应用使用.会给应用带来不好的使用…

Dubbo从入门到应用:实战技巧和最佳实践

远程调用 一、Dubbo快速上手提供者DubboService 调用者DubboReference 开启Dubbo调用EnableDubbo 二、Dubbo快速入门1、添加 Dubbo 相关的 maven 依赖。2、定义服务接口3、 定义服务端的实现4、配置服务端及消费端 Yml 配置文件5、基于 Spring 配置服务端及消费端启动类6、消费…