<template> 
 | 
  <div class="cover-uploader-wrapper"> 
 | 
    <Uploader v-model:file-list="innerFileList"> 
 | 
      <template #extra-img="{ item }"> 
 | 
        <div class="set-cover-btn" @click="handleSetCover(item)"> 
 | 
          {{ item.isMain ? '取消封面' : '设为封面' }} 
 | 
        </div> 
 | 
      </template> 
 | 
    </Uploader> 
 | 
    <div class="system-cover-uploader-wrapper" v-if="demoCoverList.length > 0"> 
 | 
      <div class="system-cover-uploader-title">您还可以从系统中选择图片</div> 
 | 
      <div class="system-cover-uploader-list"> 
 | 
        <div 
 | 
          v-for="cover in demoCoverList" 
 | 
          :key="cover.url" 
 | 
          class="system-cover-uploader-list-item" 
 | 
          @click="handleUploadSystemCover(cover.url)" 
 | 
        > 
 | 
          <img class="system-cover-uploader-list-img" :src="cover.url" /> 
 | 
        </div> 
 | 
      </div> 
 | 
    </div> 
 | 
  </div> 
 | 
</template> 
 | 
  
 | 
<script setup lang="ts"> 
 | 
import Uploader from './Uploader.vue'; 
 | 
import { CoverItem } from './uploader'; 
 | 
import { convertApiPath2Url } from '@12333/utils'; 
 | 
  
 | 
defineOptions({ 
 | 
  name: 'CoverUploader', 
 | 
}); 
 | 
  
 | 
type Props = { 
 | 
  fileList: CoverItem[]; 
 | 
  demoCoverList?: API.CoverMsg[]; 
 | 
}; 
 | 
  
 | 
const props = withDefaults(defineProps<Props>(), { 
 | 
  demoCoverList: () => [] as API.CoverMsg[], 
 | 
}); 
 | 
  
 | 
const emit = defineEmits<{ 
 | 
  (e: 'update:fileList', list: CoverItem[]): void; 
 | 
}>(); 
 | 
  
 | 
const innerFileList = computed({ 
 | 
  get() { 
 | 
    return props.fileList; 
 | 
  }, 
 | 
  set(val) { 
 | 
    emit('update:fileList', val); 
 | 
  }, 
 | 
}); 
 | 
  
 | 
function handleUploadSystemCover(url: string) { 
 | 
  emit('update:fileList', [ 
 | 
    ...props.fileList, 
 | 
    { 
 | 
      ...(convertApiPath2Url(url) as any), 
 | 
    }, 
 | 
  ]); 
 | 
} 
 | 
  
 | 
function handleSetCover(item: CoverItem) { 
 | 
  emit( 
 | 
    'update:fileList', 
 | 
    props.fileList.map((x) => { 
 | 
      return { 
 | 
        ...x, 
 | 
        isMain: x.uid === item.uid, 
 | 
      }; 
 | 
    }) 
 | 
  ); 
 | 
} 
 | 
  
 | 
watch( 
 | 
  () => props.fileList.length, 
 | 
  (newValue, oldValue) => { 
 | 
    if (newValue !== oldValue) { 
 | 
      const index = props.fileList.findIndex((x) => x.isMain); 
 | 
      if (index < 0) { 
 | 
        handleSetCover(props.fileList[0]); 
 | 
      } 
 | 
    } 
 | 
  } 
 | 
); 
 | 
</script> 
 | 
  
 | 
<style lang="scss"> 
 | 
@import '@/styles/common.scss'; 
 | 
  
 | 
.cover-uploader-wrapper { 
 | 
  padding-top: 16px; 
 | 
  
 | 
  .nut-uploader__preview.picture { 
 | 
    .set-cover-btn { 
 | 
      width: 100%; 
 | 
      position: absolute; 
 | 
      height: 30px; 
 | 
      line-height: 30px; 
 | 
      text-align: center; 
 | 
      bottom: 0; 
 | 
      left: 0; 
 | 
      font-size: 16px; 
 | 
      background-color: rgba(#000, 0.3); 
 | 
      color: #fff; 
 | 
    } 
 | 
  } 
 | 
  
 | 
  .system-cover-uploader-wrapper { 
 | 
    margin-top: 16px; 
 | 
  
 | 
    .system-cover-uploader-title { 
 | 
      font-size: 24px; 
 | 
      color: boleGetCssVar('text-color', 'regular'); 
 | 
      margin-bottom: 10px; 
 | 
    } 
 | 
  
 | 
    .system-cover-uploader-list { 
 | 
      display: flex; 
 | 
      flex-wrap: wrap; 
 | 
      margin: -10px; 
 | 
  
 | 
      .system-cover-uploader-list-item { 
 | 
        padding: 10px; 
 | 
  
 | 
        .system-cover-uploader-list-img { 
 | 
          width: 100px; 
 | 
          height: 100px; 
 | 
          border: 1px solid #dadada; 
 | 
          border-radius: 4px; 
 | 
        } 
 | 
      } 
 | 
    } 
 | 
  } 
 | 
} 
 | 
</style> 
 |