zhangjie 2 жил өмнө
parent
commit
d76948aa35

+ 1085 - 1077
src/assets/styles/mark.less

@@ -1,1077 +1,1085 @@
-// grading-group-manage
-.grading-group-manage {
-  .ivu-tag {
-    cursor: move;
-  }
-  .group-user {
-    min-height: 76px;
-    padding: 20px 20px 10px;
-    position: relative;
-  }
-  .group-user-list {
-    margin-right: 130px;
-    .ivu-btn {
-      margin-bottom: 10px;
-    }
-  }
-  .group-user-action {
-    position: absolute;
-    top: 20px;
-    right: 20px;
-    z-index: auto;
-  }
-}
-.group-list {
-  font-size: 0;
-  margin: -10px;
-
-  .group-box {
-    display: inline-block;
-    vertical-align: top;
-    font-size: 14px;
-    width: 25%;
-    padding: 10px;
-  }
-
-  &-1 {
-    .group-box {
-      width: 100%;
-    }
-  }
-  &-2 {
-    .group-box {
-      width: 50%;
-    }
-  }
-  &-3 {
-    .group-box {
-      width: 33.33%;
-    }
-  }
-  .group-container {
-    border-radius: @box-border-radius;
-    background-color: @white;
-  }
-  .group-head {
-    height: 56px;
-    padding: 15px;
-    border-bottom: 1px solid #f3f3f3;
-    font-size: 18px;
-    font-weight: 600;
-    line-height: 25px;
-    text-align: center;
-    position: relative;
-  }
-  .group-del {
-    position: absolute;
-    top: 15px;
-    right: 10px;
-    height: 24px;
-    width: 24px;
-    line-height: 24px;
-    font-size: 18px;
-    text-align: center;
-    color: @dark-color-lighter;
-    background-color: @background-color;
-    border-radius: @box-border-radius;
-    cursor: pointer;
-
-    &:hover {
-      background-color: @error-color;
-      color: @white;
-    }
-  }
-  .group-body {
-    padding: 15px;
-    height: 200px;
-  }
-  .group-drag {
-    height: 100%;
-  }
-}
-.group-action {
-  text-align: center;
-  margin-top: 20px;
-  .ivu-btn {
-    width: 100px;
-  }
-}
-
-// grading
-.grading-subnav {
-  display: flex;
-  justify-content: space-between;
-  .grading-title {
-    padding: 0 10px;
-
-    > h1 {
-      display: inline-block;
-      vertical-align: middle;
-      font-size: 20px;
-      font-weight: 600;
-      margin-right: 20px;
-    }
-    > span {
-      display: inline-block;
-      vertical-align: middle;
-      margin-right: 15px;
-      color: @dark-color-light;
-    }
-  }
-}
-
-// grading-progress
-.progress-table {
-  height: 100%;
-  .progress-line {
-    width: 230px;
-  }
-  .kzz-table {
-    margin-bottom: 10px;
-    padding-bottom: 10px;
-    border-bottom: 1px dashed #e1dfe0;
-  }
-  td:first-child {
-    font-weight: 600;
-    color: @dark-color;
-    width: 100px;
-  }
-}
-// progress-line
-.progress-line {
-  position: relative;
-  display: inline-block;
-  width: 100%;
-  height: 12px;
-  text-align: center;
-  border-radius: 6px;
-  background-color: @background-color;
-  font-size: 12px;
-  color: @dark-color;
-  line-height: 1;
-  .progress-part {
-    position: absolute;
-    height: 100%;
-    > span {
-      display: inline-block;
-      vertical-align: middle;
-      line-height: 1;
-    }
-  }
-  .progress-rate {
-    position: absolute;
-    height: 100%;
-    left: 0;
-    background-color: @info-color;
-    border-radius: 6px;
-    text-align: center;
-  }
-  .progress-current {
-    display: inline-block;
-    vertical-align: middle;
-  }
-
-  .progress-remain {
-    display: block;
-    position: absolute;
-    height: 100%;
-    right: 5px;
-    z-index: 9;
-  }
-}
-// modify-formal-grading-task
-.modify-formal-grading-task {
-  .tips-info {
-    margin-bottom: 15px;
-    text-align: center;
-  }
-}
-// modify-unformal-grading-task
-.modify-unformal-grading-task {
-  .task-body {
-    min-height: 90px;
-    text-align: center;
-  }
-  .task-tips {
-    font-size: 18px;
-    color: @dark-color-light;
-  }
-  .task-action {
-    overflow: hidden;
-    > button {
-      float: right;
-
-      &:first-child {
-        float: left;
-      }
-    }
-  }
-}
-
-// grade-step
-.grade-step {
-  font-size: 0;
-  margin-bottom: 4px;
-  &-level {
-    white-space: nowrap;
-    overflow-x: scroll;
-    overflow-y: visible;
-    padding: 0 0 10px;
-  }
-  &-other {
-    float: right;
-    padding: 0 0 10px 20px;
-  }
-  .step-item {
-    display: inline-block;
-    vertical-align: top;
-    padding: 10px;
-    min-width: 90px;
-    background-color: @white;
-    border-radius: @box-border-radius-small;
-    color: @dark-color-light;
-    text-align: center;
-    cursor: pointer;
-    &:not(:last-child) {
-      margin-right: 10px;
-    }
-    &:hover {
-      box-shadow: 0px 10px 15px 0px rgba(34, 192, 255, 0.4);
-    }
-    p {
-      font-size: 12px;
-      height: 17px;
-      line-height: 17px;
-    }
-    .step-name {
-      color: @dark-color;
-      font-size: 24px;
-      font-weight: 600;
-      height: 32px;
-      line-height: 32px;
-    }
-
-    &.step-analysis {
-      width: 72px;
-      min-width: auto;
-      margin-right: 20px;
-      .step-name {
-        font-size: 20px;
-      }
-    }
-    &.step-other {
-      min-width: 72px;
-      .step-name {
-        font-size: 20px;
-      }
-    }
-
-    &.step-act {
-      background-color: @info-color;
-      color: @white;
-      box-shadow: 0px 10px 15px 0px rgba(34, 192, 255, 0.4);
-      .step-name {
-        color: @white;
-      }
-    }
-  }
-}
-.mark-step {
-  .step-item {
-    min-width: 60px;
-  }
-}
-
-// grading-detail
-.grading-detail {
-  .grade-filter {
-    position: fixed;
-    left: 0;
-    top: 50%;
-    z-index: 199;
-    width: 20px;
-    transform: translateY(-50%);
-    transition: width 0.2s ease-in;
-    overflow: hidden;
-
-    .ivu-form {
-      white-space: nowrap;
-    }
-    .ivu-form-item {
-      margin-right: 10px;
-    }
-    .ivu-form-item:last-child {
-      margin-right: 0;
-    }
-
-    &-form {
-      display: none;
-    }
-    .detail-area {
-      background-color: @success-color;
-      border-radius: 3px;
-      color: @dark-color-light;
-      font-size: 12px;
-      line-height: 16px;
-      width: 20px;
-      padding: 5px 3px;
-      text-align: center;
-      color: #fff;
-      cursor: pointer;
-
-      &:hover {
-        background-color: fade(@success-color, 80%);
-      }
-    }
-
-    &-select {
-      width: 290px;
-      background-color: #fff;
-      padding: 10px 10px 0;
-      border-top-right-radius: 5px;
-      border-bottom-right-radius: 5px;
-      box-shadow: 0 0 15px #c0c0c0;
-      .grade-filter-form {
-        display: block;
-      }
-      .detail-area {
-        display: none;
-      }
-    }
-  }
-  .grade-step {
-    flex-grow: 0;
-  }
-
-  .detail-body {
-    flex-grow: 2;
-    min-height: 400px;
-    display: flex;
-    justify-content: space-between;
-
-    &-2 {
-      .detail-papers-list {
-        width: 100%;
-      }
-    }
-  }
-  .detail-action {
-    width: 280px;
-    padding: 20px;
-    margin-left: 20px;
-    background-color: @white;
-    border-radius: @box-border-radius;
-    overflow-x: hidden;
-    overflow-y: auto;
-    flex-grow: 0;
-  }
-  .detail-action-fullscreen {
-    position: fixed;
-    width: 280px;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    z-index: 98;
-    border-radius: 0;
-    min-height: auto;
-    margin: 0;
-    overflow-y: auto;
-    overflow-x: hidden;
-    z-index: 999;
-  }
-  .detail-papers {
-    padding: 0 20px;
-    background-color: @white;
-    border-radius: @box-border-radius;
-    font-size: 0;
-    flex-grow: 2;
-    display: flex;
-    justify-content: space-between;
-    min-height: 400px;
-
-    &-carousel {
-      position: relative;
-      padding: 10px 0 70px;
-      font-size: 14px;
-      &-split {
-        height: 40px;
-      }
-      &::after {
-        content: "";
-        position: absolute;
-        height: 100%;
-        border-left: 1px solid #eff0f5;
-        right: 0;
-        top: 0;
-        z-index: auto;
-      }
-    }
-    &-list {
-      width: 100%;
-      font-size: 14px;
-      position: relative;
-      padding: 10px 0 70px;
-      .image-view-list {
-        margin: 0;
-        height: 100%;
-      }
-      .part-page {
-        position: absolute;
-        bottom: 20px;
-        width: 100%;
-        z-index: auto;
-        margin: 0;
-      }
-    }
-    &-none {
-      padding-top: 200px;
-      text-align: center;
-      font-size: 24px;
-      color: @dark-color-lighter;
-    }
-
-    &-col-3 {
-      .detail-papers-carousel {
-        width: 33.33%;
-      }
-      .detail-papers-list {
-        width: 66.66%;
-      }
-    }
-    &-col-4 {
-      .detail-papers-carousel {
-        width: 25%;
-      }
-      .detail-papers-list {
-        width: 75%;
-      }
-    }
-    &-col-5 {
-      .detail-papers-carousel {
-        width: 20%;
-      }
-      .detail-papers-list {
-        width: 80%;
-      }
-    }
-    &-col-6 {
-      .detail-papers-carousel {
-        width: 16.66%;
-      }
-      .detail-papers-list {
-        width: 83.33%;
-      }
-    }
-
-    .ivu-page {
-      text-align: center;
-    }
-  }
-  &-image-preview {
-    .ivu-modal-mask,
-    .ivu-modal-wrap {
-      left: 0;
-      bottom: 0;
-      top: 0;
-      right: 280px;
-    }
-  }
-}
-// mark-detail
-
-// grading-operation
-.grading-operation {
-  .detail-action-fullscreen {
-    top: 0;
-  }
-  &-image-preview {
-    .ivu-modal-mask,
-    .ivu-modal-wrap {
-      left: 0;
-      bottom: 0;
-      top: 0;
-      right: 280px;
-    }
-  }
-}
-
-/* paper-carousel */
-.paper-carousel {
-  position: absolute;
-  top: 48px;
-  bottom: 62px;
-  left: 10px;
-  right: 10px;
-
-  .carousel-body > img {
-    position: absolute;
-    max-width: 100%;
-    max-height: 100%;
-    width: auto;
-    height: auto;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    margin: auto;
-    cursor: pointer;
-  }
-  .carousel-none {
-    color: @dark-color-lighter;
-    font-size: @font-size-base;
-    text-align: center;
-    position: absolute;
-    width: 100%;
-    top: 50%;
-    left: 0;
-    transform: translateY(-50%);
-    z-index: 8;
-    > i {
-      font-size: 30px;
-    }
-  }
-  .carousel-btn {
-    position: absolute;
-    width: 40px;
-    height: 40px;
-    top: 50%;
-    z-index: 9;
-    margin-top: -20px;
-    text-align: center;
-    line-height: 40px;
-    font-size: 36px;
-    color: #ccc;
-    cursor: pointer;
-
-    &:hover {
-      color: @main-color;
-    }
-
-    &-left {
-      left: 0;
-    }
-    &-right {
-      right: 0;
-    }
-  }
-}
-
-// .grade-history-paper
-.grade-history-paper {
-  position: relative;
-  padding: 10px;
-  width: 100%;
-  height: 50%;
-
-  .carousel-title {
-    text-align: center;
-    height: 32px;
-    line-height: 32px;
-    margin-bottom: 6px;
-    > h3 {
-      font-size: 16px;
-    }
-  }
-}
-// grade-standard-paper
-.grade-standard-paper {
-  position: relative;
-  padding: 10px;
-  height: 50%;
-  // margin
-  .carousel-title {
-    text-align: center;
-    height: 38px;
-
-    > h3 {
-      display: inline-block;
-      vertical-align: middle;
-      margin-right: 15px;
-      font-weight: 600;
-      font-size: 20px;
-      line-height: 32px;
-    }
-    .ivu-select {
-      width: 60px;
-      min-width: auto;
-    }
-  }
-  .carousel-loading {
-    position: absolute;
-    top: 38px;
-    left: 10px;
-    right: 10px;
-    bottom: 10px;
-    z-index: 99;
-    background-color: rgba(255, 255, 255, 0.3);
-    text-align: center;
-
-    > i {
-      font-size: 24px;
-      position: relative;
-      top: 50%;
-      margin-top: -15px;
-    }
-  }
-}
-
-// .grade-action
-.grade-action {
-  font-size: 14px;
-  text-align: center;
-  .grade-info-deviation {
-    margin-left: 10px;
-    color: @dark-color-lighter;
-
-    &-error {
-      color: @error-color;
-    }
-  }
-  .action-search {
-    margin-top: 20px;
-    padding-top: 20px;
-    border-top: 1px dashed #e0e0e0;
-    text-align: left;
-
-    .search-select {
-      display: block;
-      width: 100px;
-      min-width: auto;
-      margin-bottom: 8px;
-    }
-    .search-input {
-      display: inline-block;
-      vertical-align: top;
-      margin-right: 10px;
-      width: 150px;
-    }
-    .search-btn {
-      display: inline-block;
-      vertical-align: top;
-      width: 60px;
-    }
-  }
-  .action-paper-state {
-    position: relative;
-    display: inline-block;
-    color: @dark-color-light;
-    margin-bottom: 30px;
-    .paper-state-cont {
-      background: @background-color;
-      border-radius: @box-border-radius-small;
-      font-size: 20px;
-      line-height: 26px;
-      padding: 6px 12px;
-    }
-    .paper-state-intro {
-      position: absolute;
-      bottom: -22px;
-      width: 100%;
-      height: 20px;
-      text-align: center;
-    }
-  }
-
-  .action-paper-info {
-    font-size: 14px;
-    margin-bottom: 20px;
-    color: @dark-color-light;
-    line-height: 24px;
-    text-align: left;
-
-    p {
-      margin-bottom: 4px;
-    }
-
-    span:last-child {
-      color: @dark-color;
-      font-size: 18px;
-    }
-  }
-  .action-grade-change {
-    margin-bottom: 20px;
-    background-color: #e7eaf1;
-    color: @dark-color-light;
-    padding: 20px;
-    font-size: 20px;
-    border-radius: @box-border-radius-small;
-    line-height: 28px;
-    text-align: left;
-
-    > p:first-child {
-      margin-bottom: 10px;
-    }
-  }
-  .action-grade-change-status {
-    text-align: center;
-    padding: 8px;
-    line-height: 28px;
-    font-size: 20px;
-    font-weight: 600;
-    background: rgba(247, 247, 250, 1);
-    color: rgba(194, 199, 213, 1);
-    border-radius: @box-border-radius-small;
-
-    &-error {
-      background: rgba(255, 112, 129, 0.1);
-      color: @error-color;
-    }
-  }
-
-  .action-grade-info {
-    margin-bottom: 20px;
-    background-color: @success-color;
-    color: @white;
-    padding: 8px;
-    border-radius: @box-border-radius-small;
-
-    + .action-mark-info {
-      margin-top: -10px;
-    }
-    &-title {
-      color: @dark-color;
-      font-size: 18px;
-      font-weight: 600;
-      line-height: 1;
-      margin-bottom: 10px;
-      text-align: left;
-    }
-
-    .grade-info-name {
-      display: inline-block;
-      vertical-align: top;
-      height: 60px;
-      line-height: 60px;
-      font-size: 54px;
-      text-align: center;
-      border-radius: 50%;
-      color: #fff;
-    }
-    .grade-info-none {
-      font-size: 34px;
-    }
-    .grade-info-range {
-      display: inline-block;
-      vertical-align: top;
-      margin-left: 20px;
-      font-size: 12px;
-      text-align: left;
-      padding: 5px 0;
-      p {
-        margin: 0;
-      }
-      p:first-child {
-        line-height: 20px;
-      }
-
-      p:last-child {
-        font-size: 20px;
-        line-height: 30px;
-      }
-
-      > span {
-        margin: 0 2px;
-      }
-    }
-  }
-  .action-grade-list {
-    font-size: 0;
-    margin: -5px -5px 20px;
-  }
-  .action-grade-item {
-    display: inline-block;
-    vertical-align: top;
-    width: 33.33%;
-    padding: 5px;
-    font-size: 12px;
-    color: @dark-color-light;
-
-    &-content {
-      padding: 8px;
-      background: @background-color;
-      border-radius: @box-border-radius-small;
-      cursor: pointer;
-
-      &:hover {
-        background-color: @info-color;
-        color: @white;
-      }
-    }
-
-    p {
-      line-height: 1;
-
-      &:first-child {
-        font-size: 24px;
-        line-height: 28px;
-      }
-    }
-  }
-  .action-item-content-disabled {
-    background: #eee !important;
-    color: @btn-disable-color!important;
-    cursor: not-allowed !important;
-  }
-  .action-grade-history {
-    text-align: left;
-    > h3 {
-      font-size: 18px;
-      font-weight: 600;
-      line-height: 1;
-      margin-bottom: 10px;
-    }
-    .grade-history-item {
-      margin: 0 0 5px 0;
-      padding: 4px 4px 4px 10px;
-      background-color: @background-color;
-      color: @dark-color-light;
-      border-radius: 5px;
-      height: 34px;
-      font-size: 14px;
-      line-height: 26px;
-
-      p:first-child {
-        white-space: nowrap;
-        word-break: keep-all;
-        float: left;
-      }
-      p:last-child {
-        padding: 0 8px;
-        border-radius: 8px;
-        background-color: @white;
-        font-size: 14px;
-        float: right;
-      }
-    }
-  }
-  .action-grade-pass {
-    height: 60px;
-    background-color: #f7f7fa;
-    border-radius: @box-border-radius-small;
-    padding: 14px;
-    color: @dark-color-light;
-    font-weight: 600;
-    line-height: 32px;
-    font-size: 20px;
-    cursor: pointer;
-
-    &:hover {
-      background-color: shade(#f7f7fa, 5%);
-    }
-  }
-}
-.mark-action {
-  .mark-info {
-    font-size: 30px;
-  }
-  .action-mark-list {
-    font-size: 0;
-    margin: -5px -5px 20px;
-  }
-  .action-mark-item {
-    display: inline-block;
-    vertical-align: top;
-    padding: 5px;
-    width: 20%;
-
-    &-content {
-      height: 40px;
-      padding: 5px 2px;
-      font-size: 16px;
-      line-height: 30px;
-      color: @dark-color-light;
-      background: @background-color;
-      border-radius: @box-border-radius;
-      text-align: center;
-      cursor: pointer;
-
-      &:hover {
-        background-color: @info-color;
-        color: @white;
-      }
-    }
-  }
-  .action-mark-input {
-    margin-bottom: 20px;
-    text-align: left;
-    .tips-info {
-      line-height: 20px;
-      text-align: left;
-    }
-    .ivu-icon {
-      margin-right: 3px;
-    }
-    .ivu-input-number {
-      width: 90px;
-      min-width: 0;
-    }
-    .ivu-form-item.mark-input-confirm {
-      margin-right: 0;
-    }
-    .ivu-form-item-error + .mark-input-confirm + .tips-info {
-      color: @error-color;
-    }
-  }
-}
-
-// .grade-analysis
-.grade-analysis {
-  .analysis-chart {
-    margin-top: 20px;
-    padding: 10px;
-  }
-}
-
-// leader-grading
-.leader-grading {
-  text-align: center;
-  padding-bottom: 40px;
-  color: @dark-color-light;
-  .leader-level {
-    h3 {
-      padding: 10px;
-      width: 150px;
-      font-size: 28px;
-      background-color: @background-color;
-      color: @dark-color;
-      font-weight: 600;
-      border-radius: @box-border-radius;
-      margin: 5px auto 20px;
-    }
-  }
-  .leader-aciton {
-    display: inline-block;
-    vertical-align: top;
-    margin: 0 10px;
-    color: @dark-color;
-  }
-  .leader-markers {
-    margin-top: 20px;
-    background-color: @background-color;
-    border-radius: @box-border-radius;
-    padding: 20px;
-    .ivu-checkbox-wrapper {
-      margin-right: 20px;
-    }
-  }
-}
-// .mark-task-manage
-.mark-task {
-  &-total {
-    display: inline-block;
-    vertical-align: middle;
-    font-weight: 600;
-    margin-right: 20px;
-    span {
-      display: inline-block;
-      vertical-align: middle;
-      line-height: 36px;
-    }
-
-    span:last-child {
-      font-size: 18px;
-    }
-  }
-}
-.task-confirm-modal {
-  .ivu-modal-header {
-    padding: 20px 32px;
-    border: 0;
-  }
-  .ivu-modal-body {
-    padding: 10px 32px;
-  }
-  .ivu-modal-footer {
-    padding: 0 32px 32px;
-  }
-  .ivu-modal-header-inner {
-    text-align: left;
-  }
-  .ivu-modal-content {
-    background-color: @background-color;
-  }
-}
-
-// grading-standard-paper-manage
-.grading-standard-paper-manage {
-  .level-list {
-    font-size: 0;
-    white-space: nowrap;
-  }
-  .level-item {
-    display: inline-block;
-    vertical-align: top;
-    height: 32px;
-    line-height: 32px;
-    padding: 0 12px;
-    border-radius: @box-border-radius-small;
-    background-color: @white;
-    color: @dark-color-light;
-    font-size: 16px;
-    cursor: pointer;
-    &:not(:last-child) {
-      margin-right: 10px;
-    }
-    &:hover {
-      box-shadow: 0px 10px 10px 0px rgba(34, 192, 255, 0.4);
-    }
-
-    &-act {
-      background-color: @info-color;
-      color: @white;
-      box-shadow: 0px 10px 10px 0px rgba(34, 192, 255, 0.4);
-    }
-  }
-
-  .standard-papers-none {
-    padding-top: 200px;
-    text-align: center;
-    font-size: 24px;
-    color: @dark-color-lighter;
-  }
-  .standard-papers-list {
-    min-height: 400px;
-
-    .image-view-list .image-view {
-      height: 400px;
-    }
-  }
-}
-.change-standard-paper-dialog {
-  .level-list {
-    font-size: 0;
-    padding-bottom: 50px;
-  }
-  .level-item {
-    display: inline-block;
-    vertical-align: top;
-    height: 32px;
-    width: 40px;
-    line-height: 32px;
-    text-align: center;
-    border-radius: @box-border-radius-small;
-    color: @dark-color-lighter;
-    border: 1px solid @dark-color-lighter;
-    font-size: 16px;
-    margin: 10px;
-    cursor: pointer;
-
-    &:hover {
-      color: @main-color;
-      border-color: @main-color;
-    }
-
-    &-act {
-      border-color: rgba(34, 192, 255, 0.4) !important;
-      background-color: @info-color;
-      color: @white!important;
-      box-shadow: 0px 10px 10px 0px rgba(34, 192, 255, 0.4);
-    }
-
-    &-disabled {
-      border-color: @disabled-color !important;
-      color: @disabled-color!important;
-      cursor: not-allowed;
-    }
-  }
-}
+// grading-group-manage
+.grading-group-manage {
+  .ivu-tag {
+    cursor: move;
+  }
+  .group-user {
+    min-height: 76px;
+    padding: 20px 20px 10px;
+    position: relative;
+  }
+  .group-user-list {
+    margin-right: 130px;
+    .ivu-btn {
+      margin-bottom: 10px;
+    }
+  }
+  .group-user-action {
+    position: absolute;
+    top: 20px;
+    right: 20px;
+    z-index: auto;
+  }
+}
+.group-list {
+  font-size: 0;
+  margin: -10px;
+
+  .group-box {
+    display: inline-block;
+    vertical-align: top;
+    font-size: 14px;
+    width: 25%;
+    padding: 10px;
+  }
+
+  &-1 {
+    .group-box {
+      width: 100%;
+    }
+  }
+  &-2 {
+    .group-box {
+      width: 50%;
+    }
+  }
+  &-3 {
+    .group-box {
+      width: 33.33%;
+    }
+  }
+  .group-container {
+    position: relative;
+    border-radius: @box-border-radius;
+    background-color: @white;
+  }
+  .group-head {
+    height: 56px;
+    padding: 15px;
+    border-bottom: 1px solid #f3f3f3;
+    font-size: 18px;
+    font-weight: 600;
+    line-height: 25px;
+    text-align: center;
+    position: relative;
+  }
+  .group-del {
+    position: absolute;
+    top: 15px;
+    right: 10px;
+    height: 24px;
+    width: 24px;
+    line-height: 24px;
+    font-size: 18px;
+    text-align: center;
+    color: @dark-color-lighter;
+    background-color: @background-color;
+    border-radius: @box-border-radius;
+    cursor: pointer;
+
+    &:hover {
+      background-color: @error-color;
+      color: @white;
+    }
+  }
+  .group-body {
+    padding: 15px 15px 60px 15px;
+    height: 245px;
+  }
+  .group-drag {
+    height: 100%;
+  }
+
+  .group-footer {
+    position: absolute;
+    bottom: 15px;
+    right: 15px;
+    z-index: 8;
+  }
+}
+.group-action {
+  text-align: center;
+  margin-top: 20px;
+  .ivu-btn {
+    width: 100px;
+  }
+}
+
+// grading
+.grading-subnav {
+  display: flex;
+  justify-content: space-between;
+  .grading-title {
+    padding: 0 10px;
+
+    > h1 {
+      display: inline-block;
+      vertical-align: middle;
+      font-size: 20px;
+      font-weight: 600;
+      margin-right: 20px;
+    }
+    > span {
+      display: inline-block;
+      vertical-align: middle;
+      margin-right: 15px;
+      color: @dark-color-light;
+    }
+  }
+}
+
+// grading-progress
+.progress-table {
+  height: 100%;
+  .progress-line {
+    width: 230px;
+  }
+  .kzz-table {
+    margin-bottom: 10px;
+    padding-bottom: 10px;
+    border-bottom: 1px dashed #e1dfe0;
+  }
+  td:first-child {
+    font-weight: 600;
+    color: @dark-color;
+    width: 100px;
+  }
+}
+// progress-line
+.progress-line {
+  position: relative;
+  display: inline-block;
+  width: 100%;
+  height: 12px;
+  text-align: center;
+  border-radius: 6px;
+  background-color: @background-color;
+  font-size: 12px;
+  color: @dark-color;
+  line-height: 1;
+  .progress-part {
+    position: absolute;
+    height: 100%;
+    > span {
+      display: inline-block;
+      vertical-align: middle;
+      line-height: 1;
+    }
+  }
+  .progress-rate {
+    position: absolute;
+    height: 100%;
+    left: 0;
+    background-color: @info-color;
+    border-radius: 6px;
+    text-align: center;
+  }
+  .progress-current {
+    display: inline-block;
+    vertical-align: middle;
+  }
+
+  .progress-remain {
+    display: block;
+    position: absolute;
+    height: 100%;
+    right: 5px;
+    z-index: 9;
+  }
+}
+// modify-formal-grading-task
+.modify-formal-grading-task {
+  .tips-info {
+    margin-bottom: 15px;
+    text-align: center;
+  }
+}
+// modify-unformal-grading-task
+.modify-unformal-grading-task {
+  .task-body {
+    min-height: 90px;
+    text-align: center;
+  }
+  .task-tips {
+    font-size: 18px;
+    color: @dark-color-light;
+  }
+  .task-action {
+    overflow: hidden;
+    > button {
+      float: right;
+
+      &:first-child {
+        float: left;
+      }
+    }
+  }
+}
+
+// grade-step
+.grade-step {
+  font-size: 0;
+  margin-bottom: 4px;
+  &-level {
+    white-space: nowrap;
+    overflow-x: scroll;
+    overflow-y: visible;
+    padding: 0 0 10px;
+  }
+  &-other {
+    float: right;
+    padding: 0 0 10px 20px;
+  }
+  .step-item {
+    display: inline-block;
+    vertical-align: top;
+    padding: 10px;
+    min-width: 90px;
+    background-color: @white;
+    border-radius: @box-border-radius-small;
+    color: @dark-color-light;
+    text-align: center;
+    cursor: pointer;
+    &:not(:last-child) {
+      margin-right: 10px;
+    }
+    &:hover {
+      box-shadow: 0px 10px 15px 0px rgba(34, 192, 255, 0.4);
+    }
+    p {
+      font-size: 12px;
+      height: 17px;
+      line-height: 17px;
+    }
+    .step-name {
+      color: @dark-color;
+      font-size: 24px;
+      font-weight: 600;
+      height: 32px;
+      line-height: 32px;
+    }
+
+    &.step-analysis {
+      width: 72px;
+      min-width: auto;
+      margin-right: 20px;
+      .step-name {
+        font-size: 20px;
+      }
+    }
+    &.step-other {
+      min-width: 72px;
+      .step-name {
+        font-size: 20px;
+      }
+    }
+
+    &.step-act {
+      background-color: @info-color;
+      color: @white;
+      box-shadow: 0px 10px 15px 0px rgba(34, 192, 255, 0.4);
+      .step-name {
+        color: @white;
+      }
+    }
+  }
+}
+.mark-step {
+  .step-item {
+    min-width: 60px;
+  }
+}
+
+// grading-detail
+.grading-detail {
+  .grade-filter {
+    position: fixed;
+    left: 0;
+    top: 50%;
+    z-index: 199;
+    width: 20px;
+    transform: translateY(-50%);
+    transition: width 0.2s ease-in;
+    overflow: hidden;
+
+    .ivu-form {
+      white-space: nowrap;
+    }
+    .ivu-form-item {
+      margin-right: 10px;
+    }
+    .ivu-form-item:last-child {
+      margin-right: 0;
+    }
+
+    &-form {
+      display: none;
+    }
+    .detail-area {
+      background-color: @success-color;
+      border-radius: 3px;
+      color: @dark-color-light;
+      font-size: 12px;
+      line-height: 16px;
+      width: 20px;
+      padding: 5px 3px;
+      text-align: center;
+      color: #fff;
+      cursor: pointer;
+
+      &:hover {
+        background-color: fade(@success-color, 80%);
+      }
+    }
+
+    &-select {
+      width: 290px;
+      background-color: #fff;
+      padding: 10px 10px 0;
+      border-top-right-radius: 5px;
+      border-bottom-right-radius: 5px;
+      box-shadow: 0 0 15px #c0c0c0;
+      .grade-filter-form {
+        display: block;
+      }
+      .detail-area {
+        display: none;
+      }
+    }
+  }
+  .grade-step {
+    flex-grow: 0;
+  }
+
+  .detail-body {
+    flex-grow: 2;
+    min-height: 400px;
+    display: flex;
+    justify-content: space-between;
+
+    &-2 {
+      .detail-papers-list {
+        width: 100%;
+      }
+    }
+  }
+  .detail-action {
+    width: 280px;
+    padding: 20px;
+    margin-left: 20px;
+    background-color: @white;
+    border-radius: @box-border-radius;
+    overflow-x: hidden;
+    overflow-y: auto;
+    flex-grow: 0;
+  }
+  .detail-action-fullscreen {
+    position: fixed;
+    width: 280px;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 98;
+    border-radius: 0;
+    min-height: auto;
+    margin: 0;
+    overflow-y: auto;
+    overflow-x: hidden;
+    z-index: 999;
+  }
+  .detail-papers {
+    padding: 0 20px;
+    background-color: @white;
+    border-radius: @box-border-radius;
+    font-size: 0;
+    flex-grow: 2;
+    display: flex;
+    justify-content: space-between;
+    min-height: 400px;
+
+    &-carousel {
+      position: relative;
+      padding: 10px 0 70px;
+      font-size: 14px;
+      &-split {
+        height: 40px;
+      }
+      &::after {
+        content: "";
+        position: absolute;
+        height: 100%;
+        border-left: 1px solid #eff0f5;
+        right: 0;
+        top: 0;
+        z-index: auto;
+      }
+    }
+    &-list {
+      width: 100%;
+      font-size: 14px;
+      position: relative;
+      padding: 10px 0 70px;
+      .image-view-list {
+        margin: 0;
+        height: 100%;
+      }
+      .part-page {
+        position: absolute;
+        bottom: 20px;
+        width: 100%;
+        z-index: auto;
+        margin: 0;
+      }
+    }
+    &-none {
+      padding-top: 200px;
+      text-align: center;
+      font-size: 24px;
+      color: @dark-color-lighter;
+    }
+
+    &-col-3 {
+      .detail-papers-carousel {
+        width: 33.33%;
+      }
+      .detail-papers-list {
+        width: 66.66%;
+      }
+    }
+    &-col-4 {
+      .detail-papers-carousel {
+        width: 25%;
+      }
+      .detail-papers-list {
+        width: 75%;
+      }
+    }
+    &-col-5 {
+      .detail-papers-carousel {
+        width: 20%;
+      }
+      .detail-papers-list {
+        width: 80%;
+      }
+    }
+    &-col-6 {
+      .detail-papers-carousel {
+        width: 16.66%;
+      }
+      .detail-papers-list {
+        width: 83.33%;
+      }
+    }
+
+    .ivu-page {
+      text-align: center;
+    }
+  }
+  &-image-preview {
+    .ivu-modal-mask,
+    .ivu-modal-wrap {
+      left: 0;
+      bottom: 0;
+      top: 0;
+      right: 280px;
+    }
+  }
+}
+// mark-detail
+
+// grading-operation
+.grading-operation {
+  .detail-action-fullscreen {
+    top: 0;
+  }
+  &-image-preview {
+    .ivu-modal-mask,
+    .ivu-modal-wrap {
+      left: 0;
+      bottom: 0;
+      top: 0;
+      right: 280px;
+    }
+  }
+}
+
+/* paper-carousel */
+.paper-carousel {
+  position: absolute;
+  top: 48px;
+  bottom: 62px;
+  left: 10px;
+  right: 10px;
+
+  .carousel-body > img {
+    position: absolute;
+    max-width: 100%;
+    max-height: 100%;
+    width: auto;
+    height: auto;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    margin: auto;
+    cursor: pointer;
+  }
+  .carousel-none {
+    color: @dark-color-lighter;
+    font-size: @font-size-base;
+    text-align: center;
+    position: absolute;
+    width: 100%;
+    top: 50%;
+    left: 0;
+    transform: translateY(-50%);
+    z-index: 8;
+    > i {
+      font-size: 30px;
+    }
+  }
+  .carousel-btn {
+    position: absolute;
+    width: 40px;
+    height: 40px;
+    top: 50%;
+    z-index: 9;
+    margin-top: -20px;
+    text-align: center;
+    line-height: 40px;
+    font-size: 36px;
+    color: #ccc;
+    cursor: pointer;
+
+    &:hover {
+      color: @main-color;
+    }
+
+    &-left {
+      left: 0;
+    }
+    &-right {
+      right: 0;
+    }
+  }
+}
+
+// .grade-history-paper
+.grade-history-paper {
+  position: relative;
+  padding: 10px;
+  width: 100%;
+  height: 50%;
+
+  .carousel-title {
+    text-align: center;
+    height: 32px;
+    line-height: 32px;
+    margin-bottom: 6px;
+    > h3 {
+      font-size: 16px;
+    }
+  }
+}
+// grade-standard-paper
+.grade-standard-paper {
+  position: relative;
+  padding: 10px;
+  height: 50%;
+  // margin
+  .carousel-title {
+    text-align: center;
+    height: 38px;
+
+    > h3 {
+      display: inline-block;
+      vertical-align: middle;
+      margin-right: 15px;
+      font-weight: 600;
+      font-size: 20px;
+      line-height: 32px;
+    }
+    .ivu-select {
+      width: 60px;
+      min-width: auto;
+    }
+  }
+  .carousel-loading {
+    position: absolute;
+    top: 38px;
+    left: 10px;
+    right: 10px;
+    bottom: 10px;
+    z-index: 99;
+    background-color: rgba(255, 255, 255, 0.3);
+    text-align: center;
+
+    > i {
+      font-size: 24px;
+      position: relative;
+      top: 50%;
+      margin-top: -15px;
+    }
+  }
+}
+
+// .grade-action
+.grade-action {
+  font-size: 14px;
+  text-align: center;
+  .grade-info-deviation {
+    margin-left: 10px;
+    color: @dark-color-lighter;
+
+    &-error {
+      color: @error-color;
+    }
+  }
+  .action-search {
+    margin-top: 20px;
+    padding-top: 20px;
+    border-top: 1px dashed #e0e0e0;
+    text-align: left;
+
+    .search-select {
+      display: block;
+      width: 100px;
+      min-width: auto;
+      margin-bottom: 8px;
+    }
+    .search-input {
+      display: inline-block;
+      vertical-align: top;
+      margin-right: 10px;
+      width: 150px;
+    }
+    .search-btn {
+      display: inline-block;
+      vertical-align: top;
+      width: 60px;
+    }
+  }
+  .action-paper-state {
+    position: relative;
+    display: inline-block;
+    color: @dark-color-light;
+    margin-bottom: 30px;
+    .paper-state-cont {
+      background: @background-color;
+      border-radius: @box-border-radius-small;
+      font-size: 20px;
+      line-height: 26px;
+      padding: 6px 12px;
+    }
+    .paper-state-intro {
+      position: absolute;
+      bottom: -22px;
+      width: 100%;
+      height: 20px;
+      text-align: center;
+    }
+  }
+
+  .action-paper-info {
+    font-size: 14px;
+    margin-bottom: 20px;
+    color: @dark-color-light;
+    line-height: 24px;
+    text-align: left;
+
+    p {
+      margin-bottom: 4px;
+    }
+
+    span:last-child {
+      color: @dark-color;
+      font-size: 18px;
+    }
+  }
+  .action-grade-change {
+    margin-bottom: 20px;
+    background-color: #e7eaf1;
+    color: @dark-color-light;
+    padding: 20px;
+    font-size: 20px;
+    border-radius: @box-border-radius-small;
+    line-height: 28px;
+    text-align: left;
+
+    > p:first-child {
+      margin-bottom: 10px;
+    }
+  }
+  .action-grade-change-status {
+    text-align: center;
+    padding: 8px;
+    line-height: 28px;
+    font-size: 20px;
+    font-weight: 600;
+    background: rgba(247, 247, 250, 1);
+    color: rgba(194, 199, 213, 1);
+    border-radius: @box-border-radius-small;
+
+    &-error {
+      background: rgba(255, 112, 129, 0.1);
+      color: @error-color;
+    }
+  }
+
+  .action-grade-info {
+    margin-bottom: 20px;
+    background-color: @success-color;
+    color: @white;
+    padding: 8px;
+    border-radius: @box-border-radius-small;
+
+    + .action-mark-info {
+      margin-top: -10px;
+    }
+    &-title {
+      color: @dark-color;
+      font-size: 18px;
+      font-weight: 600;
+      line-height: 1;
+      margin-bottom: 10px;
+      text-align: left;
+    }
+
+    .grade-info-name {
+      display: inline-block;
+      vertical-align: top;
+      height: 60px;
+      line-height: 60px;
+      font-size: 54px;
+      text-align: center;
+      border-radius: 50%;
+      color: #fff;
+    }
+    .grade-info-none {
+      font-size: 34px;
+    }
+    .grade-info-range {
+      display: inline-block;
+      vertical-align: top;
+      margin-left: 20px;
+      font-size: 12px;
+      text-align: left;
+      padding: 5px 0;
+      p {
+        margin: 0;
+      }
+      p:first-child {
+        line-height: 20px;
+      }
+
+      p:last-child {
+        font-size: 20px;
+        line-height: 30px;
+      }
+
+      > span {
+        margin: 0 2px;
+      }
+    }
+  }
+  .action-grade-list {
+    font-size: 0;
+    margin: -5px -5px 20px;
+  }
+  .action-grade-item {
+    display: inline-block;
+    vertical-align: top;
+    width: 33.33%;
+    padding: 5px;
+    font-size: 12px;
+    color: @dark-color-light;
+
+    &-content {
+      padding: 8px;
+      background: @background-color;
+      border-radius: @box-border-radius-small;
+      cursor: pointer;
+
+      &:hover {
+        background-color: @info-color;
+        color: @white;
+      }
+    }
+
+    p {
+      line-height: 1;
+
+      &:first-child {
+        font-size: 24px;
+        line-height: 28px;
+      }
+    }
+  }
+  .action-item-content-disabled {
+    background: #eee !important;
+    color: @btn-disable-color!important;
+    cursor: not-allowed !important;
+  }
+  .action-grade-history {
+    text-align: left;
+    > h3 {
+      font-size: 18px;
+      font-weight: 600;
+      line-height: 1;
+      margin-bottom: 10px;
+    }
+    .grade-history-item {
+      margin: 0 0 5px 0;
+      padding: 4px 4px 4px 10px;
+      background-color: @background-color;
+      color: @dark-color-light;
+      border-radius: 5px;
+      height: 34px;
+      font-size: 14px;
+      line-height: 26px;
+
+      p:first-child {
+        white-space: nowrap;
+        word-break: keep-all;
+        float: left;
+      }
+      p:last-child {
+        padding: 0 8px;
+        border-radius: 8px;
+        background-color: @white;
+        font-size: 14px;
+        float: right;
+      }
+    }
+  }
+  .action-grade-pass {
+    height: 60px;
+    background-color: #f7f7fa;
+    border-radius: @box-border-radius-small;
+    padding: 14px;
+    color: @dark-color-light;
+    font-weight: 600;
+    line-height: 32px;
+    font-size: 20px;
+    cursor: pointer;
+
+    &:hover {
+      background-color: shade(#f7f7fa, 5%);
+    }
+  }
+}
+.mark-action {
+  .mark-info {
+    font-size: 30px;
+  }
+  .action-mark-list {
+    font-size: 0;
+    margin: -5px -5px 20px;
+  }
+  .action-mark-item {
+    display: inline-block;
+    vertical-align: top;
+    padding: 5px;
+    width: 20%;
+
+    &-content {
+      height: 40px;
+      padding: 5px 2px;
+      font-size: 16px;
+      line-height: 30px;
+      color: @dark-color-light;
+      background: @background-color;
+      border-radius: @box-border-radius;
+      text-align: center;
+      cursor: pointer;
+
+      &:hover {
+        background-color: @info-color;
+        color: @white;
+      }
+    }
+  }
+  .action-mark-input {
+    margin-bottom: 20px;
+    text-align: left;
+    .tips-info {
+      line-height: 20px;
+      text-align: left;
+    }
+    .ivu-icon {
+      margin-right: 3px;
+    }
+    .ivu-input-number {
+      width: 90px;
+      min-width: 0;
+    }
+    .ivu-form-item.mark-input-confirm {
+      margin-right: 0;
+    }
+    .ivu-form-item-error + .mark-input-confirm + .tips-info {
+      color: @error-color;
+    }
+  }
+}
+
+// .grade-analysis
+.grade-analysis {
+  .analysis-chart {
+    margin-top: 20px;
+    padding: 10px;
+  }
+}
+
+// leader-grading
+.leader-grading {
+  text-align: center;
+  padding-bottom: 40px;
+  color: @dark-color-light;
+  .leader-level {
+    h3 {
+      padding: 10px;
+      width: 150px;
+      font-size: 28px;
+      background-color: @background-color;
+      color: @dark-color;
+      font-weight: 600;
+      border-radius: @box-border-radius;
+      margin: 5px auto 20px;
+    }
+  }
+  .leader-aciton {
+    display: inline-block;
+    vertical-align: top;
+    margin: 0 10px;
+    color: @dark-color;
+  }
+  .leader-markers {
+    margin-top: 20px;
+    background-color: @background-color;
+    border-radius: @box-border-radius;
+    padding: 20px;
+    .ivu-checkbox-wrapper {
+      margin-right: 20px;
+    }
+  }
+}
+// .mark-task-manage
+.mark-task {
+  &-total {
+    display: inline-block;
+    vertical-align: middle;
+    font-weight: 600;
+    margin-right: 20px;
+    span {
+      display: inline-block;
+      vertical-align: middle;
+      line-height: 36px;
+    }
+
+    span:last-child {
+      font-size: 18px;
+    }
+  }
+}
+.task-confirm-modal {
+  .ivu-modal-header {
+    padding: 20px 32px;
+    border: 0;
+  }
+  .ivu-modal-body {
+    padding: 10px 32px;
+  }
+  .ivu-modal-footer {
+    padding: 0 32px 32px;
+  }
+  .ivu-modal-header-inner {
+    text-align: left;
+  }
+  .ivu-modal-content {
+    background-color: @background-color;
+  }
+}
+
+// grading-standard-paper-manage
+.grading-standard-paper-manage {
+  .level-list {
+    font-size: 0;
+    white-space: nowrap;
+  }
+  .level-item {
+    display: inline-block;
+    vertical-align: top;
+    height: 32px;
+    line-height: 32px;
+    padding: 0 12px;
+    border-radius: @box-border-radius-small;
+    background-color: @white;
+    color: @dark-color-light;
+    font-size: 16px;
+    cursor: pointer;
+    &:not(:last-child) {
+      margin-right: 10px;
+    }
+    &:hover {
+      box-shadow: 0px 10px 10px 0px rgba(34, 192, 255, 0.4);
+    }
+
+    &-act {
+      background-color: @info-color;
+      color: @white;
+      box-shadow: 0px 10px 10px 0px rgba(34, 192, 255, 0.4);
+    }
+  }
+
+  .standard-papers-none {
+    padding-top: 200px;
+    text-align: center;
+    font-size: 24px;
+    color: @dark-color-lighter;
+  }
+  .standard-papers-list {
+    min-height: 400px;
+
+    .image-view-list .image-view {
+      height: 400px;
+    }
+  }
+}
+.change-standard-paper-dialog {
+  .level-list {
+    font-size: 0;
+    padding-bottom: 50px;
+  }
+  .level-item {
+    display: inline-block;
+    vertical-align: top;
+    height: 32px;
+    width: 40px;
+    line-height: 32px;
+    text-align: center;
+    border-radius: @box-border-radius-small;
+    color: @dark-color-lighter;
+    border: 1px solid @dark-color-lighter;
+    font-size: 16px;
+    margin: 10px;
+    cursor: pointer;
+
+    &:hover {
+      color: @main-color;
+      border-color: @main-color;
+    }
+
+    &-act {
+      border-color: rgba(34, 192, 255, 0.4) !important;
+      background-color: @info-color;
+      color: @white!important;
+      box-shadow: 0px 10px 10px 0px rgba(34, 192, 255, 0.4);
+    }
+
+    &-disabled {
+      border-color: @disabled-color !important;
+      color: @disabled-color!important;
+      cursor: not-allowed;
+    }
+  }
+}

+ 5 - 0
src/constants/enumerate.js

@@ -140,6 +140,11 @@ export const SCORE_HANDLE_TYPE = {
   0: "非零进一",
   1: "四舍五入"
 };
+// score-calc-type
+export const SCORE_CALC_TYPE = {
+  0: "全部加权平均",
+  1: "去高去低加权平均"
+};
 
 // apply-change-level-status
 export const CHANGE_LEVEL_STATUS = {

+ 245 - 173
src/modules/grading/GradingGroupManage.vue

@@ -1,173 +1,245 @@
-<template>
-  <div class="grading-group-manage">
-    <div class="group-user part-box" v-if="users.length">
-      <draggable class="group-user-list" group="user" :list="users">
-        <Button size="small" v-for="user in users" :key="user.id">
-          {{ user.loginName }}
-        </Button>
-      </draggable>
-      <Button
-        class="group-user-action"
-        shape="circle"
-        type="success"
-        icon="recode-white icon"
-        @click="toAddGroup"
-        >新增分组</Button
-      >
-    </div>
-    <div :class="groupListClasses">
-      <div class="group-box" v-for="(group, gindex) in groups" :key="gindex">
-        <div class="group-container">
-          <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
-                size="large"
-                v-for="(user, uindex) in group.markers"
-                :key="uindex"
-                @on-close="removeGroupUser(uindex, group)"
-                closable
-              >
-                {{ user.loginName }}
-              </Tag>
-            </draggable>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div class="group-action">
-      <Button
-        shape="circle"
-        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 {
-      workId: this.$route.params.workId,
-      subjectId: this.$route.params.subjectId,
-      groups: [],
-      users: [],
-      isSubmit: false
-    };
-  },
-  computed: {
-    groupListClasses() {
-      const num = this.groups.length;
-      return ["group-list", `group-list-${num}`];
-    }
-  },
-  mounted() {
-    this.initData();
-  },
-  methods: {
-    initData() {
-      this.getGroupList();
-      this.getMarkUserList();
-    },
-    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.$Message.error("当前分组列表中存在空组!");
-        return;
-      }
-      const hasNoneLeaderGroup = this.groups.some(
-        group => !group.markers.some(marker => marker.role === "MARK_LEADER")
-      );
-      if (hasNoneLeaderGroup) {
-        this.$Message.error("请确认每一个分组都有科组长!");
-        return;
-      }
-      this.save();
-    },
-    async save() {
-      this.isSubmit = true;
-      for (let i = 0; i < this.groups.length; i++) {
-        const group = this.groups[i];
-        let result = await updateGradingGroup(
-          this.subjectId,
-          group
-        ).catch(() => {});
-        if (!result) {
-          this.isSubmit = false;
-          this.$Message.error("保存失败,请重新尝试!");
-          return;
-        }
-      }
-      this.isSubmit = false;
-      this.$Message.success("保存成功!");
-      this.initData();
-    },
-    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({
-        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>
+<template>
+  <div class="grading-group-manage">
+    <div class="group-user part-box" v-if="users.length">
+      <draggable class="group-user-list" group="user" :list="users">
+        <Button size="small" v-for="user in users" :key="user.id">
+          {{ user.loginName }}
+        </Button>
+      </draggable>
+      <Button
+        class="group-user-action"
+        shape="circle"
+        type="success"
+        icon="recode-white icon"
+        @click="toAddGroup"
+        >新增分组</Button
+      >
+    </div>
+    <div :class="groupListClasses">
+      <div class="group-box" v-for="(group, gindex) in groups" :key="gindex">
+        <div class="group-container">
+          <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
+                size="large"
+                v-for="(user, uindex) in group.markers"
+                :key="uindex"
+                @on-close="removeGroupUser(uindex, group)"
+                closable
+              >
+                {{ user.loginName }}
+              </Tag>
+            </draggable>
+          </div>
+          <div v-if="group.id" class="group-footer">
+            <Button
+              shape="circle"
+              type="primary"
+              ghost
+              icon="upload icon"
+              @click="toImportGroupStudent(group)"
+              >导入考生名单</Button
+            >
+            <Button
+              shape="circle"
+              icon="md-trash"
+              type="error"
+              ghost
+              :disabled="!group.hasStudent"
+              @click="toDeleteGroupStudent(group)"
+              >删除导入考生</Button
+            >
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="group-action">
+      <Button
+        shape="circle"
+        type="primary"
+        @click="submit"
+        :disabled="!this.groups.length || isSubmit"
+        >确认</Button
+      >
+    </div>
+
+    <!-- import student  -->
+    <import-file
+      :title="uploadTitle"
+      :upload-url="uploadStudentUrl"
+      :upload-data="uploadData"
+      :download-url="downloadStudentTemplateUrl"
+      :download-filename="downloadStudentTemplateFilename"
+      :headers="headers"
+      :format="['xls', 'xlsx']"
+      @upload-success="uploadSuccess"
+      ref="ExportStudent"
+    >
+    </import-file>
+  </div>
+</template>
+
+<script>
+import {
+  gradingGroupList,
+  markUserList,
+  updateGradingGroup,
+  deleteGradingGroup
+} from "@/api";
+import draggable from "vuedraggable";
+import ImportFile from "@/components/common/ImportFile";
+
+export default {
+  name: "grading-group-manage",
+  components: { draggable, ImportFile },
+  data() {
+    return {
+      workId: this.$route.params.workId,
+      subjectId: this.$route.params.subjectId,
+      groups: [],
+      users: [],
+      isSubmit: false,
+      // upload
+      uploadTitle: "",
+      headers: {
+        Authorization: this.$ls.get("user", { token: "" }).token,
+        workId: this.$route.params.workId,
+        userId: this.$ls.get("user", { id: "" }).id
+      },
+      uploadData: {
+        workId: this.$route.params.workId,
+        subjectId: this.$route.params.subjectId,
+        groupId: null
+      },
+      uploadStudentUrl: this.GLOBAL.domain + "/api/import/group-students",
+      downloadStudentTemplateUrl: "/templates/考生名单表-模板.xlsx",
+      downloadStudentTemplateFilename: "考生名单表-模板.xlsx"
+    };
+  },
+  computed: {
+    groupListClasses() {
+      const num = this.groups.length;
+      return ["group-list", `group-list-${num}`];
+    }
+  },
+  mounted() {
+    this.initData();
+  },
+  methods: {
+    initData() {
+      this.getGroupList();
+      this.getMarkUserList();
+    },
+    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.$Message.error("当前分组列表中存在空组!");
+        return;
+      }
+      const hasNoneLeaderGroup = this.groups.some(
+        group => !group.markers.some(marker => marker.role === "MARK_LEADER")
+      );
+      if (hasNoneLeaderGroup) {
+        this.$Message.error("请确认每一个分组都有科组长!");
+        return;
+      }
+      this.save();
+    },
+    async save() {
+      this.isSubmit = true;
+      for (let i = 0; i < this.groups.length; i++) {
+        const group = this.groups[i];
+        let result = await updateGradingGroup(
+          this.subjectId,
+          group
+        ).catch(() => {});
+        if (!result) {
+          this.isSubmit = false;
+          this.$Message.error("保存失败,请重新尝试!");
+          return;
+        }
+      }
+      this.isSubmit = false;
+      this.$Message.success("保存成功!");
+      this.initData();
+    },
+    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({
+        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);
+      });
+    },
+    toImportGroupStudent(group) {
+      this.uploadTitle = `导入考生名单-${group.name}`;
+      this.uploadData.groupId = group.id;
+      this.$refs.ExportStudent.open();
+    },
+    uploadSuccess() {
+      this.getGroupList();
+      this.$Notice.success({
+        title: "导入提示",
+        desc: "考生名单导入成功!",
+        duration: 0
+      });
+    },
+    toDeleteGroupStudent(group) {
+      this.$Modal.confirm({
+        content: "确定要删除当前分组下的考生吗?",
+        onOk: async () => {
+          await deleteGradingGroup(this.subjectId, group.id);
+          this.getGroupList();
+          this.$Message.success("删除成功!");
+        }
+      });
+    }
+  }
+};
+</script>

