index.vue 7.89 KB
<script setup lang="ts" name="audition-demo">
import { createVNode, onMounted, ref } from "vue";
import useLoading from "@/hooks/loading";
import useActivityApi, { useApply } from "@/api/activity";
import EnumTableColumn from "@/components/filter/enum-table-column.vue";
import DateTableColumn from "@/components/filter/date-table-column.vue";
import ActivityTableColumn from "@/components/filter/activity-table-column.vue";
import { AnyObject, AttributeData } from "@/types/global";
import ActivityForm from "@/views/demo/components/form-content.vue";
import { Message, TableData } from "@arco-design/web-vue";
import { createInputVNode, createModalVNode } from "@/utils/createVNode";
import { useAuthorizedStore, useSelectionStore } from "@/store";
import { promiseToBoolean } from "@/utils";
import { tryOnMounted } from "@vueuse/core";

const props = defineProps<{
  initFilter?: AttributeData;
  hideSearchItem?: string[];
  hideTool?: boolean;
  hideCreate?: boolean;
  exportName?: string;
  queryHook?: () => void;
}>();

const { statusOption, get, update, destroy, changeStatus } = useActivityApi;
const { loading, setLoading } = useLoading(false);

const filter = ref({
  songName: "",
  projectName: "",
  tagName: "",
  status: [],
  createBetween: [],
  songType: 2,
  setSort: ["-id"]
});
const tableRef = ref();

const { isCreateDemo } = useAuthorizedStore();

const onQuery = async (params: object) => {
  setLoading(true);
  props.queryHook?.();
  return get({
    ...filter.value,
    ...params,
    setColumn: ["id", "song_name", "cover", "user_id", "lyric", "expand", "status", "created_at"],
    setWith: ["user:id,real_name,nick_name,identity", "tags:id,name"]
  }).finally(() => setLoading(false));
};

const onSort = (column: string, type: string) => {
  filter.value.setSort = type ? [(type === "desc" ? "-" : "") + column, "-id"] : ["-id"];
  tableRef.value?.onFetch();
};

const onSearch = () => tableRef.value?.onPageChange(1);

const handleCreate = () => {

  const dialog = createModalVNode(
    () =>
      createVNode(ActivityForm, {
        initValue: { song_type: 2, cover: useSelectionStore().appleDemoCover, is_push: 0, expand: { push_type: [] } },
        onSubmit: (data: AnyObject) =>
          useApply.create(data).then(() => {
            Message.success(`申请上架Demo:${data.song_name}`);
            tableRef.value?.onFetch();
            dialog.close();
          })
      }),
    { title: "创建Demo", footer: false, closable: true, width: "auto" }
  );
};

const onUpdate = (record: TableData) => {
  const dialog = createModalVNode(
    () =>
      createVNode(ActivityForm, {
        initValue: record,
        onSubmit: (attribute: AnyObject) =>
          update(record.id, Object.assign(attribute, { song_type: 2 })).then(() => {
            Message.success(`编辑Demo:${record.song_name}`);
            tableRef.value?.onFetch();
            dialog.close();
          })
      }),
    { title: "编辑Demo", footer: false, width: "auto", closable: true }
  );
};

const onDown = (record: TableData) => {
  const msg = ref<string>("");

  createModalVNode(
    () =>
      createInputVNode(msg, {
        "placeholder": "请输入下架原因",
        "maxLength": 20,
        "show-word-limit": true
      }),
    {
      title: "变更状态",
      titleAlign: "start",
      okText: "下架",
      onBeforeOk: (done) =>
        changeStatus(record.id, { status: "down", msg: msg.value })
          .then(() => {
            tableRef.value?.onFetch();
            done(true);
          })
          .catch(() => done(false))
    }
  );
};

const onUp = (record: TableData, status: "up" | "reUp") => {
  createModalVNode(`请确认是否上架歌曲:${record.song_name}`, {
    title: "变更状态",
    titleAlign: "start",
    okText: "上架",
    onBeforeOk: (done) =>
      changeStatus(record.id, { status })
        .then(() => {
          tableRef.value?.onFetch();
          done(true);
        })
        .catch(() => done(false))
  });
};

