config-util.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /**
  2. * 合并字段配置Map
  3. * @param targetConfigMap 待合并字段
  4. * @param sourceConfigMaps 合并字段源数组
  5. * @return {{}}
  6. */
  7. import { cloneDeep, getFieldValue, isArray } from './util'
  8. // configMapToList即mergeFieldConfig联合使用
  9. export const generateFieldList = (...args) => configMapToList(mergeFieldConfig(...args))
  10. export const mergeFieldConfig = (targetConfigMap, ...sourceConfigMaps) => {
  11. const result = {}
  12. Object.keys(targetConfigMap).forEach(key => {
  13. const targetConfig = targetConfigMap[key] || {}
  14. result[key] = getMergeConfig(key, targetConfig, sourceConfigMaps)
  15. })
  16. return result
  17. }
  18. /**
  19. * config 对象转为数组 (table时用的较多)
  20. * @param configMap
  21. * @return {{sort, config: *, key: string}[]}
  22. */
  23. export const configMapToList = (configMap) => {
  24. return Object.keys(configMap).map((key, i) => {
  25. const config = configMap[key]
  26. key = config.realKey || key // realKey的优先级高于原本的key用于处理object相同的key智能有一个的问题
  27. return {
  28. key, // realKey的优先级高于key,
  29. config,
  30. sort: config.configSort || i
  31. }
  32. }).sort((a, b) => a.sort - b.sort)
  33. }
  34. /**
  35. * 将一个字段配置数据插入到另一个配置数据中
  36. * @param target
  37. * @param source
  38. * @returns {*}
  39. */
  40. export const insertFieldConfigToList = (target = [], source) => {
  41. target = [...target] // 需要浅拷贝一次不然会导致值被修改的问题
  42. source.forEach(fieldConfig => {
  43. const { config: { insert } = {} } = fieldConfig
  44. if (insert) {
  45. // 需要开启排序 before 的优先级高于 after
  46. const offset = insert.before ? 0 : 1
  47. const anchorKey = insert.before || insert.after
  48. const anchorIndex = target.findIndex(tFieldConfig => tFieldConfig.key === anchorKey)
  49. target.splice(anchorIndex + offset, 0, fieldConfig)
  50. } else {
  51. target.push(fieldConfig)
  52. }
  53. })
  54. return target
  55. }
  56. export const configListToMap = (configList) => {
  57. const result = {}
  58. configList.forEach(({ key, config } = {}) => {
  59. if (key) {
  60. result[key] = config
  61. }
  62. })
  63. return result
  64. }
  65. const handlerDependOn = (dependOn, newDependOn, isMerge) => {
  66. if (dependOn && newDependOn) {
  67. const result = isMerge ? [...dependOn, ...newDependOn] : newDependOn
  68. return result.length > 0 ? result : undefined
  69. } else {
  70. return dependOn || newDependOn
  71. }
  72. }
  73. /**
  74. * 合并字段配置
  75. * @param key
  76. * @param targetConfig
  77. * @param sourceConfigMaps
  78. * @return {{}}
  79. */
  80. function getMergeConfig (key, targetConfig, sourceConfigMaps) {
  81. let sourceConfig = {}
  82. const sourceKey = targetConfig.sourceKey || targetConfig.realKey || key
  83. let dependOn = []
  84. const isMergeDependOn = targetConfig.mergeDependOn === true
  85. if (sourceKey) {
  86. const sourceKeys = sourceKey.split('.')
  87. sourceConfigMaps.forEach((sourceConfigMap = {}) => {
  88. let sourceConfigNext = getFieldConfig(sourceConfigMap[sourceKey])
  89. if (!sourceConfigNext && sourceKeys.length > 1) {
  90. sourceConfigNext = getFieldConfig(sourceConfigMap[sourceKeys[0]])
  91. const preKey = [sourceKeys[0]]
  92. for (let i = 1; i < sourceKeys.length; i++) {
  93. if (!sourceConfigNext) break
  94. sourceConfigNext = getFieldConfig(sourceConfigNext[sourceKeys[i]], preKey.join('.'))
  95. preKey.push(sourceKeys[i]) // 最后一个key,舍弃
  96. }
  97. }
  98. dependOn = handlerDependOn(sourceConfig?.dependOn, sourceConfigNext?.dependOn, isMergeDependOn)
  99. sourceConfig = { ...sourceConfig, ...sourceConfigNext }
  100. })
  101. }
  102. /**
  103. * 合并逻辑
  104. */
  105. if (isMergeDependOn) {
  106. dependOn = handlerDependOn(dependOn, targetConfig.dependOn, true)
  107. } else {
  108. dependOn = targetConfig.dependOn || dependOn
  109. }
  110. return { ...sourceConfig, ...targetConfig, dependOn }
  111. }
  112. /**
  113. * 处理深层对象的副作用函数
  114. * @param fn
  115. * @param key
  116. * @param preKey
  117. * @return {(function(...[*]): *)|*}
  118. */
  119. const handlerEffectFunction = (fn, key, preKey) => {
  120. // 如果fn不为函数返回原值
  121. if (typeof fn !== 'function') return fn
  122. if (key === 'changeConfig') {
  123. return (...args) => {
  124. return fn(args[0], getFieldValue(args[1], preKey) ?? {}, getFieldValue(args[2], preKey) ?? {})
  125. }
  126. }
  127. // 私有effect中无getOptionsFilter、asyncOptions
  128. if (['changeValue', 'asyncOptions', 'getOptionsFilter'].includes(key)) {
  129. return (...args) => {
  130. return fn(getFieldValue(args[0], preKey) ?? {}, getFieldValue(args[1], preKey) ?? {})
  131. }
  132. }
  133. // 如果key不符合上述条件返回原值
  134. return fn
  135. }
  136. /**
  137. * 获取字段配置(_renderConfig为数据定义时定义的字段渲染配置)
  138. * @param config
  139. * @return {{}|*}
  140. */
  141. function getFieldConfig (config, preKey = '') {
  142. if (config?._renderConfig) {
  143. const _renderConfig = cloneDeep(config._renderConfig)
  144. if (preKey) {
  145. const dependOn = _renderConfig.dependOn
  146. if (dependOn?.length > 0) {
  147. _renderConfig.dependOn = dependOn.map(on => {
  148. if (typeof on === 'object') {
  149. const effect = handlerEffect(on.effect, preKey)
  150. return {
  151. key: `${preKey}.${on.key}`,
  152. effect
  153. }
  154. } else {
  155. return `${preKey}.${on}`
  156. }
  157. });
  158. // `${preKey}.${on}`
  159. ['changeConfig', 'changeValue', 'asyncOptions', 'getOptionsFilter'].forEach(key => {
  160. if (typeof _renderConfig[key] === 'function') {
  161. _renderConfig[key] = handlerEffectFunction(_renderConfig[key], key, preKey)
  162. }
  163. })
  164. }
  165. const otherKey = _renderConfig.otherKey
  166. if (typeof otherKey === 'string') {
  167. _renderConfig.otherKey = `${preKey}.${otherKey}`
  168. } else if (isArray(otherKey)) {
  169. _renderConfig.otherKey = otherKey.map(v => `${preKey}.${v}`)
  170. }
  171. }
  172. return _renderConfig
  173. } else {
  174. return config
  175. }
  176. }
  177. /**
  178. * 处理dependOn 为对象时的副作用配置
  179. * @param effect
  180. * @param preKey
  181. * @return {{}}
  182. */
  183. function handlerEffect (effect, preKey) {
  184. const result = {}
  185. Object.keys(effect).forEach(key => {
  186. const item = effect[key]
  187. if (typeof item !== 'function') {
  188. result[key] = item
  189. } else {
  190. // 值为function
  191. result[key] = handlerEffectFunction(item, key, preKey)
  192. }
  193. })
  194. return result
  195. }
  196. export const keysToConfigMap = (keys) => {
  197. const configMap = {}
  198. keys.forEach(key => {
  199. let config = {}
  200. if (typeof key === 'object') {
  201. config = { ...key }
  202. key = key.key
  203. config.key = undefined
  204. }
  205. configMap[key] = config
  206. })
  207. return configMap
  208. }
  209. export const defineFieldConfig = (config) => config
  210. // 为ts服务
  211. // form配置
  212. export const defineFormFieldConfig = (config) => config
  213. // table配置
  214. export const defineTableFieldConfig = (config) => config
  215. // search-form配置
  216. export const defineSearchFieldConfig = (config) => config