1、Hello World
前后端分离框如何快速进入开发,请参照下面hello world实现demo
一、后台请求实现
@RestController
@RequestMapping("/test/jeecgDemo")
@Slf4j
public class JeecgDemoController {
/**
* hello world
*
* @param id
* @return
*/
@GetMapping(value = "/hello")
public Result<String> hello() {
Result<String> result = new Result<String>();
result.setResult("Hello World!");
result.setSuccess(true);
return result;
}
}
直接访问请求http://localhost:8080/jeecg-boot/test/jeecgDemo/hello 会提示token无效, 所以需要配置下拦截器ShiroConfig排除。
配置文件: jeecg-boot-module-system/src/main/java/org/jeecg/config/ShiroConfig.java
加入配置:filterChainDefinitionMap.put("/test/jeecgDemo/hello", "anon");
再访问请求http://localhost:8080/jeect-boot/test/jeecgDemo/hello,会返回结果如下:
{
"success": true,
"message": null,
"code": null,
"result": "Hello World!",
"timestamp": 1548833208562
}
二、前台vue页面实现
(1)创建vue页面src/views/jeecg/helloworld.vue 调用后台请求,获取返回的Hello World! 输出到页面,页面代码如下:
<template>
<div>
{{ msg }}
</div>
</template>
<script>
import {getAction} from '@/api/manage'
export default {
data () {
return {
msg: ""
}
},
methods: {
hello () {
var url = "/test/jeecgDemo/hello"
getAction(url).then((res) => {
if (res.success) {
this.msg = res.result;
}
})
}
},
created() {
this.hello();
}
}
</script>
代码说明:
1、data() 方法中定义数据对象msg 2、数据对象msg输出到页面,表达式如下:
hello () {
var url = "/test/jeecgDemo/hello"
getAction(url).then((res) => {
if (res.success) {
this.msg = res.result;
}
})
}
4、Vue生命周期 created 中调用方法 created() { this.hello(); } hello方法中 this.msg = res.result; 把请求返回的Hello World! 赋值给msg数据对象,msg值改变则页面显示也改变。
三、配置菜单
配置helloword菜单【系统管理】-【菜单管理】
- 其中前端组件配置相对src/views/目录下的 目录名+文件名
- 例如页面src/views/jeecg/helloworld.vue 前端组件配置 jeecg/helloworld
用户角色授权【系统管理】-【角色管理】-授权 点击菜单访问页面展示Hello World!
2、UI前端开发技巧
2.1全局配置文件
升级日志: 20190324
前台全局配置文件 配置内容:后台域名、图片服务器域名配置 文件位置:public/index.html 好处: 前端build完也可以直接修改index.html配置内容
<!-- 全局配置 -->
<script>
window._CONFIG = {};
window._CONFIG['domianURL'] = 'http://localhost:8080/jeecg-boot';
window._CONFIG['imgDomainURL'] = 'http://localhost:8080/jeecg-boot/sys/common/view';
window._CONFIG['pdfDomainURL'] = 'http://localhost:8080/jeecg-boot/sys/common/pdf/pdfPreviewIframe';
window._CONFIG['casPrefixUrl'] = 'http://cas.example.org:8443/cas';
</script>
用法:
参数 | 写法 | 描述 |
---|---|---|
后台服务域名 | window._CONFIG['domianURL'] | - |
图片服务器域名 | window._CONFIG['imgDomainURL'] | - |
pdf文件预览地址 | window._CONFIG['pdfDomainURL'] | - |
CAS服务器地址 | window._CONFIG['casPrefixUrl'] | - |
2.2源码解读
-
登录页面代码位置
srccomponentslayoutsUserLayout.vue src/views/user/Login.vue
-
首页logo修改
src/components/tools/Logo.vue
-
图片预览路径
public/index.html <!-- 全局配置 --> <script> window._CONFIG = {}; window._CONFIG['imgDomainURL'] = 'http://localhost:8080/jeecg-boot/sys/common/view'; </script> 图文访问路径: http://127.0.0.1:8080/jeecg-boot/sys/common/view/user/h.jpg
4.首页报表
src/views/dashboard/* src/views/dashboard/Analysis.vue
-
登录退出逻辑
1.登录页面: src/views/user/Login.vue 2.相关API定义位置: src/api/index.js(很多无用的删掉) src/api/index.js src/api/login.js src/api/manage.js 3.左侧菜单加载页面:src/components/menu src/utils/util.js src/permission.js 4.隐藏路由配置 用途: 如果那个组件不想在菜单上配置,但有需要路由跳转,则需要在这个地方配置路由。 src/config/router.config.js 对象: constantRouterMap 5. 接口: /sys/login 登录接口 /sys/permission/queryByUser 获取用户信息接口(首页菜单)
6.首页风格设置 src/defaultSettings.js
2.3vue路由带参总结
2.3.1 params
配置路由格式要求: path: "/test/:id"
js参数获取:this.$route.params.id
2.3.2 query
配置路由:无要求
js参数获取:this.$route.query.id
备注:
router-link是html写法,JS中语法如下:
this.$router.push({name:'test',query: {id:'1'}})
this.$router.push({name:'test',params: {id:'1'}})
2.4vuex 使用详解
一、什么是vuex
vuex是一个专门为vue.js设计的集中式状态管理架构。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。。
二、vuex使用场景
vuex主要是是做数据交互,父子组件传值可以很容易办到,但是兄弟组件间传值(兄弟组件下又有父子组件),或者大型spa单页面框架项目,页面多并且一层嵌套一层的传值,异常麻烦,用vuex来维护共有的状态或数据会更便捷
场景说明:
- 由于vuex中的state存放的数据在页面刷新时会丢失,vuex只能用于单个页面中不同组件(例如兄弟组件)的数据流通
三、Vuex核心概念
-
1、store:类似容器,包含应用的大部分状态
一个页面只能有一个容器 状态存储是响应式的 不能直接改变store中的状态,唯一途径显示地提交mutations 在actions里面,也不能直接更改state里面的状态值,必须先定义一个mutations,然后在actions里面commit这个mutations,从而来更改state的状态值; 如果要再次请求异步,那么就是dispatch一个actions
-
2、State:包含所有应用级别状态的对象
-
3、Getters:在组件内部获取store中状态的函数,类似组件的计算属性computed
-
4、Mutations:唯一修改状态的事件回调函数,默认是同步的,如果要异步就使用Actions
-
5、Actions:包含异步操作、提交mutations改变状态
-
6、Modules:将store分割成不同的模块
四、引入Vuex
1、安装vuex
npm install vuex --save
2、新建一个store文件夹(这个不是必须的),并在文件夹下新建index.js文件,文件中引入我们的vue和vuex
3、在main.js 中引入新建的store
import store from './store/'
new Vue({
el: '#app',
router,
store,//使用store
template: '<App/>',
components: { App }
})
五、页面使用
1.读取store里的值:
this.$store.state.字段名
如果有 moudle 的话,假设叫 user ,那么取值又要变了,加上 module 名
this.$store.state.user.字段名
2.发起操作请求:
this.$store.dispatch('action中的方法名' , '参数') ;
参数你可以随便传json
3.getters的用法
this.$store.getters.filterDoned
filterDoned 是在 todo 里写的一个 getters 方法,就这么
3、菜单路由配置
3.1菜单配置说明
字段名称 | 说明 |
---|---|
菜单类型 | 一级菜单:配置一级菜单;子菜单:配置下级菜单;按钮:配置页面按钮权限 |
菜单名称 | 定义菜单名称 |
上级菜单 | 菜单类型为子菜单时,选择关联的上级菜单 |
菜单路径 | 定义菜单的路径,通常为:/包名/文件名 具体参见【菜单路径配置说明】 |
前端组件 | 定义菜单访问的组件名称,有两种类型,一种为通用组件,一种为具体的页面, |
具体参见【前端组件配置说明】 | |
菜单图标 | 菜单树展示的图标 |
排序 | 菜单展示的先后顺序 |
是否路由 | 此处很重要,默认是路由;如果是非的话,访问404 |
隐藏路由 | 不展示为菜单,但是在页面中跳转,弹出的页面路由菜单 |
聚合路由 | 多个下级菜单路由在一个页面聚合展示 |
3.1.1前端组件配置说明:
-
1、非叶子菜单(即没有下级的菜单)配置固定 前端组件layouts/RouteView
-
2、普通的叶子菜单(即具体的页面) 配置相对于src/views目录的路径
例如src/views/jeecg/helloworld.vue 这个页面(具体参考底部截图) 配置菜单时 前端组件为 jeecg/helloworld
-
3、需要跳转到第三页面的菜单 前端组件固定为:layouts/IframePageView(具体参考底部截图)
(比如跳转百度:https://www.baidu.com)/)
-
4、java后台请求的菜单
需要以{{ window._CONFIG['domianURL'] }}开头(具体参考底部截图)
3.1.2菜单路径配置说明
- 1、非叶子菜单(即没有下级的菜单),URL配置规则:按照功能模块定义的关键根路径即可,不能重复,需以“/”开头
- 2、普通的叶子菜单(即具体的页面),URL和前端组件配置保持一致即可,需在前端组件值前加“/”
- 3、需要跳转到第三方页面的菜单,菜单路径配置第三方跳转的地址即可,例如http://www.baidu.com
参考示例:
- 1.路由菜单配置截图
- 2.外部链接菜单
- 3.后台链接菜单
3.2路由菜单规则
菜单配置就是配置前端所需要的路由 菜单路径 : 对应页面访问请求URL (系统唯一,不能有重复URL) 前端组件 : 对应前端页面组件(路径+名字,无.vue后缀)
路由name取值规则:
通过菜单URL,生成路由name(去掉URL前缀斜杠,替换内容中的斜杠‘/’为-)
举例: URL = /account/settings/base
RouteName = account-settings-base
前端页面跳转用法:
<router-link :to="{ name: 'account-settings-base' }">
基本设置
</router-link>
4、系统权限用法
4.1页面表单权限
4.1.1显示隐藏控制
一、用法
v-has="'name'"
代码示例:
<a-form-item v-has="'name'"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="请假人">
<a-input placeholder="请输入请假人" v-decorator="['name', {}]" />
</a-form-item>
二、权限配置:
三、使用说明
v-has="'name'"
指令值“name”为授权标识,可对该授权标识进行“显示/访问”控制- 权限编码在【系统管理--菜单管理】中配置,添加按钮类型的菜单数据,授权标识配置值“name”,策略选择显示/访问,状态选择有效
- 控制规则:
- (1)使用
v-has
指令后,菜单权限中若没有对应指令编码的配置,则不显示控件, - (2)权限配置无效状态时,则不进行权限控制,有效状态时进行控制
- (3)策略:显示/访问,未授权时不显示,授权后显示
四、流程节点权限
(1)说明:
- 节点权限配置优先级高于菜单权限配置
- 节点权限应用于使用组件方式加载的附加表单页面,并对附加表单页面进行权限控制
- 显示控制用法见上面用法描述
- 节点权限是通过 props: ['formData'],来传递给节点表单页面的,因此页面一定要定义这个,否则,节点配置的权限不生效
- 权限配置无效状态时,则不进行权限控制,有效状态时进行控制
(2)权限配置: 在【流程管理-流程设计】中找到需要配置的流程,进入【流程配置-流程节点】选择需要进行权限控制的节点, 点击【更多-权限设置】,新增/编辑 来配置权限。
4.1.2禁用控制用法一
一、用法
(1)页面引入混入代码
import {DisabledAuthFilterMixin} from '@/mixins/DisabledAuthFilterMixin'
mixins: [DisabledAuthFilterMixin],
(2)权限控制代码示例:
<a-input-number :disabled="isDisabledAuth('name')" v-decorator="[ 'days', {}]" />
二、权限配置:
三、使用说明
:disabled="isDisabledAuth('name')"
调用方法disabledAuth,方法参数“name”为授权标识,该方法根据授权规则返回true/false,控制是否禁用- 权限编码在【系统管理--菜单管理】中配置,添加按钮类型的菜单数据,授权标识配置值“name”,策略选择可编辑,状态选择有效
- 控制规则:
- (1)菜单权限中若没有对应指令编码的配置,则不进行禁用控制,
- (2)权限配置无效状态时,则不进行权限控制,有效状态时进行控制
- (3)策略:可编辑,未授权时控件禁用,授权后可编辑
四、流程节点权限
(1)说明:
- 节点权限配置优先级高于菜单权限配置
- 节点权限应用于使用组件方式加载的附加表单页面,并对附加表单页面进行权限控制
- 显示控制用法见上面用法描述
- 节点权限是通过 props: ['formData'],来传递给节点表单页面的,因此页面一定要定义这个,否则,节点配置的权限不生效,节点表单开发方法见【流程节点对接表单页面开发方法】
- 权限配置无效状态时,则不进行权限控制,有效状态时进行控制
(2)权限配置: 在【流程管理-流程设计】中找到需要配置的流程,进入【流程配置-流程节点】选择需要进行权限控制的节点, 点击【更多-权限设置】,新增/编辑 来配置权限。
4.1.3禁用控制用法二
一、用法
(1)页面引入工具js
import { disabledAuthFilter } from "@/utils/authFilter"
(2)methods方法中实现:
isDisabledAuth(code){
return disabledAuthFilter(code);
},
(2)权限控制代码示例:
<a-input-number :disabled="isDisabledAuth('name')" v-decorator="[ 'days', {}]" />
二、权限配置:
三、使用说明
:disabled="isDisabledAuth('name')"
调用方法disabledAuth,方法参数“name”为授权标识,该方法根据授权规则返回true/false,控制是否禁用- 权限编码在【系统管理--菜单管理】中配置,添加按钮类型的菜单数据,授权标识配置值“name”,策略选择可编辑,状态选择有效
- 控制规则:
- (1)菜单权限中若没有对应指令编码的配置,则不进行禁用控制,
- (2)权限配置无效状态时,则不进行权限控制,有效状态时进行控制
- (3)策略:可编辑,未授权时控件禁用,授权后可编辑
四、流程节点权限
(1)说明:
-
节点权限配置优先级高于菜单权限配置
-
节点权限应用于使用组件方式加载的附加表单页面,并对附加表单页面进行权限控制
-
显示控制用法见上面用法描述
-
节点权限是通过 props: ['formData'],来传递给节点表单页面的,因此页面一定要定义这个,否则,节点配置的权限不生效,节点表单开发方法见【流程节点对接表单页面开发方法】
-
权限配置无效状态时,则不进行权限控制,有效状态时进行控制
-
(2)methods方法中实现:
isDisabledAuth(code){ return disabledAuthFilter(code,this.formData); },
(2)权限配置: 在【流程管理-流程设计】中找到需要配置的流程,进入【流程配置-流程节点】选择需要进行权限控制的节点, 点击【更多-权限设置】,新增/编辑 来配置权限。
4.2页面按钮权限用法
1.前端页面通过使用指令 v-has
<a-button @click="handleAdd" v-has="'user:add'" type="primary" icon="plus">添加用户</a-button>
2.后台进入菜单管理页面配置按钮权限菜单
3.进入角色管理授权按钮(授权后即可看见按钮)
4.3JAVA访问权限控制
1.后台请求权限控制,通过Shiro注解 @RequiresPermissions
@RequestMapping(value = "/add", method = RequestMethod.POST)
@RequiresPermissions("user:add")
public Result<SysUser> add(@RequestBody JSONObject jsonObject) {
2.后台进入菜单管理页面配置访问权限标识(选择按钮类型) (配置方式与按钮权限一样,即同一个授权标识,可以同时控制后台请求和前台按钮显示控制)
3.进入角色管理授权访问权限(授权后即可访问该请求)
4.4数据权限
4.4.1数据权限规则篇
一、功能说明
列表数据权限,主要通过数据权限控制行数据,让不同的人有不同的查看数据规则; 比如: 销售人员只能看自己的数据;销售经理可以看所有下级销售人员的数据;财务只看金额大于5000的数据等等;
二、数据权限分两大类型
序号 | 类型 | 规则字段区别 | 说明 |
---|---|---|---|
1 | 编码方式 | 规则字段是驼峰写法,对应mybatis实体的字段 | 编码模式(通过代码生成器生成代码) |
2 | Online方式 | 规则字段是下划线写法,对应表的字段 | Online模式(在线表单模式,无代码) |
规则字段配置说明(非常重要):
①条件规则:大于/大于等于/小于/小于等于/等于/包含/模糊/不等于
②规则值:指定值 ( 固定值/系统上下文变量 )
三、数据权限规则篇
1.当前用户上下文变量
注意:数据权限配置,规则值可以填写系统上下文变量(当前登录人信息),从而根据当前登录人信息进行权限控制。
编码 | 描述 |
---|---|
sys_user_code | 当前登录用户登录账号 |
sys_user_name | 当前登录用户真实名称 |
sys_date | 当前系统日期 |
sys_time | 当前系统时间 |
sys_org_code | 当前登录用户部门编号 |
sysMultiOrgCode | 当前登录用户拥有的所有机构编码,逗号分隔 |
规则值,配置写法如下:#{sys_user_code}
2.建表规范(系统标准字段)
如果需要通过当前登录人,进行数据权限控制,则业务表必须有以下系统标准字段;数据添加和编辑,jeecg会通过拦截器自动注入操作人的信息。 比如:创建人,创建时间,创建人所属部门、创建人所属公司,有了这些标准字段,就可以通过当前登录人进行数据隔离控制;
字段英文名 | 字段中文名 |
---|---|
CREATE_BY | 系统用户登录账号 |
CREATE_NAME | 系统用户真实名字 |
SYS_ORG_CODE | 登录用户所属部门 |
3.组织机构邮编规则
JEECG组织机构支持无限层级,上下级关系通过组织机构编码实现,组织机构编码规则类似邮编方式,看下图; 邮编规则优势: 邮编规则,上下级编码固定规律,便于定位下级和上级;
4.4.2系统数据权限用法
一、功能说明
列表数据权限,主要通过数据权限控制行数据,让不同的人有不同的查看数据规则; 比如: 销售人员只能看自己的数据;销售经理可以看所有下级销售人员的数据;财务只看金额大于5000的数据等等;
二、使用说明 (有两种使用方法,以下说明以用户管理列表查询示例 配置数据规则:只查询用户账号带1的用户)
方法A步骤如下:
- A-1.新增权限菜单:进入【系统管理】-->【菜单管理】界面 新增一个权限菜单(如下图)
- A-2.配置数据权限规则:找到上述1新增的菜单,点击操作列更多中的数据规则,配置,只查询用户账号带1的用户(如下图)
- A-3.角色授权:进入【系统管理】-->【角色管理】界面找到当前用户对应的角色,点击 更多->授权 操作,右侧弹出框中找到上述1菜单,点击后勾选权限规则,保存(如下图)
- A-4.在后台请求方法上加注解
@PermissionData
在方法上加注解是为了提高系统运行效率,这样就可以指定请求走权限过滤的逻辑,而非一棍子打死,让所有请求都去筛选一下权限(如下图) - A-5.测试,访问用户管理界面发现数据被过滤了,即权限生效!
方法A的问题在于,每个请求都需要配置一个权限菜单,这样其实也很费劲,同时对于菜单管理也不是很好,鉴于此可以考虑使用方法B 方法B基于注解属性pageComponent,步骤如下:
- B-1.找到需要配置权限的页面菜单,这里是用户管理菜单
直接在该菜单上配置数据规则(如A-2)
- B-2.角色授权(如A-3)
- B-3.添加注解 (如A-4,不同的是注解上增加了一个属性)
@PermissionData(pageComponent="system/UserList")
pageComponent的值和B-1中菜单的前端组件值保持一致 - B-4.测试,访问用户管理界面发现数据被过滤了,即权限生效!
规则字段配置说明(非常重要):
①条件规则:大于/大于等于/小于/小于等于/等于/包含/模糊/不等于/自定义SQL
②规则值:指定值 ( 固定值/系统上下文变量 )
三、数据权限规范说明
1.系统上下文变量
注意:数据权限配置,规则值可以填写系统上下文变量(当前登录人信息),从而根据当前登录人信息进行权限控制。
编码 | 描述 |
---|---|
sys_user_code | 当前登录用户登录账号 |
sys_user_name | 当前登录用户真实名称 |
sys_date | 当前系统日期 |
sys_time | 当前系统时间 |
sys_org_code | 当前登录用户部门编号 |
规则值,配置写法如下:#{sys_user_code}
2.建表规范(系统标准字段)
如果需要通过当前登录人,进行数据权限控制,则业务表必须有以下系统标准字段;数据添加和编辑,jeecg会通过拦截器自动注入操作人的信息。 比如:创建人,创建时间,创建人所属部门、创建人所属公司,有了这些标准字段,就可以通过当前登录人进行数据隔离控制;
字段英文名 | 字段中文名 |
---|---|
CREATE_BY | 系统用户登录账号 |
CREATE_NAME | 系统用户真实名字 |
SYS_ORG_CODE | 登录用户所属部门 |
3.组织机构邮编规则
JEECG组织机构支持无限层级,上下级关系通过组织机构编码实现,组织机构编码规则类似邮编方式,看下图; 邮编规则优势: 邮编规则,上下级编码固定规律,便于定位下级和上级;
4.5列表列权限控制
针对数据列表的列进行权限控制,控制列的展示与不展示,需要菜单的权限配置与页面代码配置使用 控制规则: 增加权限控制配置与代码后,配置有效的状态未授权时隐藏,授权时显示
举例: 针对常用示例列表,的用户名字段
权限控制步骤
1. 针对列表列配置权限
在配置前需要对需要控制的列表权限编码定义一个前缀,规则自己设计,不同的列表定义不同前缀最好不要重复
例如:定义前缀“testdemo:” 则需要对列表中的name列进行控制,权限编码为,前缀+列字段名 (“testdemo:name”)
在对应的列表页面菜单下配置权限:
配置说明:
- 菜单类型:选择“按钮/权限”
- 授权标识:前缀+列字段名 (“testdemo:name”)
- 授权策略:选择“显示/访问(授权后显示/可访问)”
- 状态:选择“有效”
2. 增加页面控制代码
(1)引入工具方法
import { colAuthFilter } from "@/utils/authFilter"
(2)created方法中增加方法调用,根据权限过滤展示的列
created() {
this.columns = colAuthFilter(this.columns,'testdemo:');
this.loadData();
},
说明:
colAuthFilter方法:
第一个参数:列表定义的列信息
第二个参数:列权限控制定义的权限编码前缀“t
4.6聚合路由的使用
聚合路由, 配置后子菜单路由不显示,子菜单之间的跳转通过页面上的路由链接进行跳转
备注:父级菜单配置如下
(1)配置聚合路由,选择是;
(2)菜单地址配置其子菜单中的一个菜单地址,作为默认跳转的地址;