You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							335 lines
						
					
					
						
							7.6 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							335 lines
						
					
					
						
							7.6 KiB
						
					
					
				
								<template>
							 | 
						|
								  <view class="uni-file-picker__files">
							 | 
						|
								    <view v-if="!readonly" class="files-button" @click="choose">
							 | 
						|
								      <slot></slot>
							 | 
						|
								    </view>
							 | 
						|
								    <!-- :class="{'is-text-box':showType === 'list'}" -->
							 | 
						|
								    <view v-if="list.length > 0" class="uni-file-picker__lists is-text-box" :style="borderStyle">
							 | 
						|
								      <!-- ,'is-list-card':showType === 'list-card' -->
							 | 
						|
								
							 | 
						|
								      <view
							 | 
						|
								        class="uni-file-picker__lists-box"
							 | 
						|
								        v-for="(item, index) in list"
							 | 
						|
								        :key="index"
							 | 
						|
								        :class="{
							 | 
						|
								          'files-border': index !== 0 && styles.dividline,
							 | 
						|
								        }"
							 | 
						|
								        :style="index !== 0 && styles.dividline && borderLineStyle"
							 | 
						|
								      >
							 | 
						|
								        <view class="uni-file-picker__item">
							 | 
						|
								          <!-- :class="{'is-text-image':showType === 'list'}" -->
							 | 
						|
								          <!-- 	<view class="files__image is-text-image">
							 | 
						|
														<image class="header-image" :src="item.logo" mode="aspectFit"></image>
							 | 
						|
													</view> -->
							 | 
						|
								          <view class="files__name">{{ item.name }}</view>
							 | 
						|
								          <view v-if="delIcon && !readonly" class="icon-del-box icon-files" @click="delFile(index)">
							 | 
						|
								            <view class="icon-del icon-files"></view>
							 | 
						|
								            <view class="icon-del rotate"></view>
							 | 
						|
								          </view>
							 | 
						|
								        </view>
							 | 
						|
								        <view
							 | 
						|
								          v-if="(item.progress && item.progress !== 100) || item.progress === 0"
							 | 
						|
								          class="file-picker__progress"
							 | 
						|
								        >
							 | 
						|
								          <progress
							 | 
						|
								            class="file-picker__progress-item"
							 | 
						|
								            :percent="item.progress === -1 ? 0 : item.progress"
							 | 
						|
								            stroke-width="4"
							 | 
						|
								            :backgroundColor="item.errMsg ? '#ff5a5f' : '#EBEBEB'"
							 | 
						|
								          />
							 | 
						|
								        </view>
							 | 
						|
								        <view
							 | 
						|
								          v-if="item.status === 'error'"
							 | 
						|
								          class="file-picker__mask"
							 | 
						|
								          @click.stop="uploadFiles(item, index)"
							 | 
						|
								        >
							 | 
						|
								          点击重试
							 | 
						|
								        </view>
							 | 
						|
								      </view>
							 | 
						|
								    </view>
							 | 
						|
								  </view>
							 | 
						|
								</template>
							 | 
						|
								
							 | 
						|
								<script>
							 | 
						|
								  export default {
							 | 
						|
								    name: 'uploadFile',
							 | 
						|
								    emits: ['uploadFiles', 'choose', 'delFile'],
							 | 
						|
								    props: {
							 | 
						|
								      filesList: {
							 | 
						|
								        type: Array,
							 | 
						|
								        default() {
							 | 
						|
								          return [];
							 | 
						|
								        },
							 | 
						|
								      },
							 | 
						|
								      delIcon: {
							 | 
						|
								        type: Boolean,
							 | 
						|
								        default: true,
							 | 
						|
								      },
							 | 
						|
								      limit: {
							 | 
						|
								        type: [Number, String],
							 | 
						|
								        default: 9,
							 | 
						|
								      },
							 | 
						|
								      showType: {
							 | 
						|
								        type: String,
							 | 
						|
								        default: '',
							 | 
						|
								      },
							 | 
						|
								      listStyles: {
							 | 
						|
								        type: Object,
							 | 
						|
								        default() {
							 | 
						|
								          return {
							 | 
						|
								            // 是否显示边框
							 | 
						|
								            border: true,
							 | 
						|
								            // 是否显示分隔线
							 | 
						|
								            dividline: true,
							 | 
						|
								            // 线条样式
							 | 
						|
								            borderStyle: {},
							 | 
						|
								          };
							 | 
						|
								        },
							 | 
						|
								      },
							 | 
						|
								      readonly: {
							 | 
						|
								        type: Boolean,
							 | 
						|
								        default: false,
							 | 
						|
								      },
							 | 
						|
								    },
							 | 
						|
								    computed: {
							 | 
						|
								      list() {
							 | 
						|
								        let files = [];
							 | 
						|
								        this.filesList.forEach((v) => {
							 | 
						|
								          files.push(v);
							 | 
						|
								        });
							 | 
						|
								        return files;
							 | 
						|
								      },
							 | 
						|
								      styles() {
							 | 
						|
								        let styles = {
							 | 
						|
								          border: true,
							 | 
						|
								          dividline: true,
							 | 
						|
								          'border-style': {},
							 | 
						|
								        };
							 | 
						|
								        return Object.assign(styles, this.listStyles);
							 | 
						|
								      },
							 | 
						|
								      borderStyle() {
							 | 
						|
								        let { borderStyle, border } = this.styles;
							 | 
						|
								        let obj = {};
							 | 
						|
								        if (!border) {
							 | 
						|
								          obj.border = 'none';
							 | 
						|
								        } else {
							 | 
						|
								          let width = (borderStyle && borderStyle.width) || 1;
							 | 
						|
								          width = this.value2px(width);
							 | 
						|
								          let radius = (borderStyle && borderStyle.radius) || 5;
							 | 
						|
								          radius = this.value2px(radius);
							 | 
						|
								          obj = {
							 | 
						|
								            'border-width': width,
							 | 
						|
								            'border-style': (borderStyle && borderStyle.style) || 'solid',
							 | 
						|
								            'border-color': (borderStyle && borderStyle.color) || '#eee',
							 | 
						|
								            'border-radius': radius,
							 | 
						|
								          };
							 | 
						|
								        }
							 | 
						|
								        let classles = '';
							 | 
						|
								        for (let i in obj) {
							 | 
						|
								          classles += `${i}:${obj[i]};`;
							 | 
						|
								        }
							 | 
						|
								        return classles;
							 | 
						|
								      },
							 | 
						|
								      borderLineStyle() {
							 | 
						|
								        let obj = {};
							 | 
						|
								        let { borderStyle } = this.styles;
							 | 
						|
								        if (borderStyle && borderStyle.color) {
							 | 
						|
								          obj['border-color'] = borderStyle.color;
							 | 
						|
								        }
							 | 
						|
								        if (borderStyle && borderStyle.width) {
							 | 
						|
								          let width = (borderStyle && borderStyle.width) || 1;
							 | 
						|
								          let style = (borderStyle && borderStyle.style) || 0;
							 | 
						|
								          if (typeof width === 'number') {
							 | 
						|
								            width += 'px';
							 | 
						|
								          } else {
							 | 
						|
								            width = width.indexOf('px') ? width : width + 'px';
							 | 
						|
								          }
							 | 
						|
								          obj['border-width'] = width;
							 | 
						|
								
							 | 
						|
								          if (typeof style === 'number') {
							 | 
						|
								            style += 'px';
							 | 
						|
								          } else {
							 | 
						|
								            style = style.indexOf('px') ? style : style + 'px';
							 | 
						|
								          }
							 | 
						|
								          obj['border-top-style'] = style;
							 | 
						|
								        }
							 | 
						|
								        let classles = '';
							 | 
						|
								        for (let i in obj) {
							 | 
						|
								          classles += `${i}:${obj[i]};`;
							 | 
						|
								        }
							 | 
						|
								        return classles;
							 | 
						|
								      },
							 | 
						|
								    },
							 | 
						|
								
							 | 
						|
								    methods: {
							 | 
						|
								      uploadFiles(item, index) {
							 | 
						|
								        this.$emit('uploadFiles', {
							 | 
						|
								          item,
							 | 
						|
								          index,
							 | 
						|
								        });
							 | 
						|
								      },
							 | 
						|
								      choose() {
							 | 
						|
								        this.$emit('choose');
							 | 
						|
								      },
							 | 
						|
								      delFile(index) {
							 | 
						|
								        this.$emit('delFile', index);
							 | 
						|
								      },
							 | 
						|
								      value2px(value) {
							 | 
						|
								        if (typeof value === 'number') {
							 | 
						|
								          value += 'px';
							 | 
						|
								        } else {
							 | 
						|
								          value = value.indexOf('px') !== -1 ? value : value + 'px';
							 | 
						|
								        }
							 | 
						|
								        return value;
							 | 
						|
								      },
							 | 
						|
								    },
							 | 
						|
								  };
							 | 
						|
								</script>
							 | 
						|
								
							 | 
						|
								<style lang="scss">
							 | 
						|
								  .uni-file-picker__files {
							 | 
						|
								    /* #ifndef APP-NVUE */
							 | 
						|
								    display: flex;
							 | 
						|
								    /* #endif */
							 | 
						|
								    flex-direction: column;
							 | 
						|
								    justify-content: flex-start;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .files-button {
							 | 
						|
								    // border: 1px red solid;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .uni-file-picker__lists {
							 | 
						|
								    position: relative;
							 | 
						|
								    margin-top: 5px;
							 | 
						|
								    overflow: hidden;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .file-picker__mask {
							 | 
						|
								    /* #ifndef APP-NVUE */
							 | 
						|
								    display: flex;
							 | 
						|
								    /* #endif */
							 | 
						|
								    justify-content: center;
							 | 
						|
								    align-items: center;
							 | 
						|
								    position: absolute;
							 | 
						|
								    right: 0;
							 | 
						|
								    top: 0;
							 | 
						|
								    bottom: 0;
							 | 
						|
								    left: 0;
							 | 
						|
								    color: #fff;
							 | 
						|
								    font-size: 14px;
							 | 
						|
								    background-color: rgba(0, 0, 0, 0.4);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .uni-file-picker__lists-box {
							 | 
						|
								    position: relative;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .uni-file-picker__item {
							 | 
						|
								    /* #ifndef APP-NVUE */
							 | 
						|
								    display: flex;
							 | 
						|
								    /* #endif */
							 | 
						|
								    align-items: center;
							 | 
						|
								    padding: 8px 10px;
							 | 
						|
								    padding-right: 5px;
							 | 
						|
								    padding-left: 10px;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .files-border {
							 | 
						|
								    border-top: 1px #eee solid;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .files__name {
							 | 
						|
								    flex: 1;
							 | 
						|
								    font-size: 14px;
							 | 
						|
								    color: #666;
							 | 
						|
								    margin-right: 25px;
							 | 
						|
								    /* #ifndef APP-NVUE */
							 | 
						|
								    word-break: break-all;
							 | 
						|
								    word-wrap: break-word;
							 | 
						|
								    /* #endif */
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .icon-files {
							 | 
						|
								    /* #ifndef APP-NVUE */
							 | 
						|
								    position: static;
							 | 
						|
								    background-color: initial;
							 | 
						|
								    /* #endif */
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  // .icon-files .icon-del {
							 | 
						|
								  // 	background-color: #333;
							 | 
						|
								  // 	width: 12px;
							 | 
						|
								  // 	height: 1px;
							 | 
						|
								  // }
							 | 
						|
								
							 | 
						|
								  .is-list-card {
							 | 
						|
								    border: 1px #eee solid;
							 | 
						|
								    margin-bottom: 5px;
							 | 
						|
								    border-radius: 5px;
							 | 
						|
								    box-shadow: 0 0 2px 0px rgba(0, 0, 0, 0.1);
							 | 
						|
								    padding: 5px;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .files__image {
							 | 
						|
								    width: 40px;
							 | 
						|
								    height: 40px;
							 | 
						|
								    margin-right: 10px;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .header-image {
							 | 
						|
								    width: 100%;
							 | 
						|
								    height: 100%;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .is-text-box {
							 | 
						|
								    border: 1px #eee solid;
							 | 
						|
								    border-radius: 5px;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .is-text-image {
							 | 
						|
								    width: 25px;
							 | 
						|
								    height: 25px;
							 | 
						|
								    margin-left: 5px;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .rotate {
							 | 
						|
								    position: absolute;
							 | 
						|
								    transform: rotate(90deg);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .icon-del-box {
							 | 
						|
								    /* #ifndef APP-NVUE */
							 | 
						|
								    display: flex;
							 | 
						|
								    margin: auto 0;
							 | 
						|
								    /* #endif */
							 | 
						|
								    align-items: center;
							 | 
						|
								    justify-content: center;
							 | 
						|
								    position: absolute;
							 | 
						|
								    top: 0px;
							 | 
						|
								    bottom: 0;
							 | 
						|
								    right: 5px;
							 | 
						|
								    height: 26px;
							 | 
						|
								    width: 26px;
							 | 
						|
								    // border-radius: 50%;
							 | 
						|
								    // background-color: rgba(0, 0, 0, 0.5);
							 | 
						|
								    z-index: 2;
							 | 
						|
								    transform: rotate(-45deg);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .icon-del {
							 | 
						|
								    width: 15px;
							 | 
						|
								    height: 1px;
							 | 
						|
								    background-color: #333;
							 | 
						|
								    // border-radius: 1px;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* #ifdef H5 */
							 | 
						|
								  @media all and (min-width: 768px) {
							 | 
						|
								    .uni-file-picker__files {
							 | 
						|
								      max-width: 375px;
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* #endif */
							 | 
						|
								</style>
							 |