import _ from 'lodash-es' import { nanoid } from './nanoid' const fieldsRe = /^(input|textarea|number|radio|checkbox|select|time|date|rate|switch|slider|html|cascader|uploadfile|signature|region|subform)$/ const deepTraversal = (node, fn) => { fn(node) const nodes = node.type === 'subform' ? node.list[0] : (node.list || node.rows || node.columns || node.children || []) nodes.forEach(e => { deepTraversal(e, fn) }) } const wrapElement = (element, fn) => { const result = element deepTraversal(result, (node) => { if (Array.isArray(node)) return false if (!node.style) { node.style = {} } if (!node.id) { // node.id = nanoid() node.id = new Date().getTime() } if (!node.key) { node.key = `${node.type}${node.id}` } if (/^(grid|tabs|collapse|table|divider)$/.test(node.type)) { node.style = { width: '100%' } } if (checkIsField(node)) { node.style = { width: { pc: '100%', mobile: '100%' } } } if (/^(tabs)$/.test(node.type)) { node.columns = new Array(3).fill('').map((e, index) => { const data = renderFieldData('tabsCol') data.label = `Tab ${index + 1}` data.options = {} return data }) } if (/^(collapse)$/.test(node.type)) { node.columns = new Array(3).fill('').map((e, index) => { const data = renderFieldData('collapseCol') data.label = `Tab ${index + 1}` data.options = {} return data }) } fn && fn(node) }) return result } const renderFieldData = (type) => { const result = { id: nanoid(), type, label: '', list: [], style: {} } return result } const excludes = ['grid', 'col', 'table', 'tr', 'td', 'tabs', 'tabsCol', 'collapse', 'collapseCol', 'divider', 'inline'] const flatNodes = (nodes, excludes, fn, excludesFn) => { return nodes.reduce((res, node, currentIndex) => { if (excludes.indexOf(node.type) === -1) { res.push(node) fn && fn(nodes, node, currentIndex) } else { excludesFn && excludesFn(nodes, node, currentIndex) } const children = node.type === 'subform' ? node.list[0] : (node.list || node.rows || node.columns || node.children || []) res = res.concat(flatNodes(children, excludes, fn, excludesFn)) return res }, []) } const getAllFields = (store) => flatNodes(store, excludes) const pickfields = (list) => { return flatNodes(list, excludes) } const processField = (list) => flatNodes(list, excludes, (nodes, node, currentIndex) => { nodes[currentIndex] = node.id }) const disassemblyData1 = (data) => { const result = { list: data.list, config: data.config, fields: processField(data.list), data: data.data, logic: data.logic } return result } const combinationData1 = (data) => { const result = { list: data.list, config: data.config, data: data.data, fields: data.fields, logic: data.logic } const fn = (nodes, node, currentIndex) => { const cur = _.find(data.fields, { id: node }) if (!_.isEmpty(cur)) { if (cur.type === 'subform') { flatNodes(cur.list[0], excludes, fn) } nodes[currentIndex] = cur } } flatNodes(data.list, excludes, fn) return result } const combinationData2 = (list, fields) => { const fn = (nodes, node, currentIndex) => { const cur = _.find(fields, { id: node }) if (!_.isEmpty(cur)) { if (cur.type === 'subform') { flatNodes(cur.list[0], excludes, fn) } nodes[currentIndex] = cur } } flatNodes(list, excludes, fn) } const repairLayout = (layout, fields) => { flatNodes(layout, excludes, (nodes, node, currentIndex) => { if (_.isString(node)) { if (!_.isEmpty(_.find(fields, { id: node }))) { nodes.splice(currentIndex, 1) } } }) const temporary = [] flatNodes(layout, excludes, null, (nodes, node, currentIndex) => { if (node.type === 'inline') { if (!node.columns.length) { temporary.unshift({ nodes, currentIndex }) } } }) temporary.forEach(e => { e.nodes.splice(e.currentIndex, 1) }) } const disassemblyData2 = (list) => { flatNodes(list, excludes, (nodes, node, currentIndex) => { nodes[currentIndex] = node.id && node.id }) } const checkIslineChildren = (node) => node.context.parent.type === 'inline' const checkIsField = (node) => fieldsRe.test(node.type) const calculateAverage = (count, total = 100) => { const base = Number((total / count).toFixed(2)) const result = [] for (let i = 0; i < count; i++) { // result.push(base + (i < rest ? 1 : 0)) result.push(base) } return result } const syncWidthByPlatform = (node, platform, syncFullplatform = false, value) => { // debugger const isArray = _.isArray(node) if (!isArray) { if (_.isObject(node.style.width)) { if (syncFullplatform) { node.style.width.pc = node.style.width.mobile = value + '%' } else { node.style.width[platform] = value + '%' } } else { node.style.width = value + '%' } } const otherNodes = isArray ? node : node.context.parent.columns.filter(e => e !== node) const averageWidths = calculateAverage(otherNodes.length, isArray ? 100 : 100 - value) otherNodes.forEach((node, index) => { const isFieldWidth = _.isObject(node.style.width) if (isFieldWidth) { if (syncFullplatform) { node.style.width.pc = node.style.width.mobile = averageWidths[index] + '%' } else { node.style.width[platform] = averageWidths[index] + '%' } } else { node.style.width = averageWidths[index] + '%' } }) } const transferLabelPath = (node) => { const inputTypeFlag = node.type === 'input' // input框 const selectTypeFlag = node.type === 'select' // select框 const cascaderTypeFlag = node.type === 'cascader' // cascader let defaultFields = '' if (inputTypeFlag || selectTypeFlag || cascaderTypeFlag) { defaultFields = `${node.type}.${node.options.renderType - 1}` } else { defaultFields = `${node.type}` } return `er.fields.${defaultFields}` } const fieldLabel = (t, node) => t(transferLabelPath(node)) const transferData = (lang, path, locale, options = {}) => { let result = '' if (_.isEmpty(options)) { result = _.get(locale[lang], path, '') } else { result = _.template(_.get(locale[lang], path, ''))(options) } return result } const isNull = (e) => e === '' || e === null || e === undefined const checkIsInSubform = (node) => { if (!node) return false let result = false let parent = node.context.parent while (parent && !result) { if (parent.type === 'subform') { result = true } parent = parent.context?.parent } return result } const getSubFormValues = (subform) => subform.list.map(e => { const cur = {} const children = [] e.forEach(e => { e.columns.forEach(e => { children.push(e) }) }) children.forEach(e => { cur[e.key] = e.options.defaultValue }) return cur }) const findSubFormAllFields = (subform) => { const result = [] subform.list.forEach(e => { e.forEach(e => { result.push(...e.columns) }) }) return result } export { syncWidthByPlatform, wrapElement, deepTraversal, renderFieldData, getAllFields, disassemblyData1, combinationData1, disassemblyData2, combinationData2, checkIslineChildren, checkIsField, pickfields, fieldLabel, transferData, transferLabelPath, isNull, repairLayout, checkIsInSubform, getSubFormValues, findSubFormAllFields, processField }