2024-04-23 13:12:02 +08:00

164 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* eslint-disable no-new-func */
import { cloneDeep, isString, isPlainObject, isArray } from 'lodash'
import type { formValuesType } from '/admin/components/catchForm/config/commonType'
import type { formItemType, formItemsType } from '/admin/components/catchForm/config/commonType'
import { isEqual } from 'lodash'
import type { anyObject, contextType} from '/admin/components/catchForm/config/commonType'
type handleLinkagesType = (obj: { newVal: Object; oldVal: Object; formValues: anyObject; formItems: formItemsType }) => void
// 模板转换函数将一个由双大括号包裹的字符串转化为js表达式并返回结果context限制变量范围
const templateParse = (str: string, context: contextType) => {
if (!str) return str
if (typeof str !== 'string') return str
const template = str.match(/{{(.+?)}}/)
if (template) {
try {
const parse = new Function(Object.keys(context).join(','), 'return ' + template[1])
return parse(...Object.values(context))
} catch (e) {
// console.log(str, '模板转换错误:', e)
return str
}
} else {
return str
}
}
const deepParse = (prop: any, context: contextType): any => {
const $values = context.$values
if (isString(prop)) {
return templateParse(prop, context)
}
if (isPlainObject(prop)) {
return Object.keys(prop).reduce((all, key) => {
const itemContext = { ...context }
if (prop.name && $values) {
itemContext.$val = getDataByPath($values, prop.name)
itemContext.$select = context.$selectData[prop.name]
}
return { ...all, [key]: deepParse(prop[key], itemContext) }
}, {})
}
if (isArray(prop)) {
return prop.map(item => {
return deepParse(item, context)
})
}
return prop
}
const handleLinkages: handleLinkagesType = ({ newVal, oldVal, formValues, formItems }) => {
for (const item of formItems) {
const newValue = getDataByPath(newVal, item.name)
const oldValue = getDataByPath(oldVal, item.name)
if (item.change && !isEqual(newValue, oldValue)) {
let temp = cloneDeep(formValues.value)
item.change.forEach(({ target, value }) => {
temp = setDataByPath(temp, target, value)
})
formValues.value = temp
}
if (item.children && item.component !== 'FormList') {
handleLinkages({
newVal,
oldVal,
formValues,
formItems: item.children
})
}
}
}
const recursionDelete = (items: formItemsType, callback: (item: formItemType) => boolean): formItemsType => {
const data = items.filter(callback)
return data.map(item => {
if (item.children) {
return {
...item,
children: recursionDelete(item.children, callback)
}
}
return item
})
}
const setDataByPath = (object: formValuesType, path: string, value: any) => {
const cloneObj = cloneDeep(object)
// 将路径字符串分割成路径数组
const pathArray = path.split('.')
// 递归函数,用于在对象的深层级找到要修改的位置并更新其值
function update(obj: formValuesType, pathArray: string[], value: any) {
// 如果路径数组为空,表示已经到达了最后一级,更新值并返回
if (pathArray.length === 1) {
obj[pathArray[0]] = value
return
}
// 获取当前路径的第一个部分
const currentKey = pathArray.shift()
if (currentKey) {
// 如果当前键不存在,则创建一个空对象
if (!obj[currentKey]) {
obj[currentKey] = {}
}
// 递归调用更新函数
update(obj[currentKey], pathArray, value)
}
}
// 调用递归函数
update(cloneObj, pathArray, value)
// 返回更新后的对象
return cloneObj
}
const isRegexString = (str: string) => {
const regexMetaCharacters = /[.*+?^${}()|[\]\\]/
return regexMetaCharacters.test(str)
}
const getRandomId = (length: number) => {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
let randomId = ''
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * characters.length)
randomId += characters.charAt(randomIndex)
}
return randomId
}
const getDataByPath = (obj: anyObject, path: string) => {
// 使用正则表达式分割路径字符串
const keys = path.split('.')
// 遍历路径,逐层深入对象
let result = obj
for (const key of keys) {
if (result && typeof result === 'object' && key in result) {
result = result[key]
} else {
// 如果路径无效,返回 undefined 或者其他默认值
return undefined
}
}
return result
}
export { setDataByPath, recursionDelete, isRegexString, getRandomId, handleLinkages, getDataByPath, deepParse}