<template>
  <view class="upload-page" v-if="show">
    <template v-if="custom">
      <slot name="top"></slot>
      <view @tap="chooseVideoImage">
        <slot></slot>
      </view>
      <slot name="bottom"></slot>
    </template>
    <view class="flex" v-else>
      <view class="flex justify-center align-center upload" @tap="chooseVideoImage">
        <!-- 自定义上传图片按钮样式 -->
        <slot>
          <view class="flex flex-direction justify-center align-center">
            <u--image :src="uploadIcon" width="56rpx" height="56rpx" />
            <view class="u-m-t-16 text-tip u-font-14" v-if="fileLen > 0"
              >{{ fileLen }}/{{ limit }}</view
            >
            <view class="u-m-t-16 text-tip u-font-14" v-else>上传图片</view>
          </view>
        </slot>
      </view>

      <scroll-view scroll-x enable-flex class="navscroll u-m-l-20">
        <!-- 图片 -->
        <template v-for="(val, index) in imageList">
          <view class="upload-item" :key="index">
            <view class="icon-cuo" @tap="delect(index)">
              <u-icon name="close" size="28rpx" color="white"></u-icon>
            </view>
            <image
              class="img"
              :src="val.url"
              :data-src="val.url"
              mode="aspectFill"
              @tap="previewImage"
            />
          </view>
        </template>

        <!-- 视频 -->
        <view class="upload-item" v-for="(val, index) in videoList" :key="index">
          <view class="icon-cuo" @tap="delectVideo(index)">
            <u-icon name="close" size="28rpx" color="white"></u-icon>
          </view>
          <video :src="val.url" class="video"></video>
        </view>
      </scroll-view>
    </view>

    <view v-for="(item, index) in tempFilePaths" :key="index" class="tempFile">
      <canvas
        :canvas-id="item.key"
        :style="{
          width: item.width ? `${item.width || 0}px` : '100%',
          height: item.height ? `${item.height || 0}px` : '100%',
        }"
      ></canvas>
    </view>
  </view>
</template>

