zhangjie vor 5 Jahren
Ursprung
Commit
0a17101663

+ 1 - 0
package.json

@@ -18,6 +18,7 @@
     "vue-echarts": "^5.0.0-beta.0",
     "vue-ls": "^3.2.1",
     "vue-router": "^3.1.6",
+    "vuedraggable": "^2.23.2",
     "vuex": "^3.1.3"
   },
   "devDependencies": {

+ 38 - 4
src/api.js

@@ -167,15 +167,49 @@ export const studentScoreList = datas => {
 // grading -------------------------->
 // grading-user-manage
 export const gradingUserList = datas => {
-  return $get("/api/", datas);
+  return $get("/api/admin/users", datas);
 };
 export const uploadGradingUser = datas => {
   if (datas.id) {
-    return $put(`/api/admin/subject/${datas.id}`, datas);
+    return $put(`/api/admin/users/${datas.id}`, datas);
+    // TODO:跟新之后没有返回任何东西,需要改一下
   } else {
-    return $post("/api/admin/subject", datas);
+    return $post("/api/admin/users", datas);
   }
 };
 export const deleteGradingUser = userId => {
-  return $del("/api/", { userId });
+  return $del(`/api/admin/users/${userId}`);
+};
+// grading-group-manage
+export const gradingGroupList = subjectId => {
+  return $get(`/api/marksubjects/${subjectId}/markergroups`, {});
+};
+export const updateGradingGroup = (subjectId, datas) => {
+  if (datas.groupId) {
+    return $patch(
+      `/api/marksubjects/${subjectId}/markergroups/${datas.groupId}`,
+      datas
+    );
+  } else {
+    return $post(`/api/marksubjects/${subjectId}/markergroups`, datas);
+  }
+};
+export const deleteGradingGroup = (subjectId, groupId) => {
+  return $del(`/api/marksubjects/${subjectId}/markergroups/${groupId}`);
+};
+export const markUserList = ({ workId, subjectId }) => {
+  return $get("/api/markers", { workId, subject: subjectId });
+};
+// grading-progress
+export const gradingProgressDetail = subjectId => {
+  // TODO:
+  return $get(`/api/marksubjects/${subjectId}/markergroups`, {});
+};
+export const createTryGradingTask = datas => {
+  // TODO:
+  return $post(`/api/marksubjects/${datas.subjectId}/markergroups`, datas);
+};
+export const createGradingTask = datas => {
+  // TODO:
+  return $post(`/api/marksubjects/${datas.subjectId}/markergroups`, datas);
 };

+ 18 - 0
src/assets/styles/base.less

@@ -125,6 +125,17 @@ body {
   .ivu-form-item-label {
     text-align: right;
   }
+
+  &-head {
+    margin-bottom: 15px;
+    overflow: hidden;
+    &-left {
+      float: left;
+    }
+    &-right {
+      float: right;
+    }
+  }
 }
 .part-title {
   font-size: 16px;
@@ -173,6 +184,13 @@ body {
   border-collapse: collapse;
   text-align: center;
   margin-bottom: 30px;
+
+  &.table-noborder {
+    th,
+    td {
+      border: none;
+    }
+  }
 }
 .table th {
   padding: 10px;

+ 1 - 0
src/assets/styles/index.less

@@ -5,4 +5,5 @@
 @import "./account.less";
 @import "./common-component.less";
 @import "./main.less";
+@import "./mark.less";
 @import "./iview-style-choosable.less";

+ 4 - 0
src/assets/styles/iview-style-choosable.less

@@ -63,3 +63,7 @@
 .ivu-btn + .ivu-btn {
   margin-left: 10px;
 }
+// .ivu-upload
+.ivu-upload {
+  display: inline-block;
+}

+ 95 - 0
src/assets/styles/mark.less

@@ -0,0 +1,95 @@
+// grading-group-manage
+.grading-group-manage {
+  .ivu-tag {
+    cursor: move;
+  }
+}
+.group-user {
+  min-height: 100px;
+}
+.group-list {
+  font-size: 0;
+  .group-box {
+    display: inline-block;
+    vertical-align: top;
+    font-size: 14px;
+    width: 400px;
+    margin: 10px;
+    background-color: #fff;
+    border-radius: 5px;
+  }
+  .group-head {
+    height: 40px;
+    border-bottom: 1px solid @borderGray;
+  }
+  .group-name {
+    padding: 10px;
+    float: left;
+  }
+  .group-del {
+    float: right;
+    height: 40px;
+    width: 40px;
+    line-height: 40px;
+    text-align: center;
+    font-size: 18px;
+    cursor: pointer;
+
+    &:hover {
+      color: @hoverPink;
+    }
+  }
+  .group-body {
+    padding: 15px;
+    height: 200px;
+  }
+  .group-drag {
+    height: 100%;
+  }
+}
+.group-action {
+  text-align: center;
+  margin-top: 20px;
+  .ivu-btn {
+    width: 100px;
+  }
+}
+
+// grading-progress
+.progress-title {
+  margin-bottom: 15px;
+  > span {
+    margin-right: 15px;
+  }
+}
+// progress-line
+.progress-line {
+  position: relative;
+  display: inline-block;
+  width: 100%;
+  height: 20px;
+  text-align: center;
+  border-radius: 5px;
+  overflow: hidden;
+  .progress-part {
+    position: absolute;
+    height: 100%;
+    > span {
+      display: inline-block;
+      vertical-align: middle;
+      line-height: 1;
+    }
+  }
+  .progress-rate {
+    left: 0;
+    background-color: @green;
+    border-top-left-radius: 5px;
+    border-bottom-left-radius: 5px;
+  }
+  .progress-remain {
+    right: 0;
+    background-color: @unactBtn;
+    border-top-right-radius: 5px;
+    border-bottom-right-radius: 5px;
+  }
+}

+ 2 - 0
src/assets/styles/variables.less

@@ -7,6 +7,8 @@
 
 @pink: #ed4014;
 @hoverPink: #ec9182;
+@green: #19be6b;
+@hoverGreen: #70b492;
 
 @dark: #333;
 @midDark: #666;

+ 20 - 1
src/components/UploadButton.vue

@@ -20,6 +20,7 @@
         btnContent
       }}</Button>
     </Upload>
+    <slot name="extra"></slot>
     <p
       :class="[
         {
@@ -48,7 +49,8 @@ export default {
       default: "default"
     },
     btnContent: {
-      type: String
+      type: String,
+      default: "上传文件"
     },
     format: {
       type: Array,
@@ -79,6 +81,10 @@ export default {
     addFilenameParam: {
       type: String,
       default: "fileName"
+    },
+    autoUpload: {
+      type: Boolean,
+      default: true
     }
   },
   data() {
@@ -87,6 +93,7 @@ export default {
       modalIsShow: false,
       loading: false,
       uploadDataDict: {},
+      file: null,
       res: {
         success: true,
         msg: ""
@@ -108,10 +115,22 @@ export default {
         this.$refs.UploadComp.clearFiles();
       }
     },
+    startUpload() {
+      if (this.file) {
+        this.loading = true;
+        this.$refs.UploadComp.post(this.file);
+      }
+    },
     handleBeforeUpload(file) {
       this.uploadDataDict = { ...this.uploadData };
       if (this.addFilenameParam)
         this.uploadDataDict[this.addFilenameParam] = file.name;
+      this.$emit("file-change", file);
+
+      if (!this.autoUpload) {
+        this.file = file;
+        return false;
+      }
 
       this.loading = true;
       this.$refs.UploadComp.clearFiles();

+ 12 - 0
src/constants/enumerate.js

@@ -56,3 +56,15 @@ export const CODE_TYPE = {
   1: "试卷密号",
   2: "任务密号"
 };
+
+// role type
+export const ROLE_TYPE = {
+  MARKER: "评卷员",
+  MARK_LEADER: "科组长"
+};
+
+export const MARKER_RIGHT_TYPE = {
+  ALLOW_LEVELING: "只允许分档",
+  ALLOW_SCORING: "只允许打分",
+  ALLOW_ALL: "允许分档打分"
+};

+ 145 - 3
src/modules/grading/GradingGroupManage.vue

@@ -1,15 +1,157 @@
 <template>
   <div class="grading-group-manage">
-    grading-group-manage
+    <div class="part-box-top">
+      <Button type="success" icon="md-add" @click="toAddGroup">新增分组</Button>
+    </div>
+    <div class="group-user part-box" v-if="users.length">
+      <draggable group="user" :list="users">
+        <Tag
+          color="primary"
+          size="large"
+          v-for="(user, uindex) in users"
+          :key="uindex"
+        >
+          {{ user.name }}
+        </Tag>
+      </draggable>
+    </div>
+    <div class="group-list">
+      <div class="group-box" v-for="(group, gindex) in groups" :key="gindex">
+        <div class="group-head">
+          <h2 class="group-name">{{ group.name }}</h2>
+          <div class="group-del" @click="delGroup(gindex)">
+            <Icon type="md-close" />
+          </div>
+        </div>
+        <div class="group-body">
+          <draggable class="group-drag" group="user" :list="group.markers">
+            <Tag
+              color="primary"
+              size="large"
+              v-for="(user, uindex) in group.markers"
+              :key="uindex"
+              @on-close="removeGroupUser(uindex, group)"
+              closable
+            >
+              {{ user.name }}
+            </Tag>
+          </draggable>
+        </div>
+      </div>
+    </div>
+    <div class="group-action">
+      <Button
+        type="primary"
+        @click="submit"
+        :disabled="!this.groups.length || isSubmit"
+        >确认</Button
+      >
+    </div>
   </div>
 </template>
 
 <script>
+import {
+  gradingGroupList,
+  markUserList,
+  updateGradingGroup,
+  deleteGradingGroup
+} from "@/api";
+import draggable from "vuedraggable";
+
 export default {
   name: "grading-group-manage",
+  components: { draggable },
   data() {
-    return {};
+    return {
+      workId: this.$route.params.workId,
+      subjectId: this.$route.params.subjectId,
+      groups: [],
+      users: [],
+      isSubmit: false
+    };
+  },
+  mounted() {
+    this.getGroupList();
+    this.getMarkUserList();
   },
-  methods: {}
+  methods: {
+    async getGroupList() {
+      this.groups = await gradingGroupList(this.subjectId);
+    },
+    async getMarkUserList() {
+      const data = await markUserList({
+        workId: this.workId,
+        subjectId: this.subjectId.split("-")[1]
+      });
+      this.users = data.filter(user => !user.groupId);
+    },
+    submit() {
+      if (this.isSubmit) return;
+      const hasNoneGroup = this.groups.some(group => !group.markers.length);
+      if (hasNoneGroup) {
+        this.$Modal.confirm({
+          title: "操作警告",
+          content: "当前分组列表中存在空组,确定要保存空组吗?",
+          onOk: () => {
+            this.save();
+          }
+        });
+        return;
+      }
+      this.save();
+    },
+    async save() {
+      this.isSubmit = true;
+      const toSaveAll = this.groups.map(group => {
+        return updateGradingGroup(this.subjectId, group);
+      });
+      const result = await Promise.all(toSaveAll).catch(() => {});
+      this.isSubmit = false;
+      if (!result) {
+        this.$Message.error("保存失败,请重新尝试!");
+        return;
+      }
+      this.$Message.success("保存成功!");
+    },
+    toAddGroup() {
+      this.groups.push({
+        id: "",
+        name: "评卷组" + (this.groups.length + 1),
+        markers: [],
+        subject: this.subjectId.split("-")[1],
+        workId: this.workId
+      });
+    },
+    removeGroupUser(uindex, group) {
+      this.users.push({ ...group.markers[uindex] });
+      group.markers.splice(uindex, 1);
+    },
+    delGroup(gindex) {
+      const group = this.groups[gindex];
+      if (!group.id) {
+        this.removeGroup(gindex);
+        return;
+      }
+
+      this.$Modal.confirm({
+        title: "删除警告",
+        content: "确定要删除当前账号吗?",
+        onOk: async () => {
+          await deleteGradingGroup(this.subjectId, group.id);
+          this.removeGroup(gindex);
+          this.$Message.success("删除成功!");
+        }
+      });
+    },
+    removeGroup(gindex) {
+      const group = this.groups[gindex];
+      this.users = [...this.users, ...group.markers];
+      this.groups.splice(gindex, 1);
+      this.groups.map((group, index) => {
+        group.name = "评卷组" + (index + 1);
+      });
+    }
+  }
 };
 </script>

+ 154 - 3
src/modules/grading/GradingProgress.vue

@@ -1,15 +1,166 @@
 <template>
   <div class="grading-progress">
-    grading-progress
+    <div class="progress-title">
+      <span>当前阶段:{{ stepName }}</span
+      ><span>进度:{{ stepProgress }}</span>
+    </div>
+    <div class="part-box-head">
+      <div class="part-box-head-left">
+        <Button type="primary" @click="toGrading">正评任务创建</Button>
+        <Button type="primary" @click="toTryGrading">试评任务创建</Button>
+        <Button type="primary" @click="toMark">进入打分阶段</Button>
+      </div>
+      <div class="part-box-head-right">
+        <Button type="primary" icon="md-download" @click="toExportStandard"
+          >导出标准卷信息</Button
+        >
+        <Button type="primary" icon="md-download" @click="toExportGrading"
+          >导出一键定档信息</Button
+        >
+      </div>
+    </div>
+    <div class="part-box">
+      <div class="progress-table">
+        <table class="table table-noborder">
+          <tr v-for="(area, aindex) in areaInfos" :key="aindex">
+            <td style="width: 12%">{{ area.name }}</td>
+            <td style="width: 60%;">
+              <progress-line
+                :sum="area.sum"
+                :current="area.current"
+              ></progress-line>
+            </td>
+            <td style="width: 14%;">进度:{{ area.progress }}%</td>
+            <td style="width: 14%;"></td>
+          </tr>
+        </table>
+      </div>
+      <div class="progress-table">
+        <table class="table table-noborder">
+          <tr v-for="(area, aindex) in userInfos" :key="aindex">
+            <td style="width: 12%">{{ area.name }}</td>
+            <td style="width: 60%;">
+              <progress-line
+                :sum="area.sum"
+                :current="area.current"
+              ></progress-line>
+            </td>
+            <td style="width: 14%;">进度:{{ area.progress }}%</td>
+            <td style="width: 14%;">打回:{{ area.arbitration }}</td>
+          </tr>
+        </table>
+      </div>
+    </div>
+
+    <!-- modify-unformal-grading-task -->
+    <modify-unformal-grading-task
+      ref="ModifyUnformalGradingTask"
+    ></modify-unformal-grading-task>
+    <!-- modify-formal-grading-task -->
+    <modify-formal-grading-task
+      ref="ModifyFormalGradingTask"
+    ></modify-formal-grading-task>
   </div>
 </template>
 
 <script>
+import ProgressLine from "./components/ProgressLine";
+import ModifyUnformalGradingTask from "./components/ModifyUnformalGradingTask";
+import ModifyFormalGradingTask from "./components/ModifyFormalGradingTask";
+import { gradingProgressDetail } from "@/api";
+
 export default {
   name: "grading-progress",
+  components: {
+    ProgressLine,
+    ModifyUnformalGradingTask,
+    ModifyFormalGradingTask
+  },
   data() {
-    return {};
+    return {
+      subjectId: this.$route.params.subjectId,
+      stepName: "采集阶段",
+      stepProgress: "95.56%",
+      areaInfos: [
+        {
+          name: "总体进度",
+          sum: 5500,
+          current: 0,
+          progress: 0
+        },
+        {
+          name: "考区1进度",
+          sum: 1000,
+          current: 990,
+          progress: 100
+        },
+        {
+          name: "考区2进度",
+          sum: 5500,
+          current: 2000,
+          progress: 45.45
+        },
+        {
+          name: "考区3进度",
+          sum: 5500,
+          current: 2000,
+          progress: 45.45
+        }
+      ],
+      userInfos: [
+        {
+          name: "科组长",
+          sum: 5500,
+          current: 2000,
+          arbitration: 10,
+          progress: 45.45
+        },
+        {
+          name: "评卷员1",
+          sum: 5500,
+          current: 2000,
+          arbitration: 10,
+          progress: 45.45
+        },
+        {
+          name: "评卷员2",
+          sum: 5500,
+          current: 2000,
+          arbitration: 10,
+          progress: 45.45
+        },
+        {
+          name: "评卷员3",
+          sum: 5500,
+          current: 2000,
+          arbitration: 10,
+          progress: 45.45
+        }
+      ]
+    };
   },
-  methods: {}
+  methods: {
+    async getData() {
+      const data = await gradingProgressDetail(this.subjectId);
+      console.log(data);
+    },
+    toGrading() {
+      this.$refs.ModifyFormalGradingTask.open();
+    },
+    toTryGrading() {
+      this.$refs.ModifyUnformalGradingTask.open();
+    },
+    toMark() {
+      this.$Modal.confirm({
+        title: "操作警告",
+        content: "确定要进入打分阶段吗?",
+        onOk: () => {
+          console.log("ok");
+        }
+      });
+    },
+    toExportStandard() {},
+    toExportGrading() {}
+  }
 };
 </script>

+ 16 - 4
src/modules/grading/GradingUserManage.vue

@@ -2,6 +2,9 @@
   <div class="grading-user-manage">
     <div class="part-box-top">
       <Button type="success" icon="md-add" @click="toAdd">新增</Button>
+      <Button type="primary" icon="md-download" @click="toExport"
+        >导出表格</Button
+      >
     </div>
     <div class="part-box">
       <Table
@@ -25,6 +28,7 @@
 <script>
 import { gradingUserList, deleteGradingUser, resetPwd } from "@/api";
 import ModifyGradingUser from "./components/ModifyGradingUser";
+import { ROLE_TYPE, MARKER_RIGHT_TYPE } from "@/constants/enumerate";
 
 export default {
   name: "grading-user-manage",
@@ -44,7 +48,7 @@ export default {
         },
         {
           title: "科目",
-          key: "subjectName"
+          key: "subject"
         },
         {
           title: "账号",
@@ -99,14 +103,21 @@ export default {
       ]
     };
   },
+  mounted() {
+    this.getList();
+  },
   methods: {
     async getList() {
       const datas = {
         workId: this.workId,
-        subjectId: this.subjectId
+        subject: this.subjectId.split("-")[1]
       };
       const data = await gradingUserList(datas);
-      this.users = data;
+      this.users = data.map(item => {
+        item.roleName = ROLE_TYPE[item.role];
+        item.rightName = MARKER_RIGHT_TYPE[item.markRight];
+        return item;
+      });
     },
     async toResetPwd(row) {
       await resetPwd(row.id);
@@ -136,7 +147,8 @@ export default {
       await deleteGradingUser(id);
       this.$Message.success("删除成功!");
       this.getList();
-    }
+    },
+    toExport() {}
   }
 };
 </script>

+ 100 - 0
src/modules/grading/components/ModifyFormalGradingTask.vue

@@ -0,0 +1,100 @@
+<template>
+  <Modal
+    class="modify-formal-grading-task"
+    v-model="modalIsShow"
+    title="创建正评任务"
+    :mask-closable="false"
+    @on-visible-change="visibleChange"
+  >
+    <Form
+      ref="modalFormComp"
+      :model="modalForm"
+      :rules="rules"
+      :key="modalForm.id"
+      :label-width="120"
+    >
+      <FormItem prop="areaCode" label="考区">
+        <Select v-model="modalForm.areaCode" placeholder="请选择考区">
+          <Option value=""></Option>
+        </Select>
+      </FormItem>
+      <FormItem label="已评数量">
+        <Input v-model.trim="modalForm.gradedCount" readonly></Input>
+      </FormItem>
+      <FormItem label="待评数量">
+        <Input v-model.trim="modalForm.waitCount" readonly></Input>
+      </FormItem>
+      <FormItem label="整体进度">
+        <Input v-model.trim="modalForm.gradedProgress" readonly></Input>
+      </FormItem>
+      <FormItem prop="taskCount" label="分配任务数量">
+        <InputNumber
+          :min="1"
+          :max="modalForm.waitCount"
+          :precision="0"
+          v-model.trim="modalForm.taskCount"
+          style="width: 120px"
+          clearable
+        ></InputNumber>
+      </FormItem>
+    </Form>
+    <div slot="footer">
+      <Button type="text" @click="cancel">取消</Button>
+      <Button type="primary" :disabled="isSubmit" @click="submit"
+        >发布评卷任务</Button
+      >
+    </div>
+  </Modal>
+</template>
+
+<script>
+import { createTryGradingTask } from "@/api";
+// import { password } from "@/plugins/formRules";
+
+const initModalForm = {
+  areaCode: "",
+  taskCount: null
+};
+
+export default {
+  name: "modify-formal-grading-task",
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      modalForm: { ...initModalForm },
+      rules: {}
+    };
+  },
+  methods: {
+    visibleChange(visible) {
+      if (visible) {
+        this.modalForm = { ...initModalForm };
+      }
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate();
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const data = await createTryGradingTask(this.modalForm).catch(() => {
+        this.isSubmit = false;
+      });
+
+      if (!data) return;
+
+      this.isSubmit = false;
+      this.$Message.success("发布任务成功!");
+      this.$emit("modified");
+      this.cancel();
+    }
+  }
+};
+</script>

+ 43 - 17
src/modules/grading/components/ModifyGradingUser.vue

@@ -34,31 +34,54 @@
           clearable
         ></Input>
       </FormItem>
-      <FormItem prop="roleCode" label="角色">
-        <Select v-model="modalForm.roleCode" placeholder="请选择角色">
-          <Option value=""></Option>
+      <FormItem prop="role" label="角色">
+        <Select v-model="modalForm.role" placeholder="请选择角色">
+          <Option
+            v-for="(val, key) in ROLE_TYPE"
+            :key="key"
+            :value="key"
+            :label="val"
+          ></Option>
         </Select>
       </FormItem>
-      <FormItem prop="rightCode" label="权限">
-        <Select v-model="modalForm.rightCode" placeholder="请选择权限">
-          <Option value=""></Option>
+      <FormItem
+        prop="markRight"
+        label="权限"
+        v-if="modalForm.role === 'MARKER'"
+      >
+        <Select v-model="modalForm.markRight" placeholder="请选择权限">
+          <Option
+            v-for="(val, key) in MARKER_RIGHT_TYPE"
+            :key="key"
+            :value="key"
+            :label="val"
+          ></Option>
         </Select>
       </FormItem>
-      <FormItem prop="weight" label="权重">
+      <FormItem
+        prop="weight"
+        label="权重"
+        v-if="
+          modalForm.role === 'MARKER' &&
+            modalForm.markRight &&
+            modalForm.markRight !== 'ALLOW_SCORING'
+        "
+      >
         <InputNumber
           v-model.trim="modalForm.weight"
           :min="1"
           :max="100"
+          :precision="2"
           placeholder="请输入权重"
           style="width: 120px"
         ></InputNumber>
       </FormItem>
-      <FormItem>
-        <Checkbox v-model="modalForm.canConfirmGrade">是否一键定档</Checkbox
+      <FormItem v-if="modalForm.role === 'MARK_LEADER'">
+        <Checkbox v-model="modalForm.oneClickLevel">是否一键定档</Checkbox
         ><br />
-        <Checkbox v-model="modalForm.canSetStandard">是否设立标准卷</Checkbox
+        <Checkbox v-model="modalForm.standardVolume">是否设立标准卷</Checkbox
         ><br />
-        <Checkbox v-model="modalForm.canRufuseGrade"
+        <Checkbox v-model="modalForm.levelCallback"
           >是否建议档位打回档</Checkbox
         >
       </FormItem>
@@ -73,20 +96,21 @@
 <script>
 import { uploadGradingUser } from "@/api";
 import { password } from "@/plugins/formRules";
+import { ROLE_TYPE, MARKER_RIGHT_TYPE } from "@/constants/enumerate";
 
 const initModalForm = {
   id: "",
   workId: "",
-  subjectId: "",
+  subject: "",
   loginName: "",
   password: "123456",
   name: "",
-  roleCode: null,
-  rightCode: null,
+  role: null,
+  markRight: null,
   weight: null,
-  canConfirmGrade: false,
-  canSetStandard: false,
-  canRufuseGrade: false
+  oneClickLevel: false,
+  standardVolume: false,
+  levelCallback: false
 };
 
 export default {
@@ -111,6 +135,8 @@ export default {
     return {
       modalIsShow: false,
       isSubmit: false,
+      ROLE_TYPE,
+      MARKER_RIGHT_TYPE,
       modalForm: { ...initModalForm },
       rules: {
         loginName: [

+ 104 - 0
src/modules/grading/components/ModifyUnformalGradingTask.vue

@@ -0,0 +1,104 @@
+<template>
+  <Modal
+    class="modify-unformal-grading-task"
+    v-model="modalIsShow"
+    title="创建试评任务"
+    :mask-closable="false"
+    @on-visible-change="visibleChange"
+  >
+    <div class="task-body">
+      <upload-button
+        btn-icon="md-cloud-upload"
+        :btn-content="uploadBtnName"
+        :upload-url="uploadUrl"
+        :upload-data="data"
+        :format="['xls', 'xlsx']"
+        :auto-upload="false"
+        @upload-success="uploadSuccess"
+        @file-change="selectedFile"
+        ref="UploadButton"
+      >
+        <Button
+          type="primary"
+          :disabled="$refs.UploadButton && $refs.UploadButton.loading"
+          @click="startUpload"
+          style="margin-left: 10px"
+          slot="extra"
+          >开始上传</Button
+        >
+      </upload-button>
+    </div>
+    <div slot="footer">
+      <Button type="text" @click="cancel">取消</Button>
+      <Button type="primary" :disabled="isSubmit" @click="submit"
+        >开始试评</Button
+      >
+    </div>
+  </Modal>
+</template>
+
+<script>
+import { uploadGradingUser } from "@/api";
+import UploadButton from "@/components/UploadButton";
+
+export default {
+  name: "modify-unformal-grading-task",
+  components: { UploadButton },
+  props: {
+    data: {
+      type: Object,
+      default() {
+        return {};
+      }
+    }
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      uploadBtnName: "导入考生数据",
+      uploadUrl: this.GLOBAL.domain + "/import/students/batchAllForTrial"
+    };
+  },
+  methods: {
+    visibleChange(visible) {
+      if (visible) {
+        console.log("try");
+      }
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    startUpload() {
+      this.$refs.UploadButton.startUpload();
+    },
+    selectedFile(file) {
+      this.uploadBtnName = file.name;
+    },
+    uploadSuccess(response) {
+      this.uploadBtnName = "导入考生数据";
+      console.log(response);
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate();
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const data = await uploadGradingUser(this.modalForm).catch(() => {
+        this.isSubmit = false;
+      });
+
+      if (!data) return;
+
+      this.isSubmit = false;
+      this.$Message.success("发布任务成功!");
+      this.$emit("modified");
+      this.cancel();
+    }
+  }
+};
+</script>

+ 44 - 0
src/modules/grading/components/ProgressLine.vue

@@ -0,0 +1,44 @@
+<template>
+  <div class="progress-line">
+    <div class="progress-part progress-rate" :style="{ width: progress + '%' }">
+      <span>{{ current }}</span>
+    </div>
+    <div
+      class="progress-part progress-remain"
+      :style="{ width: 100 - progress + '%' }"
+    >
+      <span v-if="progress < 99.9">{{ sum - current }}</span>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "progress-line",
+  props: {
+    sum: {
+      type: Number,
+      default: 0
+    },
+    current: {
+      type: Number,
+      default: 0
+    },
+    minRate: {
+      type: Number,
+      default: 1
+    }
+  },
+  data() {
+    return {};
+  },
+  computed: {
+    progress() {
+      const rate = this.sum ? (this.current / this.sum).toFixed(4) * 100 : 0;
+
+      return rate || this.minRate;
+    }
+  },
+  methods: {}
+};
+</script>

+ 12 - 0
yarn.lock

@@ -7563,6 +7563,11 @@ sort-keys@^1.0.0:
   dependencies:
     is-plain-obj "^1.0.0"
 
+sortablejs@^1.10.1:
+  version "1.10.2"
+  resolved "https://registry.npm.taobao.org/sortablejs/download/sortablejs-1.10.2.tgz#6e40364d913f98b85a14f6678f92b5c1221f5290"
+  integrity sha1-bkA2TZE/mLhaFPZnj5K1wSIfUpA=
+
 source-list-map@^2.0.0:
   version "2.0.1"
   resolved "https://registry.npm.taobao.org/source-list-map/download/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
@@ -8573,6 +8578,13 @@ vue@^2.6.11:
   resolved "https://registry.npm.taobao.org/vue/download/vue-2.6.11.tgz?cache=0&sync_timestamp=1589227039789&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue%2Fdownload%2Fvue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5"
   integrity sha1-dllNh31LEiNEBuhONSdcbVFBJcU=
 
+vuedraggable@^2.23.2:
+  version "2.23.2"
+  resolved "https://registry.npm.taobao.org/vuedraggable/download/vuedraggable-2.23.2.tgz#0d95d7fdf4f02f56755a26b3c9dca5c7ca9cfa72"
+  integrity sha1-DZXX/fTwL1Z1Wiazydylx8qc+nI=
+  dependencies:
+    sortablejs "^1.10.1"
+
 vuex@^3.1.3:
   version "3.4.0"
   resolved "https://registry.npm.taobao.org/vuex/download/vuex-3.4.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvuex%2Fdownload%2Fvuex-3.4.0.tgz#20cc086062d750769fce1febb34e7fceeaebde45"