riku
2024-10-24 71ed602a8b17430c119b2ae6472a47dd6e6e0c95
src/components/bg-task/FYBgTaskCard.vue
@@ -1,200 +1,166 @@
<template>
  <el-card class="m-b-8" shadow="always" :body-style="{ padding: '8px' }">
    <el-row>
      <el-col :span="4">
        <div class="status-btn">
          <el-icon v-if="waiting" color="var(--el-color-info)" :size="50"><VideoPlay /></el-icon>
          <el-icon v-else-if="running" color="var(--el-color-primary)" :size="50" class="is-loading"
            ><Loading
          /></el-icon>
          <el-icon v-else-if="success" color="var(--el-color-success)" :size="50"
            ><CircleCheck
          /></el-icon>
          <el-icon v-else-if="fail" color="var(--el-color-error)" :size="50"
            ><CircleClose
          /></el-icon>
          <el-icon v-else color="var(--el-color-warning)" :size="50"><Warning /></el-icon>
          <el-text type="info" size="small" style="position: absolute; bottom: 0">{{
            nameToLabel(model.status)
          }}</el-text>
  <el-card shadow="never" :body-style="{ padding: 0 }">
    <template #header>
      <el-row justify="space-between">
        <div>
          <div><el-text tag="b" size="large">后台任务</el-text></div>
          <el-text size="small" type="info">显示当前正在进行的后台耗时任务状态</el-text>
        </div>
      </el-col>
      <el-col :span="20" class="p-l-8">
        <el-row justify="space-between">
          <el-text class="m-l-4px w-300px" tag="b" size="large" truncated>{{ model.name }}</el-text>
          <el-tag>{{ nameToLabel(model.type) }}</el-tag>
        </el-row>
        <el-row class="p-v-8" align="bottom">
          <el-col :span="12">
            <span class="timer">{{ time }}</span>
            <el-text type="info" size="small" tag="div">运行时长</el-text>
          </el-col>
          <el-col :span="12">
            <el-text type="default" size="default" tag="div"
              >开始:{{ $fm.formatYMDH(model.startTime) }}</el-text
            >
            <el-text type="default" size="default" tag="div"
              >结束:{{ $fm.formatYMDH(model.endTime) }}</el-text
            >
          </el-col>
        </el-row>
        <el-row justify="end" align="bottom">
          <!-- <span class="f-s color-i">ID:{{ model.id }}</span> -->
          <el-row>
            <FYReconfrimButton v-if="waiting" @confirm="startTask" v-model="startConfirm">
              <el-button
                plain
                icon="VideoPlay"
                type="primary"
                size="small"
                :loading="false"
                @click="startConfirm = true"
                >开始任务</el-button
              >
            </FYReconfrimButton>
            <FYReconfrimButton v-if="running" @confirm="stopTask" v-model="stopConfirm">
              <el-button
                icon="VideoPause"
                plain
                type="danger"
                size="small"
                :loading="false"
                @click="stopConfirm = true"
                >强制结束</el-button
              >
            </FYReconfrimButton>
            <FYReconfrimButton v-if="!running" @confirm="removeTask" v-model="removeConfirm">
              <el-button
                icon="Delete"
                plain
                type="danger"
                size="small"
                :loading="false"
                @click="removeConfirm = true"
                >移除任务</el-button
              >
            </FYReconfrimButton>
            <el-button
              v-if="success"
              plain
              type="success"
              size="small"
              :loading="false"
              @click="gotoResult"
              >查看结果<el-icon class="m-l-4"><Right /></el-icon
            ></el-button>
          </el-row>
        </el-row>
      </el-col>
    </el-row>
        <el-button
          icon="Refresh"
          type="primary"
          size="default"
          :loading="loading"
          @click="fetchTask"
          >刷新任务</el-button
        >
      </el-row>
      <!-- <el-row>
        <el-button type="default" size="default" @click="newTestTask">新增测试任务</el-button>
        <el-button type="default" size="default" @click="startNewTestTask"
          >新建并运行一个测试任务</el-button
        >
        <el-button type="default" size="default" @click="shutDownTask"
          >强制关闭所有测试任务</el-button
        >
      </el-row> -->
    </template>
    <el-scrollbar height="70vh" class="scrollbar">
      <template v-for="(v, i) in taskList" :key="i">
        <FYBgTaskItem
          :model="v"
          :index="i"
          @start="startTask"
          @shutDown="shutDownTask"
          @remove="removeTask"
          @gotoResult="gotoResult"
        ></FYBgTaskItem>
      </template>
    </el-scrollbar>
  </el-card>
</template>
<script>
import { nTlBgTask, BG_TASK_STATUS } from '@/enum/bgTask';
import { useTimer } from '@/composables/timer';
// import { useTimer } from '@/composables/timer2';
/**
 * 自动评估任务管理
 */
