hanbaoshan
2020-10-27 da98d2a8a686cde09b20345e4a2b55a85410fde4
数据栈文件上传动态限制类型调试,标注切换摄像机获取底图
7个文件已修改
329 ■■■■■ 已修改文件
src/components/subComponents/FileUpload/btn.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/subComponents/FileUpload/index.vue 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/subComponents/FileUpload/uploader.vue 80 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/ai/index/App.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/cameraAccess/components/DataStackInfo.vue 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/index/App.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/labelMark/components/RightSide.vue 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/subComponents/FileUpload/btn.vue
@@ -28,8 +28,20 @@
      }
    }
  },
  watch:{
    attrs:{
      handler(n,o){
        debugger
        this.$nextTick(()=>{
          this.uploader.uploader.assignBrowse(this.$refs.btn, this.directory, this.single, n)
        })
      },
      deep: true
    }
  },
  mounted() {
    this.$nextTick(() => {
      console.log('attrs',this.attrs)
      this.uploader.uploader.assignBrowse(this.$refs.btn, this.directory, this.single, this.attrs)
    })
  }
src/components/subComponents/FileUpload/index.vue
@@ -5,12 +5,13 @@
      ref="uploader"
      :options="options"
      :file-status-text="statusText"
      :attrs="attrs"
      class="uploader-single"
      @file-added="onFileAdded"
      @complete="onComplete"
    >
      <el-input :placeholder="uploadPlaceholder" size="small" :readonly="true" v-model="fileName">
        <uploader-btn slot="suffix" >
        <uploader-btn slot="suffix">
          <el-tooltip :content="tipWords" placement="top" v-if="tip">
            <i class="el-icon-upload2" style="font-size:18px; color:#0088ff"></i>
          </el-tooltip>
@@ -23,6 +24,7 @@
    <uploader
      v-else
      ref="uploader"
      :attrs="attrs"
      :options="options"
      :file-status-text="statusText"
      class="uploader-example"
@@ -31,7 +33,7 @@
      @complete="onComplete"
      @close="closeHandle"
    >
      <uploader-btn ref="button">
      <uploader-btn ref="button" :attrs="attrs">
        <i class="el-icon-upload2" style="font-size:18px; color:#0088ff"></i>
        上传
      </uploader-btn>
