push-level-table.vue 8.17 KB
<script setup lang="ts">
  import { usePushLevelRecordApi } from '@/http/broker';
  import { AnyObject, QueryForParams } from '@/types/global';
  import useLoading from '@/hooks/loading';
  import { computed, createVNode, h, onMounted, ref } from 'vue';
  import SpaceTableColumn from '@/components/filter/space-table-column.vue';
  import NumberTableColumn from '@/components/filter/number-table-column.vue';
  import EnumTableColumn from '@/components/filter/enum-table-column.vue';
  import { pick, range } from 'lodash';
  import { Select, DatePicker, TableData } from '@arco-design/web-vue';
  import { createFormItemVNode, createFormVNode, createModalVNode } from '@/utils/createVNode';
  import dayjs, { OpUnitType } from 'dayjs';
  import { promiseToBoolean } from '@/utils';
  import PushLevelChildrenTable from '@/views/operation/broker/components/push-level-children-table.vue';
  import usePermission from '@/hooks/permission';

  const { get, update, send, rollback, destroy, statusOption } = usePushLevelRecordApi;
  const { loading, setLoading } = useLoading(false);
  const { checkPermission } = usePermission();
  const tableRef = ref();
  const filter = ref({ title: '', userName: '', sendBetween: [], status: '' });

  const queryParams = computed((): QueryForParams => {
    return { ...filter.value, setWithCount: ['items', 'readItems'], sortBy: 'publish_at', sortType: 'desc' };
  });

  const onQuery = async (params: AnyObject) => {
    setLoading(true);
    return get({ ...queryParams.value, ...params }).finally(() => setLoading(false));
  };

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

  const onReset = () => {
    filter.value = { title: '', userName: '', sendBetween: [], status: '' };
    onSearch();
  };

  onMounted(() => onReset());

  const isSameTime = (date: dayjs.ConfigType, unit: OpUnitType) => dayjs().isSame(dayjs(date), unit);

  const onView = (row: TableData) => {
    createModalVNode(() => createVNode(PushLevelChildrenTable, { recordId: row.id }), {
      title: '详情',
      titleAlign: 'center',
      width: '1200px',
      closable: true,
      footer: false,
    });
  };

  const onDelete = (row: TableData) =>
    createModalVNode(`删除等级推送:${row.title}`, {
      title: '删除操作',
      onBeforeOk: () => promiseToBoolean(destroy(row.id)),
      onOk: () => tableRef.value?.onFetch(),
    });

  const onSend = (row: TableData) =>
    createModalVNode(`确认立即发送通知《${row.title}》`, {
      title: '更新操作',
      onBeforeOk: () => promiseToBoolean(send(row.id)),
      onOk: () => tableRef.value?.onFetch(),
    });

  const onRollback = (row: TableData) =>
    createModalVNode(`确认撤回发送通知《${row.title}》`, {
      title: '撤回操作',
      onBeforeOk: () => promiseToBoolean(rollback(row.id)),
      onOk: () => tableRef.value?.onFetch(),
    });

  const onUpdate = (row: TableData) => {
    const formValue = ref({ ...pick(row, 'is_alert', 'publish_at') });
    const alertOption = [
      { value: 0, label: '否' },
      { value: 1, label: '是' },
    ];
    createModalVNode(
      () =>
        createFormVNode({ model: formValue }, [
          createFormItemVNode(
            { label: '发送时间', field: 'publish_at', required: true },
            h(DatePicker, {
              'style': { width: '100%' },
              'modelValue': formValue.value.publish_at,
              'showTime': true,
              'dayStartOfWeek': 1,
              'showNowBtn': false,
              'allowClear': false,
              'format': 'YYYY-MM-DD HH:mm',
              'valueFormat': 'YYYY-MM-DD HH:mm:ss',
              'timePickerProps': { hideDisabledOptions: true },
              'onUpdate:modelValue': (val: any) => (formValue.value.publish_at = val),
              'disabledDate': (current?: Date) => dayjs(current).isBefore(dayjs().subtract(1, 'day')),
              'disabledTime': (current?: Date) => {
                return {
                  disabledHours: () => range(0, 23).filter((item) => isSameTime(current, 'day') && item < dayjs().hour()),
                  disabledMinutes: () =>
                    range(0, 59).filter(
                      (item) => isSameTime(current, 'day') && isSameTime(current, 'hour') && item < dayjs().add(5, 'minute').minute()
                    ),
                };
              },
            })
          ),
          createFormItemVNode(
            { label: '面板提醒', field: 'is_alert', required: true, rowClass: 'mb-0' },
            h(Select, {
              'options': alertOption,
              'modelValue': formValue.value.is_alert,
              'onUpdate:modelValue': (val?: unknown) => (formValue.value.is_alert = Number(val)),
            })
          ),
        ]),
      {
        title: '编辑',
        titleAlign: 'center',
        onBeforeOk: () => promiseToBoolean(update(row.id, formValue.value)),
        onOk: () => tableRef.value?.onFetch(),
      }
    );
  };
