submit-work-panel.vue 9.23 KB
<template>
  <a-card class="general-card" title="用户试唱" :header-style="{ paddingBottom: 0 }" :body-style="{ padding: '15px 20px 13px 20px' }">
    <template #extra>
      <a-space>
        <a-range-picker
          v-model="createBetween"
          value-format="YYYY-MM-DD"
          style="width: 260px"
          :allow-clear="false"
          :disabled-date="disabledDate"
          @change="$refs.tableRef?.onPageChange()"
        />
        <export-button :on-download="onExport" />
      </a-space>
    </template>

    <filter-table ref="tableRef" :loading="loading" :on-query="onQuery">
      <link-table-column
        title="名称"
        data-index="activity_name"
        :width="160"
        :formatter="(item:SubmitWork) => item.activity_name + ([3,5].includes(item.activity_status)? '( 结束 )' : '')"
        :to="(item:SubmitWork) => $router.push({ name:item.activity_type === 1 ?'audition-activity-show':'audition-demo-show', params: { id: item.activity_id}  })"
      />
      <enum-table-column title="类型" data-index="activity_type" :width="60" :option="useActivityApi.songTypeOption" />
      <link-table-column
        title="厂牌"
        data-index="project_id"
        :width="120"
        :formatter="(item) => item.project?.name"
        :to="(item: SubmitWork) => $router.push({ name: 'project-show', params: { id: item.project_id } })"
      />
      <filter-table-column title="试唱用户" data-index="user_nick_name" nick-index="user_nick_name" :width="120" />
      <filter-table-column title="身份" data-index="user_identify" :width="80">
        <template #default="{ record }: { record: SubmitWork }">
          <span v-if="record.user_identity === 1">音乐人</span>
          <span v-else-if="[2, 3].includes(record.user_identity)">经纪人</span>
          <span v-else>未认证</span>
        </template>
      </filter-table-column>
      <filter-table-column title="经纪人" data-index="business.nick_name" :width="120">
        <template #default="{ record }: { record: SubmitWork }">
          <span v-if="record.business">{{ record.business.nick_name }}</span>
          <span v-else style="color: rgba(44, 44, 44, 0.5)"></span>
        </template>
      </filter-table-column>
      <filter-table-column title="试唱方式" data-index="mode" :width="80">
        <template #default="{ record }: { record: SubmitWork }">
          <template v-if="record.mode === 1">自主上传</template>
          <template v-else>{{ record.sing_type === 'Full' ? '唱整首' : '唱片段' }}</template>
        </template>
      </filter-table-column>
      <link-table-column
        title="合作模式"
        data-index="price_id"
        :width="80"
        :formatter="(item:SubmitWork) => (item.price ? '查看报价' : '')"
        :to="(item:SubmitWork) =>onViewPrice(item.price as UserSubmitPrice) "
      />
      <filter-table-column title="提交时间" data-index="submit_at" :width="100">
        <template #default="{ record }: { record: SubmitWork }">
          {{ dayjs(record.submit_at).format('MM/DD HH:mm') || '' }}
        </template>
      </filter-table-column>
      <filter-table-column title="试唱音频" data-index="demo_url" :width="230" :tooltip="false">
        <template #default="{ record }: { record: SubmitWork }">
          <audio-player :url="record.demo_url" :name="record.user_nick_name" />
        </template>
      </filter-table-column>
      <a-table-column title="操作" data-index="demo" :width="120">
        <template #cell="{ record }">
          <a-button v-if="record.status === 1" size="mini" type="primary" status="success">已确认合作</a-button>
          <a-button v-else-if="record.status === 2" size="mini">试唱不合适</a-button>
          <a-button v-else-if="record.status === 0 && [3, 5].indexOf(record.activity_status) !== -1" size="mini">未采纳</a-button>
          <a-space v-else-if="record.status === 0 && record.activity_status === 1" size="mini">
            <a-button type="primary" size="mini" @click="onPass(record)">合作</a-button>
            <a-button type="primary" status="danger" size="mini" @click="onNotPass(record)">不合适</a-button>
          </a-space>
          <a-button v-else size="mini">其他</a-button>
        </template>
      </a-table-column>
    </filter-table>
  </a-card>
</template>

<script lang="ts" setup>
import { computed, createVNode, h, onMounted, ref } from 'vue';
import dayjs from 'dayjs';
import useLoading from '@/hooks/loading';
import { Form, FormItem, Modal, ModalConfig } from '@arco-design/web-vue';
import { AnyObject } from '@/types/global';
import { ActivityWork } from '@/types/activity-work';
import LinkTableColumn from '@/components/filter/link-table-column.vue';
import { promiseToBoolean } from '@/utils';
import useActivityApi, { useWorkApi } from '@/api/activity';
import useDashboardApi from '@/api/dashboard';
import { createModalVNode } from '@/utils/createVNode';
import EnumTableColumn from '@/components/filter/enum-table-column.vue';