import { useFetchData } from '@/composables/fetchData';
import bgtaskApi from '@/api/fysp/bgtaskApi';
import { enumBgTask, BG_TASK_TYPE, BG_TASK_STATUS } from '@/enum/bgTask';
export default {
  setup() {
    const { time, startTimer, pauseTimer, stopTimer, count } = useTimer();
    return { time, startTimer, pauseTimer, stopTimer, count };
    const { loading, fetchData } = useFetchData();
    return { loading, fetchData };
  },
  props: {
    model: Object,
    index: Number
    modelValue: Number
  },
  emits: ['start', 'shutDown', 'remove', 'gotoResult'],
  emits: ['update:modelValue'],
  data() {
    return {
      startConfirm: false,
      stopConfirm: false,
      removeConfirm: false
      taskList: [],
      taskIndex: 0
    };
  },
  watch: {
    'model.status': {
    taskList: {
      handler(nV) {
        switch (nV) {
          case BG_TASK_STATUS.WAITING.name:
            this.stopTimer();
            break;
          case BG_TASK_STATUS.RUNNING.name:
            this.startTimer();
            break;
          case BG_TASK_STATUS.SUCCESS.name:
          case BG_TASK_STATUS.FAIL.name:
          case BG_TASK_STATUS.SHUTDOWN.name:
            this.pauseTimer();
            break;
          default:
            this.stopTimer();
            break;
        let count = 0;
        for (const e of nV) {
          if (e.status == BG_TASK_STATUS.RUNNING.name) {
            count++;
          }
        }
        this.count = this.model.runTime
        this.$emit('update:modelValue', count);
      },
      immediate: true
    }
  },
  computed: {
    waiting() {
      return this.model.status == BG_TASK_STATUS.WAITING.name;
    },
    running() {
      return this.model.status == BG_TASK_STATUS.RUNNING.name;
    },
    success() {
      return this.model.status == BG_TASK_STATUS.SUCCESS.name;
    },
    fail() {
      return this.model.status == BG_TASK_STATUS.FAIL.name;
    },
    shutdown() {
      return this.model.status == BG_TASK_STATUS.SHUTDOWN.name;
      deep: true
    }
  },
  methods: {
    nameToLabel(name) {
      const t = nTlBgTask(name);
      return t.label;
    },
    startTask() {
      this.$emit('start', this.index, (res) => {
        if (res) {
          this.startTimer();
        }
    addTask() {},
    newTestTask() {
      this.fetchData((page, pageSize) => {
        return bgtaskApi.newTestTask(`Test-Task-${++this.taskIndex}`).then((res) => {
          this.taskList.push(res.data);
        });
      });
    },
    stopTask() {
      this.$emit('shutDown', this.index, (res) => {
        if (res) {
          this.stopTimer();
        }
    startNewTestTask() {
      this.fetchData((page, pageSize) => {
        return bgtaskApi.startNewTestTask(`Test-Task-${++this.taskIndex}`).then((res) => {
          this.taskList.push(res.data);
        });
      });
    },
    removeTask() {
      this.$emit('remove', this.index, (res) => {
        if (res) {
          // this.stopTimer();
        }
    _getParam(taskStatus) {
      return {
        type: taskStatus.type,
        id: taskStatus.id
      };
    },
    fetchTask() {
      this.fetchData((page, pageSize) => {
        return bgtaskApi
          .fetchTaskStatus({
            // type: BG_TASK_TYPE.AUTO_SCORE.name
          })
          .then((res) => {
            this.taskList = res.data;
          });
      });
    },
    gotoResult() {
      this.$emit('gotoResult', this.index);
    }
    startTask(index, callback) {
      this.fetchData((page, pageSize) => {
        const param = this._getParam(this.taskList[index]);
        return bgtaskApi.startTask(param).then((res) => {
          this.taskList[index] = res.data;
          callback(true);
        });
      });
    },
    shutDownTask(index, callback) {
      this.fetchData((page, pageSize) => {
        const param = this._getParam(this.taskList[index]);
        return bgtaskApi.shutDownTask(param).then((res) => {
          if (index && res.data && res.data.length == 1) {
            this.taskList[index] = res.data[0];
          } else {
            res.data.forEach((e) => {
              let v = this.taskList.find((value) => {
                return value.id == e.id;
              });
              const i = this.taskList.indexOf(v);
              this.taskList[i] = e;
            });
          }
          callback(true);
        });
      });
    },
    removeTask(index, callback) {
      this.fetchData((page, pageSize) => {
        const param = this._getParam(this.taskList[index]);
        return bgtaskApi.removeTask(param).then((res) => {
          if (res.data) {
            this.taskList.splice(index, 1);
            callback(true);
          }
        });
      });
    },
    gotoResult(index) {}
  },
  mounted() {
    this.fetchTask();
    // setInterval(() => {
    //   this.fetchTask();
    // }, 10000);
  }
};
</script>
<style scoped>
.status-btn {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  border: var(--el-border);
  border-radius: var(--el-border-radius-base);
}
.timer {
  font-size: 30px;
.scrollbar {
  padding: 8px;
}
</style>