index.vue 5.32 KB
<script lang="ts" setup>
  import { Button, Card, Switch, Tooltip } from 'ant-design-vue';
  import {
    CloudSyncOutlined,
    PlayCircleOutlined,
    QuestionCircleOutlined,
  } from '@ant-design/icons-vue';
  import { TaskRecordType } from '/@/api/task/model';
  import { StateEnum, TaskTargetNameEnum, TaskTypeEnum } from '../../config';
  import { TaskTypeNameEnum } from '../../config';
  import AuthDropDown from '/@/components/Widget/AuthDropDown.vue';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { cancelTask, deleteTask, updateState } from '/@/api/task';
  import { computed } from '@vue/reactivity';
  import { unref } from 'vue';
  import { ref } from 'vue';

  enum DropMenuEvent {
    DELETE = 'DELETE',
    EDIT = 'EDIT',
  }

  const props = withDefaults(
    defineProps<{
      record: TaskRecordType;
      reload: Fn;
      deviceTaskCardMode?: boolean;
      tbDeviceId?: string;
    }>(),
    {
      deviceTaskCardMode: false,
    }
  );

  const emit = defineEmits(['edit']);

  const loading = ref(false);

  const { createMessage } = useMessage();

  const getRecord = computed(() => {
    return props.record;
  });

  const getCancelState = computed(() => {
    const { executeTarget } = unref(getRecord);
    const { cancelExecuteDevices } = executeTarget;
    return !!(cancelExecuteDevices && cancelExecuteDevices.length);
  });

  const handleDelete = async () => {
    try {
      await deleteTask([unref(getRecord).id]);
      createMessage.success('删除成功');
      props.reload?.();
    } catch (error) {}
  };

  const handleSwitchState = async () => {
    try {
      loading.value = true;
      await updateState(
        unref(getRecord).id,
        !unref(getRecord).state ? StateEnum.ENABLE : StateEnum.CLOSE
      );
      createMessage.success('更新状态成功');
      props.reload?.();
    } catch (error) {
      throw error;
    } finally {
      loading.value = false;
    }
  };

  const handleCancelTask = async () => {
    try {
      if (!props.tbDeviceId) return;
      loading.value = true;
      await cancelTask({ id: unref(getRecord).id, tbDeviceId: props.tbDeviceId });
      createMessage.success('设置成功');
      props.reload?.();
    } catch (error) {
      throw error;
    } finally {
      loading.value = false;
    }
  };
</script>

<template>
  <Card hoverable class="card-container !rounded">
    <div v-if="!deviceTaskCardMode" class="flex justify-end mb-4">
      <AuthDropDown
        @click.stop
        :trigger="['hover']"
        :drop-menu-list="[
          {
            text: '编辑',
            event: DropMenuEvent.DELETE,
            icon: 'ant-design:edit-outlined',
            onClick: emit.bind(null, 'edit', getRecord),
          },
          {
            text: '删除',
            event: DropMenuEvent.DELETE,
            icon: 'ant-design:delete-outlined',
            popconfirm: {
              title: '是否确认删除操作?',
              onConfirm: handleDelete.bind(null),
            },
          },
        ]"
      />
    </div>
    <div class="flex text-base font-medium justify-between mb-2">
      <Tooltip :title="getRecord.name" placement="topLeft">
        <div class="truncate max-w-48">{{ getRecord.name }}</div>
      </Tooltip>
      <span
        v-if="deviceTaskCardMode"
        class="text-xs w-12 leading-6 text-right"
        :class="getRecord.state === StateEnum.ENABLE ? 'text-green-500' : 'text-red-500'"
      >
        {{ getRecord.state === StateEnum.ENABLE ? '已启用' : '未启用' }}
      </span>
      <Switch
        v-if="!deviceTaskCardMode"
        :checked="getRecord.state === StateEnum.ENABLE"
        :loading="loading"
        size="small"
        @click="handleSwitchState"
      />
    </div>
    <div class="flex gap-2 items-center">
      <div
        class="rounded flex justify-center items-center w-6 h-6"
        :class="
          getRecord.executeContent.type === TaskTypeEnum.MODBUS_RTU
            ? ' bg-blue-400'
            : 'bg-green-400'
        "
      >
        <CloudSyncOutlined class="svg:fill-light-50" />
      </div>
      <div class="text-gray-400 truncate">
        <span>{{ TaskTypeNameEnum[getRecord.executeContent.type] }}</span>
        <span class="mx-1">-</span>
        <span>{{ TaskTargetNameEnum[getRecord.targetType] }}</span>
      </div>
    </div>
    <div class="mt-4 flex justify-between items-center gap-3">
      <Button size="small">
        <div class="text-xs px-1">
          <PlayCircleOutlined class="mr-1" />
          <span>运行任务</span>
        </div>
      </Button>
      <Tooltip title="最后运行时间:">
        <div class="text-gray-400 text-xs truncate">
          <span class="mr-2">间隔时间重复</span>
          <span>三分钟前</span>
        </div>
      </Tooltip>
    </div>

    <section
      v-if="deviceTaskCardMode"
      class="border-t mt-4 pt-2 text-sm border-gray-100 flex justify-between text-gray-400"
    >
      <div>
        <span>允许该设备</span>
        <Tooltip title="设置是否允许当前设备定时执行任务。该选项不影响手动执行任务。">
          <QuestionCircleOutlined class="ml-1" />
        </Tooltip>
      </div>
      <div>
        <Switch
          size="small"
          :loading="loading"
          :checked="getCancelState"
          @click="handleCancelTask"
        />
      </div>
    </section>
  </Card>
</template>