董国庆
8 天以前 add04dce2ad833ecbb7495a641f42fb835ddff62
laboratory/src/components/DynamicComponent/index.vue
@@ -30,7 +30,7 @@
        <div v-if="item.type == 'richText'">
          <AiEditor 
            :ref="`editor_${item.id}`"
            v-model="item.data.content"
           :value="item.data.content"
            height="200px"
            placeholder="请输入内容..." 
          />
@@ -98,20 +98,23 @@
        </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"
@@ -140,6 +143,7 @@
    <addTableHeader
      :visible.sync="tableHeaderDialog.visible"
      :participants="participants"
      @confirm="confirmAddHeader"
    ></addTableHeader>
    <addTableData
@@ -174,6 +178,10 @@
      type: String,
      default: "",
    },
    participants: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
@@ -197,6 +205,15 @@
  },
  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 = {};
@@ -207,6 +224,63 @@
      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);
@@ -299,15 +373,47 @@
        .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;
    },
  },
};
@@ -351,6 +457,29 @@
    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;