钉钉与微信小程序兼容性--文件上传

文章介绍了uni-app在与微信小程序和钉钉开发中的文件选择API差异,并提供了一个跨平台的`chooseFile.js`封装示例,旨在统一不同平台的文件选择接口。在DingChooseFile.vue组件中,展示了如何根据平台调用相应API并处理选择的文件。
摘要由CSDN通过智能技术生成

一、uni-app、微信小程序、钉钉开发相关api的区别

1、uni.chooseFile不支持微信小程序与支付宝小程序

2、wx.chooseMessageFile 可从客户端会话选择文件

支持类型type有:

all从所有文件选择
video只能选择视频文件
image只能选择图片文件
file可以选择除了图片和视频之外的其它的文件

3、钉钉应用开发没有选择文件api,只有

  • 调用dd.chooseImage从本地相册选择图片;
  • 调用dd.chooseVideo拍摄视频或从手机相册中选视频;
  • 调用dd.uploadAttachmentToDingTalk上传附件到钉盘,或从钉盘选择文件

针对以上三点,对选择文件进行封封装处理

二、代码

choose-file.js

import Vue from 'vue'
// 目前支持两种 wx 和 钉钉
export const chooseFile = async (options) => {
    console.log(options,'......')
    let _fn
    // #ifdef MP-WEIXIN
    _fn = () => new Promise((reslove, reject) => {
        wx.chooseMessageFile({
            count: 1,
            type: 'file',
            success: reslove,
            fail: reject,
            ...options
        })
    })
    // #endif

    // #ifdef MP-ALIPAY

    const instance = Vue.prototype.$initDingFileChoose({
        onSelect: options.onSelect || (() => {}),
        ...options
    })
    _fn = () => new Promise((reslove, reject) => {
        instance.show()
    })
    
    // #endif   
    await _fn()
}

DingChooseFile.vue

<template>
  <popup
    title="选择文件"
    v-model="visible"
    :clickMaskToClose="true"
    @cancelFn="visible = false"
  >
    <view class="optionsContent" slot="content">
      <view v-for="selectType in types" :key="selectType.value">
        <view
          class="optionItem"
          @tap="onSelect(selectType)"
          v-if="chooseType(selectType.value)"
        >
          <view class="paddingArea">
            <view class="optionValue">{{ selectType.name }}</view>
            <view class="optionIcon" />
          </view>
        </view>
      </view>
    </view>
  </popup>
</template>

<script>
import Vue from "vue";
import { apiGetAttachSpaceId } from "@/services/seal";
import { uploadFile } from "@/utils/uploadFile";
export default {
  name: "DingChooseFile",
  props: {
    data: {
      type: Object,
      default: null,
    },
    limit: {
      type: Number,
      default: null,
    },
  },
  data() {
    return {
      visible: false,
      types: [
        { name: "照片", value: "photo" },
        { name: "视频", value: "video" },
        { name: "钉盘", value: "space" },暂时不考虑钉盘接入,无权限
      ],
      outSideSelectHandler: () => {},
      optionDing: {},
      optionType: "",
    };
  },

  async mounted() {
    Vue.prototype.$initDingFileChoose = (arg) => {
      let { onSelect, type, ...rest } = arg;
      this.optionType = type;
      this.optionDing = rest;
      this.outSideSelectHandler = onSelect || (() => {});
      return {
        show: () => (this.visible = true),
        close: () => (this.visible = false),
      };
    };
  },
  computed: {},
  methods: {
    /*判断钉钉上传文件类型 */
    // type有space和photo、video三种
    chooseType(type) {
      if (!this.optionType || this.optionType === "all") return true;
      if (this.optionType == "file") {
        this.optionType = "space";
      }
      if (this.optionType == "image") {
        this.optionType = "photo";
      }
      return this.optionType === type ? true : false;
    },
    async onSelect(selectType) {
      let _this = this;
      const chooseImage = () =>
        new Promise((reslove, reject) => {
          dd.chooseImage({
            success: (res) => {
              res.selectType = selectType;
              reslove(res);
            },
            fail: reject,
            ..._this.optionDing,
          });
        });

      const chooseVideo = () =>
        new Promise((reslove, reject) => {
          dd.chooseVideo({
            ...this.optionDing,
            success: (res) => {
              res.selectType = selectType;
              reslove(res);
            },
            fail: reject,
          });
        });

      const chooseDingDisk = async () => {
        // 获取spaceId
        let result = await apiGetAttachSpaceId();
        return new Promise((reslove, reject) => {
          dd.uploadAttachmentToDingTalk({
            space: { spaceId: result.data, isCopy: 1, max: 9 },
            image: {
              spaceId: result.data,
              multiple: true,
              compress: false,
              max: 9,
            },
            file: { spaceId: result.data, max: 1 },
            types: ["space"], //PC端仅支持["photo","file","space"] space代表支持钉盘
            success: (res) => {
              res.selectType = selectType;
              // debugger;
              reslove(res);
            },
            fail: reject,
            // ..._this.optionDing,
          });
        });
      };

      const fnMap = {
        photo: chooseImage,
        video: chooseVideo,
        // dingDisk: chooseDingDisk,
        space: chooseDingDisk,
      };
      const res = await fnMap[selectType.value](); //res是图片等等地址

      this.outSideSelectHandler(res); //调用onselect方法
    },

    handleSuccess(res, callback) {
      this.$showLoading();
      let tempFilePaths;
      let arr = [];
      switch (res.selectType.value) {
        case "photo":
          tempFilePaths = res.files;
          tempFilePaths.forEach((item) => {
            arr.push({
              fileType:
                res.selectType.value === "photo"
                  ? "image"
                  : res.selectType.value,
              file_type: item.fileType,
              path: item.path,
              file_name: item.fileName || `用印文件.${item.fileType}`,//钉钉上传图片成功的返回值无name字段
              file_size: item.size || "",
            });
          });
          break;
        case "space":
          tempFilePaths = res.data;
          tempFilePaths.forEach((item) => {
            arr.push({
              selectType: res.selectType.value, //'space'
              fileType: res.type,
              // file_type:
              //   item.fileName.split(".")[item.fileName.split(".").length - 1],
              file_type: item.fileType,
              file_id: item.fileId,
              space_id: item.spaceId,
              file_name: item.fileName,
              file_size: item.fileSize || "",
            });
          });
          break;
        case "video":
          tempFilePaths = res.filePath;
          arr.push({
            fileType: res.selectType.value,
            path: res.filePath,
            file_size: res.size,
            file_height: res.height,
            file_width: res.width,
            file_name:
              res.fileName ||
              res.filePath.split(".")[res.filePath.split(".").length - 1],
            file_duration: res.duration,
          });
          break;
      }
      callback(arr);
      this.visible = false;
    },

    // 预览钉钉 钉盘上传文件
    handlePreviewArea(listData) {
      dd.previewFileInDingTalk({
        spaceId: listData.data[0].spaceId,
        fileId: listData.data[0].fileId,
        fileName: listData.data[0].fileName,
        fileType: listData.data[0].fileType,
        fileSize: listData.data[0].fileSize,
        success: (res) => {
          console.log(res, "预览成功");
        },
        fail: (err) => {
          console.log(err, "预览失败");
        },
      });
    },
  },
};
</script>

