springboot+vue小白升级之路13-AOP实现登录、增删改查操作日志管理

661 篇文章 4 订阅
112 篇文章 0 订阅

还是接着上一个的内容,我把这个新增的关于日志的功能代码都贴出来,供大家学习参考。数据库

数据库

drop table if exists an_log;
create table an_log(
	id int not null auto_increment primary key comment '主键id',
	name varchar(255) not null comment '操作内容',
	log_date datetime default CURRENT_TIMESTAMP comment '日志时间',
	user_name varchar(100) default null comment '操作人',
	`ip` varchar(100) default null comment 'ip地址'
) comment '操作日志表';
insert into an_log values(1,'操作','2022-01-01','admin','192.168.0.1');

pom.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

application.proerties

server.port=8089

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimeZone=UTC
spring.datasource.username=root
spring.datasource.password=mysql123
#格式化时间
spring.jackson.date-format= yyyy-MM-dd
spring.jackson.time-zone= GMT+8
#日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#配置别名
mybatis-plus.type-aliases-package=com.shrimpking.pojo
#开启逻辑删除,标识字段
mybatis-plus.global-config.db-config.logic-delete-field=is_deleted
#删除
mybatis-plus.global-config.db-config.logic-delete-value=1
#未删除
mybatis-plus.global-config.db-config.logic-not-delete-value=0
#swagger
spring.mvc.pathmatch.matching-strategy=ant_path_matcher

pojo

log.java

package com.shrimpking.pojo;

import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.io.Serializable;
import java.util.Date;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * <p>
 * 操作日志表
 * </p>
 *
 * @author shrimpking
 * @since 2023-11-15
 */
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("an_log")
@ApiModel(value="Log对象", description="操作日志表")
@AllArgsConstructor
public class Log implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "主键id")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty(value = "操作内容")
    private String name;

    @ApiModelProperty(value = "日志时间")
    private LocalDateTime logDate;

    @ApiModelProperty(value = "操作人")
    private String userName;

    @ApiModelProperty(value = "ip地址")
    private String ip;


}

mapper

logmapper.java

package com.shrimpking.mapper;

import com.shrimpking.pojo.Log;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
 * <p>
 * 操作日志表 Mapper 接口
 * </p>
 *
 * @author shrimpking
 * @since 2023-11-15
 */
public interface LogMapper extends BaseMapper<Log> {

}

mapper.xml

logMpper.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.shrimpking.mapper.LogMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.shrimpking.pojo.Log">
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="log_date" property="logDate" />
        <result column="user_name" property="userName" />
        <result column="ip" property="ip" />
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, name, log_date, user_name, ip
    </sql>

</mapper>

service

logservice.java

package com.shrimpking.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.shrimpking.pojo.Log;
import com.baomidou.mybatisplus.extension.service.IService;
import com.shrimpking.req.LogParams;
import com.shrimpking.req.QueryParams;

/**
 * <p>
 * 操作日志表 服务类
 * </p>
 *
 * @author shrimpking
 * @since 2023-11-15
 */
public interface LogService extends IService<Log> {

    IPage<Log> findBySearchPage(LogParams logParams);
}

serviceImpl

logServiceImpl.java

package com.shrimpking.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shrimpking.pojo.Hotel;
import com.shrimpking.pojo.Log;
import com.shrimpking.mapper.LogMapper;
import com.shrimpking.req.LogParams;
import com.shrimpking.req.QueryParams;
import com.shrimpking.service.LogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 操作日志表 服务实现类
 * </p>
 *
 * @author shrimpking
 * @since 2023-11-15
 */
@Service
public class LogServiceImpl extends ServiceImpl<LogMapper, Log> implements LogService {

    @Override
    public IPage<Log> findBySearchPage(LogParams logParams)
    {
        //声明分页
        IPage<Log> page = new Page<>(logParams.getCurrentPage(), logParams.getPageSize());
        //声明查询条件
        LambdaQueryWrapper<Log> queryWrapper = new LambdaQueryWrapper<>();
        //操作内容不为空,有条件值时,加入此条件
        queryWrapper.like(
                StringUtils.isNotBlank(logParams.getName()),
                Log::getName, logParams.getName())
                //操作人不为空时,加入条件
                .like(
                        StringUtils.isNotBlank(logParams.getUserName()),
                        Log::getUserName, logParams.getUserName())
                .orderByDesc(Log::getId);
        //返回结果
        return this.baseMapper.selectPage(page, queryWrapper);
    }
}

