Merge branch 'master' of gitee.com:dolahair/RuoYi-Cloud
This commit is contained in:
commit
93a930c7aa
2
pom.xml
2
pom.xml
|
|
@ -40,7 +40,7 @@
|
||||||
<common-pool.version>2.10.0</common-pool.version>
|
<common-pool.version>2.10.0</common-pool.version>
|
||||||
<commons-collections.version>3.2.2</commons-collections.version>
|
<commons-collections.version>3.2.2</commons-collections.version>
|
||||||
<transmittable-thread-local.version>2.12.2</transmittable-thread-local.version>
|
<transmittable-thread-local.version>2.12.2</transmittable-thread-local.version>
|
||||||
<log4j2.version>2.16.0</log4j2.version>
|
<log4j2.version>2.17.0</log4j2.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<!-- 依赖声明 -->
|
<!-- 依赖声明 -->
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.ruoyi.common.core.utils;
|
||||||
|
|
||||||
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import com.ruoyi.common.core.utils.sql.SqlUtil;
|
||||||
|
import com.ruoyi.common.core.web.page.PageDomain;
|
||||||
|
import com.ruoyi.common.core.web.page.TableSupport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页工具类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class PageUtils extends PageHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 设置请求分页数据
|
||||||
|
*/
|
||||||
|
public static void startPage()
|
||||||
|
{
|
||||||
|
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||||
|
Integer pageNum = pageDomain.getPageNum();
|
||||||
|
Integer pageSize = pageDomain.getPageSize();
|
||||||
|
if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
|
||||||
|
{
|
||||||
|
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
|
||||||
|
PageHelper.startPage(pageNum, pageSize, orderBy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,16 +7,12 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.web.bind.WebDataBinder;
|
import org.springframework.web.bind.WebDataBinder;
|
||||||
import org.springframework.web.bind.annotation.InitBinder;
|
import org.springframework.web.bind.annotation.InitBinder;
|
||||||
import com.github.pagehelper.PageHelper;
|
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
import com.ruoyi.common.core.constant.HttpStatus;
|
import com.ruoyi.common.core.constant.HttpStatus;
|
||||||
import com.ruoyi.common.core.utils.DateUtils;
|
import com.ruoyi.common.core.utils.DateUtils;
|
||||||
import com.ruoyi.common.core.utils.StringUtils;
|
import com.ruoyi.common.core.utils.PageUtils;
|
||||||
import com.ruoyi.common.core.utils.sql.SqlUtil;
|
|
||||||
import com.ruoyi.common.core.web.domain.AjaxResult;
|
import com.ruoyi.common.core.web.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.web.page.PageDomain;
|
|
||||||
import com.ruoyi.common.core.web.page.TableDataInfo;
|
import com.ruoyi.common.core.web.page.TableDataInfo;
|
||||||
import com.ruoyi.common.core.web.page.TableSupport;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* web层通用数据处理
|
* web层通用数据处理
|
||||||
|
|
@ -49,15 +45,7 @@ public class BaseController
|
||||||
*/
|
*/
|
||||||
protected void startPage()
|
protected void startPage()
|
||||||
{
|
{
|
||||||
PageDomain pageDomain = TableSupport.buildPageRequest();
|
PageUtils.startPage();
|
||||||
Integer pageNum = pageDomain.getPageNum();
|
|
||||||
Integer pageSize = pageDomain.getPageSize();
|
|
||||||
if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
|
|
||||||
{
|
|
||||||
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
|
|
||||||
Boolean reasonable = pageDomain.getReasonable();
|
|
||||||
PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@
|
||||||
"babel-eslint": "10.1.0",
|
"babel-eslint": "10.1.0",
|
||||||
"babel-plugin-dynamic-import-node": "2.3.3",
|
"babel-plugin-dynamic-import-node": "2.3.3",
|
||||||
"chalk": "4.1.0",
|
"chalk": "4.1.0",
|
||||||
|
"compression-webpack-plugin": "5.0.2",
|
||||||
"connect": "3.6.6",
|
"connect": "3.6.6",
|
||||||
"eslint": "7.15.0",
|
"eslint": "7.15.0",
|
||||||
"eslint-plugin-vue": "7.2.0",
|
"eslint-plugin-vue": "7.2.0",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
<template>
|
||||||
|
<el-image :src="`${realSrc}`" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="[`${realSrc}`]">
|
||||||
|
<div slot="error" class="image-slot">
|
||||||
|
<i class="el-icon-picture-outline"></i>
|
||||||
|
</div>
|
||||||
|
</el-image>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { isExternal } from '@/utils/validate'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ImagePreview',
|
||||||
|
props: {
|
||||||
|
src: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
realSrc() {
|
||||||
|
if (isExternal(this.src)) {
|
||||||
|
return this.src
|
||||||
|
}
|
||||||
|
return process.env.VUE_APP_BASE_API + this.src
|
||||||
|
},
|
||||||
|
realWidth() {
|
||||||
|
return typeof this.width == 'string' ? this.width : `${this.width}px`
|
||||||
|
},
|
||||||
|
realHeight() {
|
||||||
|
return typeof this.height == 'string' ? this.height : `${this.height}px`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.el-image {
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #ebeef5;
|
||||||
|
box-shadow: 0 0 5px 1px #ccc;
|
||||||
|
::v-deep .el-image__inner {
|
||||||
|
transition: all 0.3s;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::v-deep .image-slot {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -29,6 +29,8 @@ import Editor from "@/components/Editor"
|
||||||
import FileUpload from "@/components/FileUpload"
|
import FileUpload from "@/components/FileUpload"
|
||||||
// 图片上传组件
|
// 图片上传组件
|
||||||
import ImageUpload from "@/components/ImageUpload"
|
import ImageUpload from "@/components/ImageUpload"
|
||||||
|
// 图片预览组件
|
||||||
|
import ImagePreview from "@/components/ImagePreview"
|
||||||
// 字典标签组件
|
// 字典标签组件
|
||||||
import DictTag from '@/components/DictTag'
|
import DictTag from '@/components/DictTag'
|
||||||
// 头部标签组件
|
// 头部标签组件
|
||||||
|
|
@ -54,6 +56,7 @@ Vue.component('RightToolbar', RightToolbar)
|
||||||
Vue.component('Editor', Editor)
|
Vue.component('Editor', Editor)
|
||||||
Vue.component('FileUpload', FileUpload)
|
Vue.component('FileUpload', FileUpload)
|
||||||
Vue.component('ImageUpload', ImageUpload)
|
Vue.component('ImageUpload', ImageUpload)
|
||||||
|
Vue.component('ImagePreview', ImagePreview)
|
||||||
|
|
||||||
Vue.use(directive)
|
Vue.use(directive)
|
||||||
Vue.use(plugins)
|
Vue.use(plugins)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ import Layout from '@/layout'
|
||||||
* redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
|
* redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
|
||||||
* name:'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
|
* name:'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
|
||||||
* query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数
|
* query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数
|
||||||
|
* roles: ['admin', 'common'] // 访问路由的角色权限
|
||||||
|
* permissions: ['a:a:a', 'b:b:b'] // 访问路由的菜单权限
|
||||||
* meta : {
|
* meta : {
|
||||||
noCache: true // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
|
noCache: true // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
|
||||||
title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字
|
title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字
|
||||||
|
|
@ -85,11 +87,16 @@ export const constantRoutes = [
|
||||||
meta: { title: '个人中心', icon: 'user' }
|
meta: { title: '个人中心', icon: 'user' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// 动态路由,基于用户权限动态去加载
|
||||||
|
export const dynamicRoutes = [
|
||||||
{
|
{
|
||||||
path: '/system/user-auth',
|
path: '/system/user-auth',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
permissions: ['system:user:edit'],
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'role/:userId(\\d+)',
|
path: 'role/:userId(\\d+)',
|
||||||
|
|
@ -103,6 +110,7 @@ export const constantRoutes = [
|
||||||
path: '/system/role-auth',
|
path: '/system/role-auth',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
permissions: ['system:role:edit'],
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'user/:roleId(\\d+)',
|
path: 'user/:roleId(\\d+)',
|
||||||
|
|
@ -116,6 +124,7 @@ export const constantRoutes = [
|
||||||
path: '/system/dict-data',
|
path: '/system/dict-data',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
permissions: ['system:dict:list'],
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'index/:dictId(\\d+)',
|
path: 'index/:dictId(\\d+)',
|
||||||
|
|
@ -129,6 +138,7 @@ export const constantRoutes = [
|
||||||
path: '/monitor/job-log',
|
path: '/monitor/job-log',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
permissions: ['monitor:job:list'],
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'index',
|
path: 'index',
|
||||||
|
|
@ -142,6 +152,7 @@ export const constantRoutes = [
|
||||||
path: '/tool/gen-edit',
|
path: '/tool/gen-edit',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
permissions: ['tool:gen:edit'],
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'index',
|
path: 'index',
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { constantRoutes } from '@/router'
|
import auth from '@/plugins/auth'
|
||||||
|
import router, { constantRoutes, dynamicRoutes } from '@/router'
|
||||||
import { getRouters } from '@/api/menu'
|
import { getRouters } from '@/api/menu'
|
||||||
import Layout from '@/layout/index'
|
import Layout from '@/layout/index'
|
||||||
import ParentView from '@/components/ParentView'
|
import ParentView from '@/components/ParentView'
|
||||||
|
|
@ -42,7 +43,9 @@ const permission = {
|
||||||
const rdata = JSON.parse(JSON.stringify(res.data))
|
const rdata = JSON.parse(JSON.stringify(res.data))
|
||||||
const sidebarRoutes = filterAsyncRouter(sdata)
|
const sidebarRoutes = filterAsyncRouter(sdata)
|
||||||
const rewriteRoutes = filterAsyncRouter(rdata, false, true)
|
const rewriteRoutes = filterAsyncRouter(rdata, false, true)
|
||||||
|
const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
|
||||||
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
|
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
|
||||||
|
router.addRoutes(asyncRoutes);
|
||||||
commit('SET_ROUTES', rewriteRoutes)
|
commit('SET_ROUTES', rewriteRoutes)
|
||||||
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
|
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
|
||||||
commit('SET_DEFAULT_ROUTES', sidebarRoutes)
|
commit('SET_DEFAULT_ROUTES', sidebarRoutes)
|
||||||
|
|
@ -106,6 +109,23 @@ function filterChildren(childrenMap, lastRouter = false) {
|
||||||
return children
|
return children
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 动态路由遍历,验证是否具备权限
|
||||||
|
export function filterDynamicRoutes(routes) {
|
||||||
|
const res = []
|
||||||
|
routes.forEach(route => {
|
||||||
|
if (route.permissions) {
|
||||||
|
if (auth.hasPermiOr(route.permissions)) {
|
||||||
|
res.push(route)
|
||||||
|
}
|
||||||
|
} else if (route.roles) {
|
||||||
|
if (auth.hasRoleOr(route.roles)) {
|
||||||
|
res.push(route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
export const loadView = (view) => {
|
export const loadView = (view) => {
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
return (resolve) => require([`@/views/${view}`], resolve)
|
return (resolve) => require([`@/views/${view}`], resolve)
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24" v-if="form.menuType != 'F'">
|
<el-col :span="24" v-if="form.menuType != 'F'">
|
||||||
<el-form-item label="菜单图标">
|
<el-form-item label="菜单图标" prop="icon">
|
||||||
<el-popover
|
<el-popover
|
||||||
placement="bottom-start"
|
placement="bottom-start"
|
||||||
width="460"
|
width="460"
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ function resolve(dir) {
|
||||||
return path.join(__dirname, dir)
|
return path.join(__dirname, dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CompressionPlugin = require('compression-webpack-plugin')
|
||||||
|
|
||||||
const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题
|
const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题
|
||||||
|
|
||||||
const port = process.env.port || process.env.npm_config_port || 80 // 端口
|
const port = process.env.port || process.env.npm_config_port || 80 // 端口
|
||||||
|
|
@ -42,13 +44,29 @@ module.exports = {
|
||||||
},
|
},
|
||||||
disableHostCheck: true
|
disableHostCheck: true
|
||||||
},
|
},
|
||||||
|
css: {
|
||||||
|
loaderOptions: {
|
||||||
|
sass: {
|
||||||
|
sassOptions: { outputStyle: "expanded" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
configureWebpack: {
|
configureWebpack: {
|
||||||
name: name,
|
name: name,
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': resolve('src')
|
'@': resolve('src')
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
plugins: [
|
||||||
|
new CompressionPlugin({
|
||||||
|
test: /\.(js|css|html)?$/i, // 压缩文件格式
|
||||||
|
filename: '[path].gz[query]', // 压缩后的文件名
|
||||||
|
algorithm: 'gzip', // 使用gzip压缩
|
||||||
|
threshold: 10240, // 对超过10K的数据压缩
|
||||||
|
minRatio: 0.8 // 压缩率小于1才会压缩
|
||||||
|
})
|
||||||
|
],
|
||||||
},
|
},
|
||||||
chainWebpack(config) {
|
chainWebpack(config) {
|
||||||
config.plugins.delete('preload') // TODO: need test
|
config.plugins.delete('preload') // TODO: need test
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue