deliverUploadDialog.vue 11.3 KB
<template>
  <Dialog :dialogInfo="dialogInfo" @btnClick="dialogBtnClick">
    <div class="first-row">
      <div class="data-accept-left">
        <div class="title">选择数据接收方</div>
        <div class="data-list">
          <el-checkbox-group v-model="userReceiveCheckList">
            <div
              :class="userReceiveSelectInfo.dataReceiveGuid == item.dataReceiveGuid ? 'data-check-item selected' : 'data-check-item'"
              v-for="item in props.listData" :key="item.dataReceiveGuid" @click="handleClickItem(item)">
              <el-checkbox :label="item.dataReceiveGuid">{{ '' }}
              </el-checkbox>
              <div class="text-label">
                <ellipsis-tooltip :content="item.dataReceiveName" class-name="w100f"
                  :refName="'tooltipOver' + item.dataReceiveGuid"></ellipsis-tooltip>
              </div>
            </div>
          </el-checkbox-group>
        </div>
      </div>
      <div class="data-contract-right">
        <div class="title">{{ '选择' + (userReceiveSelectInfo.dataReceiveName || '数据接收方') + '的合同' }}</div>
        <div class="data-list contract">
          <el-checkbox-group v-show="userReceiveSelectInfo.dataReceiveContractRSVOS?.length"
            v-model="userReceiveContractCheckList[userReceiveSelectInfo.dataReceiveGuid]">
            <el-checkbox v-for="item in userReceiveSelectInfo.dataReceiveContractRSVOS" :key="item.dataContractGuid"
              :label="item.dataContractGuid">
              <ellipsis-tooltip :content="item.dataContractName" class-name="w100f"
                :refName="'tooltipOver' + item.dataContractGuid"></ellipsis-tooltip>
            </el-checkbox>
          </el-checkbox-group>
        </div>
      </div>
    </div>
    <el-upload ref="uploadRef" action="#" class="upload-delivery" drag :file-list="fileList"
      :http-request="(file) => uploadFile(file)">
      <el-icon class="el-icon--upload" style="margin-bottom: 4px;">
        <Plus />
      </el-icon>
      <div class="el-upload__text">
        点击或拖拽上传
      </div>
      <template #file="{ file }">
        <div class="file-operate">
          <template
            v-if="file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase() == 'xls' || file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase() == 'xlsx'">
            <img class="file-img" src="../../../assets/images/excel.png" />
          </template>
          <template
            v-else-if="file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase() == 'doc' || file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase() == 'docx'">
            <img class="file-img" src="../../../assets/images/word.png" />
          </template>
          <template v-else-if="file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase() == 'zip'">
            <img class="file-img" src="../../../assets/images/zip.png" />
          </template>
          <template v-else-if="file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase() == 'rar'">
            <img class="file-img" src="../../../assets/images/RAR.png" />
          </template>
          <template v-else-if="file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase() == 'pdf'">
            <img class="file-img" src="../../../assets/images/PDF.png" />
          </template>
          <template v-else-if="file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase() == 'png'">
            <img class="file-img" src="../../../assets/images/png.png" />
          </template>
          <template
            v-else-if="file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase() == 'jpg' || file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase() == 'jpeg'">
            <img class="file-img" src="../../../assets/images/jpg.png" />
          </template>
          <div class="file-name"
            :style="{ width: ['pdf', 'png', 'jpg', 'jpeg'].includes(file?.name?.substring(file.name.lastIndexOf('.') + 1).toLowerCase() ?? '') ? 'calc(100% - 300px)' : 'calc(100% - 290px)' }">
            <ellipsis-tooltip :content="file.name" class-name="w100f"
              :refName="'tooltipOver' + file.name"></ellipsis-tooltip>
          </div>
          <div class="upload-time" :style="{ right: 32 }" v-if="uploadTime"> {{ '上传时间:' + uploadTime }} </div>
          <div :style="{ right: 0 }" class="file-preview" @click="handleUploadFileRemove(file)">删除
          </div>
        </div>
      </template>
    </el-upload>
  </Dialog>
</template>

<script setup lang="ts" name="deliverUploadDialog">
import {
  Plus
} from "@element-plus/icons-vue";
import {
  getUpFileSignByUrl,
  obsUploadRequest,
  getPathUrl
} from "@/api/modules/obsService";
import {
  saveDataReceiveContract
} from "@/api/modules/dataAsset";
import { ElMessage } from "element-plus";
import Moment from "moment";

const { proxy } = getCurrentInstance() as any;

const props = defineProps({
  listData: { //数据接收方和合同列表
    type: Array<any>,
    default: [{
      dataReceiveGuid: '1',
      dataReceiveName: '北京传世博润科技有限公司',
      dataReceiveContractRSVOS: [{
        dataContractGuid: '1',
        dataContractName: '合同1'
      }, {
        dataContractGuid: '2',
        dataContractName: '合同2'
      }]
    }, {
      dataReceiveGuid: '2',
      dataReceiveName: 'xx2',
      dataReceiveContractRSVOS: [{
        dataContractGuid: '2',
        dataContractName: '合同2'
      }]
    }]
  },
  uploadDeliverItem: {
    type: Object,
    default: {}
  },
  visible: {
    type: Boolean,
    default: false
  },
})


const emits = defineEmits(['close'])

watch(() => props.visible, (val) => {
  dialogInfo.value.visible = val;
  if (val) {
    userReceiveCheckList.value = [];
    fileList.value = [];
    uploadTime.value = null;
    userReceiveSelectInfo.value = props.listData[0] || {};
    userReceiveContractCheckList.value = {};
    props.listData.forEach(list => {
      userReceiveContractCheckList.value[list.dataReceiveGuid] = [];
    })
  }
})

