<dependencies>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-generatorartifactId>
<version>3.3.1.tmpversion>
dependency>
<dependency>
<groupId>org.apache.velocitygroupId>
<artifactId>velocity-engine-coreartifactId>
<version>2.2version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.connector.java.version}version>
dependency>
dependencies>
package io.niker.basic.util;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class CodeGenerator {
//加载properties属性文件
public static Properties properties;
static {
properties = new Properties();
try {
properties.load(CodeGenerator.class.getResourceAsStream("/mybatis-generator-system.properties"));
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭流资源
}
}
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = properties.getProperty("project.base.path");//获取项目路径
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor(properties.getProperty("project.author"));
gc.setOpen(false);
gc.setFileOverride(true);
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl(properties.getProperty("jdbc.url"));
dsc.setDriverName(properties.getProperty("jdbc.driverClassName"));
dsc.setUsername(properties.getProperty("jdbc.username"));
dsc.setPassword(properties.getProperty("jdbc.password"));
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent(properties.getProperty("package.parent"));//设置父包名称
pc.setEntity("domain");
mpg.setPackageInfo(pc);
// 自定义配置 - 重新配置mapper.xml的生成规则
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义mapper.xml生成
String templatePath = "/templates/mapper.xml.vm";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath + "/src/main/resources/" + properties.getProperty("config.mapper.location") +
"/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
// 自定义controller的生成,使用自己的模板
templatePath = "/templates/controller.java.vm";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return projectPath + "/src/main/java/" + properties.getProperty("package.parent").replaceAll("\\.","/") +
"/controller/" + tableInfo.getEntityName() + "Controller" + StringPool.DOT_JAVA;
}
});
String projectCommonPath = properties.getProperty("project.common.path");
// 自定义query的生成,mybatis-generator没有query的生成策略
templatePath = "/templates/query.java.vm";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return projectCommonPath + "/src/main/java/" + properties.getProperty("package.parent").replaceAll("\\.","/") +
"/query/" + tableInfo.getEntityName() + "Query" + StringPool.DOT_JAVA;
}
});
// 自定义domain的生成,domian应该生成到common模块
templatePath = "/templates/entity.java.vm";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return projectCommonPath + "/src/main/java/" + properties.getProperty("package.parent").replaceAll("\\.","/") +
"/domain/" + tableInfo.getEntityName() + StringPool.DOT_JAVA;
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 配置模板 - mybatisplus都是根据模板生成的文件,如果不想使用它的模板,可以自己设置
//如果模板设置为null,则不会根据他的策略进行生成
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setXml(null);
templateConfig.setEntity(null);
templateConfig.setController(null);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
//生成的表
String tableNames = properties.getProperty("config.tables").replaceAll(" ","");
strategy.setInclude(tableNames.split(","));
strategy.setTablePrefix("t_");
mpg.setStrategy(strategy);
//设置模板引擎
mpg.setTemplateEngine(new VelocityTemplateEngine());
mpg.execute();
}
}
#代码生成相关的配置信息保持到这个配置文件中
project.base.path=E:/ideaProjects/hrm-parent-repository/hrm-system-parent/hrm-system-service
project.author=lidong
#数据源配置
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/hrm?useUnicode=true&useSSL=false&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456
#包配置
package.parent=io.niker.system
package.common=io.niker.common
#自定义配置
config.mapper.location=io/niker/system/mapper/
project.common.path=E:/ideaProjects/hrm-parent-repository/hrm-system-parent/hrm-system-common
config.tables=t_department, t_employee, t_employee_role, t_meal, t_meal_permission, t_menu, t_permission, t_role, t_role_permission, t_systemdictionary, t_systemdictionaryitem, t_tenant, t_tenant_meal, t_tenant_type
<dependencies>
<dependency>
<groupId>io.nikergroupId>
<artifactId>hrm-basic-utilartifactId>
<version>${project.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plusartifactId>
<version>3.3.1.tmpversion>
dependency>
dependencies>
结构如下
import Login from './views/Login.vue'
import NotFound from './views/404.vue'
import Home from './views/Home.vue'
import Table from './views/nav1/Table.vue'
import Form from './views/nav1/Form.vue'
import Page4 from './views/nav2/Page4.vue'
import Page5 from './views/nav2/Page5.vue'
import echarts from './views/charts/echarts.vue'
import Tenant from './views/system/Tenant.vue'
let routes = [
{
path: '/login',
component: Login,
name: '',
hidden: true
},
{
path: '/404',
component: NotFound,
name: '',
hidden: true
},
{
path: '/',
component: Home,
name: '',
iconCls: 'fa fa-address-card',
leaf: true,//只有一个节点
children: [
{ path: '/main', component: echarts, name: '首页' }
]
},
{
path: '/',
component: Home,
name: '系统中心',
iconCls: 'el-icon-message',//图标样式class
children: [
{ path: '/employee', component: Table, name: '用户管理' },
{ path: '/dept', component: Form, name: '部门管理' },
{ path: '/tenantType', component: Form, name: '租户类型管理' },
{ path: '/tenant', component: Tenant, name: '租户管理' },
]
},
{
path: '/',
component: Home,
name: '课程中心',
iconCls: 'fa fa-id-card-o',
children: [
{ path: '/courseType', component: Page4, name: '课程类型' },
{ path: '/course', component: Page5, name: '课程管理' }
]
},
{
path: '/',
component: Home,
name: '职位中心',
iconCls: 'fa fa-id-card-o',
children: [
{ path: '/jobType', component: Page4, name: '职位类型' },
{ path: '/job', component: Page5, name: '职位管理' }
]
},
{
path: '*',
hidden: true,
redirect: { path: '/404' }
}
];
export default routes;
/**
* 登录
* @param employee
* @return
*/
@PostMapping("/login")
public AjaxResult login(@RequestBody Employee employee){
Employee loginUser = employeeService.getOne(new QueryWrapper<Employee>().eq("username", employee.getUsername()));
if(loginUser==null){
return AjaxResult.me().setSuccess(false).setMessage("用户名不存在!");
}
if(!(loginUser.getPassword().equals(employee.getPassword()))){
return AjaxResult.me().setSuccess(false).setMessage("密码错误!");
}
//map一时爽,维护火葬场,建议编写vo实体类,响应给前端的数据的封装的对象
EmployeeVo employeeVo = new EmployeeVo();
//对象属性的拷贝,Spring的工具类
BeanUtils.copyProperties(loginUser,employeeVo);
return AjaxResult.me().setSuccess(true).setMessage("登录成功!").setResultObj(employeeVo);
}
cnpm install --save aixos vue-axios
main.js
import axios from 'axios'
import VueAxios from 'vue-axios'
//网关的地址
axios.defaults.baseURL = "http://localhost:1299/services/";
Vue.use(VueAxios, axios)
Login.vue
this.axios.post("/system/login",loginParams).then((rest) => {
this.logining = false;
let {success,message,resultObj} = rest.data;
if(success){
sessionStorage.setItem('user', JSON.stringify(resultObj));
this.$router.push({ path: '/main' });
}else{
this.$message({
message: message,
type: 'error'
});
}
})
前端发送ajax请求,在跨域请求中肯定会出现跨域问题
CORS
前端:浏览器自动发送两次请求,第一次发送options请求做询问,第二次发送正是请求
后端:配置跨域过滤器【原理:配置跨域响应头】
所有前端的请求都是通过zuul网关进行服务调用的,也就是说所有的前端请求都先访问网关,
我们就把跨域配置到zuul网关中
package io.niker.hrm.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class GlobalCorsConfig {
@Bean
public CorsFilter corsFilter() {
//1.添加CORS配置信息
CorsConfiguration config = new CorsConfiguration();
//1) 允许的域,不要写*,否则cookie就无法使用了
//浏览器认为127.0.0.1和localhost不是同一个域
config.addAllowedOrigin("http://127.0.0.1:6001");
config.addAllowedOrigin("http://localhost:6001");
//2) 是否发送Cookie信息
config.setAllowCredentials(true);
//3) 允许的请求方式
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
// 4)允许的头信息
config.addAllowedHeader("*");
//2.添加映射路径,我们拦截一切请求
UrlBasedCorsConfigurationSource configSource = new
UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
//3.返回新的CorsFilter.
return new CorsFilter(configSource);
}
}
TenantMapper.java
/**
* 1、mapper的sql只关注高级查询,只要mapper的第一个参数是Page,那么自动分页
* 而且分页后的数据自动封装到IPage对象中,IPage中就有total和rows了
*
*
* 2、mapper接口多个参数了,如何在sql中获取到指定参数
* mybatis默认按照参数位置有着默认的参数名称
* arg0,arg1,....
* param1,param2,.......
* mybatis多个参数还支持绑定参数名,使用@Param注解
* @param page
* @param query
* @return
*/
IPage<Tenant> selectByQuery(Page<?> page,@Param("query") TenantQuery query);
TenantMapper.xml
<mapper namespace="io.niker.hrm.mapper.TenantMapper">
<resultMap id="TenantMap" type="io.niker.hrm.domain.Tenant">
<result property="employee.id" column="admin_id"/>
<result property="employee.username" column="username"/>
<result property="type.id" column="tenant_type"/>
<result property="type.name" column="typename"/>
resultMap>
<select id="selectByQuery" resultMap="TenantMap">
select t.*,tt.name typename, e.username
from t_tenant t
left join t_tenant_type tt on t.tenant_type = tt.id
left join t_employee e on t.admin_id = e.id
<include refid="whereSql"/>
select>
<sql id="whereSql">
<where>
<if test="query.keyword!=null and query.keyword!=''">
and (
companyName like concat('%',#{query.keyword},'%')
or
address like concat('%',#{query.keyword},'%')
)
if>
<if test="query.typeId!=null">
and tenant_type = #{query.typeId}
if>
<if test="query.state!=null">
and t.state = #{query.state}
if>
where>
sql>
mapper>
Tenant.java
package io.niker.hrm.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
*
*
*
*
* @author lidong
* @since 2020-03-30
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("t_tenant")
public class Tenant implements Serializable {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private Long tenantType;
@TableField("companyName")
private String companyName;
@TableField("companyNum")
private String companyNum;
@TableField("registerTime")
private Date registerTime;
private Integer state;
private String address;
private String logo;
private Long adminId;
/**
* mybatis的多对一
*/
@TableField(exist = false)
private Employee admin; // 租户管理员
@TableField(exist = false)
private TenantType type; // 机构类型
}
TenantServiceImpl.java
/**
* 高级查询+分页:
* 传统方式:
* 两条sql
* (1)count(*) 查询总条目数
* (2)limit 查询当前页的数据
* (3)封装pageList返回
* mybatis分页插件的方式:
* mapper接口将page作为第一个参数,则自动分页
* IPage selectPageVo(Page> page, Integer state);
* @param query
* @return
*/
@Override
public PageList<Tenant> queryPage(TenantQuery query) {
//mapper只写高级查询,分页交给分页插件
IPage<Tenant> page =
baseMapper.selectByQuery(new Page<Tenant>(query.getPage(), query.getRows()), query);
return new PageList<>(page.getTotal(),page.getRecords());
}