material-table.vue 3.16 KB
<script setup lang="ts">
import { Modal, Textarea } from "@arco-design/web-vue";
import { computed, h } from "vue";
import { useAppStore } from "@/store";
import useAuthApi from "@/api/auth";
import { Activity } from "@/types/activity";

type MaterialData = { title: string; type: string; content: string; name?: string; size?: string; };

const props = defineProps<{ data: Pick<Activity, "expand" | "lyric" | "song_name">; hideTrack?: boolean }>();

const appStore = useAppStore();
const theme = computed(() => appStore.theme);

const lyricStyle = computed(() =>
  theme.value === "light" ? { border: "none", backgroundColor: "white" } : {
    border: "none",
    backgroundColor: "#2a2a2b"
  }
);

const bytesForHuman = (bytes: number, decimals = 2) => {
  const units = ["B", "KB", "MB", "GB", "TB", "PB"];

  let i = 0;

  // eslint-disable-next-line no-plusplus
  for (i; bytes > 1024; i++) {
    bytes /= 1024;
  }

  return `${parseFloat(bytes.toFixed(decimals))} ${units[i]}`;
};

const onDownload = (record: MaterialData) => useAuthApi.downloadFile(record.content, `${props.data.song_name}(${record.title})`);

const onViewLyric = (lyric: string) => {
  Modal.open({
    content: () => h(Textarea, { defaultValue: lyric, autoSize: { maxRows: 20 }, style: lyricStyle.value }),
    footer: false,
    closable: false
  });
};

const materials = computed((): MaterialData[] => {
  return [
    {
      title: "音频",
      type: "guide",
      name: props.data.expand?.guide_source?.name || "",
      content: props.data.expand?.guide_source?.url || "",
      size: bytesForHuman(props.data.expand?.guide_source?.size || 0)
    },
    {
      title: "伴奏",
      type: "karaoke",
      name: props.data.expand?.karaoke_source?.name || "",
      content: props.data.expand?.karaoke_source?.url || "",
      size: bytesForHuman(props.data.expand?.karaoke_source?.size || 0)
    },
    { title: "歌词", type: "Lyric", content: props.data.lyric }
  ];
});
</script>

<template>
  <a-table row-key="type" :data="materials" :bordered="false" :table-layout-fixed="true" :pagination="false">
    <template #columns>
      <a-table-column title="物料类型" align="center" data-index="title" :width="140" />
      <a-table-column title="音频播放" data-index="content">
        <template #cell="{ record }">
          <template v-if="record.content">
            <audio-player v-if="['guide', 'karaoke'].indexOf(record.type) !== -1" :name="record.type"
                          :url="record.content" />
            <div v-if="record.type === 'track'">{{ [record.name, record.size].join(",") }}</div>
          </template>
        </template>
      </a-table-column>
      <a-table-column title="操作" align="center" :width="200">
        <template #cell="{ record }">
          <template v-if="record.content">
            <a-button v-if="record.type === 'Lyric'" type="primary" size="small" @click="onViewLyric(record.content)">
              查看
            </a-button>
            <a-button v-else type="primary" size="small" @click="onDownload(record)">下载</a-button>
          </template>
        </template>
      </a-table-column>
    </template>
  </a-table>
</template>

<style scoped lang="less"></style>