controller

logController.java

package com.shrimpking.controller;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.shrimpking.annotation.AutoLog;
import com.shrimpking.pojo.Log;
import com.shrimpking.req.LogParams;
import com.shrimpking.res.Result;
import com.shrimpking.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 操作日志表 前端控制器
 * </p>
 *
 * @author shrimpking
 * @since 2023-11-15
 */
@RestController
@RequestMapping("/log")
public class LogController {

    @Autowired
    private LogService logService;

    /**
     * 有查询条件时,获取分页数据
     * @param queryParams
     * @return
     */
    @GetMapping("/searchPage")
    public Result findBySearchPage(LogParams logParams){
        IPage<Log> list = this.logService.findBySearchPage(logParams);
        return Result.success(list);
    }

//    @PostMapping("/save")
//    public Result save(@RequestBody Log log){
//        boolean save = this.logService.save(log);
//        if(!save) return Result.error("保存失败");
//        return Result.success("保存成功");
//    }
//
//    @PostMapping("/update")
//    public Result update(@RequestBody Log log){
//        boolean save = this.logService.updateById(log);
//        if(!save) return Result.error("更新失败");
//        return Result.success("更新成功");
//    }


    @DeleteMapping("/delete")
    public Result delete(@RequestParam("id") Integer id){
        boolean remove = this.logService.removeById(id);
        if(!remove) return Result.error("删除失败");
        return Result.success("删除成功");
    }

    @PostMapping("/delBatch")
    public Result delBatch(@RequestBody List<Log> list){
        //循环取出id
        List<Integer> collectList = list.stream().map(Log::getId).collect(Collectors.toList());
        boolean remove = this.logService.removeByIds(collectList);
        if(!remove) return Result.error("删除失败");
        return Result.success("删除成功");
    }

}

req

logParams.java

package com.shrimpking.req;

import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Shrimpking
 * @create 2023/11/12 21:10
 */

@Data
@EqualsAndHashCode(callSuper = true)
public class LogParams extends QueryParams
{
    private String userName;
}

router

import Vue from 'vue'
import VueRouter from 'vue-router'


Vue.use(VueRouter)

const routes = [
  {
    path: '/login',
    name:'LoginView',
    component: ()=> import('@/views/LoginView.vue'),
  },
  {
    path:'/register',
    name: 'Register',
    component: ()=> import('@/views/RegisterView.vue'),
  },
  {
    path: '/',
    redirect: '/home',
    name: 'Layout',
    component: ()=> import('@/views/Layout.vue'),
    children:[
      {
        path: 'home',
        name: 'HomeView',
        component: ()=> import('@/views/HomeView.vue')
      },
      {
        path: 'admin',
        name: 'AdminView',
        component: ()=> import('@/views/User/AdminView.vue'),
      },
      {
        path:'user',
        name:'UserView',
        component: ()=> import('@/views/User/UserView.vue'),
      },
      {
        path:'book',
        name:'BookView',
        component: ()=> import('@/views/Info/BookView.vue'),
      },
      {
        path:'type',
        name:'BookType',
        component: ()=> import('@/views/Info/BookType.vue'),
      },
      {
        path:'audit',
        name:'AuditView',
        component: ()=> import('@/views/AuditView.vue'),
      },
      {
        path:'hotel',
        name:'HotelView',
        component: ()=> import('@/views/hotel/HotelView.vue'),
      },
      {
        path:'reserve',
        name:'ReserveView',
        component: ()=> import('@/views/hotel/ReserveView.vue'),
      },
      {
        path:'log',
        name:'LogView',
        component: ()=> import('@/views/Log/LogView.vue'),
      },
    ]
  },
]

const router = new VueRouter({
  routes
})

//白名单
const IGNORE_URLS = ['/login','/register'];

//前置守卫
router.beforeEach((to, from, next) => {
  //在白名单中,放行
  if(IGNORE_URLS.includes(to.path)){
    next();
  }
  //获取用户
  let admin = JSON.parse(window.localStorage.getItem('access-admin'));
  if(!admin && !IGNORE_URLS.includes(to.path)){
    //没有登录 ,没有在白名单中,跳转登录
    return next('/login');
  }

  next();
});

export default router

logview.vue

