文件上传,二进制

33 阅读3分钟

示范代码

<template>
  <div class="container">
    <div class="left">
      <step :active="1" />
    </div>
    <div class="middle">
      <div class="middle-inner">
        <div class="top-title">上传文件</div>
        <el-upload
          class="upload"
          drag
          action="/hotpot-api/console/api/files/upload"
          multiple
          accept=".txt,.doc,.docx,.xls,.xlsx,.pdf,.csv,.html,.md"
          :file-list="fileList"
          :headers="{
            Authorization: `Bearer ${$store.state.user.hotpotToken}`
          }"
          :on-change="handleChange"
          :on-remove="handleChange"
          :on-progress="handleProgress"
        >
          <i class="el-icon-upload" />
          <div class="el-upload__text">
            将文件拖到此处,或<em>点击上传</em> <br>
            <br>
            已支持 TXT、 HTML、 Markdown、 PDF、 XLSX、CSV、DOCX,每个文件不超过 150MB。
          </div>
        </el-upload>
        <el-button
          type="primary"
          class="btn-next-step"
          :disabled="!showNextStepBtn"
          @click="nextStep()"
        >下一步</el-button>

        <div v-if="!$route.params.datasetId" class="create-empty-dataset">
          <i class="el-icon-folder-add" />
          <el-link type="primary" @click="createEmptyDataset">创建一个空数据集</el-link>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Step from './step.vue';
import { createEmptyDataset } from '@/api/dataset';

export default {
  components: { Step },
  inject: ['nextStep'],
  props: {
    fileList: {
      type: Array,
      required: true
    },
    datasetId: {
      type: String,
      required: false,
      default: null
    }
  },
  computed: {
    /**
     * 是否显示"下一步"按钮
     */
    showNextStepBtn() {
      const successNum = this.fileList.filter((item) => item.status === 'success').length;
      const uploadingNum = this.fileList.filter((item) => item.status === 'ready' || item.status === 'uploading').length;

      return successNum > 0 && uploadingNum === 0;
    }
  },
  methods: {
    /**
     * 文件状态变更
     */
    handleChange(file, fileList) {
      this.$emit('update:fileList', fileList);
    },

    /**
     * 文件删除
     */
    handleRemove(file, fileList) {
      this.$emit('update:fileList', fileList);
    },

    /**
     * 文件上传进度变更
     */
    handleProgress(event, file, fileList) {
      this.$emit('update:fileList', fileList);
    },

    /**
     * 创建空数据集
     */
    createEmptyDataset() {
      this.$prompt('空数据集中还没有文档,你可以在今后任何时候上传文档至该数据集。', '创建空数据集', {
        confirmButtonText: '创建',
        cancelButtonText: '取消',
        inputPlaceholder: '数据集名称',
        inputValidator: (name) => {
          if (!name.trim()) {
            return '名称不能为空';
          }

          if (name.length >= 40) {
            return '不能超过40个字符';
          }

          return true;
        }
      }).then(({ value }) => {
        createEmptyDataset({
          name: value
        }).then((rs) => {
          this.$message({
            type: 'success',
            message: '创建成功!'
          });
          const datasetId = rs.id;
          this.$router.push({
            path: `/dataset/${datasetId}`,
            query: {
              operate: 'doc-list'
            }
          });
        });
      }).catch(() => {
        console.log('----creating an empty dataset canceled-----');
      });
    }
  }
};
</script>

<style scoped>
.middle-inner {
  max-width: 700px;
  height: auto;
}
.upload {
  width: 100%;
}
::v-deep .el-upload {
  width: 100%;
}
::v-deep .el-upload-dragger {
  width: 100%;
}
::v-deep .el-upload-list__item {
  height: 50px;
  line-height: 50px;
  border-radius: 5px;
  border: 1px solid #e3e3e3;
  -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.1);
  -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.1);
  box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.1);
  margin-bottom: 15px;
  padding: 0 10px;
}
::v-deep .el-upload-list__item .el-icon-close {
  top: 50%;
  transform: translateY(-50%);
}
::v-deep div[role=progressbar] {
  position: absolute;
  left: 0;
  top: 37px;
}
::v-deep .el-progress-bar__outer {
  height: 6px !important;
}
.btn-next-step {
  margin-top: 20px;
}
.create-empty-dataset {
  margin-top: 32px;
  padding-top: 32px;
  border-top: 1px solid lightgray;
  width: 100%;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  color: #1890ff;
}
.create-empty-dataset img {
  width: 1.5em;
  height: 1.5em;
  display: inline-block;
}
</style>