const onDelete = (row: TableData) =>
  createModalVNode(`确认要将Demo:${row.song_name} 删除吗?`, {
    title: "删除操作",
    onBeforeOk: () => promiseToBoolean(destroy(row.id)),
    onOk: () => tableRef.value?.onFetch()
  });


const onReset = () => {
  filter.value = {
    songName: "",
    projectName: "",
    tagName: "",
    status: [],
    createBetween: [],
    ...props.initFilter,
    songType: 2,
    setSort: ["-id"]
  };
  tableRef.value?.resetSort();
  onSearch();
};


onMounted(() => onReset());
tryOnMounted(async () => {
  useSelectionStore().queryUser({ fetchType: "all", status: 1 });
  useSelectionStore().queryTag({ fetchType: "all", type: 1 });
  useSelectionStore().queryConfig({
    fetchType: "all",
    identifier: ["activity_demo_cover", "activity_lyric_tool", "activity_audio_accept"]
  });
});
</script>

<template>
  <page-view has-bread has-card>
    <filter-search :model="filter" :loading="loading" @search="onSearch" @reset="onReset">
      <filter-search-item label="歌曲名称" field="song_name">
        <a-input v-model="filter.songName" allow-clear placeholder="请输入搜索歌曲名称" />
      </filter-search-item>
      <filter-search-item label="标签名称" field="tagName">
        <a-input v-model="filter.tagName" allow-clear placeholder="请输入搜索标签名称" />
      </filter-search-item>
      <filter-search-item label="状态" field="status">
        <a-select v-model="filter.status" :options="statusOption" allow-clear multiple placeholder="请选择搜索状态" />
      </filter-search-item>
      <filter-search-item label="创建时间" field="createBetween">
        <a-range-picker v-model="filter.createBetween" show-time
                        :time-picker-props="{ defaultValue: ['00:00:00', '23:59:59'] }" />
      </filter-search-item>
    </filter-search>
    <filter-table ref="tableRef" :loading="loading" :on-query="onQuery" @row-sort="onSort">

      <template #tool="{ size }">
        <a-button v-if="isCreateDemo" :size="size" type="primary" @click="handleCreate">上架Demo</a-button>
      </template>
      <template #tool-right>
        <div class="tipsBox">
          <span>注意:如果上传后状态为“处理中”,需要“</span><i>编辑</i><span>”或“</span><i>下架</i><span>”,请点击“</span><i>搜索</i><span>”或</span><i>刷新浏览器</i>
        </div>
      </template>

      <activity-table-column data-index="id" title="试唱歌曲" :width="560" hide-sub-title />
      <date-table-column data-index="created_at" title="创建时间" :width="110" split has-sort />
      <enum-table-column data-index="status" title="状态" :option="statusOption" :width="110" has-sort />
      <a-table-column :width="90" align="center" data-index="operations" fixed="right" title="操作">
        <template #cell="{ record }">
          <a-space direction="vertical" fill>
            <a-link :hoverable="false" class="link-hover"
                    @click="$router.push({ name: 'audition-demo-show', params: { id: record.id } })">
              查看
            </a-link>
            <a-link v-if="record.status === 1" :hoverable="false" class="link-hover" @click="onDown(record)">下架
            </a-link>
            <a-link v-if="record.status === 2" :hoverable="false" class="link-hover" @click="onUp(record, 'up')">上架
            </a-link>
            <a-link v-if="record.status !== 0 && record.status !== 5" :hoverable="false" class="link-hover"
                    @click="onUpdate(record)">
              编辑
            </a-link>
            <a-link v-if="record.status === 2" :hoverable="false" class="link-hover" @click="onDelete(record)">删除
            </a-link>
          </a-space>
        </template>
      </a-table-column>
    </filter-table>
  </page-view>
</template>

<style scoped lang="less">
:deep(.arco-table-cell) {
  padding: 5px 16px !important;
}

.tipsBox {
  font-size: 14px;

  span {
    color: #333;
  }

  i {
    color: red;
    font-style: normal;
  }
}
</style>