import ProTable from '@ant-design/pro-table'
import numeral from 'numeral'
import './printBox.less'
import { CurrentUser } from 'umi'
import session from './session'
import moment from 'moment'
import { synchroBehaviorRecord } from '@/services/user'
export type TreeSelectModel = {
value: number | string,
id: number | string,
title: string,
pId: number | string,
disabled?: boolean
}
export type TreeNodeDto = {
node: any;
children: TreeNodeDto[];
}
/**
* @description: [{node:{},chidlren:[]}] => [{...node,children}]
* @param {any} node 需要拼接的父节点
* @param {any} chidlren 需要遍历的平级节点 合并节点中的
* @return {*} 返回[node:{...,children:[]}]
*/
export function wrapTreeNode(data: TreeNodeDto[]) {
const wrapData: any = data.map((item: TreeNodeDto) => {
const node = { ...item.node };
if (item.children && item.children.length > 0) {
node.children = wrapTreeNode(item.children);
}
return node
});
return wrapData;
}
export function formatTreeForProTable(data: TreeNodeDto[]) {
const wrapData = wrapTreeNode(data);
return {
data: wrapData,
current: 1,
pageSize: 100,
total: 100,
success: true,
};
}
export function tableList(list: any) {
return {
data: list.List || [],
current: list.PageIndex || 1,
pageSize: list.pageSize || 10,
total: list.TotalCount || 0,
otherData: list?.OtherData || '',
success: true,
};
}
/**
* @description:生产的数据仅提供 treeSelect组件treeDataSimpleMode模式使用的 数据,
* @param fields 需要转化的数据,
* @param treeKeys fields 与 TreeSelectModel 数据键值 如 fields as EnumItem ,treeKeys: { title: 'fieldEnumName', value: 'id', id:'id', pId:'parentId' }
* @returns TreeSelectModel[]
*/
export const getTreeSelectOption = async (treeKeys: TreeSelectModel, fields: any[]) => {
const option: TreeSelectModel[] = []
const { value, title, pId, id } = treeKeys
fields.forEach(async (item: any) => {
option.push({ value: item[value], title: item[title], pId: item[pId], id: item[id] })
if (item.children) {
const children: TreeSelectModel[] = await getTreeSelectOption(treeKeys, item.children)
option.push(...children)
}
})
return option
}
// 转换数据为option格式数据
export function formateOptions(list: [], rules: { name: string; value: string; other?: string }) {
// let options: { label: string; value: number | string; other?: string | number }[] = [];
const { name, value, other } = rules;
if (list && other) {
return list.map((n) => {
return {
label: n[name],
value: n[value],
other: n[other],
};
});
} if (list) {
return list.map((n) => {
return {
label: n[name],
value: n[value],
};
});
}
return [];
}
// 转换options数据value类型为 number
export function formateField(list: { label: string; value: string | number }[]) {
const valueNumber: { label: string; value: number }[] = [];
list.map((n: any) => {
if (!isNaN(Number(n.value))) {
valueNumber.push({
label: n.label,
value: numeral(n.value).value(),
});
}
});
return valueNumber.length > 0 ? valueNumber : list;
}
// 转换树节点的value类型为string
export function formateTreeField(list: TreeNodeDto[]) {
const valueNumber: any[] = list.map((item: TreeNodeDto) => {
const node = { label: item.node.label, value: item.node.value.toString(), type: item.node.type, ico: item.node.ico };
if (item.children && item.children.length > 0) {
node.children = formateTreeField(item.children);
}
return node
});
return valueNumber.length > 0 ? valueNumber : list;
}
// 把图片格式转化为 ui框架需要的数据格式
export const transferImg = (orgIamges: any[]) => {
const newImages = orgIamges.map((n: any) => {
if (typeof n === 'object') {
return {
uid: n.ImageId, // 注意,这个uid一定不能少,否则上传失败
name: n.ImageName,
status: 'done',
url: n.ImageUrl, // url 是展示在页面上的绝对链接
imgUrl: n.ImagePath,
}
}
const [name] = [...n.split("/")].reverse()
return {
uid: new Date().getTime(), // 注意,这个uid一定不能少,否则上传失败
name,
status: 'done',
url: n, // url 是展示在页面上的绝对链接
imgUrl: n,
}
})
return newImages
}
// 合计方法
export const handleGetSumRow = (data: any[], fieldList: string[], sumTitle: string, avgFiled?: string) => {
// data 表格数据 fieldList 要算合计的字段 sumTitle 显示合计两个字的字段 avgFiled 要算均值的字段(这个字段也必须在算合计的字段里面)
if (data && data.length > 0) {
if (data.length >= 2) {
const res: any = {}
if (fieldList && fieldList.length > 0) {
fieldList.forEach((item: any) => {
res[item] = 0
})
}
data.forEach((item: any) => {
if (res) {
for (const key in res) {
if (item[key]) {
res[key] += item[key]
}
}
}
})
if (avgFiled) {
res[avgFiled] = Number((res[avgFiled] / data.length).toFixed(2))
}
console.log('res', res);
res[sumTitle] = "合计"
data.unshift(res)
return data
}
// 一个片区的时候 判断是不是一个服务区 一个服务区的话 就单单显示一个服务区就好
if (data && data.length === 1) {
const obj: any = data[0]
if (obj.children && obj.children.length === 1) {
return obj.children
}
return data
}
return data
}
return []
}
// 自定义打印的内容的打印方法
export const handleNewPrint = (printName: string, title: string, neckBox?: any, styles?: any, tableDom?: any, footer?: any) => {
// printName 打印出来文件的名称
// title 打印内容的标题
// neckBox 标题下面可能会要求的打印的内容 数组 {label,value}格式 样式已写死
// styles 获取页面的样式
// tableDom 要打印显示的表格 直接dom元素拿进来(处理好的)
// footer 打印内容底部的自定义样式 需求不一样 样式也不一样 外面写好样式和标签直接传入
const printWindow = window.open('', '_blank', 'width=1400,height=800');
if (printWindow) {
printWindow.document.open();
printWindow.document.write(`
${printName || ''}
${neckBox && neckBox.length > 0
? neckBox
.map((item: any) => {
return `
${item.label ? item.label + ':' : ''}
${item.value}
`;
})
.join('') // 连接成单一字符串,避免逗号
: ''}
${tableDom}
${footer}
${Array(16) // 5x5 网格的水印内容
.fill('安徽省驿达高速公路服务区经营管理有限公司')
.join('')}
`)
printWindow.document.close();
printWindow.print();
// 使用定时器检测打印窗口是否关闭
const closeCheckInterval = setInterval(() => {
if (printWindow.closed) {
clearInterval(closeCheckInterval);
}
}, 500);
// 监听窗口焦点事件,若打印窗口失去焦点,关闭窗口
printWindow.onfocus = () => {
printWindow.close();
clearInterval(closeCheckInterval);
};
printWindow.onafterprint = () => printWindow.close();
}
}
// 打印图片
export const handlePrintImg = (url: any) => {
const printWindow = window.open('', '_blank', 'width=1400,height=800');
if (printWindow) {
printWindow.document.open();
printWindow.document.close();
printWindow.document.write(`
`)
printWindow.print();
// 使用定时器检测打印窗口是否关闭
const closeCheckInterval = setInterval(() => {
if (printWindow.closed) {
clearInterval(closeCheckInterval);
}
}, 500);
printWindow.onfocus = () => {
printWindow.close();
clearInterval(closeCheckInterval);
};
printWindow.onafterprint = () => printWindow.close();
}
}
// 记录每一个按钮的 调用了的方法
export const handleSetPublicLog = (obj: any) => {
// desc 一个数组 入参内容说明 startTime 开始时间 endTime 结束时间 时间戳格式 buttonType 1 为点击了查询按钮
const currentUser: CurrentUser = session.get('currentUser');
let nowMenu = session.get("currentMenu")
let basicInfo = session.get("basicInfo")
let systemBasin = session.get("systemBasin")
let browserVersion = session.get("browserVersion")
if (obj.desc && obj.desc.length > 0) {
obj.desc.forEach((item: any) => {
item.url = 'https://api.eshangtech.com' + item.url
})
}
const req: any = {
USER_ID: currentUser.ID,
USER_NAME: currentUser.Name,
BEHAVIORRECORD_TYPE: "2000", // 1000 浏览页面 2000 行为记录
BEHAVIORRECORD_EXPLAIN: `在页面${nowMenu.name}${obj.buttonType === 1 ? '点击了查询按钮' : ''}`, // 操作行为说明
BEHAVIORRECORD_ROUT: nowMenu.pathname,
BEHAVIORRECORD_ROUTNAME: nowMenu.name,
REQUEST_INFO: JSON.stringify(obj.desc),// 存的是一个JSON 存完整点的内容 在什么页面点击了什么 调用了什么接口 入参是什么 多个接口的时候是数组格式
// BEHAVIORRECORD_DESC: obj.desc, // 入参
BEHAVIORRECORD_TIME: moment(new Date(obj.startTime)).format('YYYY-MM-DD HH:mm:ss'),
BEHAVIORRECORD_LEAVETIME: moment(new Date(obj.endTime)).format('YYYY-MM-DD HH:mm:ss'),
BEHAVIORRECORD_DURATION: (obj.endTime - obj.startTime) / 1000,
OWNERUNIT_ID: currentUser.OwnerUnitId,
OWNERUNIT_NAME: currentUser.OwnerUnitName,
BUSINESSMAN_ID: currentUser.BusinessManID,
BUSINESSMAN_NAME: currentUser.BusinessManName,
SOURCE_PLATFORM: '驿商云平台',
USER_LOGINIP: basicInfo.ip,
USER_LOGINPLACE: `${basicInfo.country}${basicInfo.prov}${basicInfo.city}${basicInfo.district}`,
BROWSER_VERSION: browserVersion,
OPERATING_SYSTEM: systemBasin
}
console.log('reqreqreqreqreq', req);
synchroBehaviorRecord(req)
}
// 将一个对象的key值变为 中文字
export const handleChangeKeyTo = async (params: any, keyObj: any) => {
// params 需要变的对象 keyObj 中文内容
let newObj: any = {}
for (let key in params) {
newObj[keyObj[key]] = params[key]
}
return newObj
}
// 传入秒 返回时分
export const secondsToHuman = (seconds: number) => {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const parts = [];
if (hours > 0) parts.push(`${hours}小时`);
if (minutes > 0) parts.push(`${minutes}分钟`);
return parts.join('') || '0分钟';
}
// 封装一个只要传入操作事项的就可以记录日志
export const handleSetlogSave = async (str?: string) => {
const currentUser = session.get('currentUser')
const basicInfo = session.get('basicInfo')
const browserVersion = session.get('browserVersion')
const systemBasin = session.get('systemBasin')
let nowMenu = session.get("currentMenu")
synchroBehaviorRecord({
USER_ID: currentUser?.ID,
USER_NAME: currentUser?.Name,
BEHAVIORRECORD_TYPE: "2000",
BEHAVIORRECORD_EXPLAIN: str || "",
BEHAVIORRECORD_ROUT: nowMenu.pathname,
BEHAVIORRECORD_ROUTNAME: nowMenu.name,
BEHAVIORRECORD_TIME: moment().format('YYYY-MM-DD HH:mm:ss'),
// REQUEST_INFO: str || "",
OWNERUNIT_ID: currentUser?.OwnerUnitId,
OWNERUNIT_NAME: currentUser?.OwnerUnitName,
BUSINESSMAN_ID: currentUser?.BUSINESSMAN_ID,
BUSINESSMAN_NAME: currentUser?.BUSINESSMAN_NAME,
SOURCE_PLATFORM: "出行平台",
USER_LOGINIP: basicInfo?.ip,
USER_LOGINPLACE: `${basicInfo?.prov}${basicInfo?.city}${basicInfo?.district}`,
BROWSER_VERSION: browserVersion,
OPERATING_SYSTEM: systemBasin
})
}
export function convertTreeToLabelValue(
tree: T[],
labelKey: keyof T,
valueKey: keyof T,
childrenKey: keyof T = 'children' as keyof T
): any[] {
return tree.map((item: any) => {
const node: any = {
label: item[labelKey],
value: item[valueKey]
};
if (Array.isArray(item[childrenKey]) && item[childrenKey].length > 0) {
node.children = convertTreeToLabelValue(item[childrenKey], labelKey, valueKey, childrenKey);
}
return node;
});
}
export function convertTreeFieldToNumber(tree: any[], key: string): any[] {
return tree.map(node => {
const newNode = {
...node,
[key]: typeof node[key] === 'number' ? node[key].toString() : node[key],
};
if (Array.isArray(node.children) && node.children.length > 0) {
newNode.children = convertTreeFieldToNumber(node.children, key);
}
return newNode;
});
}