diff --git a/src/views/settings/creation/index.vue b/src/views/settings/creation/index.vue index 3e30a83..67d19d9 100644 --- a/src/views/settings/creation/index.vue +++ b/src/views/settings/creation/index.vue @@ -106,22 +106,13 @@ :show-file-list="false" class="field-upload" > - - 选择文件 - + 选择文件
{{ uploadedFile.name }} - - 删除 - + 删除
@@ -142,12 +133,7 @@
{{ uploadedFile.name }} - + 删除
@@ -155,38 +141,12 @@
-
- - - +
+ + +
- + 添加键值对
@@ -275,7 +235,11 @@ :show-file-list="false" class="custom-field-upload" > - + 选择文件 @@ -283,24 +247,14 @@
{{ uploadedFile.name }} - + 删除
- + + 添加自定义字段 @@ -1656,7 +1610,7 @@ const handleTreeNodeClick = async (data: TreeNode) => { // 后端错误会自动显示 } } - + // 处理结果节点(title) if (data.nodeType === 'title' && data.workflowId && data.fileUrl) { // 管理员权限检查:管理员只能编辑,不能进入创作模式 @@ -1785,7 +1739,7 @@ const isJudgeNode = (node: Item) => { const isSelectField = (fieldItem: NodeLibraryFormItem) => { // 如果字段类型是 select,直接返回 true if (fieldItem.type === 'select') return true; - + // 兼容旧的硬编码字段 return fieldItem.field === 'size' || fieldItem.field === 'resolution'; }; @@ -1795,7 +1749,7 @@ const getSelectOptions = (fieldItem: NodeLibraryFormItem) => { if (fieldItem.options && Array.isArray(fieldItem.options)) { return fieldItem.options; } - + // 兼容旧的硬编码选项 if (fieldItem.field === 'size') { return [ @@ -1835,15 +1789,13 @@ const handleCustomFieldUpload = async (index: number, file: any, type: string) = try { // 上传文件到OSS const uploadRes = await uploadFile(file.raw); - + // 检查上传是否成功 if (!uploadRes || !uploadRes.data || !uploadRes.data.fileURL) { throw new Error('上传失败:未返回文件URL'); } - - const fileUrl = uploadRes.data.fileAddressPrefix - ? `${uploadRes.data.fileAddressPrefix}${uploadRes.data.fileURL}` - : uploadRes.data.fileURL; + + const fileUrl = uploadRes.data.fileAddressPrefix ? `${uploadRes.data.fileAddressPrefix}${uploadRes.data.fileURL}` : uploadRes.data.fileURL; // 初始化 fileList if (!field.fileList) { @@ -1858,7 +1810,7 @@ const handleCustomFieldUpload = async (index: number, file: any, type: string) = } else if (type === 'uploadMultiple') { // 多个上传:添加到数组 field.fileList.push({ name: file.name, url: fileUrl }); - + // 解析现有的 value let urls: string[] = []; if (field.value) { @@ -1871,7 +1823,7 @@ const handleCustomFieldUpload = async (index: number, file: any, type: string) = urls = field.value ? [field.value] : []; } } - + // 添加新的 URL urls.push(fileUrl); field.value = JSON.stringify(urls); @@ -1917,39 +1869,40 @@ const removeCustomFieldFile = (index: number, fileIdx: number, type: string) => // 递增 uploadKey 来重置上传组件 field.uploadKey = (field.uploadKey || 0) + 1; }; -// 获取键值对数组 +// 获取键值对数组(使用响应式存储) const getKeyValuePairs = (field: string) => { - const value = dynamicFormValues[field]; - if (!value) { - return [{ key: '', value: '' }]; - } - - // 如果是字符串,尝试解析为JSON对象 - if (typeof value === 'string') { - try { - const parsed = JSON.parse(value); - if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) { - return Object.entries(parsed).map(([k, v]) => ({ key: k, value: String(v) })); + // 如果还没有初始化,从 dynamicFormValues 中加载 + if (!fieldKeyValuePairs[field]) { + const value = dynamicFormValues[field]; + + if (!value) { + fieldKeyValuePairs[field] = [{ key: '', value: '' }]; + } else if (typeof value === 'string') { + try { + const parsed = JSON.parse(value); + if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) { + fieldKeyValuePairs[field] = Object.entries(parsed).map(([k, v]) => ({ key: k, value: String(v) })); + } else { + fieldKeyValuePairs[field] = [{ key: '', value: '' }]; + } + } catch (e) { + fieldKeyValuePairs[field] = [{ key: '', value: '' }]; } - } catch (e) { - // 解析失败,返回空数组 + } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) { + const pairs = Object.entries(value).map(([k, v]) => ({ key: k, value: String(v) })); + fieldKeyValuePairs[field] = pairs.length > 0 ? pairs : [{ key: '', value: '' }]; + } else { + fieldKeyValuePairs[field] = [{ key: '', value: '' }]; } - return [{ key: '', value: '' }]; } - - // 如果是对象,转换为键值对数组 - if (typeof value === 'object' && value !== null && !Array.isArray(value)) { - const pairs = Object.entries(value).map(([k, v]) => ({ key: k, value: String(v) })); - return pairs.length > 0 ? pairs : [{ key: '', value: '' }]; - } - - return [{ key: '', value: '' }]; + + return fieldKeyValuePairs[field]; }; // 添加键值对 const addKeyValuePair = (field: string) => { const pairs = getKeyValuePairs(field); pairs.push({ key: '', value: '' }); - updateKeyValueFieldFromPairs(field, pairs); + updateKeyValueFieldFromPairs(field); }; // 删除键值对 const removeKeyValuePair = (field: string, index: number) => { @@ -1959,26 +1912,28 @@ const removeKeyValuePair = (field: string, index: number) => { if (pairs.length === 0) { pairs.push({ key: '', value: '' }); } - updateKeyValueFieldFromPairs(field, pairs); + updateKeyValueFieldFromPairs(field); }; // 更新键值对字段 const updateKeyValueField = (field: string) => { - const pairs = getKeyValuePairs(field); - updateKeyValueFieldFromPairs(field, pairs); + updateKeyValueFieldFromPairs(field); }; // 从键值对数组更新字段值 -const updateKeyValueFieldFromPairs = (field: string, pairs: Array<{ key: string; value: string }>) => { +const updateKeyValueFieldFromPairs = (field: string) => { + const pairs = fieldKeyValuePairs[field]; + if (!pairs) return; + // 过滤掉空的键值对 - const validPairs = pairs.filter(p => p.key.trim() !== ''); - + const validPairs = pairs.filter((p) => p.key.trim() !== ''); + // 转换为对象 const obj: Record = {}; - validPairs.forEach(p => { + validPairs.forEach((p) => { if (p.key.trim()) { obj[p.key.trim()] = p.value; } }); - + // 保存为JSON字符串 dynamicFormValues[field] = Object.keys(obj).length > 0 ? JSON.stringify(obj) : ''; }; @@ -1986,6 +1941,8 @@ const updateKeyValueFieldFromPairs = (field: string, pairs: Array<{ key: string; const fieldFileLists = reactive>({}); // 存储字段的上传key(用于重置上传组件) const fieldUploadKeys = reactive>({}); +// 存储字段的键值对(用于响应式更新) +const fieldKeyValuePairs = reactive>>({}); // 获取字段的文件列表 const getFieldFileList = (field: string) => { return fieldFileLists[field] || []; @@ -1999,15 +1956,13 @@ const handleFieldUpload = async (field: string, file: any, type: string) => { try { // 上传文件到OSS const uploadRes = await uploadFile(file.raw); - + // 检查上传是否成功 if (!uploadRes || !uploadRes.data || !uploadRes.data.fileURL) { throw new Error('上传失败:未返回文件URL'); } - - const fileUrl = uploadRes.data.fileAddressPrefix - ? `${uploadRes.data.fileAddressPrefix}${uploadRes.data.fileURL}` - : uploadRes.data.fileURL; + + const fileUrl = uploadRes.data.fileAddressPrefix ? `${uploadRes.data.fileAddressPrefix}${uploadRes.data.fileURL}` : uploadRes.data.fileURL; // 初始化文件列表 if (!fieldFileLists[field]) { @@ -2022,7 +1977,7 @@ const handleFieldUpload = async (field: string, file: any, type: string) => { } else if (type === 'uploadMultiple') { // 多个上传:添加到数组 fieldFileLists[field].push({ name: file.name, url: fileUrl }); - + // 解析现有的 value let urls: string[] = []; if (dynamicFormValues[field]) { @@ -2035,7 +1990,7 @@ const handleFieldUpload = async (field: string, file: any, type: string) => { urls = dynamicFormValues[field] ? [dynamicFormValues[field]] : []; } } - + // 添加新的 URL urls.push(fileUrl); dynamicFormValues[field] = JSON.stringify(urls); @@ -3007,7 +2962,7 @@ onBeforeUnmount(() => { .creation-page { height: calc(100vh - 100px); display: grid; - grid-template-columns: 320px minmax(0, 1fr) 340px; + grid-template-columns: 360px minmax(0, 1fr) 360px; gap: 14px; padding: 14px; background: #f6f8fb;