</script>

<template>
  <filter-search :loading="loading" :model="filter" @search="onSearch" @reset="onReset">
    <filter-search-item label="名称">
      <a-input v-model="filter.title" placeholder="请输入" allow-clear />
    </filter-search-item>
    <filter-search-item label="创建人">
      <a-input v-model="filter.userName" placeholder="请输入" allow-clear />
    </filter-search-item>
    <filter-search-item label="发送时间">
      <a-range-picker
        v-model="filter.sendBetween"
        :day-start-of-week="1"
        :time-picker-props="{ defaultValue: ['00:00:00', '23:59:59'] }"
        value-format="YYYY-MM-DD HH:mm:ss"
        format="YYYY-MM-DD"
      />
    </filter-search-item>
    <filter-search-item label="发送状态">
      <a-select v-model="filter.status" :options="statusOption" placeholder="请选择" allow-clear />
    </filter-search-item>
  </filter-search>
  <filter-table ref="tableRef" :loading="loading" :on-query="onQuery">
    <filter-table-column title="名称" data-index="title" :width="260" />
    <number-table-column title="推送经纪人(人数)" data-index="items_count" :width="160" />
    <number-table-column title="查看人数" data-index="read_items_count" :dark-value="0" :width="100" />
    <filter-table-column title="开始时间" data-index="begin_at" :width="180" />
    <filter-table-column title="结束时间" data-index="end_at" :width="180" />
    <filter-table-column title="发送时间" data-index="publish_at" :width="200" />
    <enum-table-column title="发送状态" data-index="status" :option="statusOption" :width="120" />
    <space-table-column
      v-if="
        checkPermission([
          'operation-broker-level-record-show',
          'operation-broker-level-record-edit',
          'operation-broker-level-record-send',
          'operation-broker-level-record-delete',
        ])
      "
      title="操作"
      :width="120"
    >
      <template #default="{ record }: { record: { status: number } }">
        <a-link v-permission="['operation-broker-level-record-show']" class="link-hover" :hoverable="false" @click="onView(record)">
          查看
        </a-link>
        <a-link
          v-if="record.status === 0"
          v-permission="['operation-broker-level-record-edit']"
          class="link-hover"
          :hoverable="false"
          @click="onUpdate(record)"
        >
          编辑
        </a-link>
        <a-link
          v-if="[-1, 3].includes(record.status)"
          v-permission="['operation-broker-level-record-send']"
          class="link-hover"
          :hoverable="false"
          @click="onSend(record)"
        >
          {{ record.status === -1 ? '重试' : '发送' }}
        </a-link>
        <a-link
          v-if="record.status === 2"
          v-permission="['operation-broker-level-record-send']"
          class="link-hover"
          :hoverable="false"
          @click="onRollback(record)"
        >
          撤回
        </a-link>
        <a-link
          v-if="record.status !== 1"
          v-permission="['operation-broker-level-record-delete']"
          class="link-hover"
          :hoverable="false"
          @click="onDelete(record)"
        >
          删除
        </a-link>
      </template>
    </space-table-column>
  </filter-table>
</template>

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