lu-lowcode-package-form 0.11.51 → 0.11.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lu-lowcode-package-form",
3
- "version": "0.11.51",
3
+ "version": "0.11.54",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^4.8.1",
6
6
  "@dnd-kit/core": "^6.1.0",
@@ -0,0 +1,121 @@
1
+ import React, { useRef, useState, useEffect } from "react"
2
+ import { eventEmitter } from "../../../utils/events"
3
+ import { createPortal } from "react-dom"
4
+ import { Resizable } from "react-resizable"
5
+
6
+ const DragHead = ({ children, changeWidth, ...props }) => {
7
+ const [headWidths, setHeadWidths] = useState([])
8
+ const headWidthsRef = useRef([])
9
+ const [isDragging, setIsDragging] = useState(false)
10
+ const [resizingColumn, setResizingColumn] = useState(null)
11
+ const [dragPosition, setDragPosition] = useState(0)
12
+ const startPositionRef = useRef(0)
13
+
14
+
15
+ const getColumnWidth = (index) => {
16
+ return headWidths[index] || 150
17
+ }
18
+
19
+ // 处理拖动开始
20
+ const onResizeStart = (index) => {
21
+ return (e, data) => {
22
+ e.stopPropagation()
23
+ setIsDragging(true)
24
+ setResizingColumn(index)
25
+ setDragPosition(e.clientX)
26
+ startPositionRef.current = e.clientX
27
+ }
28
+ }
29
+
30
+ // 处理拖动中
31
+ const onResize = (index) => {
32
+ return (e, { size }) => {
33
+ e.stopPropagation()
34
+ // 只在拖动过程中更新虚拟指示线位置
35
+ setDragPosition(e.clientX)
36
+ }
37
+ }
38
+
39
+ // 处理拖动结束
40
+ const onResizeStop = (index) => {
41
+ return (e, { size }) => {
42
+ // 更新列宽
43
+ const newHeadWidths = [...headWidthsRef.current]
44
+ const delta = e.clientX - startPositionRef.current
45
+ const oldWidth = headWidths[index] || 150
46
+ const newWidth = Math.max(50, oldWidth + delta)
47
+ newHeadWidths[index] = newWidth
48
+ headWidthsRef.current = newHeadWidths
49
+ setHeadWidths(newHeadWidths)
50
+ typeof changeWidth === 'function' && changeWidth(newHeadWidths)
51
+ eventEmitter.emit('changeSubTableColumnWidth', newHeadWidths)
52
+ // 重置拖动状态
53
+ setIsDragging(false)
54
+ setResizingColumn(null)
55
+ }
56
+ }
57
+
58
+ // 虚拟指示线组件
59
+ const DragIndicator = () => {
60
+ if (!isDragging) return null
61
+
62
+ const style = {
63
+ position: 'fixed',
64
+ top: 0,
65
+ left: `${dragPosition}px`,
66
+ width: '2px',
67
+ height: '100vh',
68
+ backgroundColor: '#1890ff',
69
+ pointerEvents: 'none',
70
+ zIndex: 9999
71
+ }
72
+
73
+ return createPortal(
74
+ <div style={style}></div>,
75
+ document.body
76
+ )
77
+ }
78
+
79
+ return <><div className="fflex flex-nowrap fmin-w-full fabsolute">
80
+ {React.Children.map(children, (child, childIndex) => {
81
+ const width = getColumnWidth(childIndex)
82
+
83
+ return (
84
+ <Resizable
85
+ key={childIndex}
86
+ width={width}
87
+ height={0} // 高度不用调整,设为0
88
+ onResizeStart={onResizeStart(childIndex)}
89
+ onResize={onResize(childIndex)}
90
+ onResizeStop={onResizeStop(childIndex)}
91
+ handle={
92
+ <div
93
+ className="react-resizable-handle react-resizable-handle-e"
94
+ style={{
95
+ position: 'absolute',
96
+ right: 0,
97
+ top: 0,
98
+ height: '100%',
99
+ width: '8px',
100
+ cursor: 'col-resize',
101
+ zIndex: 1
102
+ }}
103
+ />
104
+ }
105
+ resizeHandles={['e']} // 只允许从右侧拖动调整宽度
106
+ >
107
+ <div
108
+ className="fflex-1 fh-12 fflex fitems-center fpx-1 frelative"
109
+ style={{minWidth: width}}
110
+ >
111
+ &nbsp;
112
+ </div>
113
+ </Resizable>
114
+ )
115
+ })}
116
+ <div className="fsticky fright-0 fborder-b" style={{ boxShadow: "rgba(50, 50, 50, 0.15) -6px 0px 6px -6px", flex: "0 0 50px", width: "50px" }}></div>
117
+ </div>
118
+ <DragIndicator /></>
119
+ }
120
+
121
+ export default DragHead
@@ -1,16 +1,17 @@
1
1
  import React, { useEffect, useRef, useState } from "react";
