Files
xgy-oa/klp-ui/src/utils/klp.js

348 lines
9.4 KiB
JavaScript
Raw Normal View History

import QRCode from 'qrcode';
/**
* 通用js方法封装处理
2025-07-17 18:07:48 +08:00
* Copyright (c) 2019 klp
*/
// 日期格式化
export function parseTime(time, pattern) {
if (arguments.length === 0 || !time) {
return null
}
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
// 表单重置
export function resetForm(refName) {
if (this.$refs[refName]) {
this.$refs[refName].resetFields();
}
}
// 添加日期范围
export function addDateRange(params, dateRange, propName) {
let search = params;
search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
dateRange = Array.isArray(dateRange) ? dateRange : [];
if (typeof (propName) === 'undefined') {
search.params['beginTime'] = dateRange[0];
search.params['endTime'] = dateRange[1];
} else {
search.params['begin' + propName] = dateRange[0];
search.params['end' + propName] = dateRange[1];
}
return search;
}
// 回显数据字典
export function selectDictLabel(datas, value) {
if (value === undefined) {
return "";
}
var actions = [];
Object.keys(datas).some((key) => {
if (datas[key].value == ('' + value)) {
actions.push(datas[key].label);
return true;
}
})
if (actions.length === 0) {
actions.push(value);
}
return actions.join('');
}
sync: 同步 RuoYi-Vue-Plus(v4.4.0) 更新 重大更新 [重大更新] 优化支持 oss 私有库功能(数据库字段改动) #cd9c3c3f [重大更新] 连接池由 druid 修改为 hikari 更新相关配置(原因可看文档) #1f42bd3d [重大更新] 移除 tlog(不支持UI界面 使用的人太少)建议使用 skywalking [重大更新] 增加 skywalking 集成 默认注释不开启(使用看文档) 依赖升级 update springboot 2.7.5 => 2.7.6 update springboot-admin 2.7.6 => 2.7.7 update satoken 1.31.0 => 1.33.0 update spring-doc 1.6.12 => 1.6.13 update easyexcel 3.1.1 => 3.1.3 update hutool 5.8.8 => 5.8.10 update redisson 3.17.7 => 3.18.0 update lock4j 2.2.2 => 2.2.3 update s3-adk 1.12.324 => 1.12.349 update mysql-docker 8.0.29 => 8.0.31 功能更新 update 优化 oss 云厂商增加 华为obs关键字 update 优化 冗余的三元表达式 update 优化 重置时取消部门选中 update 优化 新增返回警告消息提示 update 优化 hikari 参数顺序 最常用的放上面 删除无用 druid 监控页面 update 优化 p6spy 排除健康检查 sql 执行记录 update 优化 Dockerfile 创建目录命令 update 优化 将空‘catch’块形参重命名为‘ignored’ update 优化 使用本地缓存优化 excel 导出 数据量大字典转换慢问题 update 优化 字典转换实现去除字符串查找拼接优化效率 update 优化 减小腾讯短信引入jar包的体积 update 消除Vue3控制台出现的警告信息 update 忽略不必要的属性数据返回 update 替换 mysql-jdbc 最新坐标 新增功能 add 新增 junit5 单元测试案例 #6e8ef308 add 增加 sys_oss_config access_policy 桶权限类型字段 add 增加 4.3-4.4 更新 sql 文件 add 新增 字典数据映射注解 #da94e898 add 增加 RedisUtils 获取缓存Map的key列表 问题修复 fix 修复 上传png透明图片 生成头像透明部分变成黑色 fix 修复 sqlserver sql文件 重复主键数据问题 fix 修复 sqlserver 特定情况下报 ssl 证书问题 默认关闭 ssl 认证 fix 修复 table中更多按钮切换主题色未生效修复问题 fix 修复 菜单激活无法修改其填充颜色去除某些svg图标的fill="#bfbfbf"属性 fix 修复 使用缓冲流 导致上传异常问题 fix 修复 过滤器链使用IoUtil.read方法导致request流关闭 fix 修复 Log注解GET请求记录不到参数问题 fix 修复 某些特性的环境生成代码变乱码TXT文件问题 fix 修复 开启TopNav没有子菜单隐藏侧边栏 fix 修复 回显数据字典数组异常问题 移除功能 remove 移除过期 Anonymous 注解与其实现代码 remove 移除 tlog(不支持UI界面 使用的人太少) 建议使用 skywalking
2023-01-07 16:51:51 +08:00
// 回显数据字典(字符串、数组)
export function selectDictLabels(datas, value, separator) {
sync: 同步 RuoYi-Vue-Plus(v4.4.0) 更新 重大更新 [重大更新] 优化支持 oss 私有库功能(数据库字段改动) #cd9c3c3f [重大更新] 连接池由 druid 修改为 hikari 更新相关配置(原因可看文档) #1f42bd3d [重大更新] 移除 tlog(不支持UI界面 使用的人太少)建议使用 skywalking [重大更新] 增加 skywalking 集成 默认注释不开启(使用看文档) 依赖升级 update springboot 2.7.5 => 2.7.6 update springboot-admin 2.7.6 => 2.7.7 update satoken 1.31.0 => 1.33.0 update spring-doc 1.6.12 => 1.6.13 update easyexcel 3.1.1 => 3.1.3 update hutool 5.8.8 => 5.8.10 update redisson 3.17.7 => 3.18.0 update lock4j 2.2.2 => 2.2.3 update s3-adk 1.12.324 => 1.12.349 update mysql-docker 8.0.29 => 8.0.31 功能更新 update 优化 oss 云厂商增加 华为obs关键字 update 优化 冗余的三元表达式 update 优化 重置时取消部门选中 update 优化 新增返回警告消息提示 update 优化 hikari 参数顺序 最常用的放上面 删除无用 druid 监控页面 update 优化 p6spy 排除健康检查 sql 执行记录 update 优化 Dockerfile 创建目录命令 update 优化 将空‘catch’块形参重命名为‘ignored’ update 优化 使用本地缓存优化 excel 导出 数据量大字典转换慢问题 update 优化 字典转换实现去除字符串查找拼接优化效率 update 优化 减小腾讯短信引入jar包的体积 update 消除Vue3控制台出现的警告信息 update 忽略不必要的属性数据返回 update 替换 mysql-jdbc 最新坐标 新增功能 add 新增 junit5 单元测试案例 #6e8ef308 add 增加 sys_oss_config access_policy 桶权限类型字段 add 增加 4.3-4.4 更新 sql 文件 add 新增 字典数据映射注解 #da94e898 add 增加 RedisUtils 获取缓存Map的key列表 问题修复 fix 修复 上传png透明图片 生成头像透明部分变成黑色 fix 修复 sqlserver sql文件 重复主键数据问题 fix 修复 sqlserver 特定情况下报 ssl 证书问题 默认关闭 ssl 认证 fix 修复 table中更多按钮切换主题色未生效修复问题 fix 修复 菜单激活无法修改其填充颜色去除某些svg图标的fill="#bfbfbf"属性 fix 修复 使用缓冲流 导致上传异常问题 fix 修复 过滤器链使用IoUtil.read方法导致request流关闭 fix 修复 Log注解GET请求记录不到参数问题 fix 修复 某些特性的环境生成代码变乱码TXT文件问题 fix 修复 开启TopNav没有子菜单隐藏侧边栏 fix 修复 回显数据字典数组异常问题 移除功能 remove 移除过期 Anonymous 注解与其实现代码 remove 移除 tlog(不支持UI界面 使用的人太少) 建议使用 skywalking
2023-01-07 16:51:51 +08:00
if (value === undefined || value.length ===0) {
return "";
}
sync: 同步 RuoYi-Vue-Plus(v4.4.0) 更新 重大更新 [重大更新] 优化支持 oss 私有库功能(数据库字段改动) #cd9c3c3f [重大更新] 连接池由 druid 修改为 hikari 更新相关配置(原因可看文档) #1f42bd3d [重大更新] 移除 tlog(不支持UI界面 使用的人太少)建议使用 skywalking [重大更新] 增加 skywalking 集成 默认注释不开启(使用看文档) 依赖升级 update springboot 2.7.5 => 2.7.6 update springboot-admin 2.7.6 => 2.7.7 update satoken 1.31.0 => 1.33.0 update spring-doc 1.6.12 => 1.6.13 update easyexcel 3.1.1 => 3.1.3 update hutool 5.8.8 => 5.8.10 update redisson 3.17.7 => 3.18.0 update lock4j 2.2.2 => 2.2.3 update s3-adk 1.12.324 => 1.12.349 update mysql-docker 8.0.29 => 8.0.31 功能更新 update 优化 oss 云厂商增加 华为obs关键字 update 优化 冗余的三元表达式 update 优化 重置时取消部门选中 update 优化 新增返回警告消息提示 update 优化 hikari 参数顺序 最常用的放上面 删除无用 druid 监控页面 update 优化 p6spy 排除健康检查 sql 执行记录 update 优化 Dockerfile 创建目录命令 update 优化 将空‘catch’块形参重命名为‘ignored’ update 优化 使用本地缓存优化 excel 导出 数据量大字典转换慢问题 update 优化 字典转换实现去除字符串查找拼接优化效率 update 优化 减小腾讯短信引入jar包的体积 update 消除Vue3控制台出现的警告信息 update 忽略不必要的属性数据返回 update 替换 mysql-jdbc 最新坐标 新增功能 add 新增 junit5 单元测试案例 #6e8ef308 add 增加 sys_oss_config access_policy 桶权限类型字段 add 增加 4.3-4.4 更新 sql 文件 add 新增 字典数据映射注解 #da94e898 add 增加 RedisUtils 获取缓存Map的key列表 问题修复 fix 修复 上传png透明图片 生成头像透明部分变成黑色 fix 修复 sqlserver sql文件 重复主键数据问题 fix 修复 sqlserver 特定情况下报 ssl 证书问题 默认关闭 ssl 认证 fix 修复 table中更多按钮切换主题色未生效修复问题 fix 修复 菜单激活无法修改其填充颜色去除某些svg图标的fill="#bfbfbf"属性 fix 修复 使用缓冲流 导致上传异常问题 fix 修复 过滤器链使用IoUtil.read方法导致request流关闭 fix 修复 Log注解GET请求记录不到参数问题 fix 修复 某些特性的环境生成代码变乱码TXT文件问题 fix 修复 开启TopNav没有子菜单隐藏侧边栏 fix 修复 回显数据字典数组异常问题 移除功能 remove 移除过期 Anonymous 注解与其实现代码 remove 移除 tlog(不支持UI界面 使用的人太少) 建议使用 skywalking
2023-01-07 16:51:51 +08:00
if (Array.isArray(value)) {
value = value.join(",");
}
var actions = [];
var currentSeparator = undefined === separator ? "," : separator;
var temp = value.split(currentSeparator);
Object.keys(value.split(currentSeparator)).some((val) => {
var match = false;
Object.keys(datas).some((key) => {
if (datas[key].value == ('' + temp[val])) {
actions.push(datas[key].label + currentSeparator);
match = true;
}
})
if (!match) {
actions.push(temp[val] + currentSeparator);
}
})
return actions.join('').substring(0, actions.join('').length - 1);
}
// 字符串格式化(%s )
export function sprintf(str) {
var args = arguments, flag = true, i = 1;
str = str.replace(/%s/g, function () {
var arg = args[i++];
if (typeof arg === 'undefined') {
flag = false;
return '';
}
return arg;
});
return flag ? str : '';
}
// 转换字符串undefined,null等转化为""
export function parseStrEmpty(str) {
if (!str || str == "undefined" || str == "null") {
return "";
}
return str;
}
// 数据合并
export function mergeRecursive(source, target) {
for (var p in target) {
try {
if (target[p].constructor == Object) {
source[p] = mergeRecursive(source[p], target[p]);
} else {
source[p] = target[p];
}
} catch (e) {
source[p] = target[p];
}
}
return source;
};
/**
* 构造树型结构数据
* @param {*} data 数据源
* @param {*} id id字段 默认 'id'
* @param {*} parentId 父节点字段 默认 'parentId'
* @param {*} children 孩子节点字段 默认 'children'
*/
export function handleTree(data, id, parentId, children) {
let config = {
id: id || 'id',
parentId: parentId || 'parentId',
childrenList: children || 'children'
};
var childrenListMap = {};
var nodeIds = {};
var tree = [];
for (let d of data) {
let parentId = d[config.parentId];
if (childrenListMap[parentId] == null) {
childrenListMap[parentId] = [];
}
nodeIds[d[config.id]] = d;
childrenListMap[parentId].push(d);
}
for (let d of data) {
let parentId = d[config.parentId];
if (nodeIds[parentId] == null) {
tree.push(d);
}
}
for (let t of tree) {
adaptToChildrenList(t);
}
function adaptToChildrenList(o) {
if (childrenListMap[o[config.id]] !== null) {
o[config.childrenList] = childrenListMap[o[config.id]];
}
if (o[config.childrenList]) {
for (let c of o[config.childrenList]) {
adaptToChildrenList(c);
}
}
}
return tree;
}
/**
* 参数处理
* @param {*} params 参数
*/
export function tansParams(params) {
let result = ''
for (const propName of Object.keys(params)) {
const value = params[propName];
var part = encodeURIComponent(propName) + "=";
if (value !== null && value !== "" && typeof (value) !== "undefined") {
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
let params = propName + '[' + key + ']';
var subPart = encodeURIComponent(params) + "=";
result += subPart + encodeURIComponent(value[key]) + "&";
}
}
} else {
result += part + encodeURIComponent(value) + "&";
}
}
}
return result
}
// 验证是否为blob格式
export function blobValidate(data) {
return data.type !== 'application/json'
}
/**
* 保存二维码为图片
* @param {string} code 二维码内容
* @param {string} text 下方文字
* @param {number} index 索引用于生成文件名
* @param {Object} context Vue组件实例上下文需要包含$messagebarcodeWidthbarcodeHeight
*/
export async function saveAsImage(code, text, index, context) {
// 确保上下文存在
if (!context) {
console.error('缺少组件上下文请传入Vue实例');
return;
}
try {
// 检查QRCode库是否加载
if (typeof QRCode === 'undefined') {
throw new Error('QRCode库未加载请确保已引入');
}
// 创建临时canvas用于绘制二维码和文字
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) {
throw new Error('无法获取canvas上下文');
}
// 从上下文获取尺寸参数,提供默认值
const barcodeWidth = context.barcodeWidth || 200;
const barcodeHeight = context.barcodeHeight || 200;
const textHeight = 30; // 文字区域高度
canvas.width = barcodeWidth;
canvas.height = barcodeHeight + textHeight;
// 绘制二维码
const qrCanvas = document.createElement('canvas');
qrCanvas.width = barcodeWidth;
qrCanvas.height = barcodeHeight;
// 等待二维码绘制完成
await new Promise((resolve, reject) => {
QRCode.toCanvas(qrCanvas, code, {
width: barcodeWidth,
height: barcodeHeight,
margin: 0,
errorCorrectionLevel: 'M'
}, (error) => {
if (error) reject(error);
else resolve();
});
});
// 将二维码绘制到主canvas
ctx.drawImage(qrCanvas, 0, 0);
// 绘制文字(处理文字过长情况)
ctx.fillStyle = '#000';
ctx.font = '14px Arial, sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
// 处理过长文字最多显示2行
const maxTextWidth = barcodeWidth - 20; // 预留边距
let displayText = text;
if (ctx.measureText(text).width > maxTextWidth) {
// 尝试截断并添加省略号
let i = text.length;
while (ctx.measureText(text.substring(0, i)).width > maxTextWidth && i > 0) {
i--;
}
displayText = text.substring(0, i) + '...';
}
ctx.fillText(displayText, barcodeWidth / 2, barcodeHeight + 5);
// 创建图片链接并下载
canvas.toBlob(blob => {
if (!blob) {
throw new Error('无法生成图片blob对象');
}
try {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
// 处理文件名特殊字符
a.download = `二维码_${index + 1}.png`;
a.href = url;
// 模拟点击下载
document.body.appendChild(a);
const event = new MouseEvent('click');
a.dispatchEvent(event);
// 清理资源
setTimeout(() => {
document.body.removeChild(a);
URL.revokeObjectURL(url);
}, 100);
context.$message.success('图片保存成功');
} catch (urlError) {
console.error('创建下载链接失败:', urlError);
context.$message.error('创建下载链接失败');
}
}, 'image/png'); // 明确指定MIME类型
} catch (error) {
console.error('保存图片失败:', error);
context.$message.error(`保存图片失败: ${error.message || '未知错误'}`);
}
}