Compare commits
16 Commits
v3.5.1
...
v3.5.1last
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9d61822479 | ||
![]() |
7bab382d8d | ||
![]() |
caf9622cd9 | ||
![]() |
356844e67f | ||
![]() |
1b4dca16ed | ||
![]() |
87580883d1 | ||
![]() |
21e9e88dc6 | ||
![]() |
2e8c754559 | ||
![]() |
64679f7193 | ||
![]() |
bcfb19b8bb | ||
![]() |
eb6b2f3d59 | ||
![]() |
c7ce152bab | ||
![]() |
249a66c98f | ||
![]() |
9259f57e54 | ||
![]() |
9cd45ed81d | ||
![]() |
df8d599e58 |
34
.env.test
34
.env.test
@@ -1,34 +0,0 @@
|
||||
# 是否启用mock
|
||||
VITE_USE_MOCK = true
|
||||
|
||||
# 发布路径
|
||||
VITE_PUBLIC_PATH = /
|
||||
|
||||
# 控制台不输出
|
||||
VITE_DROP_CONSOLE = true
|
||||
|
||||
# 是否启用gzip或brotli压缩
|
||||
# 选项值: gzip | brotli | none
|
||||
# 如果需要多个可以使用“,”分隔
|
||||
VITE_BUILD_COMPRESS = 'gzip'
|
||||
|
||||
# 使用压缩时是否删除原始文件,默认为false
|
||||
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
|
||||
|
||||
#后台接口父地址(必填)
|
||||
VITE_GLOB_API_URL=/jeecgboot
|
||||
|
||||
#后台接口全路径地址(必填)
|
||||
VITE_GLOB_DOMAIN_URL=http://localhost:8080/jeecg-boot
|
||||
|
||||
# 接口父路径前缀
|
||||
VITE_GLOB_API_URL_PREFIX=
|
||||
|
||||
# 是否启用图像压缩
|
||||
VITE_USE_IMAGEMIN= true
|
||||
|
||||
# 使用pwa
|
||||
VITE_USE_PWA = false
|
||||
|
||||
# 是否兼容旧浏览器
|
||||
VITE_LEGACY = false
|
@@ -13,7 +13,6 @@
|
||||
"clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite",
|
||||
"clean:lib": "rimraf node_modules",
|
||||
"build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 vite build && esno ./build/script/postBuild.ts",
|
||||
"build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode test && esno ./build/script/postBuild.ts",
|
||||
"build:no-cache": "pnpm clean:cache && npm run build",
|
||||
"report": "cross-env REPORT=true npm run build",
|
||||
"type:check": "vue-tsc --noEmit --skipLibCheck",
|
||||
|
@@ -114,6 +114,17 @@
|
||||
//--@updateBy-begin----author:liusq---date:20210914------for:判断选择模式,multiple多选情况下的value值空的情况下需要设置为数组------
|
||||
unref(attrs).mode == 'multiple' && !Array.isArray(unref(state)) && setState([]);
|
||||
//--@updateBy-end----author:liusq---date:20210914------for:判断选择模式,multiple多选情况下的value值空的情况下需要设置为数组------
|
||||
|
||||
//update-begin---author:wangshuai ---date:20230505 for:初始化value值,如果是多选字符串的情况下显示不出来------------
|
||||
initValue();
|
||||
//update-end---author:wangshuai ---date:20230505 for:初始化value值,如果是多选字符串的情况下显示不出来------------
|
||||
}
|
||||
}
|
||||
|
||||
function initValue() {
|
||||
let value = props.value;
|
||||
if (value && typeof value === 'string' && value != 'null' && value != 'undefined') {
|
||||
state.value = value.split(',');
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -35,6 +35,7 @@
|
||||
v-model:value="state"
|
||||
:filterOption="handleFilterOption"
|
||||
:getPopupContainer="getPopupContainer"
|
||||
:style="style"
|
||||
@change="handleChange"
|
||||
>
|
||||
<a-select-option v-if="showChooseOption" :value="null">请选择…</a-select-option>
|
||||
@@ -80,6 +81,7 @@
|
||||
default: [],
|
||||
required: false,
|
||||
},
|
||||
style: propTypes.any,
|
||||
},
|
||||
emits: ['options-change', 'change','update:value'],
|
||||
setup(props, { emit, refs }) {
|
||||
@@ -176,6 +178,9 @@
|
||||
/** 单选radio的值变化事件 */
|
||||
function handleChangeRadio(e) {
|
||||
state.value = e?.target?.value ?? e;
|
||||
//update-begin---author:wangshuai ---date:20230504 for:【issues/506】JDictSelectTag 组件 type="radio" 没有返回值------------
|
||||
emit('update:value',e?.target?.value ?? e)
|
||||
//update-end---author:wangshuai ---date:20230504 for:【issues/506】JDictSelectTag 组件 type="radio" 没有返回值------------
|
||||
}
|
||||
|
||||
/** 用于搜索下拉框中的内容 */
|
||||
|
@@ -124,13 +124,16 @@
|
||||
watch(
|
||||
() => props.value,
|
||||
(val, prevCount) => {
|
||||
if (val instanceof Array) {
|
||||
//update-begin---author:liusq ---date:20230601 for:【issues/556】JImageUpload组件value赋初始值没显示图片------------
|
||||
if (val && val instanceof Array) {
|
||||
val = val.join(',');
|
||||
}
|
||||
if (initTag.value == true) {
|
||||
initFileList(val);
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
//update-end---author:liusq ---date:20230601 for:【issues/556】JImageUpload组件value赋初始值没显示图片------------
|
||||
);
|
||||
|
||||
/**
|
||||
|
@@ -298,7 +298,12 @@
|
||||
// 如果设定了排序信息,需要写入排序信息,在关键词后加 [orderby:create_time,desc]
|
||||
if(props.params && props.params.column && props.params.order){
|
||||
let temp = text||''
|
||||
return temp+'[orderby:'+props.params.column+','+props.params.order+']'
|
||||
|
||||
//update-begin-author:taoyan date:2023-5-22 for: /issues/4905 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误! #4905
|
||||
temp = temp+'[orderby:'+props.params.column+','+props.params.order+']'
|
||||
return encodeURI(temp);
|
||||
//update-end-author:taoyan date:2023-5-22 for: /issues/4905 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误! #4905
|
||||
|
||||
}else{
|
||||
return text;
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
emits: ['options-change', 'change'],
|
||||
emits: ['options-change', 'change', 'update:value'],
|
||||
setup(props, { emit, refs }) {
|
||||
const emitData = ref<any[]>();
|
||||
//注册model
|
||||
@@ -108,6 +108,10 @@
|
||||
//emitData.value = values.join(",");
|
||||
state.value = values;
|
||||
selectValues.value = values;
|
||||
//update-begin-author:liusq date:20230517 for:选择职务组件v-model方式绑定值不生效
|
||||
emit('update:value', values.join(','));
|
||||
//update-begin-author:liusq date:20230517 for:选择职务组件v-model方式绑定值不生效
|
||||
|
||||
}
|
||||
|
||||
const getBindValue = Object.assign({}, unref(props), unref(attrs));
|
||||
|
@@ -64,8 +64,10 @@
|
||||
|
||||
//update-begin-author:taoyan date:2022-10-28 for: 部门选择警告类型不匹配
|
||||
let propValue = props.value === ''?[]:props.value;
|
||||
const getBindValue = Object.assign({}, unref(props), unref(attrs), {value: propValue});
|
||||
//update-end-author:taoyan date:2022-10-28 for: 部门选择警告类型不匹配
|
||||
//update-begin-author:liusq date:2023-05-26 for: [issues/538]JSelectDept组件受 dynamicDisabled 影响
|
||||
const getBindValue = Object.assign({}, unref(props), unref(attrs), {value: propValue},{disabled: false});
|
||||
//update-end-author:liusq date:2023-05-26 for: [issues/538]JSelectDept组件受 dynamicDisabled 影响
|
||||
//update-end-author:taoyan date:2022-10-28 for: 部门选择警告类型不匹配
|
||||
|
||||
const queryUrl = getQueryUrl();
|
||||
const [{ visibleChange, checkedKeys, getCheckStrictly, getSelectTreeData, onCheck, onLoadData, treeData, checkALL, expandAll, onSelect }] =
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<ModalClose :canFullscreen="getProps.canFullscreen" :fullScreen="fullScreenRef" :commentSpan="commentSpan" :enableComment="getProps.enableComment" @comment="handleComment" @cancel="handleCancel" @fullscreen="handleFullScreen" />
|
||||
</template>
|
||||
|
||||
<template #title v-if="!$slots.title">
|
||||
<template #title v-if="!isNoTitle">
|
||||
<ModalHeader :helpMessage="getProps.helpMessage" :title="getMergeProps.title" @dblclick="handleTitleDbClick" />
|
||||
</template>
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
inheritAttrs: false,
|
||||
props: basicProps,
|
||||
emits: ['visible-change', 'height-change', 'cancel', 'ok', 'register', 'update:visible'],
|
||||
setup(props, { emit, attrs }) {
|
||||
setup(props, { emit, attrs , slots}) {
|
||||
const visibleRef = ref(false);
|
||||
const propsRef = ref<Partial<ModalProps> | null>(null);
|
||||
const modalWrapperRef = ref<any>(null);
|
||||
@@ -101,6 +101,13 @@
|
||||
...(unref(propsRef) as any),
|
||||
};
|
||||
});
|
||||
//update-begin-author:liusq date:2023-05-25 for:【issues/4856】Modal控件设置 :title = null 无效
|
||||
//是否未设置标题
|
||||
const isNoTitle = computed(() => {
|
||||
//标题为空并且不含有标题插槽
|
||||
return !unref(getMergeProps).title && !slots.title;
|
||||
});
|
||||
//update-end-author:liusq date:2023-05-25 for:【issues/4856】Modal控件设置 :title = null 无效
|
||||
|
||||
const { handleFullScreen, getWrapClassName, fullScreenRef } = useFullScreen({
|
||||
modalWrapperRef,
|
||||
@@ -243,7 +250,8 @@
|
||||
handleTitleDbClick,
|
||||
getWrapperHeight,
|
||||
commentSpan,
|
||||
handleComment
|
||||
handleComment,
|
||||
isNoTitle
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@@ -5,5 +5,3 @@ import pageWrapper from './src/PageWrapper.vue';
|
||||
|
||||
export const PageFooter = withInstall(pageFooter);
|
||||
export const PageWrapper = withInstall(pageWrapper);
|
||||
|
||||
export const PageWrapperFixedHeightKey = 'PageWrapperFixedHeight';
|
||||
|
1
src/components/Page/injectionKey.ts
Normal file
1
src/components/Page/injectionKey.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const PageWrapperFixedHeightKey = 'PageWrapperFixedHeight';
|
@@ -43,7 +43,7 @@
|
||||
import { omit } from 'lodash-es';
|
||||
import { PageHeader } from 'ant-design-vue';
|
||||
import { useContentHeight } from '/@/hooks/web/useContentHeight';
|
||||
import { PageWrapperFixedHeightKey } from '..';
|
||||
import { PageWrapperFixedHeightKey } from '../injectionKey';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PageWrapper',
|
||||
|
@@ -38,7 +38,7 @@
|
||||
import { defineComponent, ref, computed, unref, toRaw, inject, watchEffect } from 'vue';
|
||||
import { Table } from 'ant-design-vue';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { PageWrapperFixedHeightKey } from '/@/components/Page';
|
||||
import { PageWrapperFixedHeightKey } from '/@/components/Page/injectionKey';
|
||||
import expandIcon from './components/ExpandIcon';
|
||||
import HeaderCell from './components/HeaderCell.vue';
|
||||
import { InnerHandlers } from './types/table';
|
||||
@@ -349,6 +349,14 @@
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
//update-begin-author:liusq---date:20230517--for: [issues/526]RangePicker 设置预设范围按钮样式问题---
|
||||
.ant-picker-preset {
|
||||
.ant-tag {
|
||||
margin-right: 8px !important;
|
||||
}
|
||||
}
|
||||
//update-end-author:liusq---date:20230517--for: [issues/526]RangePicker 设置预设范围按钮样式问题---
|
||||
|
||||
.ant-table-wrapper {
|
||||
padding: 6px;
|
||||
background-color: @component-background;
|
||||
|
@@ -190,7 +190,7 @@
|
||||
currentValueRef.value = (e as ChangeEvent).target.value;
|
||||
} else if (component === 'Checkbox') {
|
||||
currentValueRef.value = (e as ChangeEvent).target.checked;
|
||||
} else if (isString(e) || isBoolean(e) || isNumber(e)) {
|
||||
} else if (isString(e) || isBoolean(e) || isNumber(e) || isArray(e)) {
|
||||
currentValueRef.value = e;
|
||||
}
|
||||
const onChange = props.column?.editComponentProps?.onChange;
|
||||
|
@@ -46,8 +46,13 @@ export function createPermissionGuard(router: Router) {
|
||||
if (whitePathList.includes(to.path as PageEnum)) {
|
||||
if (to.path === LOGIN_PATH && token) {
|
||||
const isSessionTimeout = userStore.getSessionTimeout;
|
||||
|
||||
//update-begin---author:scott ---date:2023-04-24 for:【QQYUN-4713】登录代码调整逻辑有问题,改造待观察--
|
||||
//TODO vben默认写法,暂时不知目的,有问题暂时先注释掉
|
||||
//await userStore.afterLoginAction();
|
||||
//update-end---author:scott ---date::2023-04-24 for:【QQYUN-4713】登录代码调整逻辑有问题,改造待观察--
|
||||
|
||||
try {
|
||||
await userStore.afterLoginAction();
|
||||
if (!isSessionTimeout) {
|
||||
next((to.query?.redirect as string) || '/');
|
||||
return;
|
||||
|
@@ -7,18 +7,48 @@ import { RouteParams } from 'vue-router';
|
||||
import { toRaw } from 'vue';
|
||||
|
||||
export function getAllParentPath<T = Recordable>(treeData: T[], path: string) {
|
||||
const menuList = findPath(treeData, (n) => n.path === path) as Menu[];
|
||||
// update-begin--author:sunjianlei---date:220230426---for:【issues/478】修复菜单展开合并BUG
|
||||
// 原代码
|
||||
// const menuList = findPath(treeData, (n) => n.path === path) as Menu[];
|
||||
// 先匹配不包含隐藏菜单的路径
|
||||
let menuList = findMenuPath(treeData, path, false);
|
||||
// 如果没有匹配到,再匹配包含隐藏菜单的路径
|
||||
if(!(menuList?.length)) {
|
||||
menuList = findMenuPath(treeData, path, true)
|
||||
}
|
||||
// update-end--author:sunjianlei---date:220230426---for:【issues/478】修复菜单展开合并BUG
|
||||
return (menuList || []).map((item) => item.path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找菜单路径
|
||||
*
|
||||
* @param treeData
|
||||
* @param path
|
||||
* @param matchHide 是否匹配隐藏菜单
|
||||
*/
|
||||
function findMenuPath<T = Recordable>(treeData: T[], path: string, matchHide: boolean) {
|
||||
return findPath(treeData, (n) => {
|
||||
// 隐藏菜单不参与匹配
|
||||
if(!matchHide && n.hideMenu) {
|
||||
return false;
|
||||
}
|
||||
return n.path === path
|
||||
}) as Menu[];
|
||||
}
|
||||
|
||||
// 路径处理
|
||||
function joinParentPath(menus: Menu[], parentPath = '') {
|
||||
for (let index = 0; index < menus.length; index++) {
|
||||
const menu = menus[index];
|
||||
// https://next.router.vuejs.org/guide/essentials/nested-routes.html
|
||||
// Note that nested paths that start with / will be treated as a root path.
|
||||
// 请注意,以 / 开头的嵌套路径将被视为根路径。
|
||||
// This allows you to leverage the component nesting without having to use a nested URL.
|
||||
// 这允许你利用组件嵌套,而无需使用嵌套 URL。
|
||||
if (!(menu.path.startsWith('/') || isUrl(menu.path))) {
|
||||
// path doesn't start with /, nor is it a url, join parent path
|
||||
// 路径不以 / 开头,也不是 url,加入父路径
|
||||
menu.path = `${parentPath}/${menu.path}`;
|
||||
}
|
||||
if (menu?.children?.length) {
|
||||
@@ -37,14 +67,18 @@ export function transformMenuModule(menuModule: MenuModule): Menu {
|
||||
return menuList[0];
|
||||
}
|
||||
|
||||
// 将路由转换成菜单
|
||||
export function transformRouteToMenu(routeModList: AppRouteModule[], routerMapping = false) {
|
||||
// 借助 lodash 深拷贝
|
||||
const cloneRouteModList = cloneDeep(routeModList);
|
||||
const routeList: AppRouteRecordRaw[] = [];
|
||||
|
||||
// 对路由项进行修改
|
||||
cloneRouteModList.forEach((item) => {
|
||||
if (routerMapping && item.meta.hideChildrenInMenu && typeof item.redirect === 'string') {
|
||||
item.path = item.redirect;
|
||||
}
|
||||
|
||||
if (item.meta?.single) {
|
||||
const realItem = item?.children?.[0];
|
||||
realItem && routeList.push(realItem);
|
||||
@@ -52,6 +86,7 @@ export function transformRouteToMenu(routeModList: AppRouteModule[], routerMappi
|
||||
routeList.push(item);
|
||||
}
|
||||
});
|
||||
// 提取树指定结构
|
||||
const list = treeMap(routeList, {
|
||||
conversion: (node: AppRouteRecordRaw) => {
|
||||
const { meta: { title, hideMenu = false } = {} } = node;
|
||||
@@ -67,6 +102,7 @@ export function transformRouteToMenu(routeModList: AppRouteModule[], routerMappi
|
||||
};
|
||||
},
|
||||
});
|
||||
// 路径处理
|
||||
joinParentPath(list);
|
||||
return cloneDeep(list);
|
||||
}
|
||||
@@ -75,6 +111,7 @@ export function transformRouteToMenu(routeModList: AppRouteModule[], routerMappi
|
||||
* config menu with given params
|
||||
*/
|
||||
const menuParamRegex = /(?::)([\s\S]+?)((?=\/)|$)/g;
|
||||
|
||||
export function configureDynamicParamsMenu(menu: Menu, params: RouteParams) {
|
||||
const { path, paramPath } = toRaw(menu);
|
||||
let realPath = paramPath ? paramPath : path;
|
||||
|
@@ -83,6 +83,7 @@
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
tenantSaas: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
@@ -93,6 +94,7 @@
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
tenantSaas: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
@@ -103,6 +105,7 @@
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
tenantSaas: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -16,8 +16,10 @@
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formSchema } from './user.data';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { saveOrUpdateUser, getUserRoles, getUserDepartList } from './user.api';
|
||||
import { saveOrUpdateUser, getUserRoles, getUserDepartList, getAllRolesListNoByTenant, getAllRolesList } from './user.api';
|
||||
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
||||
import { getTenantId } from "/@/utils/auth";
|
||||
|
||||
// 声明Emits
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
const attrs = useAttrs();
|
||||
@@ -99,8 +101,27 @@
|
||||
{
|
||||
field: 'selectedroles',
|
||||
show: !data?.departDisabled ?? false,
|
||||
//update-begin---author:wangshuai ---date:20230424 for:【issues/4844】多租户模式下,新增或编辑用户,选择角色一栏,角色选项没有做租户隔离------------
|
||||
//判断是否为多租户模式
|
||||
componentProps:{
|
||||
api: data.tenantSaas?getAllRolesList:getAllRolesListNoByTenant
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230424 for:【issues/4844】多租户模式下,新增或编辑用户,选择角色一栏,角色选项没有做租户隔离------------
|
||||
},
|
||||
//update-begin---author:wangshuai ---date:20230522 for:【issues/4935】租户用户编辑界面中租户下拉框未过滤,显示当前系统所有的租户------------
|
||||
{
|
||||
field: 'relTenantIds',
|
||||
componentProps:{
|
||||
disabled: !!data.tenantSaas,
|
||||
},
|
||||
},
|
||||
//update-end---author:wangshuai ---date:20230522 for:【issues/4935】租户用户编辑界面中租户下拉框未过滤,显示当前系统所有的租户------------
|
||||
]);
|
||||
//update-begin---author:wangshuai ---date:20230522 for:【issues/4935】租户用户编辑界面中租户下拉框未过滤,显示当前系统所有的租户------------
|
||||
if(!unref(isUpdate) && data.tenantSaas){
|
||||
await setFieldsValue({ relTenantIds: getTenantId().toString() })
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230522 for:【issues/4935】租户用户编辑界面中租户下拉框未过滤,显示当前系统所有的租户------------
|
||||
// 无论新增还是编辑,都可以设置表单值
|
||||
if (typeof data.record === 'object') {
|
||||
setFieldsValue({
|
||||
|
@@ -125,6 +125,7 @@
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
tenantSaas: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
@@ -135,6 +136,7 @@
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
tenantSaas: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
@@ -145,6 +147,7 @@
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
tenantSaas: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
|
Reference in New Issue
Block a user