<template>
    <div>
        <!-- 搜索区域       -->
        <div style="margin-bottom:15px;">
            <el-input
                    v-model="searchForm.name"
                    style="width:200px;"
                    placeholder="请输入内容"
                    @clear="doSearch"
                    @keypress.native.enter="doSearch"
                    clearable>
            </el-input>
            <el-input
                    v-model="searchForm.userName"
                    style="width:200px;margin-left:10px;"
                    placeholder="请输入操作人"
                    @clear="doSearch"
                    @keypress.native.enter="doSearch"
                    clearable>
            </el-input>
            <el-button
                    type="warning"
                    style="margin-left: 10px;"
                    icon="el-icon-search"
                    @click="doSearch">查询</el-button>
            <el-button
                    type="primary"
                    style="margin-left: 10px;"
                    icon="el-icon-toilet-paper"
                    @click="clearSearch">清空</el-button>
<!--            <el-button-->
<!--                    type="primary"-->
<!--                    style="margin-left: 10px;"-->
<!--                    icon="el-icon-plus" @click="addBtn">新增</el-button>-->
            <el-button
                    type="danger"
                    style="margin-left: 10px;"
                    icon="el-icon-delete"
                    @click="delBatchBtn"
                    v-if="admin.role === 'ROLE_ADMIN'">批量删除</el-button>
        </div>
        <!-- 表格区域       -->
        <el-table
                ref="table1"
                :data="tableData"
                border
                row-key="id"
                tooltip-effect="dark"
                style="width: 100%"
                @selection-change="handleSelectionChange">
            <el-table-column
                    type="selection"
                    :reserve-selection="true"
                    width="55">
            </el-table-column>
            <el-table-column
                    prop="id"
                    label="ID">
            </el-table-column>
            <el-table-column
                    prop="name"
                    label="操作内容">
            </el-table-column>
            <el-table-column
                    prop="logDate"
                    label="日志时间">
            </el-table-column>
            <el-table-column
                    prop="userName"
                    label="操作人">
            </el-table-column>
            <el-table-column
                    prop="ip"
                    label="IP地址">
            </el-table-column>
            <el-table-column label="操作">
                <template slot-scope="scope">
<!--                    <el-button type="primary" icon="el-icon-edit" @click="editBtn(scope.row)">编辑</el-button>-->
                    <el-button
                            type="danger"
                            icon="el-icon-delete"
                            @click="deleteBtn(scope.row)"
                            v-if="admin.role === 'ROLE_ADMIN'">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
        <!-- 分页区域       -->
        <div style="margin-top:15px;">
            <el-pagination
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                    :current-page="searchForm.currentPage"
                    :page-sizes="[2, 5, 10, 20]"
                    :page-size="searchForm.pageSize"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="total">
            </el-pagination>
        </div>
        <!--  对话框      -->
<!--        <div>-->
<!--            <el-dialog-->
<!--                    :title="dialogTitle"-->
<!--                    :visible.sync="dialogFormVisible"-->
<!--                    :close-on-click-modal="false"-->
<!--                    @close="closeDialog"-->
<!--                    width="35%">-->
<!--                <el-form-->
<!--                        :model="addForm"-->
<!--                        :rules="rules"-->
<!--                        ref="addForm"-->
<!--                        :label-width="formLabelWidth"-->
<!--                        label-position="left">-->
<!--                    <el-form-item label="姓名" prop="name">-->
<!--                        <el-input v-model="addForm.name" clearable></el-input>-->
<!--                    </el-form-item>-->
<!--                    <el-form-item label="密码" prop="password">-->
<!--                        <el-input v-model="addForm.password" clearable></el-input>-->
<!--                    </el-form-item>-->
<!--                    <el-form-item label="年龄" prop="age">-->
<!--                        <el-input-number v-model="addForm.age" :max="199" :min="1" label="描述文字"></el-input-number>-->
<!--                    </el-form-item>-->
<!--                    <el-form-item label="性别" prop="sex">-->
<!--                        <el-radio v-model="addForm.sex" label="男">男</el-radio>-->
<!--                        <el-radio v-model="addForm.sex" label="女">女</el-radio>-->
<!--                    </el-form-item>-->
<!--                    <el-form-item label="电话" prop="phone">-->
<!--                        <el-input v-model="addForm.phone" clearable></el-input>-->
<!--                    </el-form-item>-->
<!--                    <el-form-item label="角色名" prop="role">-->
<!--                        <el-select v-model="addForm.role" clearable>-->
<!--                            <el-option label="教师" value="ROLE_TEACHER"></el-option>-->
<!--                            <el-option label="学生" value="ROLE_STUDENT"></el-option>-->
<!--                        </el-select>-->
<!--                    </el-form-item>-->
<!--                </el-form>-->
<!--                <div slot="footer" class="dialog-footer">-->
<!--                    <el-button @click="resetBtn" v-show="dialogTitle === '新增用户'">重 置</el-button>-->
<!--                    <el-button type="primary" @click="submitBtn">确 定</el-button>-->
<!--                </div>-->
<!--            </el-dialog>-->
<!--        </div>-->
    </div>