2
- import { Button, Form, Input,Popconfirm } from "antd";
2
+ import { Button, Form, Input, Popconfirm } from "antd";
3
3
  import { CopyOutlined, DeleteOutlined } from "@ant-design/icons";
4
4
  import { BaseWrapper } from "../base.jsx"
5
5
  import { nanoid } from "nanoid";
6
6
  import { eventEmitter } from '../../../utils/events'
7
7
  import { useMemoizedFn } from 'ahooks';
8
+ import DragHead from "./drag-head"
8
9
 
9
10
  const TableAction = ({ label, subTableIndex, children, subTableHead = false, ...props }) => {
10
11
  //fsticky fright-0
11
12
  return <div className="fsticky fright-0 fbg-white fborder-b " style={{
12
13
  boxShadow: '-6px 0 6px -6px rgba(50,50,50,0.15)',
13
- flex: '0 0 50px',
14
+ flex: '0 0 50px',
14
15
  width: '50px'
15
16
  }}>
16
17
  <div className="frelative fw-full fh-full fflex fflex-col foverflow-hidden">
@@ -22,7 +23,7 @@ const TableAction = ({ label, subTableIndex, children, subTableHead = false, ...
22
23
  </div>
23
24
  }
24
25
 
25
- const RowID = ({value,onChange,...props}) => {
26
+ const RowID = ({ value, onChange, ...props }) => {
26
27
  useEffect(() => {
27
28
  if (!value) onChange(nanoid())
28
29
  }, [value])
@@ -42,10 +43,16 @@ const TableCol = ({ children, width, hidden, ...props }) => {
42
43
  </div>
43
44
  }
44
45
 
45
- const Table = ({ children, onTableAddRow, disabled, readonly, onTableRemoveRow, form, fieldName, initializeFormRender, recordFieldsChange, getTableWithIds,removeLastFieldsValues, mode, isAllowCopy=false, isAllowAdd=true,getDependencyMapItem, ...props }) => {
46
+ const Table = ({ children, onTableAddRow, disabled, readonly, onTableRemoveRow, form, fieldName, initializeFormRender, recordFieldsChange, getTableWithIds, removeLastFieldsValues, mode, isAllowCopy = false, isAllowAdd = true, getDependencyMapItem, ...props }) => {
46
47
  useEffect(() => {
47
48
  // console.log("Table form reload", form)
48
49
  }, [form])
50
+
51
+ useEffect(() => {
52
+ console.log("Table props", props)
53
+ }, [props])
54
+
55
+ const [headWidths, setHeadWidths] = useState([])
49
56
  const tableComponentId = props.componentId || props.__id
50
57
  const newidRefs = useRef(React.Children.map(children, () => nanoid()));
51
58
  const [init, setInit] = useState(false);
@@ -68,8 +75,15 @@ const Table = ({ children, onTableAddRow, disabled, readonly, onTableRemoveRow,
68
75
  return () => {
69
76
  eventEmitter.off('reloadTable', handleReloadTable);
70
77
  }
71
-
72
78
  }, [])
79
+
80
+
81
+ const getColumnWidth = (index) => {
82
+ return headWidths[index] || 150
83
+ }
84
+ const handleChangeWidth = (newHeadWidths) => {
85
+ setHeadWidths(newHeadWidths)
86
+ }
73
87
  const getAllWithIds = () => {
74
88
  if (typeof getTableWithIds === 'function') {
75
89
  return getTableWithIds(childrenIds)
@@ -84,9 +98,9 @@ const Table = ({ children, onTableAddRow, disabled, readonly, onTableRemoveRow,
84
98
  }
85
99
  return true
86
100
  }
87
- const handleCopy = useMemoizedFn((index)=>{
101
+ const handleCopy = useMemoizedFn((index) => {
88
102
  let tableValues = form.getFieldValue(fieldName)
89
- const copyRow = {...tableValues[index],__id:nanoid()}
103
+ const copyRow = { ...tableValues[index], __id: nanoid() }
90
104
  tableValues.splice(index + 1, 0, copyRow)
91
105
  form?.setFieldValue(fieldName, tableValues)
92
106
 
@@ -95,159 +109,163 @@ const Table = ({ children, onTableAddRow, disabled, readonly, onTableRemoveRow,
95
109
  for (let i = index + 1; i < tableValues.length; i++) {
96
110
  let value = tableValues[i]
97
111
  for (let key in value) {
98
- let changedFieldName = [tableName,i,key]
99
- changedFields[changedFieldName] = { name: changedFieldName, value: value[key] }
112
+ let changedFieldName = [tableName, i, key]
113
+ changedFields[changedFieldName] = { name: changedFieldName, value: value[key] }
100
114
  }
101
115
  }
102
- typeof recordFieldsChange == "function" && recordFieldsChange(changedFields,true)
116
+ typeof recordFieldsChange == "function" && recordFieldsChange(changedFields, true)
103
117
  })
104
118
 
105
- const handleRemove = useMemoizedFn((index)=>{
119
+ const handleRemove = useMemoizedFn((index) => {
106
120
  let tableValues = form.getFieldValue(fieldName)
107
121
  tableValues.splice(index, 1)
108
- form?.setFieldValue(fieldName, tableValues)
122
+ form?.setFieldValue(fieldName, tableValues)
109
123
  typeof onTableRemoveRow === "function" && onTableRemoveRow(childrenIds);
110
- typeof removeLastFieldsValues === "function" && removeLastFieldsValues(`${name},${index}`,true)
124
+ typeof removeLastFieldsValues === "function" && removeLastFieldsValues(`${name},${index}`, true)
111
125
  })
112
126
  if (props.isRequired)
113
127
  rules.push({ required: true, message: `子表[${props.label}]必须填写` });
114
- return <Form.List name={name} rules={rules}>
115
- {(fields, { add, remove }) => {
116
- if (fields.length === 0 && !init) handleAdd();
117
- return <div className="fw-full ">
118
- <div className="fw-full frelative fmin-h-20 foverflow-x-auto" style={{ position: 'relative' }}>
119
- {fields.length === 0 && <div key={`tableHead`} className="fborder-b fflex flex-nowrap fmin-w-full ">
120
- {React.Children.map(children, (child, childIndex) => {
121
- const hidden = (child?.props?.calcHidden || !getDependencyMapShow(child?.props?.componentId || child?.props?.__id)) && mode != "desgin";
122
- return <TableCol width={150} key={`row_${0}_col_${childIndex}`} hidden={hidden}>
123
- {hidden ? null : React.cloneElement(child, {
124
- key: `row_${0}_child_${childIndex}`,
125
- subTable: true,
126
- subTableHead: true,
127
- subTableContent: false,
128
- })}
129
- </TableCol>
130
- })}
131
- {disabled != true && readonly != true && <TableAction subTableHead={true} key={`row_${0}_action`} subTable={true} subTableIndex={0} label={"操作"}>
132
- </TableAction>}
133
- </div>}
134
- {fields.map((field, index) => (
135
- <div key={`${tableId}.${field.key}`} className=" fflex flex-nowrap fmin-w-full ">
136
- <Form.Item hidden={true} name={[field.name, "__id"]}>
137
- <RowID />
138
- </Form.Item>
128
+ return <div className="fw-full fflex fflex-col fgap-2">
129
+ <Form.List name={name} rules={rules}>
130
+ {(fields, { add, remove }) => {
131
+ if (fields.length === 0 && !init) handleAdd();
132
+ return <div className="fw-full ">
133
+
134
+ <div className="fw-full frelative fmin-h-20 foverflow-x-auto" style={{ position: 'relative' }}>
135
+ <DragHead changeWidth={handleChangeWidth}>{children}</DragHead>
136
+ {fields.length === 0 && <div key={`tableHead`} className="fborder-b fflex flex-nowrap fmin-w-full ">
139
137
  {React.Children.map(children, (child, childIndex) => {
140
- let { props } = child;
141
- const col_id = child?.props?.componentId || child?.props?.__id || childIndex;
142
- // if (field?.[col_id] === undefined) field[col_id] = "";
143
- const rules = []
144
- if (props.isRequired)
145
- rules.push({ required: true, message: `${props.label}必须填写` });
146
- if (props.rules)
147
- if (Array.isArray(props.rules)) {
148
- const pattern = props.rules.join("|")
149
- rules.push({ pattern: new RegExp(pattern), message: props.rulesFailMessage ? props.rulesFailMessage : `${props.label}格式错误` })
150
- }
151
- else {
152
- rules.push({ pattern: new RegExp(props.rules), message: props.rulesFailMessage ? props.rulesFailMessage : `${props.label}格式错误` })
153
- }
138
+ const hidden = (child?.props?.calcHidden || !getDependencyMapShow(child?.props?.componentId || child?.props?.__id)) && mode != "desgin";
139
+ return <TableCol width={getColumnWidth(childIndex)} key={`row_${0}_col_${childIndex}`} hidden={hidden}>
140
+ {hidden ? null : React.cloneElement(child, {
141
+ key: `row_${0}_child_${childIndex}`,
142
+ subTable: true,
143
+ subTableHead: true,
144
+ subTableContent: false,
145
+ })}
146
+ </TableCol>
147
+ })}
148
+ {disabled != true && readonly != true && <TableAction subTableHead={true} key={`row_${0}_action`} subTable={true} subTableIndex={0} label={"操作"}>
149
+ </TableAction>}
150
+ </div>}
151
+ {fields.map((field, index) => (
152
+ <div key={`${tableId}.${field.key}`} className=" fflex flex-nowrap fmin-w-full ">
153
+ <Form.Item hidden={true} name={[field.name, "__id"]}>
154
+ <RowID />
155
+ </Form.Item>
156
+ {React.Children.map(children, (child, childIndex) => {
157
+ let { props } = child;
158
+ const col_id = child?.props?.componentId || child?.props?.__id || childIndex;
159
+ // if (field?.[col_id] === undefined) field[col_id] = "";
160
+ const rules = []
161
+ if (props.isRequired)
162
+ rules.push({ required: true, message: `${props.label}必须填写` });
163
+ if (props.rules)
164
+ if (Array.isArray(props.rules)) {
165
+ const pattern = props.rules.join("|")
166
+ rules.push({ pattern: new RegExp(pattern), message: props.rulesFailMessage ? props.rulesFailMessage : `${props.label}格式错误` })
167
+ }
168
+ else {
169
+ rules.push({ pattern: new RegExp(props.rules), message: props.rulesFailMessage ? props.rulesFailMessage : `${props.label}格式错误` })
170
+ }
154
171
 
155
- const { componentId, __id, _componentName, ...otherProps } = child.props;
156
- const componentName = child.type?.displayName || _componentName;
157
- const identifier = componentId || __id;
172
+ const { componentId, __id, _componentName, ...otherProps } = child.props;
173
+ const componentName = child.type?.displayName || _componentName;
174
+ const identifier = componentId || __id;
158
175
 
159
- const hidden = (props.calcHidden || !getDependencyMapShow(identifier) ) && mode != "desgin" ;
160
- return <TableCol width={150} key={`row_${field.key}_col_${childIndex}`} hidden={hidden}>
161
- <Form.Item
162
- style={{ margin: 0 }}
163
- hidden={hidden}
164
- shouldUpdate={(prevValues, curValues) => {
165
- let result = false;
166
- if (
167
- (componentName === "Field.WithSingleSelect" || componentName === "Field.WithMultipleSelect") &&
168
- Array.isArray(otherProps.filterRules) &&
169
- otherProps.filterRules.length > 0
170
- ) {
171
- // 验证关联表字段是否需要重新渲染
172
- for (let rule of otherProps.filterRules) {
173
- let prevFieldValue, curFieldValue;
174
- if (rule.valueType != "variable") continue
175
- if ("parent" in rule?.value && rule.value.parent != "") {
176
- prevFieldValue = prevValues?.[rule?.value?.parent]?.[field.name]?.[rule?.value?.field_key];
177
- curFieldValue = curValues?.[rule?.value?.parent]?.[field.name]?.[rule?.value?.field_key];
178
- } else {
179
- prevFieldValue = prevValues?.[rule.value.field_key];
180
- curFieldValue = curValues?.[rule.value.field_key];
181
- }
176
+ const hidden = (props.calcHidden || !getDependencyMapShow(identifier)) && mode != "desgin";
177
+ return <TableCol width={getColumnWidth(childIndex)} key={`row_${field.key}_col_${childIndex}`} hidden={hidden}>
178
+ <Form.Item
179
+ style={{ margin: 0 }}
180
+ hidden={hidden}
181
+ shouldUpdate={(prevValues, curValues) => {
182
+ let result = false;
183
+ if (
184
+ (componentName === "Field.WithSingleSelect" || componentName === "Field.WithMultipleSelect") &&
185
+ Array.isArray(otherProps.filterRules) &&
186
+ otherProps.filterRules.length > 0
187
+ ) {
188
+ // 验证关联表字段是否需要重新渲染
189
+ for (let rule of otherProps.filterRules) {
190
+ let prevFieldValue, curFieldValue;
191
+ if (rule.valueType != "variable") continue
192
+ if ("parent" in rule?.value && rule.value.parent != "") {
193
+ prevFieldValue = prevValues?.[rule?.value?.parent]?.[field.name]?.[rule?.value?.field_key];
194
+ curFieldValue = curValues?.[rule?.value?.parent]?.[field.name]?.[rule?.value?.field_key];
195
+ } else {
196
+ prevFieldValue = prevValues?.[rule.value.field_key];
197
+ curFieldValue = curValues?.[rule.value.field_key];
198
+ }
182
199
 
183
- if (prevFieldValue !== curFieldValue) {
184
- result = true;
185
- break;
200
+ if (prevFieldValue !== curFieldValue) {
201
+ result = true;
202
+ break;
203
+ }
186
204
  }
187
205
  }
188
- }
189
- if (result) {
190
- newidRefs.current[childIndex] = nanoid();
191
- console.log("newidRefs.current[childIndex]", newidRefs.current[childIndex])
192
- }
193
- return result;
206
+ if (result) {
207
+ newidRefs.current[childIndex] = nanoid();
208
+ console.log("newidRefs.current[childIndex]", newidRefs.current[childIndex])
209
+ }
210
+ return result;
211
+ }}
212
+ >
213
+ {({ getFieldsValue }) => {
214
+ const fieldsValue = getFieldsValue();
215
+ // const newid = nanoid()
216
+ // console.log(`[${child.props.label}] key`,`row_${field.key}_child_${childIndex}_${newidRefs.current[childIndex]}` )
217
+ return <Form.Item
218
+ label=""
219
+ style={{ marginBottom: 0 }}
220
+ name={[field.name, col_id]}
221
+ rules={rules}
222
+ >
223
+ {React.cloneElement(child, {
224
+ // key: `row_${field.key}_child_${childIndex}_${newidRefs.current[childIndex]}`,
225
+ key: `row_${field.key}_child_${childIndex}`,
226
+ subTable: true,
227
+ subTableIndex: index,
228
+ subTableHead: index === 0,
229
+ form,
230
+ shouldUpdateKey: newidRefs.current[childIndex],
231
+ fieldName: [fieldName, field.name, col_id],
232
+ fieldsValue: fieldsValue,
233
+ initializeFormRender,
234
+ recordFieldsChange,
235
+ getAllWithIds: getAllWithIds,
236
+ removeLastFieldsValues
237
+ })}
238
+ </Form.Item>
239
+ }}
240
+ </Form.Item>
241
+
242
+ </TableCol>
243
+ })}
244
+ {disabled != true && readonly != true && <TableAction subTableHead={index == 0} key={`row_${index}_action`} subTable={true} subTableIndex={index} label={"操作"}>
245
+ {isAllowCopy && <CopyOutlined className="fcursor-pointer" onClick={() => handleCopy(index)} />}
246
+ <Popconfirm
247
+ title="删除确认"
248
+ description="确定要删除这一行吗?"
249
+ onConfirm={() => {
250
+ handleRemove(index)
194
251
  }}
252
+ okText="确定"
253
+ cancelText="取消"
195
254
  >
196
- {({ getFieldsValue }) => {
197
- const fieldsValue = getFieldsValue();
198
- // const newid = nanoid()
199
- // console.log(`[${child.props.label}] key`,`row_${field.key}_child_${childIndex}_${newidRefs.current[childIndex]}` )
200
- return <Form.Item
201
- label=""
202
- style={{ marginBottom: 0 }}
203
- name={[field.name, col_id]}
204
- rules={rules}
205
- >
206
- {React.cloneElement(child, {
207
- // key: `row_${field.key}_child_${childIndex}_${newidRefs.current[childIndex]}`,
208
- key: `row_${field.key}_child_${childIndex}`,
209
- subTable: true,
210
- subTableIndex: index,
211
- subTableHead: index === 0,
212
- form,
213
- shouldUpdateKey: newidRefs.current[childIndex],
214
- fieldName: [fieldName, field.name, col_id],
215
- fieldsValue: fieldsValue,
216
- initializeFormRender,
217
- recordFieldsChange,
218
- getAllWithIds: getAllWithIds,
219
- removeLastFieldsValues
220
- })}
221
- </Form.Item>
222
- }}
223
- </Form.Item>
224
-
225
- </TableCol>
226
- })}
227
- {disabled != true && readonly != true && <TableAction subTableHead={index == 0} key={`row_${index}_action`} subTable={true} subTableIndex={index} label={"操作"}>
228
- {isAllowCopy && <CopyOutlined className="fcursor-pointer" onClick={()=>handleCopy(index)} />}
229
- <Popconfirm
230
- title="删除确认"
231
- description="确定要删除这一行吗?"
232
- onConfirm={() => {
233
- handleRemove(index)
234
- }}
235
- okText="确定"
236
- cancelText="取消"
237
- >
238
- <DeleteOutlined className="fcursor-pointer ftext-red-500" />
239
- </Popconfirm>
240
- </TableAction>}
241
- </div>
242
- ))}
255
+ <DeleteOutlined className="fcursor-pointer ftext-red-500" />
256
+ </Popconfirm>
257
+ </TableAction>}
258
+ </div>
259
+ ))}
260
+ </div>
261
+ {disabled != true && readonly != true && isAllowAdd && <Button onClick={() => {
262
+ add({ key: nanoid(), })
263
+ typeof onTableAddRow === "function" && onTableAddRow(childrenIds);
264
+ }} className="fmy-2">新增一行</Button>}
243
265
  </div>
244
- {disabled != true && readonly != true && isAllowAdd && <Button onClick={() => {
245
- add({ key: nanoid(), })
246
- typeof onTableAddRow === "function" && onTableAddRow(childrenIds);
247
- }} className="fmy-2">新增一行</Button>}
248
- </div>
249
- }}
250
- </Form.List>
266
+ }}
267
+ </Form.List>
268
+ </div>
251
269
  }
252
270
 
253
271
  Table.displayName = "Table"
@@ -73,6 +73,8 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
73
73
  currentCycleId: 0,
74
74
  // 当前更新周期的依赖路径
75
75
  updatePath: [],
76
+ // 最大更新深度限制,避免过深的嵌套引起栈溢出
77
+ MAX_DEPTH: 30,
76
78
  // 开始新的更新周期
77
79
  startNewCycle: function () {
78
80
  this.currentCycleId++;
@@ -81,10 +83,18 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
81
83
  },
82
84
  // 添加依赖路径
83
85
  addToPath: function (fieldId) {
84
- this.updatePath.push(fieldId);
86
+ // 限制依赖路径深度,防止栈溢出
87
+ if (this.updatePath.length >= this.MAX_DEPTH) {
88
+ console.warn(`依赖路径深度超过限制(${this.MAX_DEPTH}),可能存在过深嵌套`);
89
+ return;
90
+ }
91
+ if (fieldId) {
92
+ this.updatePath.push(fieldId);
93
+ }
85
94
  },
86
95
  // 检查是否形成循环
87
96
  hasCircularDependency: function (targetFieldId) {
97
+ if (!targetFieldId) return false;
88
98
  return this.updatePath.includes(targetFieldId);
89
99
  },
90
100
  // 获取当前依赖路径
@@ -232,6 +242,10 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
232
242
 
233
243
  // 计算字段级联关系
234
244
  const handleFieldsWith = async (identifier, fieldValues, init = false, fieldId = null) => {
245
+ if (mode == "desgin") {
246
+ console.log("设计模式下不进行字段级联计算")
247
+ return false
248
+ }
235
249
  // console.log("handleFieldsWith identifier", identifier)
236
250
  let needRefresh = false;
237
251
  let parentIdentifier = [];
@@ -734,7 +748,6 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
734
748
  }
735
749
  lastFormValues.current[field.name] = field.value;
736
750
  }
737
- else console.log(`重复的field`, field.name)
738
751
  }
739
752
  if (needRefresh) {
740
753
  console.log("needRefresh", needRefresh)
@@ -73,4 +73,5 @@ export * from './editor'
73
73
  export * from "./wangEditor"
74
74
  export * from "./wangEditorNext"
75
75
  export * from "./sortList"
76
- export * from "./TinyMCEEditor"
76
+ export * from "./TinyMCEEditor"
77
+ export {eventEmitter as packageFormEventEmitter} from "../utils/events"