riku
2026-04-02 3282e95db0207ee133d1e98d9771dec9d83b0fc4
miniprogram_npm/tdesign-miniprogram/upload/upload.wxml
@@ -1,95 +1 @@
<wxs src="../common/utils.wxs" module="_" />
<wxs src="./upload.wxs" module="this" />
<view style="{{_._style([style, customStyle])}}" class="{{classPrefix}} class {{prefix}}-class">
  <t-grid gutter="{{gutter}}" border="{{false}}" align="center" column="{{column}}">
    <!-- 图片/视频 -->
    <t-grid-item
      wx:for="{{customFiles}}"
      wx:key="index"
      wx:for-item="file"
      t-class="{{classPrefix}}__grid {{classPrefix}}__grid-file"
      t-class-content="{{classPrefix}}__grid-content"
      aria-role="presentation"
    >
      <view
        class="{{classPrefix}}__wrapper"
        style="{{gridItemStyle}}"
        aria-role="{{ariaRole || this.getWrapperAriaRole(file)}}"
        aria-label="{{ariaLabel || this.getWrapperAriaLabel(file)}}"
      >
        <t-image
          wx:if="{{file.type !== 'video'}}"
          data-file="{{file}}"
          bind:tap="onProofTap"
          data-index="{{index}}"
          t-class="{{classPrefix}}__thumbnail"
          style="{{imageProps.style || ''}}"
          src="{{file.url}}"
          mode="{{imageProps.mode || 'aspectFill'}}"
          error="{{imageProps.error || 'default'}}"
          lazy="{{imageProps.lazy || false}}"
          loading="{{imageProps.loading || 'default'}}"
          shape="{{imageProps.shape || 'round'}}"
          webp="{{imageProps.webp || false}}"
          showMenuByLongpress="{{imageProps.showMenuByLongpress || false}}"
        />
        <video
          data-file="{{file}}"
          bind:tap="onFileClick"
          wx:if="{{file.type === 'video'}}"
          class="{{classPrefix}}__thumbnail"
          src="{{file.url}}"
          controls
          autoplay="{{false}}"
          objectFit="contain"
        />
        <!-- 失败重试 -->
        <view
          data-index="{{index}}"
          wx:if="{{file.status && file.status != 'done'}}"
          class="{{classPrefix}}__progress-mask"
          data-file="{{file}}"
          bind:tap="onFileClick"
        >
          <block wx:if="{{file.status == 'loading'}}">
            <t-icon t-class="{{classPrefix}}__progress-loading" name="loading" size="24" aria-hidden />
            <view class="{{classPrefix}}__progress-text">{{file.percent ? file.percent + '%' : '上传中...'}}</view>
          </block>
          <t-icon wx:else name="{{file.status == 'reload' ? 'refresh' : 'close-circle'}}" size="24" aria-hidden />
          <view wx:if="{{file.status == 'reload' || file.status == 'failed'}}" class="{{classPrefix}}__progress-text">
            {{file.status == 'reload' ? '重新上传' : '上传失败'}}
          </view>
        </view>
      </view>
      <!-- 删除 -->
      <view
        class="{{classPrefix}}__close-btn hotspot-expanded"
        bindtap="onDelete"
        data-index="{{index}}"
        aria-role="button"
        aria-label="删除"
      >
        <t-icon name="close" size="16" color="#fff" />
      </view>
    </t-grid-item>
    <!-- 添加 -->
    <t-grid-item
      wx:if="{{customLimit > 0}}"
      t-class="{{classPrefix}}__grid"
      t-class-content="{{classPrefix}}__grid-content"
      bindclick="onAddTap"
      aria-label="上传"
    >
      <view class="{{classPrefix}}__wrapper" style="{{gridItemStyle}}">
        <slot name="add-content" />
        <block wx:if="{{addContent}}">{{addContent}}</block>
        <view wx:else class="{{classPrefix}}__add-icon">
          <t-icon name="add" />
        </view>
      </view>
    </t-grid-item>
  </t-grid>
