前后端分离项目:员工&部门管理
-
- 创建数据库/表:
-
- ssm框架—后台搭建:
-
- 项目整体框架:
- pom.xml:
- web.xml:
- db.properties:
- logback.xml:
- mybatis-config.xml:
- spring-mvc.xml:
- spring-mybatis.xml:
- Dept:
- DeptMapper :
- DeptMapper.xml:
- DeptServiceImpl :
- IDeptService :
- DeptController :
- CommonResult:
- SimpleCORSFilter :
- 配置tomcat 并运行项目:
- vue—前台搭建:
-
- 新建空项目文件:
- 在项目文件目录地址栏—cmd:
- 在cmd窗口执行命令:
- 命令执行完成并生成网址访问链接:
- 复制链接到浏览器+回车:
- 在vue脚手架项目上修改成需要的功能页面:
-
- 代码整体布局:
- 在vscode中打开《生成的》项目文件:
- 修改编辑项目文件:
- App.vue :
- views—Login.vue :
- router—index.js(部分)
- views—AdminWelcome.xue:
- 保存修改,登录页面:
- 根据项目布局结构/联系,整理代码:
- router—index.js:
- util—AxiosUtil.js:
- service—DeptService.js:
- views—DeptMgr.vue:
- components—SideBar.vue:
- views—AdminHome.vue:
- Error①Failed to compile:
- Error②端口被占用:
- 运行结果如下:
- 参考:
创建数据库/表:
创建数据库:
create database 0927_ssm_vue_db #创建数据库
default character set utf8mb4 #设置字符集
default collate utf8mb4_general_ci #设置排序规则
创建数据表:
#创建部门
CREATE TABLE tb_dept
(
dept_id int PRIMARY KEY auto_increment,
dept_name VARCHAR(20)
)
select * from tb_dept
INSERT INTO tb_dept
(dept_name)
select '人事部' UNION
select '财务部' UNION
select 'IT部'
CREATE TABLE tb_emp
(
emp_id INT PRIMARY KEY auto_increment,
emp_name varchar(20),
sex char(1),
birthday date,
phone varchar(11),
dept_d int #所属部门
)
select * from tb_emp
insert into tb_emp
VALUES
(null,'张三','男','2000-01-10','13112345678',1),
(null,'李四','女','2002-11-12','13112345679',2)
ssm框架—后台搭建:
项目整体框架:
pom.xml:
4.0.0
org.example
0927_ssm_vue_KTLX
1.0-SNAPSHOT
war
0927_ssm_vue_KTLX Maven Webapp
http://www.example.com
8
8
4.0.1
2.2
1.2
5.3.14
1.4
3.4.6
1.3.3
8.0.11
1.2.78
javax.servlet
javax.servlet-api
${servlet.version}
provided
javax.servlet.jsp
jsp-api
${jsp.version}
provided
jstl
jstl
${jstl.version}
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-jdbc
${spring.version}
commons-dbcp
commons-dbcp
${commons-dbcp.version}
org.mybatis
mybatis
${mybatis.version}
org.mybatis
mybatis-spring
${mybatis-spring.version}
com.github.pagehelper
pagehelper
5.1.0
com.github.abel533
mapper
3.0.1
mysql
mysql-connector-java
${mysql-connector-java.version}
com.alibaba
fastjson
${fastjson.version}
org.projectlombok
lombok
1.18.24
com.fasterxml.jackson.core
jackson-databind
2.13.2.2
org.logback-extensions
logback-ext-spring
0.1.4
javax.validation
validation-api
2.0.1.Final
org.hibernate
hibernate-validator
6.1.0.Final
org.apache.poi
poi
3.17
org.apache.poi
poi-ooxml
3.17
org.apache.poi
poi-ooxml-schemas
3.17
com.sun.mail
jakarta.mail
1.6.7
web.xml:
contextConfigLocation
classpath:spring-mybatis.xml
org.springframework.web.context.ContextLoaderListener
logbackConfigLocation
classpath:logback.xml
ch.qos.logback.ext.spring.web.LogbackConfigListener
SimpleCORSFilter
com.aaa.demo.filter.SimpleCORSFilter
IsCross
true
SimpleCORSFilter
/*
characterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
characterEncodingFilter
/*
springMVC
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring-mvc.xml
1
springMVC
/
db.properties:
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/0927_ssm_vue_db?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&allowPublicKeyRetrieval=true
jdbc.username=root
jdbc.password=123456
logback.xml:
%d{HH:mm:ss.SSS} [%thread] > %green(%-5level) %cyan(%logger{35}) - %m%n
/aaalogs/%d{yyyy-MM-dd}.aaa.log.zip
365
%d{yyyy-MM-dd HH:mm:ss.SSS} > %-5level %X{X-B3-TraceId:-} ${springAppName:-} %logger{35} %m%n
mybatis-config.xml:
spring-mvc.xml:
spring-mybatis.xml:
Dept:
package com.aaa.demo.entity;
import lombok.Data;
@Data
public class Dept {
private Integer deptId;
private String deptName;
}
DeptMapper :
package com.aaa.demo.mapper;
import com.aaa.demo.entity.Dept;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface DeptMapper {
@Select("select dept_id,dept_name from tb_dept")
List listAll();
@Insert("insert into tb_dept values (null,#{deptName})")
int insert(Dept dept);
}
DeptMapper.xml:
DeptServiceImpl :
package com.aaa.demo.service.impl;
import com.aaa.demo.entity.Dept;
import com.aaa.demo.mapper.DeptMapper;
import com.aaa.demo.service.IDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class DeptServiceImpl implements IDeptService {
@Autowired
private DeptMapper deptMapper;
@Override
public List listAll() {
return deptMapper.listAll();
}
@Override
public int add(Dept dept) {
return deptMapper.insert(dept);
}
}
IDeptService :
package com.aaa.demo.service;
import com.aaa.demo.entity.Dept;
import java.util.List;
public interface IDeptService {
List listAll();
int add(Dept dept);
}
DeptController :
package com.aaa.demo.controller;
import com.aaa.demo.entity.Dept;
import com.aaa.demo.service.IDeptService;
import com.aaa.demo.util.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/api/dept")
public class DeptController {
@Autowired
private IDeptService deptService;
@RequestMapping("/list")
public CommonResult listAll(){
List deptList=deptService.listAll();
return CommonResult.success(deptList);
}
@RequestMapping("/add")
public CommonResult add(@RequestBody Dept dept){
//@RequestBody:用于接收json字符串格式的对象参数
int count=deptService.add(dept);
return CommonResult.success(count);
}
}
CommonResult:
package com.aaa.demo.util;
import lombok.Data;
@Data
public class CommonResult {
//状态编码:0成功,1失败
private Integer code;
//提示信息
private String msg;
//记录数
private long count;
//数据结果
private T data;
public CommonResult() {
}
public CommonResult(Integer code, String msg, long count, T data) {
this.code = code;
this.msg = msg;
this.count = count;
this.data = data;
}
//返回成功结果:增删改,或其他不返回记录数的操作
public static CommonResult success(T data){
return new CommonResult(0,"success",0,data);
}
//返回成功结果:针对分页查询
public static CommonResult success(long count,T data){
return new CommonResult(0,"success",count,data);
}
//返回失败
public static CommonResult fail(T data){
return new CommonResult(1,"fail",0,data);
}
}
SimpleCORSFilter :
package com.aaa.demo.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SimpleCORSFilter implements Filter {
private boolean isCross = false;
@Override
public void destroy() {
isCross = false;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (isCross) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
//使用通配符 * 允许所有域名发起的跨域请求
httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
//允许访问的方式
httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
//表示每次异步请求都发起预检请求,也就是说,发送两次请求。 resp.addHeader("Access-Control-Max-Age", "1800"),表示隔30分钟才发起预检请求。也就是说,发送两次请求
httpServletResponse.setHeader("Access-Control-Max-Age", "0");
//允许携带的头
httpServletResponse.setHeader("Access-Control-Allow-Headers",
"Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
//是否允许后续请求携带认证信息(cookies),该值只能是true,否则不返回。这个是服务端下发到客户端的 response 中头部字段,意义是允许客户端携带验证信息,例如 cookie 之类的。
httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
//代表javascript和Ajax的跨域请求
httpServletResponse.setHeader("XDomainRequestAllowed", "1");
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String isCrossStr = filterConfig.getInitParameter("IsCross");
isCross = isCrossStr.equals("true") ? true : false;
System.out.println(isCrossStr);
}
}
配置tomcat 并运行项目:
vue—前台搭建:
新建空项目文件:
在项目文件目录地址栏—cmd:
在cmd窗口执行命令:
Microsoft Windows [版本 10.0.22000.978]
(c) Microsoft Corporation。保留所有权利。
D:\java-Vue-space\0927_ssm_vue_KTLX>vue create web_front_0927
Vue CLI v4.1.1
┌─────────────────────────────────────────┐
│ │
│ New version available 4.1.1 → 5.0.8 │
│ Run npm i -g @vue/cli to update! │
│ │
└─────────────────────────────────────────┘
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Vuex
? Use history mode for router? (Requires proper server setup for index fallback in production) No
? Where do you prefer placing config for Babel, ESLint, etc.? In package.json
? Save this as a preset for future projects? No
Vue CLI v4.1.1
✨ Creating project in D:\java-Vue-space\0927_ssm_vue_KTLX\web_front_0927.
Initializing git repository...
⚙ Installing CLI plugins. This might take a while...
> [email protected] postinstall D:\java-Vue-space\0927_ssm_vue_KTLX\web_front_0927\node_modules\core-js
> node -e "try{require('./postinstall')}catch(e){}"
> [email protected] postinstall D:\java-Vue-space\0927_ssm_vue_KTLX\web_front_0927\node_modules\ejs
> node ./postinstall.js
added 1259 packages from 631 contributors in 239.437s
94 packages are looking for funding
run `npm fund` for details
Invoking generators...
Installing additional dependencies...
added 11 packages from 40 contributors in 16.939s
95 packages are looking for funding
run `npm fund` for details
⚓ Running completion hooks...
Generating README.md...
Successfully created project web_front_0927.
Get started with the following commands:
$ cd web_front_0927
$ npm run serve
D:\java-Vue-space\0927_ssm_vue_KTLX> cd web_front_0927
D:\java-Vue-space\0927_ssm_vue_KTLX\web_front_0927> npm run serve
> [email protected] serve D:\java-Vue-space\0927_ssm_vue_KTLX\web_front_0927
> vue-cli-service serve
INFO Starting development server...
98% after emitting CopyPlugin
DONE Compiled successfully in 5123ms 19:30:23
App running at:
- Local: http://localhost:8080/
- Network: http://192.168.31.110:8080/
Note that the development build is not optimized.
To create a production build, run npm run build.
命令执行完成并生成网址访问链接:
复制链接到浏览器+回车:
在vue脚手架项目上修改成需要的功能页面:
代码整体布局:
在vscode中打开《生成的》项目文件:
修改编辑项目文件:
App.vue :
views—Login.vue :
router—index.js(部分)
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../views/Login.vue'
//在vue实例中使用路由组件
Vue.use(VueRouter)
const routes = [
{
path: '/',
redirect:"/login" //路径重定向
},
{
path: '/login', //地址路径
name: 'Login', //地址命名
component:Login
}
]
//创建路由对象
const router = new VueRouter({
routes
})
//导出路由对象
export default router
views—AdminWelcome.xue:
欢迎使用后台管理系统
保存修改,登录页面:
根据项目布局结构/联系,整理代码:
router—index.js:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../views/Login.vue'
//在vue实例中使用路由组件
Vue.use(VueRouter)
const routes = [
{
path: '/',
redirect:"/login" //路径重定向
},
{
path: '/login', //地址路径
name: 'Login', //地址命名
component:Login
},
{
path: '/elui',
name: 'ELUi',
component:()=>import("../views/ELUiTest")
},
{
path:"adminhome",
name:"AdminHome",
component:()=>import("../views/AdminHome"),
children:[ //配置子级视图的页面
{
path:"",
name:"AdminWelcome",
component:()=>import("../views/AdminWelcome")
},
{
path:"deptMgr",
name:"DeptMgr",
component:()=>import("../views/DeptMgr")
}
]
}
]
//创建路由对象
const router = new VueRouter({
routes
})
//导出路由对象
export default router
util—AxiosUtil.js:
//导入axios模块
import axios from 'axios'
//配置axios模块
let axiosUtil=axios.create({
baseURL:"http://localhost:8080/0927_ssm_vue_KTLX_war_exploded/api/" //配置axios组件请求的固定前缀
})
//到处具有特定配置的axios对象
export default axiosUtil;
service—DeptService.js:
//导入axios模块
import axiosUtil from "../util/AxiosUtil";
//定义业务方法,实现后台接口请求
//查询
function list(){
//返回请求指定Controller的一个promise对象(ajax异步请求对象)
return axiosUtil.get("dept/list");
}
//添加
function add(dept){
return axiosUtil.post("dept/add",dept);
}
//当前是一个js module(模块),如果想要当前模块的内容,被其他模块使用,需要进行导出
export default{
list,add
}
views—DeptMgr.vue:
components—SideBar.vue:
views—AdminHome.vue:
Error①Failed to compile:
Error②端口被占用:
运行结果如下:
参考:
axios中文文档|axios中文网
http://www.axios-js.com/zh-cn/docs/