type UserSubmitPrice = {
  id: number;
  value: { year: string; ratio: number; amounts: number; is_reward: 1 | 0; is_dividend: 1 | 0 };
  is_deduct: 1 | 0;
  is_talk: 1 | 0;
  is_accept_address: 1 | 0;
  address: { name: string; parent: { name: string } };
};

// eslint-disable-next-line @typescript-eslint/no-unused-vars
type SubmitWork = {
  id: number;
  activity_id: number;
  activity_name: string;
  activity_type: number;
  activity_status: number;
  project_id: number;
  project?: { id: number; name: string };
  user_id: number;
  user_nick_name: string;
  user_identity: number;

  business_id: number;
  business?: { id: number; nick_name: string; identify: number };

  share_id: number;
  share?: { id: number; nick_name: string; identify: number };

  price_id: number;
  price?: UserSubmitPrice;

  mode: 0 | 1;
  sing_type: 'Part' | 'Full';

  demo_url: string;
  status: 0 | 1 | 2;
  submit_at: string;
};

const { loading, setLoading } = useLoading(false);
const { submitWork, getSubmitWorkExport } = useDashboardApi;

const createBetween = ref([dayjs().subtract(7, 'day').format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD')]);

const timeFilter = computed(() => {
  return [`${createBetween.value[0]} 00:00:00`, `${createBetween.value[1]} 23:59:59`];
});

const tableRef = ref();

const onQuery = async (params: AnyObject) => {
  setLoading(true);
  return submitWork({ submitBetween: timeFilter.value, ...params, setSort: '-submit_at' }).finally(() => setLoading(false));
};

const onExport = () => getSubmitWorkExport('用户试唱', { submitBetween: timeFilter.value, setSort: '-submit_at' });

const onPass = (row: ActivityWork) => {
  const itemStyle = { lineHeight: '28px', margin: '4px 0' };

  return createModalVNode(
    () =>
      createVNode('ol', {}, [
        createVNode('li', { style: itemStyle }, '此条Demo的状态将变更为合作状态'),
        createVNode('li', { style: itemStyle }, `活动《${row.activity_name}》的状态变更为完成状态!`),
      ]),
    {
      title: '确认合作',
      bodyStyle: { padding: 0 },
      onBeforeOk: () => promiseToBoolean(useWorkApi.changeStatus(row.id, { status: 1 })),
      onOk: () => tableRef.value?.onFetch(),
    }
  );
};

const onNotPass = (row: ActivityWork) => {
  Modal.open({
    title: '不合适标记',
    content: `请确认是否将用户:${row.user_nick_name} 提交的试唱标记为不合适,并反馈给用户?`,
    closable: false,
    onBeforeOk: () => promiseToBoolean(useWorkApi.changeStatus(row.id, { status: 2, remark: '' })),
    onOk: () => tableRef.value?.onFetch(),
  });
};

const onViewPrice = (price: UserSubmitPrice) => {
  Modal.open({
    title: '用户报价',
    content: () =>
      createVNode(
        Form,
        { size: 'small', autoLabelWidth: true },
        {
          default: () => [
            h(FormItem, { label: '唱酬', showColon: true, rowClass: 'mb-0' }, price.value.is_reward ? `${price.value.amounts} 元` : '无'),
            h(
              FormItem,
              { label: '分成', showColon: true, rowClass: 'mb-0' },
              price.value.is_dividend ? `${price.value.ratio}% | ${price.value.year} | ${price.is_deduct ? '抵扣' : '不抵扣'}` : '无'
            ),
            h(FormItem, { label: '价格是否可谈', showColon: true, rowClass: 'mb-0' }, price.is_talk ? '【可谈】' : '【不可谈】'),
            h(
              FormItem,
              { label: '录音地点', showColon: true, rowClass: 'mb-0' },
              `${[price.address?.parent?.name, price.address?.name].join('/')}${
                price.is_accept_address ? '【接受其他录音地点】' : '【不接受其他录音地点】'
              }`
            ),
          ],
        }
      ),
    hideCancel: true,
    bodyStyle: { padding: '8px 20px' },
    closable: false,
    maskClosable: false,
    escToClose: false,
    okText: '我知道了',
  } as ModalConfig);
};

const disabledDate = (current?: Date) => dayjs(current).isAfter(dayjs()) || dayjs(current).isBefore(dayjs().subtract(30, 'day'));

onMounted(async () => tableRef.value?.onPageChange());
</script>

<style lang="less" scoped>
.title {
  line-height: normal;
  font-weight: 500;
  font-size: 16px;
}

:deep(.arco-table-cell) {
  padding: 5px 8px !important;

  .arco-table-td-content .arco-btn-size-small {
    padding: 5px !important;
  }
}
</style>