diff --git a/src/views/settings/creation/index.vue b/src/views/settings/creation/index.vue
index 09dd3ce..3e30a83 100644
--- a/src/views/settings/creation/index.vue
+++ b/src/views/settings/creation/index.vue
@@ -95,6 +95,64 @@
/>
+
+
+
+
+ 选择文件
+
+
+
+
+
+ {{ uploadedFile.name }}
+
+ 删除
+
+
+
+
+
+
+
+ 选择文件
+
+
+
+
+ {{ uploadedFile.name }}
+
+ 删除
+
+
+
+
-
+
+
+
+
+ 选择文件
+
+
+
+
+
+ {{ uploadedFile.name }}
+
+ 删除
+
+
+
+
+
+
+ 添加自定义字段
@@ -1718,12 +1815,108 @@ const getSelectOptions = (fieldItem: NodeLibraryFormItem) => {
};
// 添加自定义字段
const addCustomField = () => {
- customFields.value.push({ label: '', value: '', type: 'input', required: false });
+ customFields.value.push({ label: '', value: '', type: 'input', required: false, fileList: [], uploadKey: 0 });
};
// 删除自定义字段
const removeCustomField = (index: number) => {
customFields.value.splice(index, 1);
};
+// 获取自定义字段的文件列表
+const getCustomFieldFileList = (index: number) => {
+ const field = customFields.value[index];
+ if (!field || !field.fileList) return [];
+ return field.fileList;
+};
+// 处理自定义字段文件上传
+const handleCustomFieldUpload = async (index: number, file: any, type: string) => {
+ const field = customFields.value[index];
+ if (!field) return;
+
+ 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;
+
+ // 初始化 fileList
+ if (!field.fileList) {
+ field.fileList = [];
+ }
+
+ // 根据类型处理
+ if (type === 'upload') {
+ // 单个上传:替换现有文件
+ field.fileList = [{ name: file.name, url: fileUrl }];
+ field.value = fileUrl;
+ } else if (type === 'uploadMultiple') {
+ // 多个上传:添加到数组
+ field.fileList.push({ name: file.name, url: fileUrl });
+
+ // 解析现有的 value
+ let urls: string[] = [];
+ if (field.value) {
+ try {
+ urls = JSON.parse(field.value);
+ if (!Array.isArray(urls)) {
+ urls = [field.value];
+ }
+ } catch (e) {
+ urls = field.value ? [field.value] : [];
+ }
+ }
+
+ // 添加新的 URL
+ urls.push(fileUrl);
+ field.value = JSON.stringify(urls);
+ }
+
+ ElMessage.success('文件上传成功');
+ } catch (error: any) {
+ ElMessage.error(error?.message || '文件上传失败');
+ console.error('Upload error:', error);
+ // 上传失败时,递增 uploadKey 来重置上传组件
+ field.uploadKey = (field.uploadKey || 0) + 1;
+ }
+};
+// 删除自定义字段的文件
+const removeCustomFieldFile = (index: number, fileIdx: number, type: string) => {
+ const field = customFields.value[index];
+ if (!field || !field.fileList) return;
+
+ // 删除文件
+ field.fileList.splice(fileIdx, 1);
+
+ // 更新 value
+ if (type === 'upload') {
+ // 单个上传:清空 value
+ field.value = '';
+ } else if (type === 'uploadMultiple') {
+ // 多个上传:从数组中删除对应的 URL
+ try {
+ let urls: string[] = [];
+ if (field.value) {
+ urls = JSON.parse(field.value);
+ if (!Array.isArray(urls)) {
+ urls = [];
+ }
+ }
+ urls.splice(fileIdx, 1);
+ field.value = urls.length > 0 ? JSON.stringify(urls) : '';
+ } catch (e) {
+ field.value = '';
+ }
+ }
+
+ // 递增 uploadKey 来重置上传组件
+ field.uploadKey = (field.uploadKey || 0) + 1;
+};
// 获取键值对数组
const getKeyValuePairs = (field: string) => {
const value = dynamicFormValues[field];
@@ -1789,6 +1982,104 @@ const updateKeyValueFieldFromPairs = (field: string, pairs: Array<{ key: string;
// 保存为JSON字符串
dynamicFormValues[field] = Object.keys(obj).length > 0 ? JSON.stringify(obj) : '';
};
+// 存储字段的文件列表
+const fieldFileLists = reactive>({});
+// 存储字段的上传key(用于重置上传组件)
+const fieldUploadKeys = reactive>({});
+// 获取字段的文件列表
+const getFieldFileList = (field: string) => {
+ return fieldFileLists[field] || [];
+};
+// 获取字段的上传key
+const getFieldUploadKey = (field: string) => {
+ return fieldUploadKeys[field] || 0;
+};
+// 处理字段文件上传
+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;
+
+ // 初始化文件列表
+ if (!fieldFileLists[field]) {
+ fieldFileLists[field] = [];
+ }
+
+ // 根据类型处理
+ if (type === 'upload') {
+ // 单个上传:替换现有文件
+ fieldFileLists[field] = [{ name: file.name, url: fileUrl }];
+ dynamicFormValues[field] = fileUrl;
+ } else if (type === 'uploadMultiple') {
+ // 多个上传:添加到数组
+ fieldFileLists[field].push({ name: file.name, url: fileUrl });
+
+ // 解析现有的 value
+ let urls: string[] = [];
+ if (dynamicFormValues[field]) {
+ try {
+ urls = JSON.parse(dynamicFormValues[field]);
+ if (!Array.isArray(urls)) {
+ urls = [dynamicFormValues[field]];
+ }
+ } catch (e) {
+ urls = dynamicFormValues[field] ? [dynamicFormValues[field]] : [];
+ }
+ }
+
+ // 添加新的 URL
+ urls.push(fileUrl);
+ dynamicFormValues[field] = JSON.stringify(urls);
+ }
+
+ ElMessage.success('文件上传成功');
+ } catch (error: any) {
+ ElMessage.error(error?.message || '文件上传失败');
+ console.error('Upload error:', error);
+ // 上传失败时,递增 uploadKey 来重置上传组件
+ fieldUploadKeys[field] = (fieldUploadKeys[field] || 0) + 1;
+ }
+};
+// 删除字段的文件
+const removeFieldFile = (field: string, fileIdx: number, type: string) => {
+ if (!fieldFileLists[field]) return;
+
+ // 删除文件
+ fieldFileLists[field].splice(fileIdx, 1);
+
+ // 更新 value
+ if (type === 'upload') {
+ // 单个上传:清空 value
+ dynamicFormValues[field] = '';
+ } else if (type === 'uploadMultiple') {
+ // 多个上传:从数组中删除对应的 URL
+ try {
+ let urls: string[] = [];
+ if (dynamicFormValues[field]) {
+ urls = JSON.parse(dynamicFormValues[field]);
+ if (!Array.isArray(urls)) {
+ urls = [];
+ }
+ }
+ urls.splice(fileIdx, 1);
+ dynamicFormValues[field] = urls.length > 0 ? JSON.stringify(urls) : '';
+ } catch (e) {
+ dynamicFormValues[field] = '';
+ }
+ }
+
+ // 递增 uploadKey 来重置上传组件
+ fieldUploadKeys[field] = (fieldUploadKeys[field] || 0) + 1;
+};
// 判断是否可以添加自定义字段(排除判断节点、开始节点、HTTP节点等)
const canAddCustomFields = (element: SelectedState | null) => {
if (!element || element.kind !== 'node') return false;
@@ -3149,6 +3440,44 @@ onBeforeUnmount(() => {
align-self: flex-start;
margin-top: 4px;
}
+.custom-field-upload-wrapper,
+.field-upload-wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+.uploaded-files-list {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ padding: 8px;
+ background: #f9fafb;
+ border: 1px solid #e5e7eb;
+ border-radius: 6px;
+}
+.uploaded-file-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 6px 10px;
+ background: #fff;
+ border: 1px solid #e5e7eb;
+ border-radius: 4px;
+ transition: all 0.2s ease;
+}
+.uploaded-file-item:hover {
+ border-color: #cbd5e1;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
+}
+.uploaded-file-item .file-name {
+ flex: 1;
+ font-size: 13px;
+ color: #374151;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ margin-right: 12px;
+}
.input-source-list {
display: flex;
flex-direction: column;