const fileList: any = ref([]);

/** 文件上传时间 */
const uploadTime: any = ref(null);

const userReceiveCheckList = ref([]);

/** 记录接收方对应勾选的合同 */
const userReceiveContractCheckList: any = ref({});

/** 记录当前选中的高亮合同 */
const userReceiveSelectInfo: any = ref({});

const dialogInfo = ref({
  visible: false,
  size: 800,
  direction: "column",
  header: {
    title: "交付物上传",
  },
  type: '',//标识是否是重新提交
  contents: [],
  footer: {
    btns: [
      { type: "default", label: "取消", value: "cancel" },
      { type: "primary", label: "确定", value: "submit", loading: false },
    ],
  },
});

const dialogBtnClick = (btn, info) => {
  console.log('btn', btn, info);
  if (btn.value == 'submit') {
    if (!userReceiveCheckList.value.length) {
      ElMessage.error('请勾选数据接收方');
      return;
    }
    if (!fileList.value.length) {
      ElMessage.error('请点击或拖拽上传交付物文件');
      return;
    }
    let jsonValue: any = [];
    for (const u of userReceiveCheckList.value) {
      if (!userReceiveContractCheckList.value[u]?.length) {
        ElMessage.error(`【` + props.listData.find(l => l.dataReceiveGuid == u)?.dataReceiveName + '】' + '未选择合同');
        return;
      }
      jsonValue.push({
        dataReceiveGuid: u,
        contractInfo: userReceiveContractCheckList.value[u]?.map(c => {
          return {
            dataContractGuid: c,
            dataContractName: props.listData.find(l => l.dataReceiveGuid == u).dataReceiveContractRSVOS.find(d => d.dataContractGuid == c).dataContractName
          }
        })
      })
    }
    dialogInfo.value.footer.btns[1].loading = true;
    let params = {
      damGuid: props.uploadDeliverItem.guid,
      dataDelivery: fileList.value?.map(f => {
        return {
          name: f.name,
          url: f.url
        }
      }),
      uploadTime: uploadTime.value,
      dataReceiveRQVOS: jsonValue 
    };
    saveDataReceiveContract(params).then((res: any) => {
      dialogInfo.value.footer.btns[1].loading = false;
      if (res.code == proxy.$passCode) {
        proxy.$ElMessage.success('上传交付物成功');
        dialogInfo.value.visible = false;
        emits('close', props.uploadDeliverItem.guid);
      } else {
        proxy.$ElMessage.error(res.msg);
      }
    })
  } else if (btn.value == 'cancel') {
    dialogInfo.value.visible = false;
    emits('close')
  }
}

const handleClickItem = (item) => {
  userReceiveSelectInfo.value = item;
}

const uploadRef = ref();

const uploadFile = (file) => {
  return getUpFileSignByUrl({ fileName: file.file.name })
    .then((res: any) => {
      obsUploadRequest({
        signedUrl: res.data.signedUrl,
        file: file.file,
        actualSignedRequestHeaders: res.data.actualSignedRequestHeaders
      }).then(() => {
        if (res.code == '00000') {
          file.file.url = res.data.signedUrl && getPathUrl(res.data.signedUrl);
          let fileItem = {
            name: file.file.name,
            url: res.data.signedUrl,
            file: file.file
          };
          fileList.value = [fileItem];
          uploadTime.value = Moment(Date.now()).format('YYYY-MM-DD HH:mm:ss');
          ElMessage.success('上传成功');
        } else {
          uploadRef.value.handleRemove(file);
          ElMessage.error('上传失败,请重新上传!');
        }
      })
    })
    .catch(() => {
      uploadRef.value.handleRemove(file);
      ElMessage.error('上传失败,请重新上传');
    });
}

const handleUploadFileRemove = (file) => {
  fileList.value = [];
  uploadRef.value.handleRemove(file);
}
</script>

<style lang="scss" scoped>
.first-row {
  display: flex;
  justify-content: space-between;
  height: 202px;
  margin-top: 16px;
}

.data-contract-right,
.data-accept-left {
  width: calc(50% - 6px);

  .title {
    line-height: 21px;
    color: #666;
    margin-bottom: 4px;
  }

  .data-list {
    border: 1px solid #d9d9d9;
    height: 178px;
    padding: 8px 12px;

    .data-check-item {
      display: flex;
      padding-left: 12px;

      &.selected {
        background-color: #ebf6f7;
      }

      .text-label {
        width: calc(100% - 36px);
        line-height: 32px;
        cursor: pointer;
        font-size: 14px;
      }
    }
  }
}

:deep(.data-list) {
  .el-checkbox-group {
    margin-left: -12px;
    margin-right: -12px;
  }
}

:deep(.data-list.contract) {
  .el-checkbox {
    width: 100%;
    margin-right: 0px;
    padding-left: 12px;

    .el-checkbox__label {
      width: calc(100% - 22px);
    }
  }
}

.upload-delivery {
  margin-top: 16px;

  .file-operate {
    display: flex;
    align-items: center;
    position: relative;
    width: 100%;

    .file-img {
      width: 30px;
      height: 30px;
    }

    &:hover {
      background-color: #f5f5f5;
    }
  }

  .file-name {
    color: var(--el-color-regular);
    margin-left: 4px;
    margin-right: 4px;
    width: calc(100% - 130px);
  }

  .file-preview {
    position: absolute;
    cursor: pointer;
    color: var(--el-color-primary);
    margin-right: 8px;
  }
}

:deep(.el-upload.is-drag) {

  .el-upload-dragger {
    height: 160px;
    align-items: center;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
}

:deep(.el-upload-list) {
  margin-top: 16px;
}

.upload-time {
  right: 46px;
  position: absolute;
  color: #999;
}
</style>