mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2026-01-03 20:35:29 +08:00
Jeecg-Boot 2.2.0 版本发布 | 重磅升级
This commit is contained in:
@ -14,6 +14,7 @@ const FormTypes = {
|
||||
sel_search:"sel_search",
|
||||
radio:'radio',
|
||||
checkbox_meta:"checkbox_meta",
|
||||
input_pop:'input_pop',
|
||||
|
||||
slot: 'slot',
|
||||
hidden: 'hidden'
|
||||
@ -77,18 +78,22 @@ export function validateFormAndTables(form, cases) {
|
||||
/**
|
||||
* 验证并获取一个或多个表格的所有值
|
||||
* @param cases 接收一个数组,每项都是一个JEditableTable实例
|
||||
* @param deleteTempId 是否删除临时ID,如果设为true,行编辑就不返回新增行的ID,ID需要后台生成
|
||||
* @author sunjianlei
|
||||
*/
|
||||
export function validateTables(cases) {
|
||||
export function validateTables(cases, deleteTempId) {
|
||||
if (!(cases instanceof Array)) {
|
||||
throw `'validateTables'函数的'cases'参数需要的是一个数组,而传入的却是${typeof cases}`
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let tables = []
|
||||
let index = 0;
|
||||
if(!cases || cases.length==0){
|
||||
resolve()
|
||||
}
|
||||
(function next() {
|
||||
let vm = cases[index]
|
||||
vm.getAll(true).then(all => {
|
||||
vm.getAll(true, deleteTempId).then(all => {
|
||||
tables[index] = all
|
||||
// 判断校验是否全部完成,完成返回成功,否则继续进行下一步校验
|
||||
if (++index === cases.length) {
|
||||
|
||||
@ -9,9 +9,10 @@ export function disabledAuthFilter(code,formData) {
|
||||
}
|
||||
|
||||
function nodeDisabledAuth(code,formData){
|
||||
console.log("页面权限禁用--NODE--开始");
|
||||
let permissionList = [];
|
||||
try {
|
||||
//console.log("页面权限禁用--NODE--开始",obj);
|
||||
console.log("页面权限禁用--NODE--开始",formData);
|
||||
if (formData) {
|
||||
let bpmList = formData.permissionList;
|
||||
permissionList = bpmList.filter(item=>item.type=='2')
|
||||
@ -52,10 +53,10 @@ function nodeDisabledAuth(code,formData){
|
||||
}
|
||||
|
||||
function globalDisabledAuth(code){
|
||||
//console.log("全局页面禁用权限--Global--开始");
|
||||
console.log("全局页面禁用权限--Global--开始");
|
||||
|
||||
var permissionList = [];
|
||||
var allPermissionList = [];
|
||||
let permissionList = [];
|
||||
let allPermissionList = [];
|
||||
|
||||
//let authList = Vue.ls.get(USER_AUTH);
|
||||
let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
|
||||
@ -72,8 +73,8 @@ function globalDisabledAuth(code){
|
||||
}
|
||||
}
|
||||
//设置全局配置是否有命中
|
||||
var gFlag = false;//禁用命中
|
||||
var invalidFlag = false;//无效命中
|
||||
let gFlag = false;//禁用命中
|
||||
let invalidFlag = false;//无效命中
|
||||
if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){
|
||||
for (let itemG of allPermissionList) {
|
||||
if(code === itemG.action){
|
||||
@ -116,7 +117,7 @@ function globalDisabledAuth(code){
|
||||
|
||||
|
||||
export function colAuthFilter(columns,pre) {
|
||||
var authList = getNoAuthCols(pre);
|
||||
let authList = getNoAuthCols(pre);
|
||||
const cols = columns.filter(item => {
|
||||
if (hasColoum(item,authList)) {
|
||||
return true
|
||||
@ -126,6 +127,44 @@ export function colAuthFilter(columns,pre) {
|
||||
return cols
|
||||
}
|
||||
|
||||
/**
|
||||
* 【子表行编辑】实现两个功能:
|
||||
* 1、隐藏JEditableTable无权限的字段
|
||||
* 2、禁用JEditableTable无权限的字段
|
||||
* @param columns
|
||||
* @param pre
|
||||
* @returns {*}
|
||||
*/
|
||||
export function colAuthFilterJEditableTable(columns,pre) {
|
||||
let authList = getAllShowAndDisabledAuthCols(pre);
|
||||
const cols = columns.filter(item => {
|
||||
let oneAuth = authList.find(auth => {
|
||||
return auth.action === pre + item.key;
|
||||
});
|
||||
if(!oneAuth){
|
||||
return true
|
||||
}
|
||||
|
||||
//代码严谨处理,防止一个授权标识,配置多次
|
||||
if(oneAuth instanceof Array){
|
||||
oneAuth = oneAuth[0]
|
||||
}
|
||||
|
||||
//禁用逻辑
|
||||
if (oneAuth.type == '2' && !oneAuth.isAuth) {
|
||||
item["disabled"] = true
|
||||
return true
|
||||
}
|
||||
//隐藏逻辑逻辑
|
||||
if (oneAuth.type == '1' && !oneAuth.isAuth) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
return cols
|
||||
}
|
||||
|
||||
|
||||
function hasColoum(item,authList){
|
||||
if (authList.includes(item.dataIndex)) {
|
||||
return false
|
||||
@ -164,6 +203,32 @@ function getNoAuthCols(pre){
|
||||
return cols;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 额外增加方法【用于行编辑组件】
|
||||
* date: 2020-04-05
|
||||
* author: scott
|
||||
* @param pre
|
||||
* @returns {*[]}
|
||||
*/
|
||||
function getAllShowAndDisabledAuthCols(pre){
|
||||
//用户拥有的权限
|
||||
let userAuthList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
|
||||
//全部权限配置
|
||||
let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]");
|
||||
|
||||
let newAllAuthList = allAuthList.map(function (item, index) {
|
||||
let hasAuthArray = userAuthList.filter(u => u.action===item.action );
|
||||
if (hasAuthArray && hasAuthArray.length>0) {
|
||||
item["isAuth"] = true
|
||||
}
|
||||
return item;
|
||||
})
|
||||
|
||||
return newAllAuthList;
|
||||
}
|
||||
|
||||
function startWith(str,pre) {
|
||||
if (pre == null || pre == "" || str==null|| str==""|| str.length == 0 || pre.length > str.length)
|
||||
return false;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { getFileAccessHttpUrl } from '@/api/manage'
|
||||
const getFileName=(path)=>{
|
||||
if(path.lastIndexOf("\\")>=0){
|
||||
let reg=new RegExp("\\\\","g");
|
||||
@ -15,7 +16,7 @@ const getFilePaths=(uploadFiles)=>{
|
||||
if(!uploadFiles){
|
||||
return ""
|
||||
}
|
||||
for(var a=0;a<uploadFiles.length;a++){
|
||||
for(let a=0;a<uploadFiles.length;a++){
|
||||
arr.push(uploadFiles[a].response.message)
|
||||
}
|
||||
if(arr && arr.length>0){
|
||||
@ -30,7 +31,7 @@ const getUploadFileList=(paths)=>{
|
||||
}
|
||||
let fileList = [];
|
||||
let arr = paths.split(",")
|
||||
for(var a=0;a<arr.length;a++){
|
||||
for(let a=0;a<arr.length;a++){
|
||||
if(!arr[a]){
|
||||
continue
|
||||
}else{
|
||||
@ -38,7 +39,7 @@ const getUploadFileList=(paths)=>{
|
||||
uid:uidGenerator(),
|
||||
name:getFileName(arr[a]),
|
||||
status: 'done',
|
||||
url: window._CONFIG['staticDomainURL']+"/"+arr[a],
|
||||
url: getFileAccessHttpUrl(arr[a]),
|
||||
response:{
|
||||
status:"history",
|
||||
message:arr[a]
|
||||
|
||||
22
ant-design-vue-jeecg/src/utils/desform/CustomExpression.js
Normal file
22
ant-design-vue-jeecg/src/utils/desform/CustomExpression.js
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
*
|
||||
* 这里填写用户自定义的表达式
|
||||
* 可用在Online表单的默认值表达式中使用
|
||||
* 需要外部使用的变量或方法一定要 export,否则无法识别
|
||||
* 示例:
|
||||
* export const name = '张三'; // const 是常量
|
||||
* export let age = 17; // 看情况 export const 还是 let ,两者都可正常使用
|
||||
* export function content(arg) { // export 方法,可传参数,使用时要加括号,值一定要return回去,可以返回Promise
|
||||
* return 'content' + arg;
|
||||
* }
|
||||
* export const address = (arg) => content(arg) + ' | 北京市'; // export 箭头函数也可以
|
||||
*
|
||||
*/
|
||||
|
||||
/** 字段默认值官方示例:获取地址 */
|
||||
export function demoFieldDefVal_getAddress(arg) {
|
||||
if (!arg) {
|
||||
arg = '朝阳区'
|
||||
}
|
||||
return `北京市 ${arg}`
|
||||
}
|
||||
@ -2,16 +2,16 @@ import { USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types"
|
||||
|
||||
const hasPermission = {
|
||||
install (Vue, options) {
|
||||
//console.log(options);
|
||||
console.log(options);
|
||||
Vue.directive('has', {
|
||||
inserted: (el, binding, vnode)=>{
|
||||
//console.log("页面权限控制----");
|
||||
console.time()
|
||||
console.log("页面权限控制----");
|
||||
//console.time()
|
||||
//节点权限处理,如果命中则不进行全局权限处理
|
||||
if(!filterNodePermission(el, binding, vnode)){
|
||||
filterGlobalPermission(el, binding, vnode);
|
||||
}
|
||||
console.timeEnd() //计时结束并输出时长
|
||||
//console.timeEnd() //计时结束并输出时长
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
115
ant-design-vue-jeecg/src/utils/props-util.js
Normal file
115
ant-design-vue-jeecg/src/utils/props-util.js
Normal file
@ -0,0 +1,115 @@
|
||||
/**
|
||||
* 该文件截取自 "ant-design-vue/es/_util/props-util.js" 文件,并对其做出特殊修改
|
||||
*/
|
||||
function classNames() {
|
||||
let classes = []
|
||||
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
let arg = arguments[i]
|
||||
if (!arg) continue
|
||||
|
||||
let argType = typeof arg
|
||||
|
||||
if (argType === 'string' || argType === 'number') {
|
||||
classes.push(arg)
|
||||
} else if (Array.isArray(arg) && arg.length) {
|
||||
let inner = classNames.apply(null, arg)
|
||||
if (inner) {
|
||||
classes.push(inner)
|
||||
}
|
||||
} else if (argType === 'object') {
|
||||
for (let key in arg) {
|
||||
if (arg.hasOwnProperty(key) && arg[key]) {
|
||||
classes.push(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return classes.join(' ')
|
||||
}
|
||||
|
||||
const camelizeRE = /-(\w)/g
|
||||
|
||||
function camelize(str) {
|
||||
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''))
|
||||
}
|
||||
|
||||
|
||||
function objectCamelize(obj) {
|
||||
let res = {}
|
||||
Object.keys(obj).forEach(k => (res[camelize(k)] = obj[k]))
|
||||
return res
|
||||
}
|
||||
|
||||
function parseStyleText(cssText = '', camel) {
|
||||
const res = {}
|
||||
const listDelimiter = /;(?![^(]*\))/g
|
||||
const propertyDelimiter = /:(.+)/
|
||||
cssText.split(listDelimiter).forEach(function (item) {
|
||||
if (item) {
|
||||
const tmp = item.split(propertyDelimiter)
|
||||
if (tmp.length > 1) {
|
||||
const k = camel ? camelize(tmp[0].trim()) : tmp[0].trim()
|
||||
res[k] = tmp[1].trim()
|
||||
}
|
||||
}
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
export function getClass(ele) {
|
||||
let data = {}
|
||||
if (ele.data) {
|
||||
data = ele.data
|
||||
} else if (ele.$vnode && ele.$vnode.data) {
|
||||
data = ele.$vnode.data
|
||||
}
|
||||
const tempCls = data.class || {}
|
||||
const staticClass = data.staticClass
|
||||
let cls = {}
|
||||
staticClass &&
|
||||
staticClass.split(' ').forEach(c => {
|
||||
cls[c.trim()] = true
|
||||
})
|
||||
if (typeof tempCls === 'string') {
|
||||
tempCls.split(' ').forEach(c => {
|
||||
cls[c.trim()] = true
|
||||
})
|
||||
} else if (Array.isArray(tempCls)) {
|
||||
classNames(tempCls)
|
||||
.split(' ')
|
||||
.forEach(c => {
|
||||
cls[c.trim()] = true
|
||||
})
|
||||
} else {
|
||||
cls = { ...cls, ...tempCls }
|
||||
}
|
||||
return cls
|
||||
}
|
||||
|
||||
export function getStyle(ele, camel) {
|
||||
|
||||
getClass(ele)
|
||||
|
||||
let data = {}
|
||||
if (ele.data) {
|
||||
data = ele.data
|
||||
} else if (ele.$vnode && ele.$vnode.data) {
|
||||
data = ele.$vnode.data
|
||||
}
|
||||
|
||||
// update-begin-author:sunjianlei date:20200303 for: style 和 staticStyle 可以共存
|
||||
let style = data.style || {}
|
||||
let staticStyle = data.staticStyle
|
||||
staticStyle = staticStyle ? objectCamelize(data.staticStyle) : {}
|
||||
// update-end-author:sunjianlei date:20200303 for: style 和 staticStyle 可以共存
|
||||
|
||||
if (typeof style === 'string') {
|
||||
style = parseStyleText(style, camel)
|
||||
} else if (camel && style) {
|
||||
// 驼峰化
|
||||
style = objectCamelize(style)
|
||||
}
|
||||
return { ...staticStyle, ...style }
|
||||
}
|
||||
|
||||
@ -5,16 +5,18 @@ import { VueAxios } from './axios'
|
||||
import {Modal, notification} from 'ant-design-vue'
|
||||
import { ACCESS_TOKEN } from "@/store/mutation-types"
|
||||
|
||||
//自动设置后台服务 baseURL (也可以手工指定写死项目名字)
|
||||
let baseDomain = window._CONFIG['domianURL'];
|
||||
let baseProject = baseDomain.substring(baseDomain.lastIndexOf("/"));
|
||||
console.log("baseDomain= ",baseDomain)
|
||||
console.log("baseProject= ",baseProject)
|
||||
|
||||
/**
|
||||
* 【指定 axios的 baseURL】
|
||||
* 如果手工指定 baseURL: '/jeecg-boot'
|
||||
* 则映射后端域名,通过 vue.config.js
|
||||
* @type {*|string}
|
||||
*/
|
||||
let apiBaseUrl = window._CONFIG['domianURL'] || "/jeecg-boot";
|
||||
console.log("apiBaseUrl= ",apiBaseUrl)
|
||||
// 创建 axios 实例
|
||||
const service = axios.create({
|
||||
//baseURL: '/jeecg-boot',
|
||||
baseURL: baseProject, // api base_url
|
||||
baseURL: apiBaseUrl, // api base_url
|
||||
timeout: 9000 // 请求超时时间
|
||||
})
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import * as api from '@/api/api'
|
||||
import { isURL } from '@/utils/validate'
|
||||
import onlineCommons from '@jeecg/antd-online-beta220'
|
||||
|
||||
export function timeFix() {
|
||||
const time = new Date()
|
||||
@ -33,7 +34,7 @@ export function filterObj(obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( var key in obj) {
|
||||
for ( let key in obj) {
|
||||
if (obj.hasOwnProperty(key)
|
||||
&& (obj[key] == null || obj[key] == undefined || obj[key] === '')) {
|
||||
delete obj[key];
|
||||
@ -49,7 +50,7 @@ export function filterObj(obj) {
|
||||
* @returns {*}
|
||||
*/
|
||||
export function formatDate(value, fmt) {
|
||||
var regPos = /^\d+(\.\d+)?$/;
|
||||
let regPos = /^\d+(\.\d+)?$/;
|
||||
if(regPos.test(value)){
|
||||
//如果是数字
|
||||
let getDate = new Date(value);
|
||||
@ -100,7 +101,7 @@ let indexRouter = [{
|
||||
|
||||
function generateChildRouters (data) {
|
||||
const routers = [];
|
||||
for (var item of data) {
|
||||
for (let item of data) {
|
||||
let component = "";
|
||||
if(item.component.indexOf("layouts")>=0){
|
||||
component = "components/"+item.component;
|
||||
@ -114,11 +115,33 @@ function generateChildRouters (data) {
|
||||
item.meta.url = URL;
|
||||
}
|
||||
|
||||
//online菜单路由加载逻辑
|
||||
let componentPath
|
||||
if(item.component=="modules/online/cgform/OnlCgformHeadList"){
|
||||
componentPath = onlineCommons.OnlCgformHeadList
|
||||
}else if(item.component=="modules/online/cgform/OnlCgformCopyList"){
|
||||
componentPath = onlineCommons.OnlCgformCopyList
|
||||
}else if(item.component=="modules/online/cgform/auto/OnlCgformAutoList"){
|
||||
componentPath = onlineCommons.OnlCgformAutoList
|
||||
}else if(item.component=="modules/online/cgform/auto/OnlCgformTreeList"){
|
||||
componentPath = onlineCommons.OnlCgformTreeList
|
||||
}else if(item.component=="modules/online/cgform/auto/erp/OnlCgformErpList"){
|
||||
componentPath = onlineCommons.OnlCgformErpList
|
||||
}else if(item.component=="modules/online/cgform/auto/innerTable/OnlCgformInnerTableList"){
|
||||
componentPath = onlineCommons.OnlCgformInnerTableList
|
||||
}else if(item.component=="modules/online/cgreport/OnlCgreportHeadList"){
|
||||
componentPath = onlineCommons.OnlCgreportHeadList
|
||||
}else if(item.component=="modules/online/cgreport/auto/OnlCgreportAutoList"){
|
||||
componentPath = onlineCommons.OnlCgreportAutoList
|
||||
}else{
|
||||
componentPath = resolve => require(['@/' + component+'.vue'], resolve)
|
||||
}
|
||||
|
||||
let menu = {
|
||||
path: item.path,
|
||||
name: item.name,
|
||||
redirect:item.redirect,
|
||||
component: resolve => require(['@/' + component+'.vue'], resolve),
|
||||
component: componentPath,
|
||||
hidden:item.hidden,
|
||||
//component:()=> import(`@/views/${item.component}.vue`),
|
||||
meta: {
|
||||
@ -414,4 +437,44 @@ export function alwaysResolve(promise) {
|
||||
reject('alwaysResolve: 传入的参数不是一个Promise对象或返回Promise对象的方法')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 简单实现防抖方法
|
||||
*
|
||||
* 防抖(debounce)函数在第一次触发给定的函数时,不立即执行函数,而是给出一个期限值(delay),比如100ms。
|
||||
* 如果100ms内再次执行函数,就重新开始计时,直到计时结束后再真正执行函数。
|
||||
* 这样做的好处是如果短时间内大量触发同一事件,只会执行一次函数。
|
||||
*
|
||||
* @param fn 要防抖的函数
|
||||
* @param delay 防抖的毫秒数
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function simpleDebounce(fn, delay = 100) {
|
||||
let timer = null
|
||||
return function () {
|
||||
let args = arguments
|
||||
if (timer) {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
timer = setTimeout(() => {
|
||||
fn.apply(null, args)
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 不用正则的方式替换所有值
|
||||
* @param text 被替换的字符串
|
||||
* @param checker 替换前的内容
|
||||
* @param replacer 替换后的内容
|
||||
* @returns {String} 替换后的字符串
|
||||
*/
|
||||
export function replaceAll(text, checker, replacer) {
|
||||
let lastText = text
|
||||
text = text.replace(checker, replacer)
|
||||
if (lastText !== text) {
|
||||
return replaceAll(text, checker, replacer)
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user