<script>
import { UPLOAD_IMG_URL } from '@/common/api.js';
export default {
  props: {
    // 回显数据
    option: {
      type: Object,
      default: {
        imageList: [], // 图片资源
        videoList: [], // 视频资源
      },
    },
    // 上传类型
    type: {
      type: Array,
      default: () => ['image', 'video'], // 组件展示类型   image图片    video视频
    },
    // 最大允许上传个数
    limit: {
      type: Number,
      default: 9,
    },
    // 上传图片大于4M进行压缩
    maxSize: {
      type: Number,
      default: () => 1024 * 1024 * 4,
    },
    // 是否显示操作视图
    isView: {
      type: Boolean,
      default: false,
    },
    // 是否压缩图片
    isCompress: {
      type: Boolean,
      default: true,
    },
    // 是否自定义样式
    custom: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      tempFilePaths: [],

      show: true,
      upload_url: UPLOAD_IMG_URL, // 上传地址

      imageList: [], //图片
      videoList: [], //视频存放
      cameraIndex: 0,
      cameraList: [
        {
          value: 'back',
          name: '后置摄像头',
          checked: 'true',
        },
        {
          value: 'front',
          name: '前置摄像头',
        },
      ],
    };
  },
  watch: {
    option: {
      deep: true,
      immediate: true,
      handler(val) {
        if (val.imageList !== undefined) {
          this.imageList = val.imageList;
        }
        if (val.videoList !== undefined) {
          this.videoList = val.videoList;
        }
      },
    },
  },
  computed: {
    fileLen() {
      return this.imageList.length + this.videoList.length;
    },
    VideoOfImagesShow() {
      let show = true;
      if (this.fileLen >= this.limit) {
        show = false;
      }
      return show;
    },
    uploadIcon() {
      if (this.VideoOfImagesShow) {
        return '/static/public/upload-icon.svg';
      }
      return '/static/public/upload-disabled.svg';
    },
    Token() {
      return uni.getStorageSync(this.$store.STORE.TOKEN) || '';
    },
  },
  methods: {
    refersh(val) {
      if (val.imageList !== undefined) {
        this.imageList = val.imageList;
      }
      if (val.videoList !== undefined) {
        this.videoList = val.videoList;
      }
      this.show = false;
      this.$nextTick(() => {
        this.show = true;
      });
    },
    chooseVideoImage() {
      // // 图片选满已在进行选择图片
      if (this.fileLen >= this.limit) return;
      if (this.type.length >= 2) {
        uni.showActionSheet({
          title: '选择上传类型',
          itemList: ['图片', '视频'],
          success: res => {
            if (res.tapIndex == 0) {
              this.chooseImages();
            } else {
              this.chooseVideo();
            }
          },
        });
      } else {
        if (this.type.length == 1) {
          // 只上传图片
          if (this.type.includes('image')) {
            this.chooseImages();
          }
          // 只上传视频
          else if (this.type.includes('video')) {
            this.chooseVideo();
          }
        }
      }
    },
    // 上传图片
    chooseImages() {
      let _this = this;
      let len = this.limit - this.fileLen; // 可选文件数量
      uni.chooseImage({
        count: len, //可以选择文件长度
        sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
        sourceType: ['album', 'camera'], //从相册选择
        success: res => {
          uni.showLoading({
            title: '图片上传中',
            mask: true,
          });
          res.tempFilePaths.forEach((filePath, index) => {
            // 图片大小
            const imgSize =
              res.tempFiles[index] && res.tempFiles[index].size ? res.tempFiles[index].size : 0;

            if (imgSize > this.maxSize && this.isCompress) {
              console.log(
                '图片大小 == ',
                parseInt(imgSize / 1024) + 'KB',
                parseInt(imgSize / 1024 / 1024) + 'M',
              );
              _this.compressImage(filePath, index);
              // setTimeout(() => {
              // 	uni.hideLoading();
              // 	uni.showToast({
              // 		title: '上传图片太大，不能超过2M',
              // 		icon: 'none'
              // 	});
              // }, 1000);
            } else {
              _this.uploadimage(filePath, index);
            }
          });
        },
      });
    },
    // 选择视频
    chooseVideo() {
      let _this = this;
      // 上传视频
      uni.chooseVideo({
        maxDuration: 60,
        count: 1,
        camera: _this.cameraList[_this.cameraIndex].value,
        sourceType: ['album'],
        compressed: false, //是否压缩所选的视频源文件，默认值为 true，需要压缩。
        success: res => {
          let filePath = res.tempFilePath;
          // 大于10M压缩
          console.log('视频压缩前大小---', parseInt(res.size / 1024 / 1024) + 'M');
          if (res.size / 1024 > 1025 * 10 && this.isCompress) {
            // _this.videoCompress(filePath);
          } else {
            _this.uploadVideo(filePath);
          }
        },
      });
    },

    // 上传图片
    uploadimage(filePath, index) {
      console.log(filePath);
      uni.hideLoading();
      uni.showLoading({
        title: '图片上传中',
        mask: true,
      });
      let _this = this;
      uni.uploadFile({
        url: _this.upload_url,
        method: 'POST',
        name: 'file',
        filePath: filePath,
        header: {
          token: this.Token,
          Model: 'development',
        },
        success: res => {
          const { data } = JSON.parse(res.data); //微信和头条支持
          if (data) {
            // console.log('uploadFile === ', data);
            let obj = data || {};
            if (obj.sFid) {
              obj['id'] = obj.sFid;
            }
            if (obj.staticPath) {
              obj['url'] = obj.staticPath;
            }
            _this.imageList.push(obj);
            _this.changeFile();
          } else {
            uni.showToast({
              title: '上传失败',
              icon: 'none',
            });
          }
        },
        fail: () => {
          setTimeout(() => {
            uni.hideLoading();
            uni.showToast({
              title: '图片上传失败',
              icon: 'none',
            });
          }, 1000);
        },
        // 接口调用结束的回调函数（调用成功、失败都会执行）
        complete: () => {
          if (index == _this.imageList.length - 1) {
            setTimeout(() => {
              uni.hideLoading();
            }, 1000);
          } else {
            setTimeout(() => {
              uni.hideLoading();
            }, 1000 * _this.imageList.length);
          }
        },
      });
    },
    // 上传视频
    uploadVideo(filePath) {
      uni.showLoading({
        title: '视频上传中',
        mask: true,
      });
      let _this = this;
      uni.uploadFile({
        url: _this.upload_url,
        method: 'POST',
        name: 'file',
        filePath: filePath,
        header: {
          token: this.Token,
          Model: 'development',
        },
        success: res => {
          const { data } = JSON.parse(res.data); //微信和头条支持
          let obj = data || {};
          if (obj.sFid) {
            obj['id'] = obj.sFid;
          }
          if (obj.staticPath) {
            obj['url'] = obj.staticPath;
          }
          _this.videoList.push(obj);
          _this.changeFile();
        },
        fail: () => {
          setTimeout(() => {
            uni.hideLoading();
            uni.showToast({
              title: '视频上传失败',
              icon: 'none',
            });
          }, 1000);
        },
        // 接口调用结束的回调函数（调用成功、失败都会执行）
        complete: () => {
          setTimeout(() => {
            uni.hideLoading();
          }, 2000);
        },
      });
    },
    changeFile() {
      this.$emit('change', {
        videoList: this.videoList,
        imageList: this.imageList,
      });
    },
    previewImage: function (e) {
      //预览图片
      let current = e.target.dataset.src;
      console.log('current == ', current);
      uni.previewImage({
        current: current,
        urls: this.imageList.map(v => v.url),
      });
    },
    delect(index) {
      uni.showModal({
        title: '提示',
        content: '是否要删除此图片?',
        success: res => {
          if (res.confirm) {
            this.imageList.splice(index, 1);
            this.changeFile();
          }
        },
      });
    },
    // base64转Blob
    base64ToBlob(base64) {
      var arr = base64.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], {
        type: mime,
      });
    },
    // 图片压缩
    compressImage(src, index) {
      let that = this;
      uni.showLoading({
        title: '图片压缩中',
      });
      var img = new Image(); //创建Image对象生成一个<img>标签
      img.src = src; //将图片路径赋给<img>标签的src
      img.onload = () => {
        //onload在图片加载成功后触发，在onload中完成压缩功能
        var h = img.height / 2; // 获取原本图片的宽高
        var w = img.width / 2; //默认按比例压缩,根据需求修改
        var canvas = document.createElement('canvas'); //创建画布
        var ctx = canvas.getContext('2d'); //设置为2d效果
        var width = document.createAttribute('width'); //创建属性节点
        width.nodeValue = w; //设置属性值
        var height = document.createAttribute('height');
        height.nodeValue = h;
        canvas.setAttributeNode(width); //设置画布宽高
        canvas.setAttributeNode(height);
        ctx.drawImage(img, 0, 0, w, h); //将图片贴到画布上
        //img:图片 0,0:粘贴的位置 w,h:粘贴图片的大小
        var base64 = canvas.toDataURL('image/png', 1);
        // //'image/png':压缩返回图片的类型 scale:图片质量
        // //如果要base64的流，可以直接将结果返回了
        // canvas = null; //清除画布
        // var blob = this.base64ToBlob(base64); //需要二进制流调用该方法拿到
        // let blobUrl = window.URL.createObjectURL(blob); //blob地址
        // console.log("blobUrl == ", blobUrl);
        // console.log("base64 == ", base64);
        uni.getFileInfo({
          filePath: base64,
          success(res) {
            console.log('getFileInfo == ', res);
            const imgSize = res.size / 1024;
            console.log(
              '压缩后大小---',
              parseInt(imgSize / 1024) + 'KB',
              parseInt(imgSize / 1024 / 1024) + 'M',
            );
            // 压缩后的大小仍大于所设大小继续压缩
            if (imgSize > this.maxSize) {
              // 图片太大，继续压缩
              console.log('----- 图片太大，继续压缩  ------');
              that.compressImage(base64, index);
            } else {
              that.uploadimage(base64, index);
            }
          },
        });
      };
      // uni.getImageInfo({
      // 	src,
      // 	success(res) {
      // 		let canvasWidth = res.width; //图片原始长宽
      // 		let canvasHeight = res.height;

      // 		let scale1 = 2;
      // 		let scale2 = 2;
      // 		if (res.width > res.height) {
      // 			while (canvasWidth > 1024) {
      // 				canvasWidth = Math.trunc(res.width / scale1);
      // 				scale1++;
      // 			}
      // 			while (canvasHeight > 750) {
      // 				canvasHeight = Math.trunc(res.height / scale2);
      // 				scale2++;
      // 			}
      // 		} else if (res.width == res.height) {
      // 			while (canvasWidth > 750) {
      // 				canvasWidth = Math.trunc(res.width / scale1);
      // 				canvasHeight = Math.trunc(res.height / scale1);
      // 			}
      // 		} else {
      // 			while (canvasWidth > 750) {
      // 				canvasWidth = Math.trunc(res.width / scale1);
      // 				scale1++;
      // 			}
      // 			while (canvasHeight > 1024) {
      // 				canvasHeight = Math.trunc(res.height / scale2);
      // 				scale2++;
      // 			}
      // 		}
      // 		let cId = `myCanvas_${index + 1}`;
      // 		let info = that.tempFilePaths.find((v) => v.key == index);
      // 		if (info) {
      // 			cId = info.key;
      // 		} else {
      // 			that.tempFilePaths.push({
      // 				key: cId,
      // 				url: src,
      // 				width: canvasWidth,
      // 				height: canvasHeight
      // 			});
      // 		}
      // 		console.log('that.tempFilePaths == ', that.tempFilePaths);

      // 		let ctx = uni.createCanvasContext(cId, that);
      // 		console.log('ctx == ', ctx);
      // 		// ctx.drawImage(res.path, 0, 0, canvasWidth, canvasHeight);
      // 		ctx.drawImage(src, 0, 0, canvasWidth, canvasHeight);

      // 		setTimeout(() => {
      // 			ctx.draw(
      // 				false,
      // 				setTimeout(() => {
      // 					console.log('cId == ', cId);
      // 					uni.canvasToTempFilePath({
      // 							canvasId: cId,
      // 							fileType: 'jpg',
      // 							success: function(res) {
      // 								// res图片临时路径
      // 								uni.getFileInfo({
      // 									filePath: res
      // 										.tempFilePath,
      // 									success(ress) {
      // 										// console.log(ress)    // 图片大小
      // 										const imgSize =
      // 											ress.size /
      // 											1024;
      // 										console.log(
      // 											'压缩后大小---',
      // 											parseInt(
      // 												imgSize /
      // 												1024) +
      // 											'KB',
      // 											parseInt(
      // 												imgSize /
      // 												1024 /
      // 												1024) +
      // 											'M');
      // 										// 压缩后的大小仍大于所设大小继续压缩
      // 										if (imgSize > this
      // 											.maxSize) {
      // 											// 图片太大，继续压缩
      // 											console.log(
      // 												'----- 图片太大，继续压缩  ------'
      // 											);
      // 											that.compressImage(
      // 												res
      // 												.tempFilePath,
      // 												index);
      // 										} else {
      // 											uni.hideLoading();
      // 											that.uploadimage(
      // 												res
      // 												.tempFilePath
      // 											);
      // 										}
      // 									}
      // 								});
      // 							},
      // 							fail: function(res) {
      // 								console.log('图片压缩失败 == ', res
      // 									.errMsg);
      // 								uni.hideLoading();
      // 								uni.showToast({
      // 										title: '图片压缩失败',
      // 										icon: 'none'
      // 									},
      // 									2000
      // 								);
      // 							}
      // 						},
      // 						that
      // 					); // 这里是新增的this，只有在微信小程序中需要加入，不然会报错
      // 				}, 1000)
      // 			);
      // 			//留一定的时间绘制canvas
      // 		}, 1000);
      // 	},
      // 	fail(err) {
      // 		console.log(err.errMsg);
      // 		uni.hideLoading();
      // 		uni.showToast({
      // 				title: '图片压缩失败!',
      // 				icon: 'none'
      // 			},
      // 			2000
      // 		);
      // 	}
      // });
    },
    delectVideo(index) {
      uni.showModal({
        title: '提示',
        content: '是否要删除此视频?',
        success: res => {
          if (res.confirm) {
            this.videoList.splice(index, 1);
            this.changeFile();
          }
        },
      });
    },
    // 视频压缩 微信开发者工具需要ffepeg 在D盘
    videoCompress(tempFilePath) {
      uni.showLoading({
        title: '视频压缩中',
      });
      let that = this;
      uni.compressVideo(
        {
          src: tempFilePath,
          quality: 'high', //'low':低，'medium':中，'high':高
          success: function (res) {
            // 压缩后的大小 大于10MB,继续压缩
            console.log('压缩后大小---', res.size / 1024 / 1024 + 'M');
            if (res.size / 1024 > 1025 * 10) {
              console.log('------ 视频太大，再次压缩 ----- ');
              that.videoCompress(res.tempFilePath);
            } else {
              that.uploadVideo(res.tempFilePath);
            }
          },
          fail: function (err) {
            console.log(err);
            uni.showToast(
              {
                title: '视频压缩失败',
                icon: 'none',
              },
              2000,
            );
          },
          complete: () => {
            setTimeout(() => {
              uni.hideLoading();
            }, 2000);
          },
        },
        this,
      );
    },
  },
};
</script>

<style lang="scss">
.upload-page {
  .upload {
    width: 160rpx !important;
    height: 160rpx !important;
    min-width: 160rpx !important;
    background: #f7f8fa;
    border: 1px dashed #e5e6eb;
    border-radius: 10px;
  }

  .navscroll {
    white-space: nowrap; // 必须要这个属性，否者不能出现横线滚动
    height: 160rpx;
    width: calc(100vw - 110px);
    display: flex;
  }

  .upload-item {
    width: 160rpx;
    min-width: 160rpx !important;
    height: 160rpx;
    border: 1px solid #eee;
    border-radius: 10px;
    position: relative;
    margin-right: 20rpx;
    background: #f7f8fa;
    display: inline-block;

    .icon-cuo {
      height: 36rpx;
      width: 36rpx;
      position: absolute;
      top: 0;
      right: 0;
      z-index: 999;
      background: rgba(0, 0, 0, 0.8);
      border-radius: 4px;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .video {
      border-radius: 10px;
    }

    .video,
    .img {
      width: 100%;
      height: 100%;
      border-radius: 10px;
    }
  }

  .tempFile {
    visibility: hidden;
    position: absolute;
    z-index: -1;
    left: -10000rpx;
    top: -10000rpx;
  }
}
</style>