xiatian 5 年 前
コミット
08101bb62a

+ 12 - 1
src/modules/reports/routes/routes.js

@@ -1,6 +1,8 @@
 import Home from "../../portal/views/home/Home.vue";
 import Tips from "../../portal/views/tips/Tips.vue";
 import Project from "../views/Project.vue";
+import Overview from "../views/Overview.vue";
+import ComputeJobList from "../views/ComputeJobList.vue";
 
 export default [
   {
@@ -12,9 +14,18 @@ export default [
         component: Tips
       },
       {
-        path: "project", //分析项目
+        path: "project", //项目列表
         meta: { privilegeCodes: "index_project" },
         component: Project
+      },
+      {
+        path: "overview", //报表展示
+        meta: { privilegeCodes: "index_overview" },
+        component: Overview
+      },
+      {
+        path: "compute-job-list/:projectId",
+        component: ComputeJobList
       }
     ]
   }

+ 230 - 0
src/modules/reports/views/ComputeJobList.vue

@@ -0,0 +1,230 @@
+<template>
+  <section class="content">
+    <div class="box box-info">
+      <div
+        class="box-body"
+        v-loading.body="loading"
+        v-loading.fullscreen="loading"
+        element-loading-text="请稍后..."
+      >
+        <!-- 表单 -->
+        <el-form inline :model="formSearch">
+          <el-form-item>
+            <el-button
+              size="small"
+              type="primary"
+              icon="el-icon-search"
+              @click="handleSearchBtn"
+            >
+              刷新
+            </el-button>
+            <el-button size="small" type="primary" @click="back">
+              返回
+            </el-button>
+          </el-form-item>
+        </el-form>
+
+        <div class="block-seperator"></div>
+        <!-- 页面列表 -->
+        <el-table
+          :data="tableData"
+          border
+          resizable
+          stripe
+          style="width: 100%;"
+        >
+          <el-table-column width="50" label="ID">
+            <span slot-scope="scope">{{ scope.row.id }}</span>
+          </el-table-column>
+          <el-table-column width="120" prop="statusName" label="状态">
+          </el-table-column>
+          <el-table-column width="180" prop="creationTime" label="任务生成时间">
+          </el-table-column>
+          <el-table-column width="180" prop="startTime" label="计算开始时间">
+          </el-table-column>
+          <el-table-column width="180" prop="endTime" label="计算结束时间">
+          </el-table-column>
+          <el-table-column prop="errorDesc" label="错误信息"> </el-table-column>
+          <el-table-column :context="_self" label="操作" width="120">
+            <div slot-scope="scope">
+              <el-button
+                size="mini"
+                type="danger"
+                plain
+                :disabled="disStopJob(scope.row)"
+                @click="stopJob(scope.row)"
+              >
+                终止计算
+              </el-button>
+            </div>
+          </el-table-column>
+        </el-table>
+        <div class="page pull-right">
+          <el-pagination
+            v-if="paginationShow"
+            @current-change="handleCurrentChange"
+            :current-page="currentPage"
+            :page-size="pageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            @size-change="handleSizeChange"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="total"
+          />
+        </div>
+      </div>
+    </div>
+  </section>
+</template>
+<script>
+import { TASK_API } from "@/constants/constants.js";
+import { mapState } from "vuex";
+
+export default {
+  name: "ComputeJobList",
+  data() {
+    return {
+      loading: false,
+
+      paginationShow: false,
+      formSearch: {
+        projectId: ""
+      },
+      tableData: [],
+      currentPage: 1,
+      pageSize: 10,
+      total: 10,
+
+      rules: {
+        passScore: [
+          { required: true, message: "请输入及格分数", trigger: "change" }
+        ],
+        totalScore: [
+          { required: true, message: "请输入满分分数", trigger: "change" }
+        ],
+        partitionDetails: [
+          {
+            required: true,
+            type: "array",
+            message: "请设置分数段",
+            trigger: "change"
+          }
+        ]
+      }
+    };
+  },
+  computed: {
+    ...mapState({ user: state => state.user }),
+    isSuperAdmin() {
+      return this.user.roleList.some(role => role.roleCode == "SUPER_ADMIN");
+    }
+  },
+  methods: {
+    back() {
+      this.$router.push({
+        path: "/reports/overview"
+      });
+    },
+    disStopJob(row) {
+      if (row.status != "NONE" && row.status != "COMPUTING") {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    stopJob(row) {
+      this.loading = true;
+      let url = TASK_API + "/reportsCompute/stopJob/" + row.id;
+      this.$httpWithMsg
+        .post(url)
+        .then(() => {
+          this.$notify({
+            type: "success",
+            message: "操作成功!"
+          });
+          this.searchForm();
+        })
+        .finally(() => (this.loading = false));
+    },
+    handleSearchBtn() {
+      this.currentPage = 1;
+      this.searchForm();
+    },
+    handleSizeChange(val) {
+      this.pageSize = val;
+      this.currentPage = 1;
+      this.searchForm();
+    },
+    handleCurrentChange(val) {
+      this.currentPage = val;
+      this.searchForm();
+    },
+    //查询
+    searchForm() {
+      this.loading = true;
+      var url =
+        TASK_API +
+        "/reportsCompute/page/" +
+        this.formSearch.projectId +
+        "/" +
+        this.currentPage +
+        "/" +
+        this.pageSize;
+      this.$httpWithMsg
+        .get(url, { params: this.formSearch })
+        .then(response => {
+          this.tableData = response.data.list;
+          this.total = response.data.total;
+          this.loading = false;
+
+          this.$nextTick(function() {
+            this.paginationShow = true;
+          });
+        })
+        .finally(() => (this.loading = false));
+    },
+    init() {
+      this.searchForm();
+    }
+  },
+  //初始化查询
+  created() {
+    this.formSearch.projectId = this.$route.params.projectId;
+    this.init();
+  }
+};
+</script>
+
+<style scoped>
+.page {
+  margin-top: 10px;
+}
+.pull-length {
+  width: 100px;
+}
+.details-length {
+  width: 400px;
+}
+.pull-center {
+  margin-top: 20px;
+}
+.editForm .el-form-item {
+  margin-bottom: 12px;
+}
+.partition-main-left-div {
+  width: 300px;
+  padding: 5px;
+  float: left;
+  border: 1px solid #ddd;
+  margin-left: 5px;
+}
+.partition-main-rigth-div {
+  width: 200px;
+  padding: 5px;
+  float: right;
+  border: 1px solid #ddd;
+  margin-right: 5px;
+}
+.partition-detail-div {
+  margin-top: 5px;
+}
+</style>

+ 491 - 0
src/modules/reports/views/Overview.vue

@@ -0,0 +1,491 @@
+<template>
+  <section class="content">
+    <div class="box box-info">
+      <div
+        class="box-body"
+        v-loading.body="loading"
+        v-loading.fullscreen="loading"
+        element-loading-text="请稍后..."
+      >
+        <!-- 表单 -->
+        <el-form inline :model="formSearch">
+          <el-form-item label="项目名称">
+            <el-input
+              placeholder="请输入项目名称"
+              v-model="formSearch.name"
+              style="width: 180px"
+            />
+          </el-form-item>
+          <el-form-item>
+            <el-button
+              size="small"
+              type="primary"
+              icon="el-icon-search"
+              @click="handleSearchBtn"
+            >
+              查询
+            </el-button>
+          </el-form-item>
+        </el-form>
+
+        <div class="block-seperator"></div>
+        <!-- 页面列表 -->
+        <el-table
+          :data="tableData"
+          border
+          resizable
+          stripe
+          style="width: 100%;"
+        >
+          <el-table-column width="50" label="ID">
+            <span slot-scope="scope">{{ scope.row.id }}</span>
+          </el-table-column>
+          <el-table-column prop="name" label="项目名称"> </el-table-column>
+          <el-table-column width="90" prop="analyseTypeName" label="分析类型">
+          </el-table-column>
+          <el-table-column width="90" prop="orgCount" label="中心数量">
+          </el-table-column>
+          <el-table-column width="90" prop="courseCount" label="课程数量">
+          </el-table-column>
+          <el-table-column width="90" prop="passScore" label="及格线">
+          </el-table-column>
+          <el-table-column width="90" prop="partitionCount" label="分段数量">
+          </el-table-column>
+          <el-table-column width="90" prop="reportStatusName" label="项目状态">
+          </el-table-column>
+          <el-table-column :context="_self" label="操作" width="380">
+            <div slot-scope="scope">
+              <el-button
+                size="mini"
+                type="primary"
+                plain
+                :disabled="disSetScore(scope.row)"
+                @click="openEdtDialog(scope.row)"
+              >
+                分段设定
+              </el-button>
+              <el-button
+                v-if="scope.row.reportStatus == 'NONE'"
+                size="mini"
+                type="primary"
+                plain
+                @click="doCompute(scope.row)"
+              >
+                开始统计
+              </el-button>
+              <el-button
+                v-if="scope.row.reportStatus != 'NONE'"
+                size="mini"
+                type="primary"
+                plain
+                :disabled="disReCompute(scope.row)"
+                @click="doCompute(scope.row)"
+              >
+                重新统计
+              </el-button>
+              <el-button
+                size="mini"
+                type="primary"
+                :disabled="disViewReport(scope.row)"
+                plain
+                @click="openEdtDialog(scope.row)"
+              >
+                查看报表
+              </el-button>
+              <el-button
+                size="mini"
+                type="primary"
+                plain
+                @click="viewComputeJob(scope.row.id)"
+              >
+                计算详情
+              </el-button>
+            </div>
+          </el-table-column>
+        </el-table>
+        <div class="page pull-right">
+          <el-pagination
+            v-if="paginationShow"
+            @current-change="handleCurrentChange"
+            :current-page="currentPage"
+            :page-size="pageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            @size-change="handleSizeChange"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="total"
+          />
+        </div>
+      </div>
+      <el-dialog
+        title="及格线及分数段设定"
+        width="600px"
+        :visible.sync="model"
+        :close-on-click-modal="false"
+        @close="closeModel"
+      >
+        <el-form
+          :inline="true"
+          :model="projectForm"
+          ref="projectForm"
+          :rules="rules"
+          label-width="90px"
+          :key="modelKey"
+          class="editForm"
+        >
+          <el-row
+            ><span style="color:#F00" v-if="projectForm.reportStatus != 'NONE'"
+              >重新设定分数将会删除当前项目已生成的报表数据并重新计算!</span
+            ></el-row
+          >
+          <el-row>
+            <el-form-item label="满分" prop="totalScore" class="form-item">
+              <el-input-number
+                size="mini"
+                v-model="projectForm.totalScore"
+                :precision="1"
+                :step="0.5"
+                :min="1"
+                :max="1000"
+              ></el-input-number>
+            </el-form-item>
+            <el-form-item label="及格分" prop="passScore" class="form-item">
+              <el-input-number
+                size="mini"
+                v-model="projectForm.passScore"
+                :precision="1"
+                :step="0.5"
+                :min="0.5"
+                :max="projectForm.totalScore"
+              ></el-input-number>
+            </el-form-item>
+          </el-row>
+          <el-row> <span>分段区域设定</span> </el-row>
+          <div class="block-seperator"></div>
+          <el-row>
+            <el-form-item
+              label="分数段"
+              prop="partitionDetails"
+              class="form-item"
+            >
+              <span style="width: 100px; display: inline-block;">
+                <el-button
+                  v-if="projectForm.partitionDetails.length == 0"
+                  type="primary"
+                  size="mini"
+                  plain
+                  @click="addPartition(0)"
+                  >新增分数段</el-button
+                >
+              </span>
+            </el-form-item>
+          </el-row>
+          <el-row>
+            <div
+              class="partition-main-left-div"
+              v-if="projectForm.partitionDetails.length > 0"
+            >
+              <div
+                class="partition-detail-div"
+                v-for="(item, index) in projectForm.partitionDetails"
+                :key="index"
+              >
+                <span style="min-width: 20px; display: inline-block;">
+                  间断{{ index + 1 }}:
+                </span>
+                <el-input-number
+                  size="mini"
+                  v-model="projectForm.partitionDetails[index]"
+                  :precision="1"
+                  :step="0.5"
+                  :min="0.5"
+                  :max="projectForm.totalScore - 0.5"
+                ></el-input-number>
+                <el-button
+                  :disabled="projectForm.partitionDetails.length == 1"
+                  style="margin: 0 0 0 30px;"
+                  type="danger"
+                  circle
+                  size="mini"
+                  icon="el-icon-minus"
+                  @click="delPartition(index)"
+                ></el-button>
+                <el-button
+                  circle
+                  size="mini"
+                  icon="el-icon-plus"
+                  @click="addPartition(index + 1)"
+                ></el-button>
+              </div>
+            </div>
+            <div
+              class="partition-main-rigth-div"
+              v-if="projectForm.partitionDetails.length > 0"
+            >
+              <div
+                class="partition-detail-div"
+                v-for="(item, index) in projectForm.partitionDetails"
+                :key="index"
+              >
+                <span style="min-width: 20px; display: inline-block;">
+                  <div v-if="index == 0">
+                    0&lt;=分数&lt;{{ projectForm.partitionDetails[index] }}
+                  </div>
+                  <div
+                    v-if="
+                      index > 0 && index < projectForm.partitionDetails.length
+                    "
+                  >
+                    {{ projectForm.partitionDetails[index - 1] }}&lt;=分数&lt;{{
+                      projectForm.partitionDetails[index]
+                    }}
+                  </div>
+                  <div v-if="index == projectForm.partitionDetails.length - 1">
+                    {{ projectForm.partitionDetails[index] }}&lt;=分数&lt;={{
+                      projectForm.totalScore
+                    }}
+                  </div>
+                </span>
+              </div>
+            </div></el-row
+          >
+          <el-row class="pull-center">
+            <el-button
+              type="primary"
+              @click="sub"
+              :loading="this.projectForm.loading"
+              >确定</el-button
+            >
+            <el-button @click="closeModel">取消</el-button>
+          </el-row>
+        </el-form>
+      </el-dialog>
+    </div>
+  </section>
+</template>
+<script>
+import { REPORTS_API } from "@/constants/constants.js";
+import { mapState } from "vuex";
+
+export default {
+  name: "Overview",
+  data() {
+    return {
+      loading: false,
+      model: false,
+      modelKey: Math.random(),
+
+      paginationShow: false,
+      formSearch: {
+        name: "",
+        enable: true
+      },
+      projectForm: {
+        reportStatus: "",
+        passScore: 0.0,
+        totalScore: 0.0,
+        partitionDetails: [],
+        id: null,
+        partitionCount: 0,
+        loading: false
+      },
+      tableData: [],
+      currentPage: 1,
+      pageSize: 10,
+      total: 10,
+
+      rules: {
+        passScore: [
+          { required: true, message: "请输入及格分数", trigger: "change" }
+        ],
+        totalScore: [
+          { required: true, message: "请输入满分分数", trigger: "change" }
+        ],
+        partitionDetails: [
+          {
+            required: true,
+            type: "array",
+            message: "请设置分数段",
+            trigger: "change"
+          }
+        ]
+      }
+    };
+  },
+  computed: {
+    ...mapState({ user: state => state.user }),
+    isSuperAdmin() {
+      return this.user.roleList.some(role => role.roleCode == "SUPER_ADMIN");
+    }
+  },
+  methods: {
+    doCompute(row) {
+      this.loading = true;
+      let url = REPORTS_API + "/project/compute/" + row.id;
+      this.$httpWithMsg
+        .post(url)
+        .then(() => {
+          this.$notify({
+            type: "success",
+            message: "操作成功!"
+          });
+          this.searchForm();
+        })
+        .finally(() => (this.loading = false));
+    },
+    delPartition(index) {
+      this.projectForm.partitionDetails.splice(index, 1);
+    },
+    addPartition(index) {
+      if (index == 0) {
+        this.projectForm.partitionDetails.splice(index, 0, 0.5);
+        this.$refs.projectForm.validate();
+      } else {
+        this.projectForm.partitionDetails.splice(
+          index,
+          0,
+          this.projectForm.partitionDetails[index - 1] + 0.5
+        );
+      }
+    },
+    disSetScore(row) {
+      if (
+        row.reportStatus == "WAITCOMPUTE" ||
+        row.reportStatus == "COMPUTING"
+      ) {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    viewComputeJob(projectId) {
+      this.$router.push({
+        path: "/reports/compute-job-list/" + projectId
+      });
+    },
+    disViewReport(row) {
+      if (row.reportStatus != "SUCCESS") {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    disReCompute(row) {
+      if (
+        row.reportStatus == "NONE" ||
+        row.reportStatus == "WAITCOMPUTE" ||
+        row.reportStatus == "COMPUTING"
+      ) {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    openEdtDialog(row) {
+      this.modelKey = Math.random();
+      this.projectForm = Object.assign({}, row);
+      if (this.projectForm.partitionDetails == null) {
+        this.projectForm.partitionDetails = [];
+      }
+      this.model = true;
+    },
+    async sub() {
+      const res = await this.$refs.projectForm.validate();
+
+      if (res === false) {
+        return;
+      }
+      this.projectForm.loading = true;
+      let url = REPORTS_API + "/project/updateScore";
+      this.$httpWithMsg
+        .post(url, this.projectForm)
+        .then(() => {
+          this.$notify({
+            type: "success",
+            message: "保存成功!"
+          });
+          this.closeModel();
+          this.searchForm();
+        })
+        .finally(() => (this.projectForm.loading = false));
+    },
+    closeModel() {
+      this.model = false;
+      this.$refs.projectForm.resetFields();
+      this.modelKey = Math.random();
+    },
+    handleSearchBtn() {
+      this.currentPage = 1;
+      this.searchForm();
+    },
+    handleSizeChange(val) {
+      this.pageSize = val;
+      this.currentPage = 1;
+      this.searchForm();
+    },
+    handleCurrentChange(val) {
+      this.currentPage = val;
+      this.searchForm();
+    },
+    //查询
+    searchForm() {
+      this.loading = true;
+      var url =
+        REPORTS_API + "/project/page/" + this.currentPage + "/" + this.pageSize;
+      this.$httpWithMsg
+        .get(url, { params: this.formSearch })
+        .then(response => {
+          this.tableData = response.data.list;
+          this.total = response.data.total;
+          this.loading = false;
+
+          this.$nextTick(function() {
+            this.paginationShow = true;
+          });
+        })
+        .finally(() => (this.loading = false));
+    },
+    init() {
+      this.searchForm();
+    }
+  },
+  //初始化查询
+  created() {
+    this.init();
+  }
+};
+</script>
+
+<style scoped>
+.page {
+  margin-top: 10px;
+}
+.pull-length {
+  width: 100px;
+}
+.details-length {
+  width: 400px;
+}
+.pull-center {
+  margin-top: 20px;
+}
+.editForm .el-form-item {
+  margin-bottom: 12px;
+}
+.partition-main-left-div {
+  width: 300px;
+  padding: 5px;
+  float: left;
+  border: 1px solid #ddd;
+  margin-left: 5px;
+}
+.partition-main-rigth-div {
+  width: 200px;
+  padding: 5px;
+  float: right;
+  border: 1px solid #ddd;
+  margin-right: 5px;
+}
+.partition-detail-div {
+  margin-top: 5px;
+}
+</style>