</template>

<script>
    import request from "@/utils/request";

    export default {
        name: "LogView",
        computed: {
            admin(){
                return JSON.parse(window.localStorage.getItem('access-admin')) || { name: '未登录'};
            }
        },
        data() {
            return {
                //多选
                multipleSelection:[],
                //添加表单
                // addForm:{
                //     name:'',
                //     password:'',
                //     age:'',
                //     sex:'',
                //     phone:'',
                //     role: '',
                // },
                // rules:{
                //     name:[{required: true, message: '请输入姓名', trigger: 'blur'}],
                //     password:[{required: true, message: '请输入密码', trigger: 'blur'}],
                //     age:[{required: true, message: '请输入年龄', trigger: 'blur'}],
                //     sex:[{required: true, message: '请选择性别', trigger: 'blur'}],
                //     phone:[{required: true, message: '请输入电话', trigger: 'blur'}],
                //     role:[{required: true, message: '请选择角色名', trigger: 'change'}],
                // },
                // //表单标题宽度
                // formLabelWidth:'80px',
                // //对话框标题
                // dialogTitle:'',
                // //对话框
                // dialogFormVisible: false,
                //搜索条件
                searchForm:{
                    name: '',
                    userName:'',
                    currentPage: 1,
                    pageSize: 5
                },
                tableData: [],
                total:0
            }
        },
        methods: {
            //批量删除
            delBatchBtn(){
                if(this.multipleSelection.length <= 0){
                    this.$message.warning("请先勾选数据,再删除!");
                    return;
                }

                this.$confirm(`您确定要删除这些数据吗`,'删除提示',{
                    confirmButtonText:'删除',
                    cancelButtonText:'取消',
                    type:'warning',
                }).then(()=>{
                    //todo
                    request.post('/log/delBatch',this.multipleSelection)
                        .then(res => {
                            if(res.code === '200'){
                                this.$message.success(res.data);
                                this.doSearch();
                            }else {
                                this.$message.error(res.msg);
                                this.doSearch();
                            }
                        })
                }).catch(_=>{
                    this.$message.warning('已取消删除');
                })
            },
            //多选变化
            handleSelectionChange(val) {
                this.multipleSelection = val;
            },
            //删除
            deleteBtn(row){
                this.$confirm(`您确定要删除【${row.name}】吗`,'删除提示',{
                    confirmButtonText:'删除',
                    cancelButtonText:'取消',
                    type:'warning',
                }).then(()=>{
                    request.delete('/log/delete',{
                        params:{ id : row.id}
                    }).then(res => {
                        if(res.code === '200'){
                            this.$message.success(res.data);
                            this.doSearch();
                        }
                    })
                }).catch(_=>{
                    this.$message.warning('已取消删除');
                })
            },
            //编辑
            // editBtn(row){
            //     let obj = JSON.parse(JSON.stringify(row));
            //     this.addForm = obj;
            //     this.dialogTitle = "编辑用户";
            //     this.dialogFormVisible = true;
            // },
            //关闭对话框
            // closeDialog(){
            //     this.resetBtn();
            //     this.dialogFormVisible = false;
            // },
            //新增保存
            // submitBtn(){
            //     this.$refs.addForm.validate((valid)=>{
            //         if(valid){
            //             //校验通过
            //             //有id,编辑,没有id是新增
            //             request.post(this.addForm.id ? '/user/update':'/user/save',this.addForm)
            //                 .then(res=>{
            //                     if(res.code === '200'){
            //                         this.$message.success(res.data);
            //                         this.resetBtn();
            //                         this.dialogFormVisible = false;
            //                         this.doSearch();
            //                     }else {
            //                         this.$message.error(res.msg);
            //                     }
            //                 })
            //         }
            //     })
            // },
            //新增重置
            // resetBtn(){
            //     this.$refs.addForm.resetFields();
            //     //修复bug
            //     this.addForm = {};
            //     //this.$refs.addForm.id = '';
            // },
            // addBtn(){
            //     this.dialogTitle = '新增用户';
            //     this.dialogFormVisible = true;
            // },
            clearSearch(){
                this.searchForm.name = '';
                this.searchForm.userName = '';
                this.doSearch();
            },
            //搜索
            doSearch(){
                //修复bug
                this.searchForm.currentPage = 1;
                this.getData();

            },
            handleSizeChange(val) {
                this.searchForm.pageSize = val;
                this.searchForm.currentPage = 1;
                this.getData();
            },
            handleCurrentChange(val) {
                this.searchForm.currentPage = val;
                this.getData();
            },
            //获取数据
            getData(){
                request.get('/log/searchPage',{
                    params: this.searchForm
                }).then(res=>{
                    if(res.code === '200'){
                        this.tableData = res.data.records; //数据
                        this.searchForm.currentPage = res.data.current; //当前页
                        this.searchForm.pageSize = res.data.size; //页条数
                        this.total = res.data.total; //总条数
                    }else {
                        this.$message.error(res.msg);
                    }
                });
            }
        },
        created(){
            //获取数据
            this.getData();
        }
    }