</view>
<wxs src="../common/utils.wxs" module="_"/><wxs src="./upload.wxs" module="_this"/><wxs src="./drag.wxs" module="handler"/><view style="{{_._style([style, customStyle])}}" class="{{classPrefix}} class {{prefix}}-class"><t-grid gutter="{{gutter}}" border="{{false}}" align="center" column="{{column}}" style="{{draggable? 'overflow: visible' : ''}}"><block wx:if="{{!dragLayout}}"><t-grid-item wx:for="{{customFiles}}" wx:key="url" wx:for-item="file" t-class="{{classPrefix}}__grid {{classPrefix}}__grid-file" t-class-content="{{classPrefix}}__grid-content" aria-role="presentation"><view class="{{classPrefix}}__wrapper {{disabled? classPrefix + '__wrapper--disabled' : '' }}" style="{{gridItemStyle}}" aria-role="{{ariaRole || _this.getWrapperAriaRole(file)}}" aria-label="{{ariaLabel || _this.getWrapperAriaLabel(file)}}"><t-image wx:if="{{file.type !== 'video'}}" data-file="{{file}}" data-index="{{index}}" t-class="{{classPrefix}}__thumbnail" style="{{imageProps && imageProps.style || ''}}" src="{{ file.thumb || file.url }}" mode="{{imageProps && imageProps.mode || 'aspectFill'}}" error="{{imageProps && imageProps.error || 'default'}}" lazy="{{imageProps && imageProps.lazy || false}}" loading="{{imageProps && imageProps.loading || 'default'}}" shape="{{imageProps && imageProps.shape || 'round'}}" webp="{{imageProps && imageProps.webp || false}}" showMenuByLongpress="{{imageProps && imageProps.showMenuByLongpress || false}}" bind:tap="onPreview"/><video wx:if="{{file.type === 'video'}}" class="{{classPrefix}}__thumbnail" src="{{file.url}}" poster="{{ file.thumb }}" controls autoplay="{{false}}" objectFit="contain" data-file="{{file}}" data-index="{{index}}" bind:tap="onPreview"/><view wx:if="{{file.status && file.status != 'done'}}" class="{{classPrefix}}__progress-mask" data-index="{{index}}" data-file="{{file}}" bind:tap="onFileClick"><block wx:if="{{file.status == 'loading'}}"><t-icon t-class="{{classPrefix}}__progress-loading" name="loading" size="48rpx" aria-hidden/><view class="{{classPrefix}}__progress-text">{{file.percent ? file.percent + '%' : '上传中...'}}</view></block><t-icon wx:else name="{{file.status == 'reload' ? 'refresh' : 'close-circle'}}" size="48rpx" aria-hidden/><view wx:if="{{file.status == 'reload' || file.status == 'failed'}}" class="{{classPrefix}}__progress-text">{{file.status == 'reload' ? '重新上传' : '上传失败'}}</view></view><view wx:if="{{ _.isBoolean(file.removeBtn) ? file.removeBtn : removeBtn}}" class="{{classPrefix}}__close-btn hotspot-expanded" data-index="{{index}}" aria-role="button" aria-label="删除" bindtap="onDelete"><t-icon name="close" size="32rpx" color="#fff"/></view></view></t-grid-item><t-grid-item wx:if="{{ addBtn && customLimit > 0}}" t-class="{{classPrefix}}__grid" t-class-content="{{classPrefix}}__grid-content" aria-label="上传" bindclick="onAddTap"><view class="{{classPrefix}}__wrapper" style="{{gridItemStyle}}"><slot name="add-content"/><block wx:if="{{addContent}}">{{addContent}}</block><view wx:else class="{{classPrefix}}__add-icon {{disabled? classPrefix + '__add-icon--disabled' : '' }}"><t-icon name="add"/></view></view></t-grid-item></block><block wx:else><view class="{{classPrefix}}__drag" list="{{dragList}}" style="{{dragWrapStyle}};" dragBaseData="{{dragBaseData}}" change:list="{{handler.listObserver}}" change:dragBaseData="{{handler.baseDataObserver}}"><view class="{{classPrefix}}__drag-item" style="width: {{100 / column}}%; --td-upload-drag-transition-duration: {{transition.duration}}ms; --td-upload-drag-transition-timing-function: {{transition.timingFunction}}" wx:for="{{customFiles}}" wx:key="url" wx:for-item="file" data-index="{{index}}" bind:longpress="{{handler.longPress}}" catch:touchmove="{{dragging ? handler.touchMove : ''}}" catch:touchend="{{dragging ? handler.touchEnd : ''}}"><t-grid-item t-class="{{classPrefix}}__grid {{classPrefix}}__grid-file" t-class-content="{{classPrefix}}__grid-content" aria-role="presentation" style="width: 100%"><view class="{{classPrefix}}__wrapper {{disabled? classPrefix + '__wrapper--disabled' : '' }}" style="{{gridItemStyle}};" aria-role="{{ariaRole || _this.getWrapperAriaRole(file)}}" aria-label="{{ariaLabel || _this.getWrapperAriaLabel(file)}}"><t-image wx:if="{{file.type !== 'video'}}" data-file="{{file}}" data-index="{{index}}" t-class="{{classPrefix}}__thumbnail" style="{{imageProps && imageProps.style || ''}}" src="{{ file.thumb || file.url }}" mode="{{imageProps && imageProps.mode || 'aspectFill'}}" error="{{imageProps && imageProps.error || 'default'}}" lazy="{{imageProps && imageProps.lazy || false}}" loading="{{imageProps && imageProps.loading || 'default'}}" shape="{{imageProps && imageProps.shape || 'round'}}" webp="{{imageProps && imageProps.webp || false}}" showMenuByLongpress="{{imageProps && imageProps.showMenuByLongpress || false}}" bind:tap="onPreview"/><video wx:if="{{file.type === 'video'}}" class="{{classPrefix}}__thumbnail" src="{{file.url}}" poster="{{ file.thumb }}" controls autoplay="{{false}}" objectFit="contain" data-file="{{file}}" data-index="{{index}}" bind:tap="onPreview"/><view wx:if="{{file.status && file.status != 'done'}}" class="{{classPrefix}}__progress-mask" data-index="{{index}}" data-file="{{file}}" bind:tap="onFileClick"><block wx:if="{{file.status == 'loading'}}"><t-icon t-class="{{classPrefix}}__progress-loading" name="loading" size="48rpx" aria-hidden/><view class="{{classPrefix}}__progress-text">{{file.percent ? file.percent + '%' : '上传中...'}}</view></block><t-icon wx:else name="{{file.status == 'reload' ? 'refresh' : 'close-circle'}}" size="48rpx" aria-hidden/><view wx:if="{{file.status == 'reload' || file.status == 'failed'}}" class="{{classPrefix}}__progress-text">{{file.status == 'reload' ? '重新上传' : '上传失败'}}</view></view><view wx:if="{{ _.isBoolean(file.removeBtn) ? file.removeBtn : removeBtn}}" class="{{classPrefix}}__close-btn hotspot-expanded" data-index="{{index}}" data-url="{{file.url}}" aria-role="button" aria-label="删除" bindtap="onDelete"><t-icon name="close" size="32rpx" color="#fff"/></view></view></t-grid-item></view><view wx:if="{{addBtn && customLimit > 0}}" class="{{classPrefix}}__drag-item" style="width: {{100 / column}}%"><t-grid-item t-class="{{classPrefix}}__grid" t-class-content="{{classPrefix}}__grid-content" aria-label="上传" style="width: 100%" bindclick="onAddTap"><view class="{{classPrefix}}__wrapper" style="{{gridItemStyle}}"><slot name="add-content"/><block wx:if="{{addContent}}">{{addContent}}</block><view wx:else class="{{classPrefix}}__add-icon {{disabled? classPrefix + '__add-icon--disabled' : '' }}"><t-icon name="add"/></view></view></t-grid-item></view></view></block></t-grid></view>