<style lang="less" scoped>
.optionsContent {
  flex-grow: 1;
  overflow: auto;

  .optionItem {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-left: 32rpx;
    height: 112rpx;

    .paddingArea {
      height: 112rpx;
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: space-between;
      border-bottom: 0.6px solid #e7e7e7;
    }

    .optionValue {
      flex: 1;
      width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      font-size: 32rpx;
      color: rgba(0, 0, 0, 0.9);
      margin-right: 20rpx;
    }
  }
}
</style>

选择文件的使用

   // 选择文件
    async handleChooseFile() {
      let res;
      let pathMap = "OSS_SEAL_FILE_PATH";
      let _this = this;

      // 钉钉上传文件图片要成功时的回调
      function callback(arr) {
        uploadFile(arr, pathMap, (resp) => {
          resp.forEach((item) => {
            (item.attach_url = encodeURI(item.fileKey)), //encode转化
              (item.attach_name = item.file_name);
          });
          // 关闭loading状态
          _this.$closeLoading();
          _this.$emit(
            "changeValue",
            _this.data.tmpValue.concat(resp),
            "",
            true
          );
        });
      }

      let options = {
        // #ifdef MP-ALIPAY
        onSelect(_res) {
          res = _res;
          _this.spaceList = _res;
          if (!_this.limit) {
            this.handleSuccess(res, callback);
            return;
          }
          //选择上传图片
          let size;
          if (res.files) {
            size = res.files.every((item) => {
              return item.size <= 1024 * 1000 * _this.limit;
            });
          }

          // 判断图片大小
          if (!size) {
            dd.showToast({
              type: "fail",
              content: "上传图片不能大于10M",
            });
          } else {
            this.handleSuccess(res, callback);
          }
        },
        // #endif

        // #ifdef MP-WEIXIN
        success: (res) => {
          if (!this.limit) {
            this.handleSuccess(res);
            return;
          }
          let size = res.tempFiles.every((item) => {
            //限制上传图片大小为2M,所有图片少于2M才能上传
            return item.size <= 1024 * 1000 * this.limit;
          });
          if (!size) {
            wx.showToast({
              title: "上传图片不能大于10M!",
              icon: "none",
            });
          } else {
            this.handleSuccess(res);
          }
        },
        // #endif
        count: 9,
        type: "all", //暂时不考虑钉盘接入
        types: ["file", "space"], //types是钉盘上传支持的类型
      };

      chooseFile(options);

       // #endif
    },

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值