| | |
| | | <div v-if="item.type == 'richText'"> |
| | | <AiEditor |
| | | :ref="`editor_${item.id}`" |
| | | v-model="item.data.content" |
| | | :value="item.data.content" |
| | | height="200px" |
| | | placeholder="请输入内容..." |
| | | /> |
| | |
| | | </div> |
| | | <!-- 图片上传 --> |
| | | <div v-else-if="item.type == 'imageUpload'"> |
| | | <el-upload |
| | | action="#" |
| | | :file-list="item.data.imageList" |
| | | :on-change="(file, fileList) => handleImageChange(idx, fileList)" |
| | | :on-success=" |
| | | (res, file, fileList) => |
| | | handleImageSuccess(res, file, fileList, idx) |
| | | " |
| | | list-type="picture-card" |
| | | > |
| | | <i class="el-icon-plus"></i> |
| | | <div class="upload-text">上传图片</div> |
| | | </el-upload> |
| | | <div class="uploaf-notice">支持.jpg .png格式</div> |
| | | <div class="image-upload-container"> |
| | | <el-upload |
| | | action="#" |
| | | :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" |
| | | list-type="picture-card" |
| | | class="image-uploader" |
| | | > |
| | | <i class="el-icon-plus"></i> |
| | | <div class="upload-text">上传图片</div> |
| | | </el-upload> |
| | | <div class="uploaf-notice">支持.jpg .png格式</div> |
| | | </div> |
| | | </div> |
| | | <img |
| | | src="@/assets/public/delete.png" |
| | |
| | | |
| | | <addTableHeader |
| | | :visible.sync="tableHeaderDialog.visible" |
| | | :participants="participants" |
| | | @confirm="confirmAddHeader" |
| | | ></addTableHeader> |
| | | <addTableData |
| | |
| | | type: String, |
| | | default: "", |
| | | }, |
| | | participants: { |
| | | type: Array, |
| | | default: () => [] |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | |
| | | }, |
| | | methods: { |
| | | addComponent(type) { |
| | | // 如果是添加自定义表格,需要检查是否已选择实验调度 |
| | | if (type === "customTable") { |
| | | if (!this.participants || this.participants.length === 0) { |
| | | this.$message.warning('请先选择实验调度'); |
| | | this.showAddDialog = false; |
| | | return; |
| | | } |
| | | } |
| | | |
| | | this.showAddDialog = false; |
| | | const id = Date.now() + Math.random(); |
| | | let data = {}; |
| | |
| | | console.log(type, "111111111111111", this.components); |
| | | |
| | | this.components.push({ id, type, data }); |
| | | }, |
| | | submit() { |
| | | // 获取所有组件的数据 |
| | | const data = this.components.map(component => { |
| | | let componentData = null; |
| | | |
| | | switch (component.type) { |
| | | case 'richText': |
| | | const editorRef = this.$refs[`editor_${component.id}`]; |
| | | const editor = Array.isArray(editorRef) ? editorRef[0] : editorRef; |
| | | console.log('editor ref:', editor); |
| | | const content = editor ? editor.getContent() : ''; |
| | | componentData = content && content !== '<p></p>' ? content : ''; |
| | | break; |
| | | case 'customTable': |
| | | // 获取表格数据 |
| | | componentData = { |
| | | headers: component.data.headers, |
| | | rows: component.data.rows |
| | | }; |
| | | break; |
| | | case 'fileUpload': |
| | | // 获取文件列表 |
| | | componentData = component.data.fileList; |
| | | break; |
| | | case 'imageUpload': |
| | | // 获取图片列表 |
| | | componentData = component.data.imageList; |
| | | break; |
| | | } |
| | | |
| | | return { |
| | | type: component.type, |
| | | data: componentData |
| | | }; |
| | | }); |
| | | |
| | | // 触发 submit 事件,将数据传递给父组件 |
| | | this.$emit('submit', data); |
| | | }, |
| | | confirmAddRow(formData) { |
| | | const { idx, rowIndex, isEdit } = this.rowDialog; |
| | | if (isEdit) { |
| | | // 编辑模式 |
| | | this.components[idx].data.rows[rowIndex] = { |
| | | ...formData, |
| | | updateTime: new Date().toLocaleString() |
| | | }; |
| | | } else { |
| | | // 新增模式 |
| | | this.components[idx].data.rows.push({ |
| | | ...formData, |
| | | updateTime: new Date().toLocaleString() |
| | | }); |
| | | } |
| | | this.rowDialog.visible = false; |
| | | this.rowDialog.form = {}; |
| | | }, |
| | | removeComponent(idx) { |
| | | this.components.splice(idx, 1); |
| | |
| | | .catch(() => {}); |
| | | }, |
| | | handleFileChange(idx, fileList) { |
| | | // 为每个文件添加默认的URL和名称 |
| | | fileList = fileList.map(file => { |
| | | if (!file.url) { |
| | | file.url = 'https://picsum.photos/200/200'; |
| | | } |
| | | if (!file.name) { |
| | | file.name = '默认文件.txt'; |
| | | } |
| | | return file; |
| | | }); |
| | | this.components[idx].data.fileList = fileList; |
| | | }, |
| | | handleImageChange(idx, fileList) { |
| | | // 为每个文件添加默认的URL |
| | | fileList = fileList.map(file => { |
| | | if (!file.url) { |
| | | file.url = 'https://picsum.photos/200/200'; |
| | | } |
| | | return file; |
| | | }); |
| | | this.components[idx].data.imageList = fileList; |
| | | }, |
| | | handleImageSuccess(res, file, fileList, idx) { |
| | | // 假设后端返回的图片地址在 res.url |
| | | file.url = res.url; |
| | | // 使用默认图片URL |
| | | file.url = 'https://picsum.photos/200/200'; |
| | | this.components[idx].data.imageList = fileList; |
| | | }, |
| | | beforeImageUpload(file) { |
| | | const isJPG = file.type === 'image/jpeg'; |
| | | const isPNG = file.type === 'image/png'; |
| | | 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; |
| | | } |
| | | return true; |
| | | }, |
| | | }, |
| | | }; |
| | |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | .image-uploader{ |
| | | display: flex; |
| | | ::v-deep .el-upload-list__item{ |
| | | width: 104px !important; |
| | | height: 104px !important; |
| | | } |
| | | } |
| | | .image-upload-container { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | align-items: flex-start; |
| | | gap: 10px; |
| | | } |
| | | |
| | | ::v-deep .image-uploader { |
| | | .el-upload--picture-card { |
| | | margin: 0; |
| | | } |
| | | .el-upload-list--picture-card .el-upload-list__item { |
| | | margin: 0 10px 10px 0; |
| | | } |
| | | } |
| | | |
| | | ::v-deep .el-upload { |
| | | width: 104px; |
| | | height: 104px; |