v3.9.0 里程碑版本发布

This commit is contained in:
JEECG
2025-11-26 11:25:35 +08:00
parent 1f73837b7d
commit 9919ae2bc5
380 changed files with 11450 additions and 4555 deletions

View File

@ -101,10 +101,9 @@ export class Memory<T = any, V = any> {
const item = this.cache[key];
item.timeoutId && clearTimeout(item.timeoutId);
});
//update-begin---author:liusq Date:20220108 for不删除登录用户的租户id其他缓存信息都清除----
// 代码逻辑说明: 不删除登录用户的租户id其他缓存信息都清除----
this.cache = {
...omit(this.cache, [TOKEN_KEY, USER_INFO_KEY, ROLES_KEY, DB_DICT_DATA_KEY, TENANT_ID, LOGIN_INFO_KEY, PROJ_CFG_KEY]),
};
//update-end---author:liusq Date:20220108 for不删除登录用户的租户id其他缓存信息都清除----
}
}

View File

@ -60,14 +60,12 @@ function initPersistentMemory() {
export class Persistent {
static getLocal<T>(key: LocalKeys) {
//update-begin---author:scott ---date:2022-10-27 fortoken过期退出重新登录online菜单还是提示token过期----------
// 代码逻辑说明: token过期退出重新登录online菜单还是提示token过期----------
const globalCache = ls.get(APP_LOCAL_CACHE_KEY);
// update-begin--author:liaozhiyang---date:20240920---for【issues/7250】自动锁屏无法解锁
// 代码逻辑说明: 【issues/7250】自动锁屏无法解锁
if (globalCache && router?.currentRoute?.value.path !== PageEnum.BASE_LOGIN) {
localMemory.setCache(globalCache);
}
// update-end--author:liaozhiyang---date:20240920---for【issues/7250】自动锁屏无法解锁
//update-end---author:scott ---date::2022-10-27 fortoken过期退出重新登录online菜单还是提示token过期----------
return localMemory.get(key)?.value as Nullable<T>;
}

View File

@ -5,6 +5,7 @@ import ECB from 'crypto-js/mode-ecb';
import md5 from 'crypto-js/md5';
import UTF8 from 'crypto-js/enc-utf8';
import Base64 from 'crypto-js/enc-base64';
import CryptoJS from 'crypto-js';
export interface EncryptionParams {
key: string;
@ -53,3 +54,28 @@ export function decodeByBase64(cipherText: string) {
export function encryptByMd5(password: string) {
return md5(password).toString();
}
// ================== 密码加密相关 ==================
// 密码加密统一使用 AES CBC 模式,前后端 key 和 iv 必须保持一致
// AES_KEY 和 AES_IV 需与后端配置完全一致,否则加密/解密会失败
// ================== 密码加密相关 ===========BEGIN=======
// AES加密key和iv常量
export const AES_KEY = '1234567890adbcde';
export const AES_IV = '1234567890hjlkew';
/**
* AES CBC 加密,使用全局常量 AES_KEY 和 AES_IV
* @param plainText 明文
* @returns 加密后的密文
*/
export function encryptAESCBC(plainText: string): string {
const key = parse(AES_KEY);
const iv = parse(AES_IV);
return encrypt(plainText, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: pkcs7
}).toString();
}
// ================== 密码加密相关 =============END=====

View File

@ -2,8 +2,8 @@ import { useGlobSetting } from '/@/hooks/setting';
import { merge, random } from 'lodash-es';
import { isArray } from '/@/utils/is';
import { FormSchema } from '/@/components/Form';
import { reactive } from "vue";
import { getTenantId, getToken, getAuthCache, setAuthCache } from "/@/utils/auth";
import { h, reactive, ref } from "vue";
import { getTenantId, getToken } from "/@/utils/auth";
import { useUserStoreWithOut } from "/@/store/modules/user";
import dayjs from 'dayjs';
import Big from 'big.js';
@ -11,6 +11,8 @@ import Big from 'big.js';
import { Modal } from "ant-design-vue";
import { defHttp } from "@/utils/http/axios";
import { useI18n } from "@/hooks/web/useI18n";
//存放部门路径的数组
const departNamePath = ref<Record<string, string>>({});
const globSetting = useGlobSetting();
const baseApiUrl = globSetting.domainUrl;
@ -146,19 +148,16 @@ export function mapTableTotalSummary(tableData: Recordable[], fieldKeys: string[
let totals: any = { _row: '合计', _index: '合计' };
fieldKeys.forEach((key) => {
totals[key] = tableData.reduce((prev, next) => {
// update-begin--author:liaozhiyang---date:20240118---for【QQYUN-7891】PR 合计工具方法转换为Nuber类型再计算
// 代码逻辑说明: 【QQYUN-7891】PR 合计工具方法转换为Nuber类型再计算
const value = Number(next[key]);
if (!Number.isNaN(value)) {
// update-begin--author:liaozhiyang---date:20250224---for【issues/7830】合计小数计算精度
// 代码逻辑说明: 【issues/7830】合计小数计算精度
prev = Big(prev).plus(value).toString();
// update-end--author:liaozhiyang---date:20250224---for【issues/7830】合计小数计算精度
}
// update-end--author:liaozhiyang---date:20240118---for【issues/7830】PR 合计工具方法转换为Nuber类型再计算
return prev;
}, 0);
// update-begin--author:liaozhiyang---date:20250224---for【issues/7830】合计小数计算精度
// 代码逻辑说明: 【issues/7830】合计小数计算精度
totals[key] = +totals[key];
// update-end--author:liaozhiyang---date:20250224---for【issues/7830】合计小数计算精度
});
return totals;
}
@ -512,12 +511,10 @@ export async function userExitChangeLoginTenantId(tenantId){
let loginTenantId = getTenantId();
userStore.setTenant(currentTenantId);
//update-begin---author:wangshuai---date:2023-11-07---for:【QQYUN-7005】退租户判断退出的租户ID与当前租户ID一致再刷新---
//租户为空,说明没有租户了,需要刷新页面。或者当前租户和退出的租户一致则需要刷新浏览器
if(!currentTenantId || tenantId == loginTenantId){
window.location.reload();
}
//update-end---author:wangshuai---date:2023-11-07---for:【QQYUN-7005】退租户判断退出的租户ID与当前租户ID一致再刷新---
}
/**
@ -619,18 +616,91 @@ export function freezeDeep(obj: Recordable | Recordable[]) {
* @return 部门名称
*/
export async function getDepartPathNameByOrgCode(orgCode, label, depId){
let key:any = "DEPARTNAME" + depId + orgCode;
let authCache = getAuthCache(key);
if (authCache) {
return authCache;
}
if (orgCode) {
depId = "";
}
let result = await defHttp.get({ url: "/sys/sysDepart/getDepartPathNameByOrgCode", params:{ orgCode: orgCode, depId: depId } }, { isTransformResponse: false });
if (result.success) {
setAuthCache(key,result.result);
return result.result;
}
return label;
}
/**
* 获取部门路径名称
* @param title
* @param key 部门code或者部门id
* @param izOrgCode 是否是机构编码
*/
export function getDepartPathName(title,key,izOrgCode) {
if (departNamePath.value[key]) {
return departNamePath.value[key];
}
if(izOrgCode){
getDepartPathNameByOrgCode(key, title, "").then(result => {
departNamePath.value[key] = result;
});
}else{
getDepartPathNameByOrgCode("", title, key).then(result => {
departNamePath.value[key] = result;
});
}
}
/**
* 获取多个部门路径名称
* @param title
* @param id
*/
export function getMultiDepartPathName(title,id) {
if(!id || id.length === 0){
return '';
}
let postIds:any = "";
if(id instanceof Array){
postIds = id;
} else {
postIds = id.split(",")
}
let postNames = "";
postIds.forEach((postId)=>{
postNames += getDepartPathName(title,postId,false) + ",";
});
if(postNames.endsWith(",")){
postNames = postNames.substring(0,postNames.length - 1);
}
return postNames;
}
/**
* 获取部门名称 返回h
* @param departNamePath 部门路径
*/
export function getDepartName(departNamePath) {
if(departNamePath){
let names = departNamePath.split(",");
let textElements:any = [];
for (let i = 0; i < names.length; i++) {
textElements.push(h("p", { style: { marginBottom: '2px'} }, names[i]));
}
// 组合完整内容字符串用于title属性
const fullContent = names.join('\n');
return h("div",{
style: {
overflow: 'hidden',
textOverflow: 'ellipsis',
display: '-webkit-box',
WebkitLineClamp: 3,
WebkitBoxOrient: 'vertical',
lineHeight: '1.5em',
maxHeight: '4.5em',
width: '100%',
whiteSpace: 'normal'
},
// 鼠标悬停显示全部内容
title: fullContent
},textElements)
}
return departNamePath;
}

View File

@ -84,7 +84,6 @@ const render = {
});
})
);
//update-end-author:taoyan date:2022-5-24 for: VUEN-1084 【vue3】online表单测试发现的新问题 41、生成的代码树默认图大小未改
},
/**
* 渲染 Tooltip

View File

@ -16,7 +16,7 @@ export async function validateFormModelAndTables(validate, formData, cases, prop
// 验证主表表单
validate()
.then(() => {
//update-begin---author:wangshuai ---date:20220507 for[VUEN-912]一对多用户组件(所有风格,单表和树没问题)保存报错------------
// 代码逻辑说明: [VUEN-912]一对多用户组件(所有风格,单表和树没问题)保存报错------------
for (let data in formData) {
//如果该数据是数组
if (formData[data] instanceof Array) {
@ -27,13 +27,11 @@ export async function validateFormModelAndTables(validate, formData, cases, prop
}
}
}
//update-end---author:wangshuai ---date:20220507 for[VUEN-912]一对多用户组件(所有风格,单表和树没问题)保存报错--------------
resolve(formData);
})
//update-begin---author:wangshuai---date:2024-06-17---for:【TV360X-1064】非原生提交表单滚动校验没通过的项---
// 代码逻辑说明: 【TV360X-1064】非原生提交表单滚动校验没通过的项---
.catch(({ errorFields }) => {
reject({ error: VALIDATE_FAILED, index: 0, errorFields: errorFields });
//update-end---author:wangshuai---date:2024-06-17---for:【TV360X-1064】非原生提交表单滚动校验没通过的项---
});
});
Object.assign(dataMap, { formValue: values });
@ -81,9 +79,8 @@ export function validateTables(cases, autoJumpTab = true) {
}
}
// 出现未验证通过的表单,不再进行下一步校验,直接返回失败
//update-begin-author:liusq date:2024-06-12 for: TV360X-478 一对多tab校验未通过时tab没有跳转
// 代码逻辑说明: TV360X-478 一对多tab校验未通过时tab没有跳转
reject({ error: VALIDATE_FAILED, index, paneKey, errMap, subIndex: index });
//update-end-author:liusq date:2024-06-12 for: TV360X-478 一对多tab校验未通过时tab没有跳转
}
});
})();

View File

@ -52,10 +52,9 @@ export function filterDictText(dictOptions, text) {
for (let txt of splitText) {
let dictText = txt;
for (let dictItem of dictOptions) {
// update-begin--author:liaozhiyang---date:20240524---for【TV360X-469】兼容数据null值防止报错
// 代码逻辑说明: 【TV360X-469】兼容数据null值防止报错
if (dictItem == null) continue;
if (dictItem.value == null) continue;
// update-end--author:liaozhiyang---date:20240524---for【TV360X-469】兼容数据null值防止报错
if (txt.toString() === dictItem.value.toString()) {
dictText = dictItem.text || dictItem.title || dictItem.label;
break;
@ -132,7 +131,6 @@ export function filterDictTextByCache(dictCode, key) {
/** 通过code获取字典数组 */
export async function getDictItems(dictCode, params) {
// update-begin--author:liaozhiyang---date:20230809---for【issues/668】JDictSelectUtil数据字典工具类中的getDictItems方法出错
//优先从缓存中读取字典配置
if (getDictItemsByCode(dictCode)) {
let desformDictItems = getDictItemsByCode(dictCode).map((item) => ({
@ -158,5 +156,4 @@ export async function getDictItems(dictCode, params) {
console.error('getDictItems error: ', res);
return Promise.resolve([]);
});
// update-end--author:liaozhiyang---date:20230809---for【issues/668】JDictSelectUtil数据字典工具类中的getDictItems方法出错
}

View File

@ -8,20 +8,17 @@ import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
* @param code
*/
export const getDictItemsByCode = (code) => {
// update-begin--author:liaozhiyang---date:20230908---for【QQYUN-6417】生产环境字典慢的问题
// 代码逻辑说明: 【QQYUN-6417】生产环境字典慢的问题
const userStore = useUserStore();
const dictItems = userStore.getAllDictItems;
if (null != dictItems && typeof dictItems === 'object' && dictItems[code]) {
return dictItems[code];
}
//update-begin-author:liusq---date:2023-10-13--for: 【issues/777】列表 分类字典不显示
//兼容以前的旧写法
if (getAuthCache(DB_DICT_DATA_KEY) && getAuthCache(DB_DICT_DATA_KEY)[code]) {
return getAuthCache(DB_DICT_DATA_KEY)[code];
}
//update-end-author:liusq---date:2023-10-13--for:【issues/777】列表 分类字典不显示
// update-end--author:liaozhiyang---date:20230908---for【QQYUN-6417】生产环境字典慢的问题
};
/**
@ -52,12 +49,11 @@ export const initDictOptions = (code) => {
});
}
//2.获取字典数组
//update-begin-author:taoyan date:2022-6-21 for: 字典数据请求前将参数编码处理,但是不能直接编码,因为可能之前已经编码过了
// 代码逻辑说明: 字典数据请求前将参数编码处理,但是不能直接编码,因为可能之前已经编码过了
if (code.indexOf(',') > 0 && code.indexOf(' ') > 0) {
// 编码后类似sys_user%20where%20username%20like%20xxx' 是不包含空格的,这里判断如果有空格和逗号说明需要编码处理
code = encodeURI(code);
}
//update-end-author:taoyan date:2022-6-21 for: 字典数据请求前将参数编码处理,但是不能直接编码,因为可能之前已经编码过了
return defHttp.get({ url: `/sys/dict/getDictItems/${code}` });
};
/**

View File

@ -32,11 +32,10 @@ export default class signMd5Utils {
static getSign(url, requestParams, requestBodyParams) {
let urlParams = this.parseQueryString(url);
let jsonObj = this.mergeObject(urlParams, requestParams);
//update-begin---author:wangshuai---date:2024-04-16---for:【QQYUN-9005】发送短信加签---
// 代码逻辑说明: 【QQYUN-9005】发送短信加签---
if(requestBodyParams){
jsonObj = this.mergeObject(jsonObj, requestBodyParams)
}
//update-end---author:wangshuai---date:2024-04-16---for:【QQYUN-9005】发送短信加签---
let requestBody = this.sortAsc(jsonObj);
delete requestBody._t;
// console.log('sign requestBody:', requestBody);
@ -60,11 +59,9 @@ export default class signMd5Utils {
if (lastpathVariable.includes('?')) {
lastpathVariable = lastpathVariable.substring(0, lastpathVariable.indexOf('?'));
}
//update-begin---author:wangshuai ---date:20221103 for[issues/183]下拉搜索,使用动态字典,在线页面不报错,生成的代码报错 ------------
//解决Sign 签名校验失败 #2728
//decodeURI对特殊字符没有没有编码和解码的能力需要使用decodeURIComponent
result['x-path-variable'] = decodeURIComponent(lastpathVariable);
//update-end---author:wangshuai ---date:20221103 for[issues/183]下拉搜索,使用动态字典,在线页面不报错,生成的代码报错 ------------
}
if (urlArray && urlArray[1]) {
let paramString = urlArray[1],

View File

@ -0,0 +1,23 @@
import { MenuTypeEnum } from '/@/enums/menuEnum';
import { APP_PRESET_COLOR_LIST } from '/@/settings/designSetting';
/**
* 根据菜单类型和模式获取对应的主题色
* @param menuType 菜单类型
*/
export function getThemeColorByMenuType(menuType: MenuTypeEnum): string {
if (menuType === MenuTypeEnum.TOP_MENU) {
// 顶部栏导航
return APP_PRESET_COLOR_LIST[1];
} else if (menuType === MenuTypeEnum.MIX) {
// 顶部混合菜单使用青绿色主题
return APP_PRESET_COLOR_LIST[2];
} else if (menuType === MenuTypeEnum.MIX_SIDEBAR) {
// 侧边折叠导航模式
return APP_PRESET_COLOR_LIST[1];
} else if (menuType === MenuTypeEnum.SIDEBAR) {
// 侧边栏导航
return APP_PRESET_COLOR_LIST[1];
}
return APP_PRESET_COLOR_LIST[1];
}

View File

@ -126,7 +126,6 @@ export const rules = {
},
};
//update-begin-author:taoyan date:2022-6-16 for: 代码生成-原生表单用
/**
* 唯一校验函数,给原生<a-form>使用vben的表单校验建议使用上述rules
* @param tableName 表名
@ -152,4 +151,3 @@ export async function duplicateValidate(tableName, fieldName, fieldVal, dataId)
return Promise.reject('校验失败,可能是断网等问题导致的校验失败');
}
}
//update-end-author:taoyan date:2022-6-16 for: 代码生成-原生表单用

View File

@ -1,8 +1,7 @@
import { isObject, isString } from '/@/utils/is';
import dayjs from "dayjs";
// update-begin--author:liaozhiyang---date:20240426---for【QQYUN-9138】系统用户保存的时间没有秒
// 代码逻辑说明: 【QQYUN-9138】系统用户保存的时间没有秒
const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss';
// update-end--author:liaozhiyang---date:20240426---for【QQYUN-9138】系统用户保存的时间没有秒
export function joinTimestamp<T extends boolean>(join: boolean, restful: T): T extends true ? string : object;

View File

@ -92,19 +92,17 @@ const transform: AxiosTransform = {
beforeRequestHook: (config, options) => {
const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true, urlPrefix } = options;
//update-begin---author:scott ---date:2024-02-20 for以http开头的请求url不拼加前缀--
// http开头的请求url不加前缀
let isStartWithHttp = false;
const requestUrl = config.url;
if(requestUrl!=null && (requestUrl.startsWith("http:") || requestUrl.startsWith("https:"))){
isStartWithHttp = true;
}
// update-begin--author:sunjianlei---date:20250411---for【QQYUN-9685】构建 electron 桌面应用
// 代码逻辑说明: 【QQYUN-9685】构建 electron 桌面应用
if (!isStartWithHttp && requestUrl != null) {
// 由于electron的url是file://开头的,所以需要判断一下
isStartWithHttp = requestUrl.startsWith('file://');
}
// update-end----author:sunjianlei---date:20250411---for【QQYUN-9685】构建 electron 桌面应用
if (!isStartWithHttp && joinPrefix) {
config.url = `${urlPrefix}${config.url}`;
}
@ -112,7 +110,6 @@ const transform: AxiosTransform = {
if (!isStartWithHttp && apiUrl && isString(apiUrl)) {
config.url = `${apiUrl}${config.url}`;
}
//update-end---author:scott ---date::2024-02-20 for以http开头的请求url不拼加前缀--
const params = config.params || {};
const data = config.data || false;
@ -147,13 +144,12 @@ const transform: AxiosTransform = {
}
}
// update-begin--author:sunjianlei---date:220241019---for【JEECG作为乾坤子应用】作为乾坤子应用启动时拼接请求路径
// 代码逻辑说明: 【JEECG作为乾坤子应用】作为乾坤子应用启动时拼接请求路径
if (globSetting.isQiankunMicro) {
if (config.url && config.url.startsWith('/')) {
config.url = globSetting.qiankunMicroAppEntry + config.url
}
}
// update-end--author:sunjianlei---date:220241019---for【JEECG作为乾坤子应用】作为乾坤子应用启动时拼接请求路径
return config;
},
@ -166,18 +162,11 @@ const transform: AxiosTransform = {
const token = getToken();
let tenantId: string | number = getTenantId();
//update-begin---author:wangshuai---date:2024-04-16---for:【QQYUN-9005】发送短信加签。解决没有token无法加签---
// 将签名和时间戳,添加在请求接口 Header
config.headers[ConfigEnum.TIMESTAMP] = signMd5Utils.getTimestamp();
//update-begin---author:wangshuai---date:2024-04-25---for: 生成签名的时候复制一份,避免影响原来的参数---
config.headers[ConfigEnum.Sign] = signMd5Utils.getSign(config.url, cloneDeep(config.params), cloneDeep(config.data));
//update-end---author:wangshuai---date:2024-04-25---for: 生成签名的时候复制一份,避免影响原来的参数---
//update-end---author:wangshuai---date:2024-04-16---for:【QQYUN-9005】发送短信加签。解决没有token无法加签---
// update-begin--author:liaozhiyang---date:20240509---for【issues/1220】登录时vue3版本不加载字典数据设置无效
//--update-begin--author:liusq---date:20220325---for: 增加vue3标记
config.headers[ConfigEnum.VERSION] = 'v3';
//--update-end--author:liusq---date:20220325---for:增加vue3标记
// update-end--author:liaozhiyang---date:20240509---for【issues/1220】登录时vue3版本不加载字典数据设置无效
if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
// jwt token
config.headers.Authorization = options.authenticationScheme ? `${options.authenticationScheme} ${token}` : token;
@ -190,20 +179,19 @@ const transform: AxiosTransform = {
tenantId = 0;
}
// update-begin--author:sunjianlei---date:220230428---for【QQYUN-5279】修复分享的应用租户和当前登录租户不一致时提示404的问题
// 代码逻辑说明: 【QQYUN-5279】修复分享的应用租户和当前登录租户不一致时提示404的问题
const userStore = useUserStoreWithOut();
// 判断是否有临时租户id
if (userStore.hasShareTenantId && userStore.shareTenantId !== 0) {
// 临时租户id存在使用临时租户id
tenantId = userStore.shareTenantId!;
}
// update-end--author:sunjianlei---date:220230428---for【QQYUN-5279】修复分享的应用租户和当前登录租户不一致时提示404的问题
config.headers[ConfigEnum.TENANT_ID] = tenantId;
//--update-end--author:liusq---date:20211105---for:将多租户id添加在请求接口 Header
// ========================================================================================
// update-begin--author:sunjianlei---date:20220624--for: 添加低代码应用ID
// 代码逻辑说明: 添加低代码应用ID
let routeParams = router.currentRoute.value.params;
if (routeParams.appId) {
config.headers[ConfigEnum.X_LOW_APP_ID] = routeParams.appId;
@ -213,7 +201,6 @@ const transform: AxiosTransform = {
delete routeParams.lowAppFilter;
}
}
// update-end--author:sunjianlei---date:20220624--for: 添加低代码应用ID
// ========================================================================================
}

View File

@ -6,9 +6,8 @@ import { unref } from 'vue';
import { isObject, isFunction, isString } from '/@/utils/is';
import Big from 'big.js';
import dayjs from "dayjs";
// update-begin--author:sunjianlei---date:20220408---for: 【VUEN-656】配置外部网址打不开原因是带了#号,需要替换一下
// 代码逻辑说明: 【VUEN-656】配置外部网址打不开原因是带了#号,需要替换一下
export const URL_HASH_TAB = `__AGWE4H__HASH__TAG__PWHRG__`;
// update-end--author:sunjianlei---date:20220408---for: 【VUEN-656】配置外部网址打不开原因是带了#号,需要替换一下
export const noop = () => {};
@ -41,11 +40,11 @@ export function setObjToUrlParams(baseUrl: string, obj: any): string {
export function deepMerge<T = any>(src: any = {}, target: any = {}): T {
let key: string;
for (key in target) {
// update-begin--author:liaozhiyang---date:20240329---for【QQYUN-7872】online表单label较长优化
// 代码逻辑说明: 【QQYUN-7872】online表单label较长优化
if (isObject(src[key]) && isObject(target[key])) {
src[key] = deepMerge(src[key], target[key]);
} else {
// update-begin--author:liaozhiyang---date:20250318---for【issues/7940】componentProps写成函数形式时updateSchema写成对象时参数没合并
// 代码逻辑说明: 【issues/7940】componentProps写成函数形式时updateSchema写成对象时参数没合并
try {
if (isFunction(src[key]) && isObject(src[key]()) && isObject(target[key])) {
// src[key]是函数且返回对象且target[key]是对象
@ -62,9 +61,7 @@ export function deepMerge<T = any>(src: any = {}, target: any = {}): T {
} catch (error) {
src[key] = target[key];
}
// update-end--author:liaozhiyang---date:20250318---for【issues/7940】componentProps写成函数形式时updateSchema写成对象时参数没合并
}
// update-end--author:liaozhiyang---date:20240329---for【QQYUN-7872】online表单label较长优化
}
return src;
}
@ -98,11 +95,21 @@ export function getDynamicProps<T, U>(props: T): Partial<U> {
* @updateBy:zyf
*/
export function getValueType(props, field) {
let formSchema = unref(unref(props)?.schemas);
let formSchema = unref(unref(props)?.schemas)
let valueType = 'string';
if (formSchema) {
let schema = formSchema.filter((item) => item.field === field)[0];
valueType = schema && schema.componentProps && schema.componentProps.valueType ? schema.componentProps.valueType : valueType;
// 代码逻辑说明: 【issues/8976】useListPage 查询中componentProps是函数时获取不到valueType
if (schema && schema.componentProps) {
if (isFunction(schema.componentProps)) {
try {
const result = schema.componentProps({ schema, tableAction: {}, formModel: {}, formActionType: {} });
valueType = result?.valueType ?? valueType;
} catch (err) {}
} else {
valueType = schema.componentProps.valueType ? schema.componentProps.valueType : valueType;
}
}
}
return valueType;
}
@ -116,14 +123,15 @@ export function getValueTypeBySchema(schema: FormSchema, formAction: FormActionT
let valueType = 'string';
if (schema) {
const componentProps = formAction.getSchemaComponentProps(schema);
// update-begin--author:liaozhiyang---date:20250825---for【issues/8738】componentProps是函数时获取不到valueType
// 代码逻辑说明: 【issues/8738】componentProps是函数时获取不到valueType
if (isFunction(componentProps)) {
const result = componentProps(schema);
valueType = result?.valueType ?? valueType;
try {
const result = componentProps({ schema, tableAction: {}, formModel: {}, formActionType: {} });
valueType = result?.valueType ?? valueType;
} catch (err) {}
} else {
valueType = componentProps?.valueType ? componentProps?.valueType : valueType;
}
// update-end--author:liaozhiyang---date:20250825---for【issues/8738】componentProps是函数时获取不到valueType
}
return valueType;
}
@ -308,9 +316,8 @@ export function numToUpper(value) {
}
};
let lth = value.toString().length;
// update-begin--author:liaozhiyang---date:20241202---for【issues/7493】numToUpper方法返回解决错误
// 代码逻辑说明: 【issues/7493】numToUpper方法返回解决错误
value = new Big(value).times(100);
// update-end--author:liaozhiyang---date:20241202---for【issues/7493】numToUpper方法返回解决错误
value += '';
let length = value.length;
if (lth <= 8) {
@ -340,7 +347,7 @@ export function numToUpper(value) {
return null;
}
//update-begin-author:taoyan date:2022-6-8 for:解决老的vue2动态导入文件语法 vite不支持的问题
// 代码逻辑说明: 解决老的vue2动态导入文件语法 vite不支持的问题
const allModules = import.meta.glob('../views/**/*.vue');
export function importViewsFile(path): Promise<any> {
if (path.startsWith('/')) {
@ -368,7 +375,6 @@ export function importViewsFile(path): Promise<any> {
}
});
}
//update-end-author:taoyan date:2022-6-8 for:解决老的vue2动态导入文件语法 vite不支持的问题
/**
@ -378,10 +384,8 @@ export function importViewsFile(path): Promise<any> {
* @param token
*/
export function goJmReportViewPage(url, id, token) {
// update-begin--author:liaozhiyang---date:20230904---for【QQYUN-6390】eval替换成new Function解决build警告
// URL支持{{ window.xxx }}占位符变量
url = url.replace(/{{([^}]+)?}}/g, (_s1, s2) => _eval(s2))
// update-end--author:liaozhiyang---date:20230904---for【QQYUN-6390】eval替换成new Function解决build警告
if (url.includes('?')) {
url += '&'
} else {

View File

@ -53,9 +53,8 @@ export function isNumber(val: unknown): val is number {
}
export function isPromise<T = any>(val: any): val is Promise<T> {
// update-begin--author:sunjianlei---date:20211022---for: 不能既是 Promise 又是 Object --------
// 代码逻辑说明: 不能既是 Promise 又是 Object --------
return is(val, 'Promise') && isFunction(val.then) && isFunction(val.catch);
// update-end--author:sunjianlei---date:20211022---for: 不能既是 Promise 又是 Object --------
}
export function isString(val: unknown): val is string {