submit-work-panel.vue 8.47 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="onSearch"
        />
        <export-button :on-download="onExport" />
      </a-space>
    </template>

    <filter-table ref="tableRef" :loading="loading" :on-query="onQuery" size="mini">
      <link-table-column
        title="名称"
        data-index="activity_name"
        :link-style="{ fontSize: '12px' }"
        :width="160"
        :formatter="(item:TableData) => item.activity_name + ([3,5].includes(item.activity_status)? '( 结束 )' : '')"
        :to="(item:TableData) => $router.push({ name:'audition-activity-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"
        :link-style="{ fontSize: '12px' }"
        :width="120"
        :formatter="(item:TableData) => item.project?.name || ''"
        :to="(item: TableData) => $router.push({ name: 'audition-project-show', params: { id: item.project_id } })"
      />
      <user-table-column
        title="试唱用户"
        data-index="user_id"
        nick-index="user_nick_name"
        :link-style="{ fontSize: '12px' }"
        :width="120"
        show-href
      />
      <filter-table-column title="身份" data-index="user_identify" :width="70">
        <template #default="{ record }">
          <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>
      <user-table-column
        title="经纪人"
        data-index="business_id"
        user="business"
        show-href
        :width="110"
        dark-value=""
        :link-style="{ fontSize: '12px' }"
      />
      <filter-table-column title="试唱方式" data-index="mode" :width="80">
        <template #default="{ record }">
          <template v-if="record.mode === 1">自主上传</template>
          <template v-else>{{ record.sing_type === 'Full' ? '唱整首' : '唱片段' }}</template>
        </template>
      </filter-table-column>
      <link-table-column
        v-if="usePermission().checkPermission('audition-activity-show-submit-user-view')"
        title="合作模式"
        data-index="price_id"
        :link-style="{ fontSize: '12px' }"
        :width="80"
        :formatter="(item:TableData) => (item.price ? '查看报价' : '')"
        :to="(item:TableData) =>onViewPrice(item.price) "
      />
      <filter-table-column title="提交时间" data-index="submit_at" :width="100">
        <template #default="{ record }">
          {{ dayjs(record.submit_at).format('MM/DD HH:mm') || '' }}
        </template>
      </filter-table-column>
      <filter-table-column title="试唱音频" data-index="demo_url" :width="240">
        <template #default="{ record }">
          <audio-player :url="record.demo_url" :name="record.user_nick_name" />
        </template>
      </filter-table-column>
      <a-table-column title="操作" data-index="operation" :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>
          <template v-else-if="record.status === 0 && record.activity_status === 1">
            <a-space v-if="usePermission().checkPermission('audition-activity-show-submit-user-audit')">
              <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-button v-else size="mini">其他</a-button>
        </template>
      </a-table-column>
    </filter-table>
  </a-card>
</template>

<script lang="ts" setup>
  import { computed, createVNode, onMounted, ref } from 'vue';
  import dayjs from 'dayjs';
  import useLoading from '@/hooks/loading';
  import { Modal, TableData } from '@arco-design/web-vue';
  import { createFormItemVNode, createFormVNode, createModalVNode } from '@/utils/createVNode';
  import useDashboardApi from '@/http/dashboard';
  import { AnyObject } from '@/types/global';
  import FilterTable from '@/components/filter/table.vue';
  import UserTableColumn from '@/components/filter/user-table-column.vue';
  import LinkTableColumn from '@/components/filter/link-table-column.vue';
  import { promiseToBoolean } from '@/utils';
  import { useWorkApi } from '@/http/activity';
  import usePermission from '@/hooks/permission';

  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<typeof FilterTable>();

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

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

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

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

  const onNotPass = (row: TableData) => {
    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: TableData) => {
    createModalVNode(
      () =>
        createFormVNode({ size: 'small', model: price }, [
          createFormItemVNode(
            { label: '唱酬', showColon: true, rowClass: 'mb-0' },
            price.value.is_reward ? `${price.value.amounts} 元` : '无'
          ),
          createFormItemVNode(
            { label: '分成', showColon: true, rowClass: 'mb-0' },
            price.value.is_dividend ? `${price.value.ratio}% | ${price.value.year} | ${price.is_deduct ? '抵扣' : '不抵扣'}` : '无'
          ),
          createFormItemVNode({ label: '价格是否可谈', showColon: true, rowClass: 'mb-0' }, price.is_talk ? '【可谈】' : '【不可谈】'),
          createFormItemVNode(
            { label: '录音地点', showColon: true, rowClass: 'mb-0' },
            `${[price.address?.parent?.name, price.address?.name].join('/')}${
              price.is_accept_address ? '【接受其他录音地点】' : '【不接受其他录音地点】'
            }`
          ),
        ]),
      {
        title: '用户报价',
        hideCancel: true,
        okText: '我知道了',
        bodyStyle: { padding: '8px 20px' },
        width: '600px',
      }
    );
  };

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

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

  onMounted(async () => onSearch());
</script>

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