riku
2023-12-26 aa1f56d5ef2d48b980a2fab3e88379efbe09b0d1
评估任务模块新增任务状态管理逻辑
已修改6个文件
已删除1个文件
已添加5个文件
400 ■■■■ 文件已修改
src/api/fysp/bgtaskApi.js 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components.d.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/bg-task/FYBgTaskCard.vue 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/form/FYForm.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/composables/fetchData.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/composables/formConfirm.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/enum/bgTask.js 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/enum/enum.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/evaluation/DataSource.vue 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/evaluation/components/CompEvaTask.vue 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/evaluation/components/CompHistoryRecord.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fytz/user/components/CompUserInfo.vue 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/fysp/bgtaskApi.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
import { $fysp } from '../index';
/**
 * è€—时任务相关API
 */
export default {
  /**
   * èŽ·å–åŽå°ä»»åŠ¡çŠ¶æ€
   * @param {Object} param åŽå°ä»»åŠ¡æŸ¥è¯¢æ¡ä»¶
   */
  fetchTaskStatus(param) {
    return $fysp.post(`bgTask/status`, param).then((res) => res.data);
  },
  /**
   * æ–°å»ºä¸€ä¸ªæµ‹è¯•任务
   * @param {String} taskId
   * @returns {Promise}
   */
  newTestTask(taskId) {
    return $fysp.put(`bgTask/newTask/test?taskId=${taskId}`).then((res) => res.data);
  },
  /**
   * æ–°å»ºä¸€ä¸ªæµ‹è¯•任务
   * @param {String} taskId
   * @returns {Promise}
   */
  startTask(param) {
    return $fysp.put(`bgTask/start`, param).then((res) => res.data);
  },
  /**
   * æ–°å»ºå¹¶è¿è¡Œä¸€ä¸ªæµ‹è¯•任务
   * @param {String} taskId
   * @returns {Promise}
   */
  startNewTestTask(taskId) {
    return $fysp.put(`bgTask/newTask/test/start?taskId=${taskId}`).then((res) => res.data);
  },
  /**
   * å¼ºåˆ¶å…³é—­æµ‹è¯•任务
   * @param {Object} param åŽå°ä»»åŠ¡æŸ¥è¯¢æ¡ä»¶
   * @returns {Promise}
   */
  shutDownTask(param) {
    return $fysp.put(`bgTask/shutDown`, param).then((res) => res.data);
  },
};
src/components.d.ts
@@ -64,6 +64,7 @@
    ElTree: typeof import('element-plus/es')['ElTree']
    Footer: typeof import('./components/core/Footer.vue')['default']
    FormCol: typeof import('./components/layout/FormCol.vue')['default']
    FYBgTaskCard: typeof import('./components/bg-task/FYBgTaskCard.vue')['default']
    FYForm: typeof import('./components/form/FYForm.vue')['default']
    FYOptionLocation: typeof import('./components/search-option/FYOptionLocation.vue')['default']
    FYOptionOnlineStatus: typeof import('./components/search-option/FYOptionOnlineStatus.vue')['default']
src/components/bg-task/FYBgTaskCard.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
<template>
  <el-card class="bg-task-card" shadow="hover" :body-style="{ padding: '8px' }">
    <!-- <template #header> -->
    <el-row>
      <el-space>
        <el-tag>{{ nameToLabel(model.type) }}</el-tag>
        <el-text tag="b" size="large" truncated>{{ model.name }}啊实打实大苏打啊实打实大苏打阿大撒大撒</el-text>
      </el-space>
    </el-row>
    <!-- </template> -->
    <el-text type="info" size="small">状态:{{ nameToLabel(model.status) }}</el-text>
    <el-text type="info" size="small">开始:{{ model.startTime }}</el-text>
    <el-text type="info" size="small">结束:{{ model.endTime }}</el-text>
    <!-- <template #footer> -->
    <el-button type="primary" size="small" :loading="false" @click="$emit('start', model)"
      >开始任务</el-button
    >
    <el-button type="danger" size="small" :loading="false" @click="$emit('shutDown', model)"
      >强制结束</el-button
    >
    <el-button type="danger" size="small" :loading="false" @click="$emit('remove', model)"
      >移除任务</el-button
    >
    <el-button type="danger" size="small" :loading="false" @click="$emit('gotoResult', model)"
      >查看结果</el-button
    >
    <el-text type="info" size="small">ID:{{ model.id }}</el-text>
    <!-- </template> -->
  </el-card>