+ 459 - 459
src/modules/main/StudentManage.vue

@@ -1,459 +1,459 @@
-<template>
-  <div class="students ">
-    <div class="part-box-head">
-      <div class="part-box-head-left">
-        <Button
-          icon="upload icon"
-          shape="circle"
-          @click="$refs.ExportStudent.open()"
-          >导入考生信息</Button
-        >
-        <!-- <Button
-          icon="upload icon"
-          shape="circle"
-          @click="$refs.ExportRelate.open()"
-          >导入关联信息</Button
-        > -->
-      </div>
-      <div class="part-box-head-right">
-        <Button
-          type="success"
-          icon="recode-white icon"
-          shape="circle"
-          @click="toAdd"
-          >添加考生</Button
-        >
-        <Button
-          shape="circle"
-          type="success"
-          icon="upload-white icon"
-          @click="toExport"
-          >导出表格</Button
-        >
-      </div>
-    </div>
-    <div class="part-box part-box-filter">
-      <Form ref="FilterForm" label-position="left" inline>
-        <FormItem>
-          <Select
-            v-model="filter.areaCode"
-            @on-change="areaChange"
-            placeholder="考区"
-            clearable
-          >
-            <Option
-              v-for="area in cascadeList"
-              :key="area.areaCode"
-              :value="area.areaCode"
-              :label="area.areaName"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select
-            v-model="filter.school"
-            @on-change="schoolChange"
-            placeholder="学校"
-            filterable
-            clearable
-          >
-            <Option
-              v-for="(item, index) in schools"
-              :key="index"
-              :value="item.school"
-              :label="item.school"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select v-model="filter.examRoom" placeholder="考场" clearable>
-            <Option
-              v-for="(room, index) in rooms"
-              :key="index"
-              :value="room"
-              :label="room"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Input
-            v-model="filter.startNumber"
-            type="text"
-            placeholder="输入开始编号"
-            clearable
-          />
-        </FormItem>
-        <FormItem>
-          <Input
-            v-model="filter.endNumber"
-            type="text"
-            placeholder="输入结束编号"
-            clearable
-          />
-        </FormItem>
-        <FormItem>
-          <Input
-            v-model.trim="filter.studentName"
-            placeholder="输入姓名"
-            clearable
-          ></Input>
-        </FormItem>
-        <FormItem>
-          <Select v-model="filter.isAbsent" placeholder="是否缺考" clearable>
-            <Option
-              v-for="(val, key) in BOOLEAN_TYPE"
-              :key="key"
-              :value="key * 1"
-              >{{ val }}</Option
-            >
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select v-model="filter.upload" placeholder="是否上传" clearable>
-            <Option
-              v-for="(val, key) in PAPER_UPLOAD_TYPE"
-              :key="key"
-              :value="key * 1"
-              >{{ val }}</Option
-            >
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select v-model="filter.subject" placeholder="科目" clearable>
-            <Option
-              v-for="item in subjects"
-              :key="item.subject"
-              :value="item.subject"
-              :label="item.name"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Button
-            size="small"
-            class="btn-form-search"
-            type="primary"
-            @click="toPage(1)"
-            >查询</Button
-          >
-        </FormItem>
-      </Form>
-    </div>
-    <Table
-      ref="TableList"
-      :columns="columns"
-      :data="students"
-      disabled-hover
-      border
-    ></Table>
-
-    <div class="part-page" v-if="total > size">
-      <Page
-        :current="current"
-        :total="total"
-        :page-size="size"
-        show-total
-        show-elevator
-        @on-change="toPage"
-      ></Page>
-    </div>
-
-    <!-- import student  -->
-    <import-file
-      title="导入考生信息"
-      :upload-url="uploadStudentUrl"
-      :upload-data="uploadData"
-      :download-url="downloadStudentTemplateUrl"
-      :download-filename="downloadStudentTemplateFilename"
-      :headers="headers"
-      :format="['xls', 'xlsx']"
-      @upload-success="uploadSuccess"
-      ref="ExportStudent"
-    >
-    </import-file>
-    <!-- import-relate -->
-    <import-file
-      title="导入关联信息"
-      :upload-url="uploadRelateUrl"
-      :upload-data="uploadData"
-      :download-url="downloadRelateTemplateUrl"
-      :download-filename="downloadRelateTemplateFilename"
-      :headers="headers"
-      :format="['xls', 'xlsx']"
-      ref="ExportRelate"
-    >
-    </import-file>
-    <!-- modify-student -->
-    <modify-student
-      :cascade-list="cascadeList"
-      :instance="curStudent"
-      @modified="getList"
-      @on-close="getAreaList"
-      ref="ModifyStudent"
-    ></modify-student>
-  </div>
-</template>
-
-<script>
-import {
-  subjectList,
-  studentPageList,
-  deleteStudent,
-  areaSchoolRoomCascadeList
-} from "@/api";
-import ImportFile from "@/components/common/ImportFile";
-import ModifyStudent from "./components/ModifyStudent";
-import { BOOLEAN_TYPE, PAPER_UPLOAD_TYPE } from "@/constants/enumerate";
-import qs from "qs";
-
-export default {
-  name: "students",
-  components: { ImportFile, ModifyStudent },
-  data() {
-    return {
-      filter: {
-        workId: this.$route.params.workId,
-        subject: null,
-        areaCode: null,
-        school: "",
-        examRoom: "",
-        startNumber: null,
-        endNumber: null,
-        studentName: "",
-        upload: null,
-        isAbsent: null
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      students: [],
-      curStudent: {},
-      subjects: [],
-      cascadeList: [],
-      schools: [],
-      rooms: [],
-      BOOLEAN_TYPE,
-      PAPER_UPLOAD_TYPE,
-      columns: [
-        {
-          type: "index",
-          title: "序号",
-          width: 80,
-          align: "center",
-          indexMethod: row => {
-            return (this.current - 1) * this.size + row._index + 1;
-          }
-        },
-        {
-          title: "姓名",
-          key: "name",
-          width: 100
-        },
-        {
-          title: "考号",
-          key: "examNumber",
-          minWidth: 120
-        },
-        // {
-        //   title: "关联考号",
-        //   key: "relateExamNumber",
-        //   minWidth: 120
-        // },
-        {
-          title: "考区",
-          key: "areaName",
-          minWidth: 120
-        },
-        {
-          title: "学校",
-          key: "school",
-          minWidth: 150
-        },
-        {
-          title: "考场",
-          key: "examRoom",
-          minWidth: 100
-        },
-        {
-          title: "操作",
-          key: "action",
-          width: 100,
-          align: "center",
-          className: "table-action",
-          render: (h, param) => {
-            let actions = [];
-
-            if (param.row.canEdit) {
-              actions.push({
-                icon: "md-create",
-                attrs: {
-                  title: "编辑"
-                },
-                action: () => {
-                  this.toEdit(param.row);
-                }
-              });
-            }
-            if (param.row.canDelete) {
-              actions.push({
-                icon: "md-trash",
-                classes: ["icon-danger"],
-                attrs: {
-                  title: "删除"
-                },
-                action: () => {
-                  this.toDelete(param.row);
-                }
-              });
-            }
-
-            return h("div", this.$tableIconAction(h, actions));
-          }
-        }
-      ],
-      // upload
-      headers: {
-        Authorization: this.$ls.get("user", { token: "" }).token,
-        workId: this.$route.params.workId,
-        userId: this.$ls.get("user", { id: "" }).id
-      },
-      uploadData: {
-        workId: this.$route.params.workId
-      },
-      uploadStudentUrl: this.GLOBAL.domain + "/api/import/students",
-      downloadStudentTemplateUrl: "/templates/考生信息表-模板.xlsx",
-      downloadStudentTemplateFilename: "考生信息表-模板.xlsx",
-      uploadRelateUrl: "/api/import/students/relateStudent",
-      downloadRelateTemplateUrl: "/templates/关联考生信息表-模板.xlsx",
-      downloadRelateTemplateFilename: "关联考生信息表-模板.xlsx"
-    };
-  },
-  mounted() {
-    this.iniData();
-  },
-  methods: {
-    async iniData() {
-      await this.getSubjects();
-      this.getAreaList();
-      this.getList();
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        page: this.current - 1,
-        size: this.size
-      };
-      // if (
-      //   ((datas.upload || datas.upload === 0) && !datas.subject) ||
-      //   (!datas.upload && datas.upload !== 0 && datas.subject)
-      // ) {
-      //   this.$Message.error("上传状态和科目必须同时选择!");
-      //   return;
-      // }
-      // if (datas.subject === "ONE") datas.subject = null;
-      const data = await studentPageList(datas);
-      this.students = data.data.map(student => {
-        student.uploadStatus.split(",").map(status => {
-          const [subjectCode, subjectUploadStatus] = status.split(":");
-          student[subjectCode] = subjectUploadStatus * 1;
-        });
-        student.canEdit = student.uploadStatus.includes("0");
-        student.canDelete = !student.uploadStatus.includes("1");
-        student.uploadStatus.split(",").map(status => {
-          const [subject, hasScan] = status.split(":");
-          student[subject] = hasScan;
-        });
-        student.workId = this.filter.workId;
-        student.relateExamNumber =
-          student.relateExamNumber === student.examNumber
-            ? "--"
-            : student.relateExamNumber;
-        return student;
-      });
-      this.total = data.totalCount;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    async getAreaList() {
-      this.cascadeList = await areaSchoolRoomCascadeList(this.filter.workId);
-    },
-    async getSubjects() {
-      const data = await subjectList(this.filter.workId);
-      this.subjects = data.filter(item => item.enable);
-      this.subjects.map(item => {
-        const column = {
-          title: item.name,
-          key: item.subject,
-          minWidth: 80
-        };
-        this.columns.splice(this.columns.length - 1, 0, column);
-      });
-      this.subjects.unshift({
-        subject: "ONE",
-        name: "查漏"
-      });
-    },
-    areaChange() {
-      const curArea = this.cascadeList.find(
-        item => item.areaCode === this.filter.areaCode
-      );
-      this.schools = curArea ? curArea.schools : [];
-      this.rooms = [];
-      this.filter.school = null;
-      this.filter.examRoom = null;
-      if (curArea.schools.length === 1) {
-        this.filter.school = curArea.schools[0].school;
-        this.schoolChange();
-      }
-    },
-    schoolChange() {
-      const curSchool = this.schools.find(
-        item => item.school === this.filter.school
-      );
-      this.rooms = curSchool ? curSchool.rooms : [];
-      this.filter.examRoom = null;
-    },
-    uploadSuccess() {
-      this.getList();
-      this.getAreaList();
-      this.$Notice.success({
-        title: "导入提示",
-        desc: "考生信息导入成功!",
-        duration: 0
-      });
-    },
-    toAdd() {
-      this.curStudent = { workId: this.filter.workId };
-      this.$refs.ModifyStudent.open();
-    },
-    toEdit(row) {
-      this.curStudent = row;
-      this.$refs.ModifyStudent.open();
-    },
-    toDelete(row) {
-      this.$Modal.confirm({
-        width: 340,
-        content: "确定要删除该考生吗?",
-        onOk: () => {
-          this.toDel(row.id);
-        }
-      });
-    },
-    async toDel(id) {
-      await deleteStudent(id);
-      this.$Message.success("删除成功!");
-      this.deletePageLastItem();
-    },
-    toExport() {
-      const sqDatas = qs.stringify(this.filter, {
-        arrayFormat: "brackets"
-      });
-      window.open(
-        this.urlAddAuthor(`${this.GLOBAL.domain}/api/export/student?${sqDatas}`)
-      );
-    }
-  }
-};
-</script>
+<template>
+  <div class="students ">
+    <div class="part-box-head">
+      <div class="part-box-head-left">
+        <Button
+          icon="upload icon"
+          shape="circle"
+          @click="$refs.ExportStudent.open()"
+          >导入考生信息</Button
+        >
+        <!-- <Button
+          icon="upload icon"
+          shape="circle"
+          @click="$refs.ExportRelate.open()"
+          >导入关联信息</Button
+        > -->
+      </div>
+      <div class="part-box-head-right">
+        <Button
+          type="success"
+          icon="recode-white icon"
+          shape="circle"
+          @click="toAdd"
+          >添加考生</Button
+        >
+        <Button
+          shape="circle"
+          type="success"
+          icon="upload-white icon"
+          @click="toExport"
+          >导出表格</Button
+        >
+      </div>
+    </div>
+    <div class="part-box part-box-filter">
+      <Form ref="FilterForm" label-position="left" inline>
+        <FormItem>
+          <Select
+            v-model="filter.areaCode"
+            @on-change="areaChange"
+            placeholder="考区"
+            clearable
+          >
+            <Option
+              v-for="area in cascadeList"
+              :key="area.areaCode"
+              :value="area.areaCode"
+              :label="area.areaName"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select
+            v-model="filter.school"
+            @on-change="schoolChange"
+            placeholder="学校"
+            filterable
+            clearable
+          >
+            <Option
+              v-for="(item, index) in schools"
+              :key="index"
+              :value="item.school"
+              :label="item.school"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select v-model="filter.examRoom" placeholder="考场" clearable>
+            <Option
+              v-for="(room, index) in rooms"
+              :key="index"
+              :value="room"
+              :label="room"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Input
+            v-model="filter.startNumber"
+            type="text"
+            placeholder="输入开始编号"
+            clearable
+          />
+        </FormItem>
+        <FormItem>
+          <Input
+            v-model="filter.endNumber"
+            type="text"
+            placeholder="输入结束编号"
+            clearable
+          />
+        </FormItem>
+        <FormItem>
+          <Input
+            v-model.trim="filter.studentName"
+            placeholder="输入姓名"
+            clearable
+          ></Input>
+        </FormItem>
+        <FormItem>
+          <Select v-model="filter.isAbsent" placeholder="是否缺考" clearable>
+            <Option
+              v-for="(val, key) in BOOLEAN_TYPE"
+              :key="key"
+              :value="key * 1"
+              >{{ val }}</Option
+            >
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select v-model="filter.upload" placeholder="是否上传" clearable>
+            <Option
+              v-for="(val, key) in PAPER_UPLOAD_TYPE"
+              :key="key"
+              :value="key * 1"
+              >{{ val }}</Option
+            >
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select v-model="filter.subject" placeholder="科目" clearable>
+            <Option
+              v-for="item in subjects"
+              :key="item.subject"
+              :value="item.subject"
+              :label="item.name"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Button
+            size="small"
+            class="btn-form-search"
+            type="primary"
+            @click="toPage(1)"
+            >查询</Button
+          >
+        </FormItem>
+      </Form>
+    </div>
+    <Table
+      ref="TableList"
+      :columns="columns"
+      :data="students"
+      disabled-hover
+      border
+    ></Table>
+
+    <div class="part-page" v-if="total > size">
+      <Page
+        :current="current"
+        :total="total"
+        :page-size="size"
+        show-total
+        show-elevator
+        @on-change="toPage"
+      ></Page>
+    </div>
+
+    <!-- import student  -->
+    <import-file
+      title="导入考生信息"
+      :upload-url="uploadStudentUrl"
+      :upload-data="uploadData"
+      :download-url="downloadStudentTemplateUrl"
+      :download-filename="downloadStudentTemplateFilename"
+      :headers="headers"
+      :format="['xls', 'xlsx']"
+      @upload-success="uploadSuccess"
+      ref="ExportStudent"
+    >
+    </import-file>
+    <!-- import-relate -->
+    <import-file
+      title="导入关联信息"
+      :upload-url="uploadRelateUrl"
+      :upload-data="uploadData"
+      :download-url="downloadRelateTemplateUrl"
+      :download-filename="downloadRelateTemplateFilename"
+      :headers="headers"
+      :format="['xls', 'xlsx']"
+      ref="ExportRelate"
+    >
+    </import-file>
+    <!-- modify-student -->
+    <modify-student
+      :cascade-list="cascadeList"
+      :instance="curStudent"
+      @modified="getList"
+      @on-close="getAreaList"
+      ref="ModifyStudent"
+    ></modify-student>
+  </div>
+</template>
+
+<script>
+import {
+  subjectList,
+  studentPageList,
+  deleteStudent,
+  areaSchoolRoomCascadeList
+} from "@/api";
+import ImportFile from "@/components/common/ImportFile";
+import ModifyStudent from "./components/ModifyStudent";
+import { BOOLEAN_TYPE, PAPER_UPLOAD_TYPE } from "@/constants/enumerate";
+import qs from "qs";
+
+export default {
+  name: "students",
+  components: { ImportFile, ModifyStudent },
+  data() {
+    return {
+      filter: {
+        workId: this.$route.params.workId,
+        subject: null,
+        areaCode: null,
+        school: "",
+        examRoom: "",
+        startNumber: null,
+        endNumber: null,
+        studentName: "",
+        upload: null,
+        isAbsent: null
+      },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      students: [],
+      curStudent: {},
+      subjects: [],
+      cascadeList: [],
+      schools: [],
+      rooms: [],
+      BOOLEAN_TYPE,
+      PAPER_UPLOAD_TYPE,
+      columns: [
+        {
+          type: "index",
+          title: "序号",
+          width: 80,
+          align: "center",
+          indexMethod: row => {
+            return (this.current - 1) * this.size + row._index + 1;
+          }
+        },
+        {
+          title: "姓名",
+          key: "name",
+          width: 100
+        },
+        {
+          title: "考号",
+          key: "examNumber",
+          minWidth: 120
+        },
+        // {
+        //   title: "关联考号",
+        //   key: "relateExamNumber",
+        //   minWidth: 120
+        // },
+        {
+          title: "考区",
+          key: "areaName",
+          minWidth: 120
+        },
+        {
+          title: "学校",
+          key: "school",
+          minWidth: 150
+        },
+        {
+          title: "考场",
+          key: "examRoom",
+          minWidth: 100
+        },
+        {
+          title: "操作",
+          key: "action",
+          width: 100,
+          align: "center",
+          className: "table-action",
+          render: (h, param) => {
+            let actions = [];
+
+            if (param.row.canEdit) {
+              actions.push({
+                icon: "md-create",
+                attrs: {
+                  title: "编辑"
+                },
+                action: () => {
+                  this.toEdit(param.row);
+                }
+              });
+            }
+            if (param.row.canDelete) {
+              actions.push({
+                icon: "md-trash",
+                classes: ["icon-danger"],
+                attrs: {
+                  title: "删除"
+                },
+                action: () => {
+                  this.toDelete(param.row);
+                }
+              });
+            }
+
+            return h("div", this.$tableIconAction(h, actions));
+          }
+        }
+      ],
+      // upload
+      headers: {
+        Authorization: this.$ls.get("user", { token: "" }).token,
+        workId: this.$route.params.workId,
+        userId: this.$ls.get("user", { id: "" }).id
+      },
+      uploadData: {
+        workId: this.$route.params.workId
+      },
+      uploadStudentUrl: this.GLOBAL.domain + "/api/import/students",
+      downloadStudentTemplateUrl: "/templates/考生信息表-模板.xlsx",
+      downloadStudentTemplateFilename: "考生信息表-模板.xlsx",
+      uploadRelateUrl: "/api/import/students/relateStudent",
+      downloadRelateTemplateUrl: "/templates/关联考生信息表-模板.xlsx",
+      downloadRelateTemplateFilename: "关联考生信息表-模板.xlsx"
+    };
+  },
+  mounted() {
+    this.iniData();
+  },
+  methods: {
+    async iniData() {
+      await this.getSubjects();
+      this.getAreaList();
+      this.getList();
+    },
+    async getList() {
+      const datas = {
+        ...this.filter,
+        page: this.current - 1,
+        size: this.size
+      };
+      // if (
+      //   ((datas.upload || datas.upload === 0) && !datas.subject) ||
+      //   (!datas.upload && datas.upload !== 0 && datas.subject)
+      // ) {
+      //   this.$Message.error("上传状态和科目必须同时选择!");
+      //   return;
+      // }
+      // if (datas.subject === "ONE") datas.subject = null;
+      const data = await studentPageList(datas);
+      this.students = data.data.map(student => {
+        student.uploadStatus.split(",").map(status => {
+          const [subjectCode, subjectUploadStatus] = status.split(":");
+          student[subjectCode] = subjectUploadStatus * 1;
+        });
+        student.canEdit = student.uploadStatus.includes("0");
+        student.canDelete = !student.uploadStatus.includes("1");
+        student.uploadStatus.split(",").map(status => {
+          const [subject, hasScan] = status.split(":");
+          student[subject] = hasScan;
+        });
+        student.workId = this.filter.workId;
+        student.relateExamNumber =
+          student.relateExamNumber === student.examNumber
+            ? "--"
+            : student.relateExamNumber;
+        return student;
+      });
+      this.total = data.totalCount;
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    },
+    async getAreaList() {
+      this.cascadeList = await areaSchoolRoomCascadeList(this.filter.workId);
+    },
+    async getSubjects() {
+      const data = await subjectList(this.filter.workId);
+      this.subjects = data.filter(item => item.enable);
+      this.subjects.map(item => {
+        const column = {
+          title: item.name,
+          key: item.subject,
+          minWidth: 80
+        };
+        this.columns.splice(this.columns.length - 1, 0, column);
+      });
+      this.subjects.unshift({
+        subject: "ONE",
+        name: "查漏"
+      });
+    },
+    areaChange() {
+      const curArea = this.cascadeList.find(
+        item => item.areaCode === this.filter.areaCode
+      );
+      this.schools = curArea ? curArea.schools : [];
+      this.rooms = [];
+      this.filter.school = null;
+      this.filter.examRoom = null;
+      if (curArea.schools.length === 1) {
+        this.filter.school = curArea.schools[0].school;
+        this.schoolChange();
+      }
+    },
+    schoolChange() {
+      const curSchool = this.schools.find(
+        item => item.school === this.filter.school
+      );
+      this.rooms = curSchool ? curSchool.rooms : [];
+      this.filter.examRoom = null;
+    },
+    uploadSuccess() {
+      this.getList();
+      this.getAreaList();
+      this.$Notice.success({
+        title: "导入提示",
+        desc: "考生信息导入成功!",
+        duration: 0
+      });
+    },
+    toAdd() {
+      this.curStudent = { workId: this.filter.workId };
+      this.$refs.ModifyStudent.open();
+    },
+    toEdit(row) {
+      this.curStudent = row;
+      this.$refs.ModifyStudent.open();
+    },
+    toDelete(row) {
+      this.$Modal.confirm({
+        width: 340,
+        content: "确定要删除该考生吗?",
+        onOk: () => {
+          this.toDel(row.id);
+        }
+      });
+    },
+    async toDel(id) {
+      await deleteStudent(id);
+      this.$Message.success("删除成功!");
+      this.deletePageLastItem();
+    },
+    toExport() {
+      const sqDatas = qs.stringify(this.filter, {
+        arrayFormat: "brackets"
+      });
+      window.open(
+        this.urlAddAuthor(`${this.GLOBAL.domain}/api/export/student?${sqDatas}`)
+      );
+    }
+  }
+};
+</script>

+ 137 - 117
src/modules/mark-set/MarkRuleSet.vue

@@ -1,117 +1,137 @@
-<template>
-  <div class="mark-rule-set part-box">
-    <Form
-      ref="modalFormComp"
-      :model="modalForm"
-      :label-width="230"
-      style="width: 400px"
-    >
-      <FormItem label="分数处理方式:">
-        <Select
-          v-model="modalForm.roundUp"
-          :disabled="!modalFormCanEdit"
-          placeholder="选择"
-        >
-          <Option
-            v-for="(val, key) in SCORE_HANDLE_TYPE"
-            :key="key"
-            :value="key * 1"
-            >{{ val }}</Option
-          >
-        </Select>
-      </FormItem>
-      <FormItem label="阅卷员是否显示改档及改档打分:">
-        <Select
-          v-model="modalForm.changeStage"
-          :disabled="!modalFormCanEdit"
-          placeholder="选择"
-        >
-          <Option
-            v-for="(val, key) in BOOLEAN_TYPE"
-            :key="key"
-            :value="key * 1"
-            :label="val"
-          ></Option>
-        </Select>
-      </FormItem>
-      <FormItem label="阅卷员是否显示所有试卷:">
-        <Select
-          v-model="modalForm.scoreShowAllPaper"
-          :disabled="!modalFormCanEdit"
-          placeholder="选择"
-        >
-          <Option
-            v-for="(val, key) in BOOLEAN_TYPE"
-            :key="key"
-            :value="key * 1"
-            :label="val"
-          ></Option>
-        </Select>
-      </FormItem>
-      <FormItem>
-        <Button
-          shape="circle"
-          style="width: 80px;"
-          @click="modalFormCanEdit = true"
-          >编辑</Button
-        >
-        <Button
-          type="primary"
-          shape="circle"
-          style="width: 80px;"
-          :disabled="isSubmit"
-          @click="submit"
-          >保存</Button
-        >
-      </FormItem>
-    </Form>
-  </div>
-</template>
-
-<script>
-import { getParamsSet, updateScoreParams } from "@/api";
-import { BOOLEAN_TYPE, SCORE_HANDLE_TYPE } from "@/constants/enumerate";
-
-export default {
-  name: "mark-rule-set",
-  data() {
-    return {
-      isSubmit: false,
-      workId: this.$route.params.workId,
-      BOOLEAN_TYPE,
-      SCORE_HANDLE_TYPE,
-      initModalForm: {
-        workId: "",
-        roundUp: 0,
-        changeStage: 0,
-        scoreShowAllPaper: 0
-      },
-      modalFormCanEdit: false,
-      modalForm: {}
-    };
-  },
-  mounted() {
-    this.modalForm = { ...this.initModalForm };
-    this.getParamsSetInfo();
-  },
-  methods: {
-    async getParamsSetInfo() {
-      const data = await getParamsSet(this.workId);
-      this.modalForm = this.$objAssign(this.modalForm, data);
-    },
-    async submit() {
-      if (this.isSubmit) return;
-      this.isSubmit = true;
-      let result = true;
-      await updateScoreParams(this.modalForm).catch(() => {
-        result = false;
-      });
-      this.isSubmit = false;
-
-      if (!result) return;
-      this.modalFormCanEdit = false;
-      this.$Message.success("保存成功!");
-    }
-  }
-};
-</script>
+<template>
+  <div class="mark-rule-set part-box">
+    <Form
+      ref="modalFormComp"
+      :model="modalForm"
+      :label-width="230"
+      style="width: 400px"
+    >
+      <FormItem label="分数计算方式:">
+        <Select
+          v-model="modalForm.calcType"
+          :disabled="!modalFormCanEdit"
+          placeholder="选择"
+        >
+          <Option
+            v-for="(val, key) in SCORE_CALC_TYPE"
+            :key="key"
+            :value="key * 1"
+            >{{ val }}</Option
+          >
+        </Select>
+      </FormItem>
+      <FormItem label="分数处理方式:">
+        <Select
+          v-model="modalForm.roundUp"
+          :disabled="!modalFormCanEdit"
+          placeholder="选择"
+        >
+          <Option
+            v-for="(val, key) in SCORE_HANDLE_TYPE"
+            :key="key"
+            :value="key * 1"
+            >{{ val }}</Option
+          >
+        </Select>
+      </FormItem>
+      <FormItem label="阅卷员是否显示改档及改档打分:">
+        <Select
+          v-model="modalForm.changeStage"
+          :disabled="!modalFormCanEdit"
+          placeholder="选择"
+        >
+          <Option
+            v-for="(val, key) in BOOLEAN_TYPE"
+            :key="key"
+            :value="key * 1"
+            :label="val"
+          ></Option>
+        </Select>
+      </FormItem>
+      <FormItem label="阅卷员是否显示所有试卷:">
+        <Select
+          v-model="modalForm.scoreShowAllPaper"
+          :disabled="!modalFormCanEdit"
+          placeholder="选择"
+        >
+          <Option
+            v-for="(val, key) in BOOLEAN_TYPE"
+            :key="key"
+            :value="key * 1"
+            :label="val"
+          ></Option>
+        </Select>
+      </FormItem>
+      <FormItem>
+        <Button
+          shape="circle"
+          style="width: 80px;"
+          @click="modalFormCanEdit = true"
+          >编辑</Button
+        >
+        <Button
+          type="primary"
+          shape="circle"
+          style="width: 80px;"
+          :disabled="isSubmit"
+          @click="submit"
+          >保存</Button
+        >
+      </FormItem>
+    </Form>
+  </div>
+</template>
+
+<script>
+import { getParamsSet, updateScoreParams } from "@/api";
+import {
+  BOOLEAN_TYPE,
+  SCORE_HANDLE_TYPE,
+  SCORE_CALC_TYPE
+} from "@/constants/enumerate";
+
+export default {
+  name: "mark-rule-set",
+  data() {
+    return {
+      isSubmit: false,
+      workId: this.$route.params.workId,
+      BOOLEAN_TYPE,
+      SCORE_HANDLE_TYPE,
+      SCORE_CALC_TYPE,
+      initModalForm: {
+        workId: "",
+        calcType: 0,
+        roundUp: 0,
+        changeStage: 0,
+        scoreShowAllPaper: 0
+      },
+      modalFormCanEdit: false,
+      modalForm: {}
+    };
+  },
+  mounted() {
+    this.modalForm = { ...this.initModalForm };
+    this.getParamsSetInfo();
+  },
+  methods: {
+    async getParamsSetInfo() {
+      const data = await getParamsSet(this.workId);
+      this.modalForm = this.$objAssign(this.modalForm, data);
+    },
+    async submit() {
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      let result = true;
+      await updateScoreParams(this.modalForm).catch(() => {
+        result = false;
+      });
+      this.isSubmit = false;
+
+      if (!result) return;
+      this.modalFormCanEdit = false;
+      this.$Message.success("保存成功!");
+    }
+  }
+};
+</script>