@@ -53,6 +55,10 @@
    UploaderList
  },
  props: {
    acptTypes: {
      type: String,
      default: ''
    },
    tip: {
      type: Boolean,
      default: false
@@ -73,14 +79,22 @@
      type: String,
      default: "/data/api-f/file/upload" //"//192.168.20.10:3000/upload"
    },
    attrs: {
      type: Object,
      // default () {
      //   return {
      //   }
      // }
    }
  },
  data() {
  data () {
    return {
      fileName: "",
      fileMd5: "",
      attrs: {
        accept: 'image/*'
      },
      // attrs: {
      //   accept: 'image/*'
      // },
      statusText: {
        success: '上传成功',
        error: '上传失败',
@@ -91,10 +105,10 @@
    }
  },
  computed: {
    uploader() {
    uploader () {
      return this.$refs.uploader.uploader;
    },
    options() {
    options () {
      return {
        target: this.url,
        testChunks: true,
@@ -105,14 +119,14 @@
    }
  },
  methods: {
    onFileAdded(file) {
    onFileAdded (file) {
      if (this.single) {
        this.uploader.fileList = this.uploader.fileList.slice([-1]);
        this.$emit("file-added")
      }
      this.computeMD5(file);
    },
    computeMD5(file) {
    computeMD5 (file) {
      let fileReader = new FileReader();
      let time = new Date().getTime();
      let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
@@ -141,13 +155,13 @@
        this.error(`文件${file.name}读取出错,请检查该文件`)
        file.cancel();
      };
      function loadNext() {
      function loadNext () {
        let start = currentChunk * chunkSize;
        let end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
        fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
      }
    },
    computeMD5Success(md5, file) {
    computeMD5Success (md5, file) {
      // 将自定义参数直接加载uploader实例的opts上
      // if (this.$route.path.indexOf("VideoManage") >= 0) {
      //   Object.assign(this.uploader.opts, {
@@ -170,19 +184,20 @@
      file.resume();
      this.statusText.paused = "暂停中";
    },
    onComplete() {
    onComplete () {
      debugger
      this.$emit("complete", { filename: this.fileName, identifier: this.fileMd5 });
    },
    fileComplete() {
    fileComplete () {
      // console.log('file complete', arguments)
    },
    closeHandle() {
    closeHandle () {
      this.$emit("close")
    }
  },
  mounted() {
  mounted () {
    this.$nextTick(() => {
      console.log(this.acptTypes)
      window.uploader = this.$refs.uploader.uploader
    })
  }
@@ -191,10 +206,11 @@
<style lang="scss">
.file-uploader {
  .el-input__suffix,.el-input__suffix-inner{
    outline: none!important;
  .el-input__suffix,
  .el-input__suffix-inner {
    outline: none !important;
  }
  .el-tooltip.focusing{
  .el-tooltip.focusing {
    outline: none;
  }
  .uploader-example {
@@ -223,7 +239,7 @@
      display: none;
    }
    .uploader-btn {
      border: 0px;
      border: 0px;
    }
    .uploader-file {
      height: 2px;
src/components/subComponents/FileUpload/uploader.vue
@@ -5,8 +5,8 @@
      <uploader-unsupport></uploader-unsupport>
      <uploader-drop>
        <!-- <p>拖动文件到该区域上传</p> -->
        <uploader-btn>选择文件</uploader-btn>
        <uploader-btn :directory="true">选择文件夹</uploader-btn>
        <uploader-btn :attrs="attrs">选择文件</uploader-btn>
        <uploader-btn :directory="true" :attrs="attrs">选择文件夹</uploader-btn>
      </uploader-drop>
      <uploader-list></uploader-list>
    </slot>
@@ -33,7 +33,26 @@
      uploader: this
    }
  },
  watch:{
    attrs:{
      handler(n,o){
        console.log('uploader attrs update',n)
        this.$nextTick(()=>{
          //this.unBindUploader();
          this.bindUploader();
        })
      },
      deep: true
    },
  },
  props: {
    attrs: {
      type: Object,
      default() {
        return {}
      }
    },
    options: {
      type: Object,
      default() {
@@ -94,6 +113,7 @@
      }
    },
    allEvent(...args) {
      console.log(args)
      const name = args[0]
      const EVENTSMAP = {
        [FILE_ADDED_EVENT]: true,
@@ -112,27 +132,51 @@
    },
    closeHandle() {
      this.$emit("close")
    },
    bindUploader(){
      console.log('new Uploader')
      this.options.initialPaused = !this.autoStart
      const uploader = new Uploader(this.options)
      this.uploader = uploader
      this.uploader.fileStatusText = this.fileStatusText
      uploader.on('catchAll', this.allEvent)
      uploader.on(FILE_ADDED_EVENT, this.fileAdded)
      uploader.on(FILES_ADDED_EVENT, this.filesAdded)
      uploader.on('fileRemoved', this.fileRemoved)
      uploader.on('filesSubmitted', this.filesSubmitted)
    },
    unBindUploader(){
      const uploader = this.uploader
      uploader.off('catchAll', this.allEvent)
      uploader.off(FILE_ADDED_EVENT, this.fileAdded)
      uploader.off(FILES_ADDED_EVENT, this.filesAdded)
      uploader.off('fileRemoved', this.fileRemoved)
      uploader.off('filesSubmitted', this.filesSubmitted)
      this.uploader = null
    }
  },
  created() {
    this.options.initialPaused = !this.autoStart
    const uploader = new Uploader(this.options)
    this.uploader = uploader
    this.uploader.fileStatusText = this.fileStatusText
    uploader.on('catchAll', this.allEvent)
    uploader.on(FILE_ADDED_EVENT, this.fileAdded)
    uploader.on(FILES_ADDED_EVENT, this.filesAdded)
    uploader.on('fileRemoved', this.fileRemoved)
    uploader.on('filesSubmitted', this.filesSubmitted)
    console.log('uploader attrs',this.attrs);
    this.bindUploader();
    // this.options.initialPaused = !this.autoStart
    // const uploader = new Uploader(this.options)
    // this.uploader = uploader
    // this.uploader.fileStatusText = this.fileStatusText
    // uploader.on('catchAll', this.allEvent)
    // uploader.on(FILE_ADDED_EVENT, this.fileAdded)
    // uploader.on(FILES_ADDED_EVENT, this.filesAdded)
    // uploader.on('fileRemoved', this.fileRemoved)
    // uploader.on('filesSubmitted', this.filesSubmitted)
  },
  destroyed() {
    const uploader = this.uploader
    uploader.off('catchAll', this.allEvent)
    uploader.off(FILE_ADDED_EVENT, this.fileAdded)
    uploader.off(FILES_ADDED_EVENT, this.filesAdded)
    uploader.off('fileRemoved', this.fileRemoved)
    uploader.off('filesSubmitted', this.filesSubmitted)
    this.uploader = null
    this.unBindUploader();
    // const uploader = this.uploader
    // uploader.off('catchAll', this.allEvent)
    // uploader.off(FILE_ADDED_EVENT, this.fileAdded)
    // uploader.off(FILES_ADDED_EVENT, this.filesAdded)
    // uploader.off('fileRemoved', this.fileRemoved)
    // uploader.off('filesSubmitted', this.filesSubmitted)
    // this.uploader = null
  },
  components: {
    UploaderBtn,
src/pages/ai/index/App.vue
@@ -869,10 +869,10 @@
      downloadSdk({ path: item.id })
        .then(rsp => {
          this.$notify({
            type: "success",
            message: "算法已安装"
          });
          // this.$notify({
          //   type: "success",
          //   message: "算法已安装"
          // });
          item.upgradeLoading = false;
          //this.downloading = false;
          this.downloadItem = "";
src/pages/cameraAccess/components/DataStackInfo.vue
@@ -105,7 +105,12 @@
        </el-tooltip>
        <!-- 文件上传 -->
        <el-button type="primary" size="small" :disabled="!DataStackPool.selectedDir.id" @click="handleUpload">
        <el-button
          type="primary"
          size="small"
          :disabled="!DataStackPool.selectedDir.id"
          @click="handleUpload"
        >
          上传
          <i class="el-icon-upload el-icon--right"></i>
        </el-button>
@@ -118,7 +123,6 @@
      v-show="activeName === 'uploaded' "
      :data="fileList"
      tooltip-effect="dark"
      border
      :header-cell-style="{background:'#f8f8f8', color:'#222222', textAlign:'center'}"
      @select="handleSelect"
@@ -260,6 +264,7 @@
    </div>
    <!-- 文件上传组件 -->
    <!-- <file-uploader ref="uploader" v-show="activeName === 'uploading'" :attrs="attrs" /> -->
    <file-uploader ref="uploader" v-show="activeName === 'uploading'" />
    <!-- 文件预览 -->
@@ -323,7 +328,7 @@
    }
  },
  filters: {
    statusFormat(value) {
    statusFormat (value) {
      let statusCode = {
        "-1": "已删除",
        "0": "暂停处理",
@@ -333,7 +338,7 @@
      }
      return statusCode[value];
    },
    readFileSizeUnit(value) {
    readFileSizeUnit (value) {
      let UNITS = [' B', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB'];
      let format = function (value, power) {
        return (value / Math.pow(1024, power)).toFixed(2) + UNITS[power];
@@ -352,7 +357,7 @@
    }
  },
  computed: {
    snapshotClass() {
    snapshotClass () {
      let classs = ["snapshot"];
      if (this.form.type === 1) {
        classs.push("snapshot-video")
@@ -366,13 +371,13 @@
      return classs;
    },
    dirOptions() {
    dirOptions () {
      return this.DataStackPool.dirs.filter(dir => {
        return dir.id !== this.DataStackPool.selectedDir.id
      })
    }
  },
  data() {
  data () {
    return {
      videoUrl: "",
      imgUrl: "",
@@ -403,39 +408,55 @@
      editRowId: "",
      timer: 0,
      targetDir: "",
      targetFile: ""
      targetFile: "",
      attrs: {
        accept: ""
      }
    };
  },
  mounted() {
  mounted () {
    this.initFormData();
    console.log(this.PollData.barCharts)
  },
  beforeDestroy() {
  beforeDestroy () {
    this.taskUid = 0;
  },
  watch:{
    'fileList.length':{
      handler(n,o){
  watch: {
    'fileList.length': {
      handler (n, o) {
        //数据栈文件数量变更
        //更新独立场景数据栈文件
        console.log(this.$root.$children[0].$children[1].$refs['sepRule'])
        console.log(this.$root.$children[0].$children[1].$refs['sepRule']);
        this.$root.$children[0].$children[1].$refs['sepRule'].getStackFiles();
      }
    },
    'form.type': {
      handler (n, o) {
        console.log(n, o)
        if (n == 1) {
          //仅支持上传视频
          this.$set(this.attrs, 'accept', ".mp4");
        }else if (n == 2) {
          //图片
          this.$set(this.attrs, 'accept', "image/jpg,image/jpeg,image/png");
        }
      }
    }
  },
  methods: {
    preview(row) {
    preview (row) {
      this.previewDialog = true;
      if (row.type === 1) {
        this.videoUrl = "/files/" + row.identifier + ".mp4"
      }else if(row.type===2){
        this.imgUrl = "/files/" + row.path.substr(row.path.lastIndexOf('/')+1)
      } else if (row.type === 2) {
        this.imgUrl = "/files/" + row.path.substr(row.path.lastIndexOf('/') + 1)
      }
    },
    // 清空输入框
    initFormData() {
    initFormData () {
      this.form = {
        enable: false,
        id: "",
@@ -447,15 +468,15 @@
      };
    },
    // 添加设备
    addDir(node) {
    addDir (node) {
      this.isAdd = true;
      this.isDisabled = false;
      this.initFormData();
      this.DataStackPool.clean();
      this.fileList = [];
    },
    selectDir(node) {
    selectDir (node) {
      if (node.id === "") {
        return
      }
@@ -481,12 +502,12 @@
      this.videoUrl = '';
      this.imgUrl = '';
    },
    initFetchListTask() {
    initFetchListTask () {
      const uid = Math.round(Math.random() * 1000);
      this.taskUid = uid;
      this.timingtask(uid);
    },
    timingtask(uid) {
    timingtask (uid) {
      if (uid !== this.taskUid || this.form.id === "") {
        return;
      }
@@ -498,11 +519,11 @@
        _this.timingtask(uid);
      }, 2 * 1000);
    },
    fetchFileList() {
    fetchFileList () {
      findAllFileByStackId({ name: this.searchInput, stackId: this.form.id, page: this.page, size: this.size, type: 0 }).then(rsp => {
        if (rsp && rsp.success && rsp.data.total > 0) {
          this.fileList = rsp.data.dataList;
          this.total = rsp.data.total;
          // 定时刷新会清空选中状态,在这里恢复
@@ -522,7 +543,7 @@
    },
    // 保存
    onSubmit(formName) {
    onSubmit (formName) {
      this.$refs[formName].validate(async valid => {
        if (valid) {
          saveDir(this.form).then(rsp => {
@@ -543,7 +564,7 @@
      });
    },
    // 删除摄像机
    deleteDir() {
    deleteDir () {
      this.$confirm("是否删除此文件夹?", {
        center: true,
        cancelButtonClass: "comfirm-class-cancle",
@@ -572,32 +593,34 @@
        });
      });
    },
    handleTabClick(tab, event) {
    handleTabClick (tab, event) {
      console.log(tab, event);
    },
    handleSelect(val) {
    handleSelect (val) {
      this.multipleSelection = val.map(row => {
        return row.id;
      });
    },
    handelSearchInputChange(val) {
    handelSearchInputChange (val) {
      this.multipleSelection = [];
    },
    handleUpload() {
    handleUpload () {
      console.log(this.DataStackPool.selectedDir.id)
      console.log(this.$refs.uploader.$refs.button.attrs)
      console.log(this.$refs.uploader.$refs.button.$refs.btn.click())
    },
    handleRefrashFileList(val) {
    handleRefrashFileList (val) {
      this.page = val;
      this.multipleSelection = [];
      this.fetchFileList();
    },
    handleSizeChange(val) {
    handleSizeChange (val) {
      this.size = val;
      this.multipleSelection = [];
      this.fetchFileList();
    },
    async handleSortFile(direct, id) {
    async handleSortFile (direct, id) {
      let res = await sortFile({
        id: id,
        direct: direct
@@ -613,7 +636,7 @@
        })
      }
    },
    async handleFileStatus(row, status, multi = false) {
    async handleFileStatus (row, status, multi = false) {
      let ids = this.multipleSelection;
      if (!multi) {
        ids = [row.id];
@@ -641,10 +664,10 @@
        console.log("err")
      }
    },
    dropdownClick(cmd) {
    dropdownClick (cmd) {
      cmd.cb(cmd.data);
    },
    handleFileDelete(rows, multi = false) {
    handleFileDelete (rows, multi = false) {
      let _this = this;
      let ids = this.multipleSelection;
      if (!multi) {
@@ -668,20 +691,20 @@
            message: "文件已删除"
          })
        });
      }).catch(() => { })
    },
    handleFileMove(row) {
    handleFileMove (row) {
      this.targetDir = "";
      this.targetFile = row.id;
      this.fileDialog = true;
    },
    handleFileRename(row) {
    handleFileRename (row) {
      this.editRowId = row.id;
      clearTimeout(this.timer);
      this.timer = null;
    },
    cellRenameFile(row) {
    cellRenameFile (row) {
      this.editRowId = "";
      renameFile({ id: row.id, name: row.name }).then(rsp => {
        if (rsp && rsp.success) {
@@ -704,10 +727,10 @@
        }
      })
    },
    isSelectable(row, rowIndex) {
    isSelectable (row, rowIndex) {
      return row.status !== 2
    },
    cellFileCopy() {
    cellFileCopy () {
      copyFile({ id: this.targetFile, stackIds: [this.targetDir] }).then(rsp => {
        if (rsp && rsp.success) {
          this.$notify({
@@ -723,7 +746,7 @@
        }
      })
    },
    cellFileMove() {
    cellFileMove () {
      moveFile({ id: this.targetFile, stackId: this.targetDir }).then(rsp => {
        if (rsp && rsp.success) {
          this.$notify({
@@ -756,9 +779,9 @@
  .el-form-item__label {
    text-align: left;
  }
  .el-button--primary.is-disabled{
  .el-button--primary.is-disabled {
    background-color: #9eb4f0 !important;
    border-color: #9eb4f0 !important;
    border-color: #9eb4f0 !important;
  }
  .label {
    color: #606266;
@@ -843,19 +866,19 @@
    vertical-align: middle;
  }
  .snapshot-video {
    background: url("/images/cameraAccess/video.png");
    background: url('/images/cameraAccess/video.png');
    background-repeat: round;
  }
  .snapshot-image {
    background: url("/images/cameraAccess/image.png");
    background: url('/images/cameraAccess/image.png');
    background-repeat: round;
  }
  .snapshot-audio {
    background: url("/images/cameraAccess/audio.png");
    background: url('/images/cameraAccess/audio.png');
    background-repeat: round;
  }
  .snapshot-files {
    background: url("/images/cameraAccess/files.png");
    background: url('/images/cameraAccess/files.png');
    background-repeat: round;
  }
}
src/pages/index/App.vue
@@ -45,7 +45,10 @@
          </el-form-item>
        </el-form>
      </div>
      <p class="gradient-text gradient-text-one">——— {{serverTitle || 'SmartAI — ReID'}} ———</p>
      <!-- <p class="gradient-text gradient-text-one">——— {{serverTitle || 'SmartAI — ReID'}} ———</p> -->
      <p class="gradient-text gradient-text-one">—— <b>SmartAI</b> 人工智能操作系统 ——</p>
      <p class="gradient-text gradient-text-one" style="letter-spacing: 1.8px;font-size:15px;"> V1.0.0 </p>
    </div>
  </div>
</template>
@@ -238,10 +241,10 @@
}
.left-bg {
  position: absolute;
  top: 30%;
  top: 29%;
  right: 18%;
  width: 390px;
  height: 402px;
  height: 426px;
  background: rgba(146, 208, 255, 0.23);
  border-radius: 4px;
  text-align: center;
@@ -261,11 +264,14 @@
    // margin: 24px 10px 40px 10px;
  }
  .gradient-text {
    line-height: 50px;
    font-size: 20px;
    line-height: 36px;
    font-size: 17px;
    font-family: -webkit-pictograph;
    font-weight: bolder;
    position: relative;
    b{
      font-size: 20px;
    }
  }
  .gradient-text-one {
    background-image: linear-gradient(to right, #51feff 5%, #ff8725 100%);
src/pages/labelMark/components/RightSide.vue
@@ -18,7 +18,7 @@
      <div class="mask" :class="{'edit-status-mask':isEdit}" ref="editBoard" >
        <div class="label" @click="editLabel(item)" v-for="(item,index) in labels" :key="index" :style="{left:`${item.x}px`, top:`${item.y}px`, backgroundColor: colorPick, width: `${dotSize}px`, height: `${dotSize}px` }"></div>
      </div>
      <img :src="baseUrl" alt />
      <img :src="`/httpImage/${snapshot_url}`" alt />
      <div class="popBox" v-show="isShowPop" :style="`top:${curLabel.y + 22}px;left:${curLabel.x}px`">
        <div class="title">标注信息</div>
        <div class="details">
@@ -59,6 +59,7 @@
</template>
<script>
import { getCamerasByServer } from '@/api/pollConfig'
import TreeDataPool from "@/Pool/TreeData";
export default {
  data () {
@@ -76,19 +77,30 @@
        x:'',
        y:''
      },
      baseUrl: ''
      baseUrl: '',
      snapshot_url: '',
      cameraData:[],
    }
  },
  computed: {
    
  },
  mounted(){
    this.getAllCameraData();
    setTimeout(()=>{
      let mockData = [{id:'a1',x:15, y:33, posX:150, posY:330},{id:'b2',x:56, y:87, posX:560, posY:870}];
      this.labels = mockData;
    },1000);
  },
  watch:{
    'TreeDataPool.selectedNode':{
      handler(n,o){
        debugger
        let curCamera = this.cameraData.find(item => item.id==n.id);
        this.snapshot_url = curCamera.snapshot_url;
      },
      deep: true
    },
    isEdit(n,o){
      if(n){
        this.$refs['editBoard'].addEventListener('click',this.bindListen);
@@ -98,6 +110,16 @@
    }
  },
  methods: {
    getAllCameraData(){
      getCamerasByServer().then(res=>{
        if(res.success){
          debugger
          this.cameraData = res.data;
        }
      }).catch(e=>{
        console.log(e)
      })
    },
    bindListen(e){
      this.newLabel(e);
    },
@@ -231,7 +253,7 @@
          align-items: center;
          margin: 5px 0;
          label{
            color: #ccc;
            color: #a9a9a9;
            width:65px;
            display: inline-block;
          }
@@ -250,7 +272,7 @@
          .devide{
            width: 10px;
            height: 1px;
            background: #ccc;
            background: #a9a9a9;
            margin: 0 3px;
          }
        }