</template>
<script>
import { nTlBgTask } from '@/enum/bgTask';
export default {
  props: {
    model: Object
  },
  emits: ['start', 'shutDown', 'remove', 'gotoResult'],
  methods: {
    nameToLabel(name) {
      const t = nTlBgTask(name);
      return t.label;
    }
  }
};
</script>
<style scoped>
.bg-task-card {
  margin-bottom: 8px;
}
</style>
src/components/form/FYForm.vue
@@ -136,7 +136,7 @@
  (nValue) => {
    formObj.value = nValue;
  },
  { deep: true, immediate: true }
  { deep: false, immediate: true }
);
//监听表单重置功能触发
src/composables/fetchData.js
@@ -1,13 +1,13 @@
// æŽ¥å£æ•°æ®çš„获取
import { onActivated, onDeactivated, ref, watch } from 'vue';
import { ref, watch, computed } from 'vue';
export function useFetchData(fetch) {
export function useFetchData() {
  // åˆ†é¡µä¿¡æ¯
  const currentPage = ref(1);
  const totalPage = ref(1);
  const page = ref(1);
  const pageNum = ref(1);
  const pageSize = ref(20);
  const total = ref(0);
  watch(currentPage, (nValue, oValue) => {
  watch(page, (nValue, oValue) => {
    if (nValue != oValue) {
      fetchData();
    }
@@ -21,14 +21,20 @@
  // åŠ è½½çŠ¶æ€, 0: åŠ è½½å®Œæˆ; 1: åŠ è½½ä¸­; 2: å·²å…¨éƒ¨åŠ è½½; 3: åŠ è½½å¤±è´¥;
  const loadStatus = ref(0);
  const loading = computed(() => {
    return loadStatus.value == 1;
  });
  // æ•°æ®èŽ·å–
  function fetchData() {
  function fetchData(fetch) {
    loadStatus.value = 1;
    fetch(currentPage.value, pageSize.value)
    fetch(page.value, pageSize.value)
      .then((pageInfo) => {
        currentPage.value = pageInfo.currentPage;
        totalPage.value = pageInfo.totalPage;
        total.value = pageInfo.total;
        if (pageInfo) {
          page.value = pageInfo.page ? pageInfo.page : 1;
          pageNum.value = pageInfo.pageNum ? pageInfo.pageNum : 1;
          total.value = pageInfo.total ? pageInfo.total : 0;
        }
        loadStatus.value = 0;
      })
@@ -40,5 +46,5 @@
      });
  }
  return {currentPage, totalPage, pageSize, total, loadStatus, fetchData}
  return { page, pageNum, pageSize, total, loadStatus, loading, fetchData };
}
src/composables/formConfirm.js
@@ -26,8 +26,7 @@
  // });
  //表单内容
  const formObj = reactive(defaultForm ? defaultForm : {});
  // const formObj = reactive({});
  const formObj = ref(defaultForm ? defaultForm : {});
  let formObjClone = useCloned(formObj, { manual: true });
  //表单组件引用
  const formRef = ref(null);
src/enum/bgTask.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
// è€—时任务枚举
import { Enum } from './enum';
const BG_TASK_TYPE = Enum({
  TEST: {
    name: 'TEST',
    label: '测试任务',
    value: '0'
  },
  AUTO_SCORE: {
    name: 'AUTO_SCORE',
    label: '自动评估任务',
    value: '1'
  }
});
const BG_TASK_STATUS = Enum({
  WAITING: {
    name: 'WAITING',
    label: '等待',
    value: '0'
  },
  RUNNING: {
    name: 'RUNNING',
    label: '运行中',
    value: '1'
  },
  SUCCESS: {
    name: 'SUCCESS',
    label: '任务成功',
    value: '2'
  },
  FAIL: {
    name: 'FAIL',
    label: '任务出错',
    value: '3'
  },
  SHUTDOWN: {
    name: 'SHUTDOWN',
    label: '已关闭',
    value: '4'
  }
});
/**
 * é€šè¿‡åç§°æŸ¥æ‰¾æžšä¸¾ç±»
 * @param {String} name
 * @returns
 */
function nTlBgTask(name) {
  if (name in BG_TASK_TYPE) {
    return BG_TASK_TYPE[name];
  } else if (name in BG_TASK_STATUS) {
    return BG_TASK_STATUS[name];
  }
}
function enumBgTask(allOption = true) {
  const l = _enumBgTask();
  if (!allOption) {
    l.shift();
  }
  return l;
}
function _enumBgTask() {
  return Object.values(BG_TASK_TYPE).unshift({
    label: '全部',
    value: null
  });
}
export { enumBgTask, BG_TASK_TYPE, BG_TASK_STATUS, nTlBgTask };
src/enum/enum.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
const validator = {
  get(target, name) {
    // eslint-disable-next-line no-prototype-builtins
    if (!target.hasOwnProperty(name)) {
      throw new Error(`"${name}" value does not exist in the enum`);
    } else if (typeof target[name] === 'object' && target[name] != null) {
      return new Proxy(target[name], validator);
    } else {
      return target[name];
    }
  },
  set(target, name, value) {
    throw new Error('Cannot add a new value to the enum');
  }
};
export function Enum(baseEnum) {
  return new Proxy(baseEnum, validator);
}
src/views/fysp/evaluation/DataSource.vue
@@ -4,28 +4,17 @@
      <CompPreCheck></CompPreCheck>
    </el-col>
    <el-col :span="8">
      <el-card shadow="never" class="radius">
        <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-button icon="Refresh" type="primary" size="default" :loading="loading" @click="submit"
              >刷新任务</el-button
            >
          </el-row>
        </template>
      </el-card>
      <CompEvaTask></CompEvaTask>
    </el-col>
  </el-row>
</template>
<script>
import CompEvaTask from './components/CompEvaTask.vue';
import CompPreCheck from './components/CompPreCheck.vue';
export default {
  name: 'DataSource',
  components: { CompPreCheck },
  components: { CompPreCheck, CompEvaTask },
  data() {
    return {};
  }
src/views/fysp/evaluation/components/CompEvaTask.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,125 @@
<template>
  <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-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">
        <FYBgTaskCard
          :model="v"
          @start="startTask"
          @shutDown="shutDownTask"
          @remove="removeTask"
          @gotoResult="gotoResult"
        ></FYBgTaskCard>
      </template>
    </el-scrollbar>
  </el-card>
</template>
<script>
/**
 * è‡ªåŠ¨è¯„ä¼°ä»»åŠ¡ç®¡ç†
 */
import { useFetchData } from '@/composables/fetchData';
import bgtaskApi from '@/api/fysp/bgtaskApi';
import { enumBgTask, BG_TASK_TYPE } from '@/enum/bgTask';
export default {
  setup() {
    const { loading, fetchData } = useFetchData();
    return { loading, fetchData };
  },
  data() {
    return {
      taskList: [],
      taskIndex: 0
    };
  },
  methods: {
    _getParam(taskStatus) {
      return {
        type: taskStatus.type,
        id: taskStatus.id
      };
    },
    fetchTask() {
      this.fetchData((page, pageSize) => {
        return bgtaskApi
          .fetchTaskStatus({
            type: BG_TASK_TYPE.TEST.name
          })
          .then((res) => {
            this.taskList = res.data;
          });
      });
    },
    startTask(taskStatus) {
      this.fetchData((page, pageSize) => {
        return bgtaskApi.startTask(this._getParam(taskStatus)).then((res) => {
          this.taskList = this.taskList.concat(res.data);
        });
      });
    },
    newTestTask() {
      this.fetchData((page, pageSize) => {
        return bgtaskApi.newTestTask(`Test-Task-${++this.taskIndex}`).then((res) => {
          this.taskList = this.taskList.concat(res.data);
        });
      });
    },
    startNewTestTask() {
      this.fetchData((page, pageSize) => {
        return bgtaskApi.startNewTestTask(`Test-Task-${++this.taskIndex}`).then((res) => {
          this.taskList = this.taskList.concat(res.data);
        });
      });
    },
    shutDownTask(taskStatus) {
      this.fetchData((page, pageSize) => {
        return bgtaskApi.shutDownTask(this._getParam(taskStatus)).then((res) => {
          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;
          });
        });
      });
    },
    removeTask(taskStatus){
    },
    gotoResult(taskStatus) {
    }
  },
};
</script>
<style scoped>
.scrollbar {
  padding: 8px;
}
</style>
src/views/fysp/evaluation/components/CompHistoryRecord.vue
ÎļþÒÑɾ³ý
src/views/fytz/user/components/CompUserInfo.vue
@@ -92,10 +92,10 @@
const props = defineProps({
  //基本信息
  model: {
    type: Object,
    default: () => {
      return { isenable: true };
    }
    type: Object
    // default: () => {
    //   return { isenable: true };
    // }
  },
  create: {
    type: Boolean,
@@ -107,9 +107,14 @@
  }
});
const formInfo = computed(() => {
  return parseUserInfo(props.model);
});
const formInfo = ref({ isenable: true });
watch(
  () => props.model,
  (nValue) => {
    formInfo.value = parseUserInfo(nValue);
  }
);
const emit = defineEmits(['onSubmit', 'onCancel', 'updateEdit']);