前端vue
先执行vue init webpack vue-new
cd vue-new
# 安装路由
cnpm insatll vue-router --save-dev
# 安装element-ui
cnpm i element-ui -S
# 安装依赖
cnpm install
# 安装SASS加载器
cnpm insall sass-loader node-sass --save-dve
# 启动测试
npm run dev
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import axios from 'axios'
import router from './router'//路由
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
Vue.config.productionTip = false
import moment from 'moment'
Vue.prototype.$moment = moment
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(router);
Vue.use(ElementUI);
/* eslint-disable no-new */
new Vue({
el: '#app',
// components: { App },
// template: '<App/>'
router,
render:h=>h(App)
})
Login.vue
<template>
<div>
<el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
<h3 class="login-title">欢迎登录</h3>
<el-form-item lable="账号" prop="username">
<el-input type="text" placeholder="请输入账号" v-model="form.username"/>
</el-form-item>
<el-form-item lable="密码" prop="password">
<el-input type="password" placeholder="请输入密码" v-model="form.password"/>
</el-form-item>
<el-form-item>
<el-button type="primary" v-on:click="onsubmit('loginForm')">登录</el-button>
</el-form-item>
</el-form>
<el-dialog
title="温馨提示"
:visible.sync="dialogVisible"
width="30%"
:before-close="handleClose">
<span>请输入账号和密码</span>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false">确定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
name: "Login",
data(){
return{
form :{
username:'',
password:''
},
rules:{
username:[
{required:true,message:'账号不能为空',trigger:'blur'}
],
password:[
{required:true,message:'密码不能为空',trigger:'blur'}
]
},
dialogVisible:false
}
},
methods:{
onsubmit(loginForm){
this.$refs[loginForm].validate((valid)=>{
// console.log(this.form.username)
// console.log(this.form.password)
// console.log(loginForm)
// console.log(valid)
// 先进行数据校验,校验通过true才能传数据
if (valid){
this.axios.post('http://localhost:8083/user/login',
{'username':this.form.username,'password':this.form.password}).then(
(resp)=>{
console.log(resp.data.code)
if (resp.data.code===200){
this.$router.push("/blog")
}else {
console.log(false)
alert(resp.data.msg)
}
}
)
}else {
//如果数据校验不通过就弹窗
this.dialogVisible=true;
return false;
}
})
// this.axios.post('http://localhost:8083/user/login',
// {'username':this.form.username,'password':this.form.password}).then(
// (resp)=>{
// console.log(resp.data.code)
// if (resp.data.code===200){
// this.$router.push("/blog")
// }else {
// console.log(false)
// }
// }
// )
}
}
}
</script>
<style scoped>
.login-box{
border: 1px solid #DCDFE6;
width: 350px;
margin: 180px auto;
padding: 35px 35px 15px 15px;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
box-shadow: 0 0 25px #909399;
}
.login-title{
text-align: center;
margin: 0 auto 40px auto;
color: #303133;
}
</style>
Main.vue
<template>
<el-container style="border: 1px solid #eee">
<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
<el-radio-group v-model="isCollapse" style="margin-bottom: 20px;">
<el-radio-button :label="false">展开</el-radio-button>
<el-radio-button :label="true">收起</el-radio-button>
</el-radio-group>
<el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span slot="title">导航一</span>
</template>
<el-menu-item-group>
<!-- <span slot="title">分组一</span>-->
<el-menu-item index="1-1">
<router-link to="/blog">博客页面</router-link>
</el-menu-item>
<el-menu-item index="1-2">
<router-link to="/user/list">用户页面</router-link>
</el-menu-item>
</el-menu-item-group>
<!-- <el-menu-item-group title="分组2">-->
<el-menu-item index="1-3">选项3</el-menu-item>
<!-- </el-menu-item-group>-->
<el-submenu index="1-4">
<span slot="title">选项4</span>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</template>
<script>
export default {
name: "Main",
data() {
return {
isCollapse: true
};
},
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
}
}
}
</script>
<style scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
min-height: 400px;
}
</style>
Blog.vue
<!--<template>-->
<!-- <div>-->
<!-- <table>-->
<!-- <tr>-->
<!-- <td>编号</td>-->
<!-- <td>作者id</td>-->
<!-- <td>题目</td>-->
<!-- <td>描述</td>-->
<!-- <td>文章</td>-->
<!-- <td>创建时间</td>-->
<!-- <td>状态</td>-->
<!-- </tr>-->
<!-- <tr v-for="item in books">-->
<!-- <td>{{item.id}}</td>-->
<!-- <td>{{item.userId}}</td>-->
<!-- <td>{{item.title}}</td>-->
<!-- <td>{{item.description}}</td>-->
<!-- <td>{{item.content}}</td>-->
<!-- <td>{{item.created}}</td>-->
<!-- <td>{{item.status}}</td>-->
<!-- </tr>-->
<!-- </table>-->
<!-- </div>-->
<!--</template>-->
<template>
<el-table
<!--data赋值 -->
:data="books"
style="width: 100%">
<el-table-column
label="编号"
width="180">
<template slot-scope="scope">
<!-- 插槽 -->
<el-popover trigger="hover" placement="top">
<p>id:{{scope.row.id}}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{scope.row.id}}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column
label="作者id"
width="180">
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>作者Id:{{scope.row.userId}}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{scope.row.userId}}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column
label="题目"
width="180">
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>题目:{{scope.row.title}}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{scope.row.title}}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column
label="描述"
width="180">
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>描述:{{scope.row.description}}</p>
<p>文章:{{scope.row.content}}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{scope.row.description}}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column
label="创建日期"
width="180">
<template slot-scope="scope">
<!-- 插槽-->
<i class="el-icon-time"></i>
<span style="margin-left: 10px">{{$moment(scope.row.created).format('YYYY-MM-DD') }}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
size="mini"
@click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script>
export default {
name: "book",
data(){
return{
books:[
]
}
},
created(){
const _this = this;
//用axios来请求
this.axios.get('http://localhost:8083/blog/findAll').then(
function(resp){
console.log(resp);//放回回来的resp
_this.books = resp.data;//赋值
}
)
}
}
</script>
<style scoped>
</style>
router/index.js
//导入vue
import Vue from 'vue';
import VueRouter from 'vue-router';
//导入组件
import Blog from "../views/Blog";
import Login from "../views/Login";
import Main from "../views/Main";
import User from "../views/user/User"
//使用
Vue.use(VueRouter);
//导出
export default new VueRouter({
mode: 'history',
// scrollBehavior (to, from, savedPosition) { //解决跳转下一个页面底部的方法
// if (savedPosition) {
// return savedPosition
// } else {
// return { x: 0, y: 0 }
// }
// },
routes: [
//首页
{
path: '/',
component: Login
},
{
path: '/main',
component: Main,
children:[//路由嵌套
{path:'/blog', name:'blog', component:Blog,props:true},
{path:'/user/list', name:'userList', component:User,props:true},
]
},
]
})
导入依赖
<dependencies>
<!-- 数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- mybatis-plus -->
<!-- mybatis-plus 是自己开发,并非官方的! -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
运行
package com.ycz;/*
@author ycz
@date 2021-09-08-19:14
*/
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;
/**
* 代码自动生成器
*/
public class Test2 {
public static void main(String[] args) {
AutoGenerator mpg=new AutoGenerator();
//全局配置
GlobalConfig config=new GlobalConfig();
config.setAuthor("ycz");
String projectPath = System.getProperty("user.dir");
config.setOutputDir(projectPath+"/src/main/java");
config.setOpen(false);//是否自动打开文件夹
config.setFileOverride(false);//是否覆盖
config.setIdType(IdType.ID_WORKER);
config.setServiceName("%sService"); // 去Service的I前缀
config.setDateType(DateType.ONLY_DATE);
config.setSwagger2(true);
mpg.setGlobalConfig(config);
DataSourceConfig dataSourceConfig=new DataSourceConfig();
dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/vueblog?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");
dataSourceConfig.setUsername("root");
dataSourceConfig.setPassword("123456");
dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
dataSourceConfig.setDbType(DbType.MYSQL);
mpg.setDataSource(dataSourceConfig);
PackageConfig pc = new PackageConfig();
// pc.setModuleName("blog");
pc.setParent("com.ycz");
pc.setEntity("entity");
pc.setMapper("mapper");
pc.setService("service");
pc.setController("controller");
mpg.setPackageInfo(pc);
StrategyConfig strategy=new StrategyConfig();
strategy.setInclude("m_user");// 设置要映射的表名
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true); // 自动lombok;
strategy.setLogicDeleteFieldName("deleted");
TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(gmtCreate);
tableFills.add(gmtModified);
strategy.setTableFillList(tableFills);
// 乐观锁
strategy.setVersionFieldName("version");
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true); //localhost:8080/hello_id_2
mpg.setStrategy(strategy);
mpg.execute(); //执行
}
}
配置config
package com.ycz.config;/*
@author ycz
@date 2021-10-10-13:57
*/
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyConfig implements WebMvcConfigurer {
//重新addCorsMappings方法
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") //添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置
.allowedOriginPatterns("*") //开放哪些ip、端口、域名的访问权限
.allowedMethods( "GET", "POST", "PUT", "OPTIONS", "DELETE") //开放哪些Http方法,允许跨域访问
.allowCredentials(true) //是否允许发送Cookie信息
.maxAge(3600)
.allowedHeaders("*"); //允许HTTP请求中的携带哪些Header信息
}
}
UserController
package com.ycz.controller;
import com.ycz.entity.MUser;
import com.ycz.service.MUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
* 前端控制器
* </p>
*
* @author ycz
* @since 2021-10-10
*/
@RestController
@RequestMapping("/user")
public class MUserController {
@Autowired
private MUserService userService;
@PostMapping("/login")
public Map<String,Object> login(@RequestBody MUser user){
System.out.println(user);
Map<String,Object> map1=new HashMap<>();
map1.put("username",user.getUsername());
map1.put("password",user.getPassword());
Collection<MUser> mUsers = userService.listByMap(map1);
System.out.println(mUsers);
Map<String,Object> maps=new HashMap<>();
if (mUsers.isEmpty()){
maps.put("msg","操作失败");
maps.put("code",500);
}else {
maps.put("msg","操作成功");
maps.put("code",200);
}
return maps;
}
@GetMapping("/list")
public List<MUser> getList(){
return userService.list(null);
}
}
BlogController
package com.ycz.controller;
import com.ycz.entity.MBlog;
import com.ycz.service.MBlogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author ycz
* @since 2021-10-10
*/
@RestController
@RequestMapping("/blog")
public class MBlogController {
@Autowired
private MBlogService blogService;
@GetMapping("/findAll")
public List<MBlog> blogList(){
return blogService.list(null);
}
}
\