</script>

<style scoped>

</style>

layout.vue

<template>
    <div>
        <el-container class="container">
            <el-header class="header-area">
                <img src="@/assets/logo.png" alt="logo" class="logo">
                <span class="title">手牵手带小白做毕设</span>
                <span class="admin-info">
                <el-dropdown @command="handleCommand">
                    <span class="el-dropdown-link">
                        用户:&nbsp;&nbsp; <strong>{{ admin.name }}</strong>
                        <i class="el-icon-arrow-down el-icon--right"></i>
                    </span>
                    <el-dropdown-menu slot="dropdown">
                        <el-dropdown-item command="logout">退出</el-dropdown-item>
                    </el-dropdown-menu>
                    </el-dropdown>
                </span>
            </el-header>
            <el-container class="middle-area">
                <el-aside  class="left-aside">
                    <el-menu
                            :default-active="$route.path"
                            class="el-menu-vertical-demo"
                            background-color="#545c64"
                            text-color="#fff"
                            active-text-color="#ffd04b"
                            :unique-opened="true"
                            router>
                        <el-menu-item index="/home">
                            <i class="el-icon-menu"></i>
                            <span slot="title">系统首页</span>
                        </el-menu-item>
                        <el-submenu index="/admin" v-if="admin.role === 'ROLE_ADMIN'">
                            <template slot="title">
                                <i class="el-icon-location"></i>
                                <span>用户管理</span>
                            </template>
                            <el-menu-item-group>
                                <el-menu-item index="/admin">用户信息</el-menu-item>
                            </el-menu-item-group>
                        </el-submenu>
                        <el-submenu index="/book">
                            <template slot="title">
                                <i class="el-icon-location"></i>
                                <span>信息管理</span>
                            </template>
                            <el-menu-item-group>
                                <el-menu-item index="/book">图书信息</el-menu-item>
                                <el-menu-item index="/type">图书分类</el-menu-item>
                            </el-menu-item-group>
                        </el-submenu>
                        <el-submenu index="/audit">
                            <template slot="title">
                                <i class="el-icon-location"></i>
                                <span>请假管理</span>
                            </template>
                            <el-menu-item-group>
                                <el-menu-item index="/audit">请假申请</el-menu-item>
                            </el-menu-item-group>
                        </el-submenu>
                        <el-submenu index="/hotel">
                            <template slot="title">
                                <i class="el-icon-location"></i>
                                <span>酒店管理</span>
                            </template>
                            <el-menu-item-group>
                                <el-menu-item index="/hotel">酒店信息</el-menu-item>
                                <el-menu-item index="/reserve">预订记录</el-menu-item>
                            </el-menu-item-group>
                        </el-submenu>
                        <el-submenu index="/log" v-if="admin.role === 'ROLE_ADMIN'">
                            <template slot="title">
                                <i class="el-icon-location"></i>
                                <span>日志管理</span>
                            </template>
                            <el-menu-item-group>
                                <el-menu-item index="/log">操作日志</el-menu-item>
                            </el-menu-item-group>
                        </el-submenu>
                    </el-menu>
                </el-aside>
                <el-main>
                    <router-view/>
                </el-main>
            </el-container>
        </el-container>
    </div>
</template>

