From 0c9660562a03191d44fc779a889d3da0dc624b6d Mon Sep 17 00:00:00 2001
From: 董国庆 <364620639@qq.com>
Date: 星期五, 25 七月 2025 10:47:19 +0800
Subject: [PATCH] 修改弹窗ui和客户反馈
---
laboratory/src/components/DynamicComponent/index.vue | 180 +++++++++++++++++++++++++++++++++++------------------------
1 files changed, 107 insertions(+), 73 deletions(-)
diff --git a/laboratory/src/components/DynamicComponent/index.vue b/laboratory/src/components/DynamicComponent/index.vue
index 7a1ff5e..218e9c9 100644
--- a/laboratory/src/components/DynamicComponent/index.vue
+++ b/laboratory/src/components/DynamicComponent/index.vue
@@ -16,16 +16,17 @@
<div v-for="(item, idx) in components" :key="item.id" class="dynamic-component">
<!-- 富文本 -->
<div v-if="item.type == 'richText'">
- <AiEditor :ref="`editor_${item.id}`" :value="item.data.content" height="200px" :readOnly="!editable" placeholder="请输入内容..."
- :disabled="!editable" />
+ <AiEditor :ref="`editor_${item.id}`" :value="item.data.content" height="400px" :readOnly="!editable"
+ placeholder="请输入内容..." :disabled="!editable" />
</div>
<!-- 自定义表格 -->
<div v-else-if="item.type == 'customTable'" style="flex: 1">
<div v-if="editable" class="table-actions">
- <el-button size="mini" @click="showTableHeaderDialog(idx)">添加表头</el-button>
+ <el-button size="mini" @click="showTableHeaderDialog(idx)">添加表头</el-button>
<el-button size="mini" type="primary" @click="showAddRowDialog(idx, item.data.headers)">添加数据</el-button>
</div>
- <Table :data="item.data.rows" :total="null" :height="null" class="groupTable" :key="item.id + '_' + JSON.stringify(item.data.rows).length">
+ <Table :data="item.data.rows" :total="null" :height="null" class="groupTable"
+ :key="item.id + '_' + JSON.stringify(item.data.rows).length">
<el-table-column v-for="(header, hidx) in item.data.headers" :key="hidx" :label="header.name"
:prop="header.name">
<template slot-scope="scope">
@@ -33,12 +34,25 @@
<template v-if="header.type === 'user'">
{{ getUserDisplayText(header.name, scope.row) }}
</template>
- <!-- 图片类型显示 -->
+ <!-- 图片类型显示,兼容数组和字符串 -->
<template v-else-if="header.type === 'image'">
- <img v-if="scope.row[header.name]"
- :src="scope.row[header.name]"
- alt="头像"
- class="table-image" />
+ <template v-if="Array.isArray(scope.row[header.name])">
+ <el-image
+ v-for="(img, i) in scope.row[header.name]"
+ :key="i"
+ :src="getFullUrl(img)"
+ :preview-src-list="scope.row[header.name].map(getFullUrl)"
+ class="table-image"
+ />
+ </template>
+ <template v-else>
+ <el-image
+ v-if="scope.row[header.name]"
+ :src="getFullUrl(scope.row[header.name])"
+ :preview-src-list="[getFullUrl(scope.row[header.name])]"
+ class="table-image"
+ />
+ </template>
</template>
<!-- 其他类型 -->
<template v-else>
@@ -47,9 +61,9 @@
</template>
</el-table-column>
<el-table-column label="更新时间" prop="updateTime" min-width="180"></el-table-column>
- <el-table-column label="操作" min-width="200" v-if="dialogCanEdit">
+ <el-table-column label="操作" min-width="200" v-if="dialogCanEdit">
<template slot-scope="scope">
- <el-button type="text" @click="handleEditRow(idx, scope.$index)" >编辑</el-button>
+ <el-button type="text" @click="handleEditRow(idx, scope.$index)">编辑</el-button>
<el-button type="text" v-if="editable" @click="handleDeleteRow(idx, scope.$index)">删除</el-button>
</template>
</el-table-column>
@@ -57,37 +71,36 @@
</div>
<!-- 文件上传 -->
<div v-else-if="item.type == 'fileUpload'">
- <el-upload v-if="editable" action="#" :file-list="item.data.fileList"
- :on-change="(file, fileList) => handleFileChange(idx, fileList)" list-type="text">
+ <el-upload v-if="editable" :action="uploadUrl" :headers="uploadHeaders" :file-list="item.data.fileList"
+ :on-change="(file, fileList) => handleFileChange(idx, fileList)"
+ :on-success="(res, file, fileList) => handleFileSuccess(res, file, fileList, idx)"
+ list-type="text">
<el-button size="small" icon="el-icon-upload2">点击上传</el-button>
</el-upload>
<div v-else>
- <div v-for="file in item.data.fileList" :key="file.uid" class="file-list-item">
- {{ file.name }}
+ <div v-for="file in item.data.fileList" :key="file.uid" class="file-list-item" >
+ <span style="color: #409EFF; cursor: pointer;" @click="downloadFileByUrl(file.url, file.name)">{{ file.name }}</span>
</div>
</div>
</div>
<!-- 图片上传 -->
<div v-else-if="item.type == 'imageUpload'">
<div class="image-upload-container">
- <el-upload v-if="editable" action="#" :file-list="item.data.imageList"
+ <el-upload v-if="editable"
+ :action="uploadUrl"
+ :headers="uploadHeaders"
+ :file-list="item.data.imageList"
:on-change="(file, fileList) => handleImageChange(idx, fileList)"
- :on-success="(res, file, fileList) => handleImageSuccess(res, file, fileList, idx)"
- :auto-upload="true"
- :http-request="() => { }"
- :before-upload="beforeImageUpload"
+ :on-success="(res, file, fileList) => handleImageSuccess(res, file, fileList, idx)" :auto-upload="true"
+ :before-upload="beforeImageUpload"
list-type="picture-card"
- :on-preview="(file) => handlePreview(file, idx)"
- class="image-uploader">
+ :on-preview="(file) => handlePreview(file, idx)" class="image-uploader">
<i class="el-icon-plus"></i>
<div class="upload-text">上传图片</div>
</el-upload>
<div v-else class="image-preview">
- <el-image v-for="image in item.data.imageList"
- :key="image.uid"
- :src="image.url"
- :preview-src-list="item.data.imageList.map(img => img.url)"
- class="preview-image" />
+ <el-image v-for="image in item.data.imageList" :key="image.uid" :src="getFullUrl(image.url)"
+ :preview-src-list="item.data.imageList.map(img => getFullUrl(img.url))" class="preview-image" />
</div>
<div class="uploaf-notice">支持.jpg .png格式</div>
</div>
@@ -98,10 +111,10 @@
</div>
- <addTableHeader :visible.sync="tableHeaderDialog.visible" :participants="participants"
- @confirm="confirmAddHeader"></addTableHeader>
- <addTableData :visible.sync="rowDialog.visible" :headerList="rowDialog.headers"
- :editData="rowDialog.form" :isEdit="rowDialog.isEdit" @success="confirmAddRow">
+ <addTableHeader :visible.sync="tableHeaderDialog.visible" :participants="participants" @confirm="confirmAddHeader">
+ </addTableHeader>
+ <addTableData :visible.sync="rowDialog.visible" :headerList="rowDialog.headers" :editData="rowDialog.form"
+ :isEdit="rowDialog.isEdit" @success="confirmAddRow">
</addTableData>
<el-dialog :visible.sync="imagePreviewVisible" width="auto" top="10vh" :show-close="true" v-if="imagePreviewUrl">
@@ -116,6 +129,9 @@
import Table from "../Table/index.vue";
import addTableHeader from "./addTableHeader.vue";
import addTableData from "./addTableData.vue";
+import apiConfig from '../../utils/baseurl'
+import { getFullUrl } from '@/utils/utils'
+import { downloadFileByUrl } from '@/utils/utils'
export default {
name: "DynamicComponent",
@@ -150,6 +166,11 @@
},
data() {
return {
+ apiConfig: apiConfig,
+ uploadUrl: apiConfig.imgUrl,
+ uploadHeaders: {
+ Authorization: sessionStorage.getItem('token') || ''
+ },
showAddDialog: false,
components: [],
tableHeaderDialog: {
@@ -190,9 +211,15 @@
break;
case 'fileUpload':
componentData = { fileList: component.data };
+ console.log('component.data component.data',component.data)
break;
case 'imageUpload':
- componentData = { imageList: component.data };
+ componentData = { imageList: component.data.map(item=>{
+ return {
+ ...item,
+ url: getFullUrl(item.url),
+ }
+ }) };
break;
}
return {
@@ -209,20 +236,22 @@
}
},
methods: {
+ getFullUrl,
+ downloadFileByUrl,
getUserDisplayText(fieldName, rowData) {
// 检查是否有对应的userInfo数据
const userInfoKey = `${fieldName}_userInfo`;
-
+
// 如果没有rowData或fieldName,直接返回空字符串
if (!rowData || !fieldName) {
return '';
}
-
+
// 情况1: 有_userInfo数据
if (rowData[userInfoKey] && Array.isArray(rowData[userInfoKey])) {
return rowData[userInfoKey].map(user => user.label || '').join(', ');
}
-
+
// 情况2: 只有用户ID数组
if (Array.isArray(rowData[fieldName])) {
// 使用participants查找用户信息
@@ -231,12 +260,12 @@
return user ? (user.nickName || user.userName || userId) : userId;
}).join(', ');
}
-
+
// 情况3: 已经是字符串(可能是之前格式化过的)
if (typeof rowData[fieldName] === 'string') {
return rowData[fieldName];
}
-
+
// 默认返回空字符串
return '';
},
@@ -244,7 +273,7 @@
if (!userArray || !Array.isArray(userArray) || userArray.length === 0) {
return '';
}
-
+
// 查找参与者列表中的用户,获取昵称并用逗号拼接
const userNames = userArray.map(userId => {
const user = this.participants.find(p => p.userId === userId);
@@ -277,6 +306,7 @@
submit() {
const data = this.components.map(component => {
let componentData = null;
+ const prefix = apiConfig.showImgUrl;
switch (component.type) {
case 'richText':
@@ -292,10 +322,21 @@
};
break;
case 'fileUpload':
- componentData = component.data.fileList;
+ componentData = component.data.fileList.map(file => {
+ console.log('fileUpload fileUpload fileUpload',file)
+ if (file.url && file.url.startsWith(prefix)) {
+ return { ...file, url: file.url.substring(prefix.length) };
+ }
+ return file;
+ });
break;
case 'imageUpload':
- componentData = component.data.imageList;
+ componentData = component.data.imageList.map(image => {
+ if (image.url && image.url.startsWith(prefix)) {
+ return { ...image, url: image.url.substring(prefix.length) };
+ }
+ return image;
+ });
break;
}
@@ -311,18 +352,16 @@
// if (!this.editable) return;
const { idx, rowIndex, isEdit } = this.rowDialog;
-
+
// 处理formData中的数据,保证用户信息的完整性
const processedData = { ...formData };
-
+
// 调试输出
- console.log('添加/编辑行数据:', processedData,'isEdit',isEdit);
-
if (isEdit) {
// Vue无法检测到对象或数组深层属性的变化,使用Vue.set来确保响应式
this.$set(
- this.components[idx].data.rows,
- rowIndex,
+ this.components[idx].data.rows,
+ rowIndex,
{
...processedData,
updateTime: new Date().toLocaleString()
@@ -335,15 +374,14 @@
updateTime: new Date().toLocaleString()
});
}
- console.log('this.components',this.components);
-
+
// 手动触发组件更新
this.$forceUpdate();
// 延迟发送事件,确保数据已更新
this.$nextTick(() => {
this.emitUpdate();
});
-
+
this.rowDialog.visible = false;
this.rowDialog.form = {};
},
@@ -439,55 +477,49 @@
},
handleFileChange(idx, fileList) {
if (!this.editable) return;
-
- fileList = fileList.map(file => {
- if (!file.url) {
- file.url = 'https://picsum.photos/200/200';
- }
- if (!file.name) {
- file.name = '默认文件.txt';
- }
- return file;
- });
+ // 只做 fileList 同步
+ this.components[idx].data.fileList = fileList;
+ this.emitUpdate();
+ },
+ handleFileSuccess(res, file, fileList, idx) {
+ // 上传成功后设置真实 url
+ file.url = this.getFullUrl(res.msg);
this.components[idx].data.fileList = fileList;
this.emitUpdate();
},
handleImageChange(idx, fileList) {
if (!this.editable) return;
-
- fileList = fileList.map(file => {
- if (!file.url) {
- file.url = 'https://picsum.photos/200/200';
- }
- return file;
- });
+ // 只做 imageList 同步
this.components[idx].data.imageList = fileList;
this.emitUpdate();
},
handleImageSuccess(res, file, fileList, idx) {
- file.url = 'https://picsum.photos/200/200';
+ // 上传成功后设置真实 url
+ file.url = this.getFullUrl(res.msg);
this.components[idx].data.imageList = fileList;
+ this.emitUpdate();
},
beforeImageUpload(file) {
const isJPG = file.type === 'image/jpeg';
const isPNG = file.type === 'image/png';
- const isLt2M = file.size / 1024 / 1024 < 2;
+ // const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG && !isPNG) {
this.$message.error('上传图片只能是 JPG 或 PNG 格式!');
return false;
}
- if (!isLt2M) {
- this.$message.error('上传图片大小不能超过 2MB!');
- return false;
- }
+ // if (!isLt2M) {
+ // this.$message.error('上传图片大小不能超过 2MB!');
+ // return false;
+ // }
+ this.imagePreviewVisible = true;
return true;
},
handlePreview(file, idx) {
// 使用el-image的preview-src-list实现预览
// 这里直接用Element的图片预览能力,实际上el-upload会自动处理
// 但如果你想自定义弹窗,可以用如下代码:
- this.imagePreviewUrl = file.url;
+ this.imagePreviewUrl = this.getFullUrl(file.url);
this.imagePreviewVisible = true;
},
emitUpdate() {
@@ -496,6 +528,8 @@
this.$emit('update:dataSource', updatedComponents);
},
},
+ computed: {
+ },
};
</script>
--
Gitblit v1.7.1