目前的代码

<template>
  <div class="body">
    <div>
      <el-upload
       :file-list="fileList"
       :on-success	="successUpload"
       :action="baseURL + '/clean/'"
       :auto-upload="false"
       :limit="1"
       :multiple="false"
       :data="{
         script_name: value
       }"
       name="file"
       drag
       ref="upload"
       :on-change="changeFile"
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">选择要清洗的文件</div>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        <!-- <div class="el-upload__tip" slot="tip">只能上传XXXX文件,且不超过500kb</div> -->
      </el-upload>
    </div>
    <div class="marginTop">
      <span class="text">清洗脚本:</span>
      <el-select v-model="value" placeholder="请选择">
        <el-option
          v-for="item in scripts"
          :label="item.name"
          :value="item.name">
        </el-option>
      </el-select>
    </div>
    <div class="marginTop">
      <span class="text">规则说明:</span>
      <el-input
      class="textarea"
       :disabled="true"
        type="textarea"
        :autosize="{ minRows: 1, maxRows: 6}"
        placeholder="规则说明"
        v-model="textarea">
      </el-input>
    </div>
    <div class="marginTop width-button">
      <el-button type="primary" class="width-center" @click="toClean()">提交</el-button>
    </div>
    <!-- 分段展示 -->
    <div class="marginTop segments">
      <Segment :segments="segments"></Segment>
    </div>
  </div>
</template>

<script>
import { getFileInfo, } from '@/api/dataset/clean.js';
import Segment from '../../../components/Clean/Segment.vue';

export default {
  components: {
    Segment,
  },
  data() {
    
    return {
      /**
       * 上传的文件, File对像
       */
      file: null,
      fileList:[],
      /**
       * 脚本列表
       */
      scripts: [],
      value: '',
      textarea:"",
      name: "",
      // 基础URL,上传图标没有使用axios,因此需自行设置baseURL
      baseURL: process.env.VUE_APP_CLEAN_BASE_API,
      segments:[{content:"我是第一段"}, {content:"我是第二段"},{content:"我是第一段"}, {content:"我是第二段"},{content:"我是第一段"}, {content:"我是第二段"},{content:"我是第一段"}, {content:"我是第二段"}]
    }
  },
  watch:{
    value(val){
      if(val){
        this.textarea = this.scripts.find(item => item.name === val).support_rules[0]?.description || "";
      }
      
    }
  },
  methods: {
    changeFile(prefile) {
      this.file = prefile;
      if (this.file){
        this.getInfo()
      }
    },
    // 获取参数
    getInfo(){
      if (this.file){
        getFileInfo(this.file.name).then((res) => {
        this.scripts = res.support_scripts
      });
    }
    },
    toClean(){
      this.$refs.upload.submit();
    },
    successUpload(){
      this.$message({
        type: 'success',
        message: "清洗成功",
      });

    }
  }
};
</script>
<style scoped>
.body{
  margin: 30px;
}
.text{
  color: #606266;
  
}
.textarea{
  width:500px;
  
}
.marginTop{
  margin-top: 20px;
  align-items: flex-start; 
}
.upload{
  width: 500px;
}
.body/deep/.el-upload-dragger {
  width: 570px;
  height: 215px;
}
.body/deep/.el-upload-list__item-name {
  width: 570px;
}
.body/deep/.el-upload-list--text  {
  width: 570px;
}
.width-center{
  display: flex;
  margin: auto;
}
.width-button{
  width: 600px;
}
.segments-item{
  background-color: #fff;
  padding: 20px;
  margin: 10px;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.1);
  width: calc(25% - 20px);
  box-sizing: border-box;
  vertical-align: top;
  display: inline-block;
  height: 160px;
  position: relative;
  cursor: pointer;
  border-radius: 5px;
}
.agent-card {
  background-color: #fff;
  padding: 20px;
  margin: 10px;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.1);
  width: calc(25% - 20px);
  box-sizing: border-box;
  vertical-align: top;
  display: inline-block;
  height: 160px;
  position: relative;
  cursor: pointer;
  border-radius: 5px;
}
</style>

之前的错误代码