<script>
    import request from "@/utils/request";

    export default {
        name: "Layout",
        computed: {
            admin(){
                return JSON.parse(window.localStorage.getItem('access-admin')) || { name: '未登录'};
            }
        },
        methods: {
            //下拉菜单命令
            handleCommand(command){
                if (command === 'logout') {
                    this.logout();
                }
            },
            //退出
            logout(){
                request.post('/user/logout',this.admin).then(res => {
                    if(res.code === '200'){
                        window.localStorage.clear();
                        this.$message.success(res.data);
                        this.$router.replace('/login');
                    }
                })

            }
        }
    }
</script>

<style lang="scss" scoped>
    .container{
        height: 100vh;

        .header-area{
            background-color: #4c535a;

            .logo {
                width: 40px;
                position: relative;
                top: 10px;
            }

            .title{
                font-size: 20px;
                margin-left: 15px;
                color: white;
            }

            .admin-info{
                float: right;
                margin-right: 30px;
                line-height: 60px;
                .el-dropdown-link{
                    color: #cccccc;
                }
            }

        }

        .middle-area{

            .left-aside{
                overflow: hidden;
                height: 100%;
                /*background-color: #545c64;*/
                width:230px  !important;

                .el-menu-vertical-demo{
                    height: 100%;
                }


            }



        }

    }
</style>

测试

  • 30
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Spring BootVue.js可以很好地搭配使用,实现前后端分离的Web应用程序。以下是一个简单的例子,演示如何使用Spring BootVue.js实现增删改查功能。 1. 创建一个Spring Boot项目,包含Spring Web和Spring Data JPA依赖。创建一个实体类和一个Repository接口,用于操作数据库。 ```java @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; // 省略getter和setter } @Repository public interface UserRepository extends JpaRepository<User, Long> { } ``` 2. 创建一个RESTful API,使用Spring MVC和Spring Data REST实现,用于获取、创建、更新和删除用户。 ```java @RestController @RequestMapping("/api/users") public class UserController { @Autowired private UserRepository userRepository; @GetMapping public List<User> findAll() { return userRepository.findAll(); } @PostMapping public User create(@RequestBody User user) { return userRepository.save(user); } @PutMapping("/{id}") public User update(@PathVariable Long id, @RequestBody User user) { user.setId(id); return userRepository.save(user); } @DeleteMapping("/{id}") public void delete(@PathVariable Long id) { userRepository.deleteById(id); } } ``` 3. 创建一个Vue.js应用程序,使用axios库与后端进行通信。创建一个组件,用于显示用户列表,以及一个表单组件,用于创建或更新用户。 ```html <template> <div> <table> <tr> <th>ID</th> <th>Name</th> <th>Email</th> <th>Actions</th> </tr> <tr v-for="user in users" :key="user.id"> <td>{{ user.id }}</td> <td>{{ user.name }}</td> <td>{{ user.email }}</td> <td> <button @click="edit(user)">Edit</button> <button @click="remove(user)">Remove</button> </td> </tr> </table> <form v-if="editing" @submit.prevent="save"> <input type="text" v-model="user.name" placeholder="Name"> <input type="email" v-model="user.email" placeholder="Email"> <button type="submit">{{ editing.id ? 'Update' : 'Create' }}</button> </form> </div> </template> <script> import axios from 'axios'; export default { data() { return { users: [], user: {}, editing: false, }; }, methods: { async fetchUsers() { const { data } = await axios.get('/api/users'); this.users = data; }, async save() { if (this.editing.id) { await axios.put(`/api/users/${this.editing.id}`, this.user); } else { await axios.post('/api/users', this.user); } this.editing = false; this.user = {}; await this.fetchUsers(); }, async remove(user) { await axios.delete(`/api/users/${user.id}`); await this.fetchUsers(); }, edit(user) { this.editing = true; this.user = { ...user }; }, }, async mounted() { await this.fetchUsers(); }, }; </script> ``` 4. 在Spring Boot应用程序中配置静态资源路径,将Vue.js应用程序打包为静态资源,并在Spring Boot应用程序中提供静态资源服务。 ```properties spring.mvc.static-path-pattern=/static/** spring.resources.static-locations=classpath:/static/ ``` 5. 打包Vue.js应用程序,并将生成的dist目录复制到Spring Boot应用程序的静态资源目录中。 6. 运行Spring Boot应用程序,访问http://localhost:8080/static/index.html即可看到用户列表和表单。现在可以使用Vue.js应用程序与后端进行交互,实现增删改查功能了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

虾米大王

有你的支持,我会更有动力

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

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

打赏作者

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

抵扣说明:

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

余额充值